1 /*
   2  * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef CPU_ARM_ASSEMBLER_ARM_32_HPP
  26 #define CPU_ARM_ASSEMBLER_ARM_32_HPP
  27 
  28 // ARM Addressing Mode 1 - Data processing operands
  29 class AsmOperand {
  30  private:
  31   int _encoding;
  32 
  33   void initialize_rotated_imm(unsigned int imm);
  34 
  35   void encode(int imm_8) {
  36     if ((imm_8 >> 8) == 0) {
  37       _encoding = 1 << 25 | imm_8;  // the most common case
  38     } else {
  39       initialize_rotated_imm((unsigned int)imm_8);  // slow case
  40     }
  41   }
  42 
  43   void encode(Register rm, AsmShift shift, int shift_imm) {
  44     assert((shift_imm >> 5) == 0, "encoding constraint");
  45     _encoding = shift_imm << 7 | shift << 5 | rm->encoding();
  46   }
  47 
  48  public:
  49 
  50   AsmOperand(Register reg) {
  51     _encoding = reg->encoding();
  52   }
  53 
  54   AsmOperand(int imm_8) {
  55     encode(imm_8);
  56   }
  57 
  58 #ifdef ASSERT
  59   AsmOperand(ByteSize bytesize_8) {
  60     const int imm_8 = in_bytes(bytesize_8);
  61     encode(imm_8);
  62   }
  63 #endif // ASSERT
  64 
  65   AsmOperand(Register rm, AsmShift shift, int shift_imm) {
  66     encode(rm,shift,shift_imm);
  67   }
  68 
  69   AsmOperand(Register rm, AsmShift shift, Register rs) {
  70     assert(rm != PC && rs != PC, "unpredictable instruction");
  71     _encoding = rs->encoding() << 8 | shift << 5 | 1 << 4 | rm->encoding();
  72   }
  73 
  74   AsmOperand(RegisterOrConstant offset, AsmShift shift = lsl, int shift_imm = 0) {
  75     if (offset.is_register()) {
  76       encode(offset.as_register(), shift, shift_imm);
  77     } else {
  78       assert(shift == lsl,"shift type not yet encoded");
  79       int imm_8 = ((int)offset.as_constant()) << shift_imm;
  80       encode(imm_8);
  81     }
  82   }
  83 
  84   int encoding() const {
  85     return _encoding;
  86   }
  87 
  88   bool is_immediate() const {
  89     return _encoding & (1 << 25) ? true : false;
  90   }
  91 
  92   Register base_register() const {
  93     assert(!is_immediate(), "is_immediate, no base reg");
  94     return as_Register(_encoding & 15);
  95   }
  96 
  97   static bool is_rotated_imm(unsigned int imm);
  98 };
  99 
 100 
 101 // ARM Addressing Mode 4 - Load and store multiple
 102 class RegisterSet {
 103  private:
 104   int _encoding;
 105 
 106   RegisterSet(int encoding) {
 107     _encoding = encoding;
 108   }
 109 
 110  public:
 111 
 112   RegisterSet(Register reg) {
 113     _encoding = 1 << reg->encoding();
 114   }
 115 
 116   RegisterSet() {
 117     _encoding = 0;
 118   }
 119 
 120   RegisterSet(Register first, Register last) {
 121     assert(first < last, "encoding constraint");
 122     _encoding = (1 << (last->encoding() + 1)) - (1 << first->encoding());
 123   }
 124 
 125   friend RegisterSet operator | (const RegisterSet set1, const RegisterSet set2) {
 126     assert((set1._encoding & set2._encoding) == 0,
 127            "encoding constraint");
 128     return RegisterSet(set1._encoding | set2._encoding);
 129   }
 130 
 131   int encoding() const {
 132     return _encoding;
 133   }
 134 
 135   bool contains(Register reg) const {
 136     return (_encoding & (1 << reg->encoding())) != 0;
 137   }
 138 
 139   // number of registers in the set
 140   int size() const {
 141     int count = 0;
 142     unsigned int remaining = (unsigned int) _encoding;
 143     while (remaining != 0) {
 144       if ((remaining & 1) != 0) count++;
 145       remaining >>= 1;
 146     }
 147     return count;
 148   }
 149 };
 150 
 151 #if R9_IS_SCRATCHED
 152 #define R9ifScratched RegisterSet(R9)
 153 #else
 154 #define R9ifScratched RegisterSet()
 155 #endif
 156 
 157 // ARM Addressing Mode 5 - Load and store multiple VFP registers
 158 class FloatRegisterSet {
 159  private:
 160   int _encoding;
 161 
 162  public:
 163 
 164   FloatRegisterSet(FloatRegister reg) {
 165     if (reg->hi_bit() == 0) {
 166       _encoding = reg->hi_bits() << 12 | reg->lo_bit() << 22 | 1;
 167     } else {
 168       assert (reg->lo_bit() == 0, "impossible encoding");
 169       _encoding = reg->hi_bits() << 12 | reg->hi_bit() << 22 | 1;
 170     }
 171   }
 172 
 173   FloatRegisterSet(FloatRegister first, int count) {
 174     assert(count >= 1, "encoding constraint");
 175     if (first->hi_bit() == 0) {
 176       _encoding = first->hi_bits() << 12 | first->lo_bit() << 22 | count;
 177     } else {
 178       assert (first->lo_bit() == 0, "impossible encoding");
 179       _encoding = first->hi_bits() << 12 | first->hi_bit() << 22 | count;
 180     }
 181   }
 182 
 183   int encoding_s() const {
 184     return _encoding;
 185   }
 186 
 187   int encoding_d() const {
 188     assert((_encoding & 0xFF) <= 16, "no more than 16 double registers" );
 189     return (_encoding & 0xFFFFFF00) | ((_encoding & 0xFF) << 1);
 190   }
 191 
 192 };
 193 
 194 
 195 class Assembler : public AbstractAssembler  {
 196 
 197  public:
 198 
 199   static const int LogInstructionSize = 2;
 200   static const int InstructionSize    = 1 << LogInstructionSize;
 201 
 202   //---<  calculate length of instruction  >---
 203   // We just use the values set above.
 204   // instruction must start at passed address
 205   static unsigned int instr_len(unsigned char *instr) { return InstructionSize; }
 206 
 207   //---<  longest instructions  >---
 208   static unsigned int instr_maxlen() { return InstructionSize; }
 209 
 210   static inline AsmCondition inverse(AsmCondition cond) {
 211     assert ((cond != al) && (cond != nv), "AL and NV conditions cannot be inversed");
 212     return (AsmCondition)((int)cond ^ 1);
 213   }
 214 
 215   // Returns true if given value can be used as immediate in arithmetic (add/sub/cmp/cmn) instructions.
 216   static inline bool is_arith_imm_in_range(intx value) {
 217     return AsmOperand::is_rotated_imm(value);
 218   }
 219 
 220   // Arithmetic instructions
 221 
 222 #define F(mnemonic, opcode) \
 223   void mnemonic(Register rd, Register rn, AsmOperand operand, AsmCondition cond = al) {    \
 224     emit_int32(cond << 28 | opcode << 21 | rn->encoding() << 16 |                          \
 225                rd->encoding() << 12 | operand.encoding());                                 \
 226   }                                                                                        \
 227   void mnemonic##s(Register rd, Register rn, AsmOperand operand, AsmCondition cond = al) { \
 228     emit_int32(cond << 28 | opcode << 21 | 1 << 20 | rn->encoding() << 16 |                \
 229                rd->encoding() << 12 | operand.encoding());                                 \
 230   }
 231 
 232   F(andr, 0)
 233   F(eor,  1)
 234   F(sub,  2)
 235   F(rsb,  3)
 236   F(add,  4)
 237   F(adc,  5)
 238   F(sbc,  6)
 239   F(rsc,  7)
 240   F(orr,  12)
 241   F(bic,  14)
 242 #undef F
 243 
 244 #define F(mnemonic, opcode) \
 245   void mnemonic(Register rn, AsmOperand operand, AsmCondition cond = al) {  \
 246     emit_int32(cond << 28 | opcode << 21 | 1 << 20 | rn->encoding() << 16 | \
 247               operand.encoding());                                          \
 248   }
 249 
 250   F(tst, 8)
 251   F(teq, 9)
 252   F(cmp, 10)
 253   F(cmn, 11)
 254 #undef F
 255 
 256 #define F(mnemonic, opcode) \
 257   void mnemonic(Register rd, AsmOperand operand, AsmCondition cond = al) {    \
 258     emit_int32(cond << 28 | opcode << 21 | rd->encoding() << 12 |             \
 259               operand.encoding());                                            \
 260   }                                                                           \
 261   void mnemonic##s(Register rd, AsmOperand operand, AsmCondition cond = al) { \
 262     emit_int32(cond << 28 | opcode << 21 | 1 << 20 | rd->encoding() << 12 |   \
 263               operand.encoding());                                            \
 264   }
 265 
 266   F(mov, 13)
 267   F(mvn, 15)
 268 #undef F
 269 
 270   void msr(uint fields, AsmOperand operand, AsmCondition cond = al) {
 271     assert((operand.encoding() & (1<<25)) || ((operand.encoding() & 0xff0) == 0), "invalid addressing mode");
 272     emit_int32(cond << 28 | 1 << 24 | 1 << 21 | fields << 16 | 0xf << 12 | operand.encoding());
 273   }
 274 
 275   void mrs(uint fields, Register Rd, AsmCondition cond = al) {
 276     emit_int32(cond << 28 | 1 << 24 | (fields|0xf) << 16 | (Rd->encoding() << 12));
 277   }
 278 
 279 
 280   enum {
 281     CPSR = 0x00, CPSR_c = 0x01, CPSR_x = 0x02, CPSR_xc = 0x03,
 282     CPSR_s = 0x004, CPSR_sc = 0x05, CPSR_sx = 0x06, CPSR_sxc = 0x07,
 283     CPSR_f = 0x08, CPSR_fc = 0x09, CPSR_fx = 0x0a, CPSR_fxc = 0x0b,
 284     CPSR_fs = 0x0c, CPSR_fsc = 0x0d, CPSR_fsx = 0x0e, CPSR_fsxc = 0x0f,
 285     SPSR = 0x40, SPSR_c = 0x41, SPSR_x = 0x42, SPSR_xc = 0x43,
 286     SPSR_s = 0x44, SPSR_sc = 0x45, SPSR_sx = 0x46, SPSR_sxc = 0x47,
 287     SPSR_f = 0x48, SPSR_fc = 0x49, SPSR_fx = 0x4a, SPSR_fxc = 0x4b,
 288     SPSR_fs = 0x4c, SPSR_fsc = 0x4d, SPSR_fsx = 0x4e, SPSR_fsxc = 0x4f
 289   };
 290 
 291 #define F(mnemonic, opcode) \
 292   void mnemonic(Register rdlo, Register rdhi, Register rm, Register rs,                  \
 293                 AsmCondition cond = al) {                                                \
 294     emit_int32(cond << 28 | opcode << 21 | rdhi->encoding() << 16 |                      \
 295               rdlo->encoding() << 12 | rs->encoding() << 8 | 0x9 << 4 | rm->encoding()); \
 296   }                                                                                      \
 297   void mnemonic##s(Register rdlo, Register rdhi, Register rm, Register rs,               \
 298                    AsmCondition cond = al) {                                             \
 299     emit_int32(cond << 28 | opcode << 21 | 1 << 20 | rdhi->encoding() << 16 |            \
 300               rdlo->encoding() << 12 | rs->encoding() << 8 | 0x9 << 4 | rm->encoding()); \
 301   }
 302 
 303   F(umull, 4)
 304   F(umlal, 5)
 305   F(smull, 6)
 306   F(smlal, 7)
 307 #undef F
 308 
 309   void mul(Register rd, Register rm, Register rs, AsmCondition cond = al) {
 310     emit_int32(cond << 28 | rd->encoding() << 16 |
 311               rs->encoding() << 8 | 0x9 << 4 | rm->encoding());
 312   }
 313 
 314   void muls(Register rd, Register rm, Register rs, AsmCondition cond = al) {
 315     emit_int32(cond << 28 | 1 << 20 | rd->encoding() << 16 |
 316               rs->encoding() << 8 | 0x9 << 4 | rm->encoding());
 317   }
 318 
 319   void mla(Register rd, Register rm, Register rs, Register rn, AsmCondition cond = al) {
 320     emit_int32(cond << 28 | 1 << 21 | rd->encoding() << 16 |
 321               rn->encoding() << 12 | rs->encoding() << 8 | 0x9 << 4 | rm->encoding());
 322   }
 323 
 324   void mlas(Register rd, Register rm, Register rs, Register rn, AsmCondition cond = al) {
 325     emit_int32(cond << 28 | 1 << 21 | 1 << 20 | rd->encoding() << 16 |
 326               rn->encoding() << 12 | rs->encoding() << 8 | 0x9 << 4 | rm->encoding());
 327   }
 328 
 329   // Loads and stores
 330 
 331 #define F(mnemonic, l, b) \
 332   void mnemonic(Register rd, Address addr, AsmCondition cond = al) { \
 333     emit_int32(cond << 28 | 1 << 26 | b << 22 | l << 20 |            \
 334               rd->encoding() << 12 | addr.encoding2());              \
 335   }
 336 
 337   F(ldr,  1, 0)
 338   F(ldrb, 1, 1)
 339   F(str,  0, 0)
 340   F(strb, 0, 1)
 341 #undef F
 342 
 343 #undef F
 344 
 345 #define F(mnemonic, l, sh, even) \
 346   void mnemonic(Register rd, Address addr, AsmCondition cond = al) { \
 347     assert(!even || (rd->encoding() & 1) == 0, "must be even");      \
 348     emit_int32(cond << 28 | l << 20 | rd->encoding() << 12 |         \
 349               1 << 7 | sh << 5 | 1 << 4 | addr.encoding3());         \
 350   }
 351 
 352   F(strh,  0, 1, false)
 353   F(ldrh,  1, 1, false)
 354   F(ldrsb, 1, 2, false)
 355   F(ldrsh, 1, 3, false)
 356   F(strd,  0, 3, true)
 357 
 358 #undef F
 359 
 360   void ldrd(Register rd, Address addr, AsmCondition cond = al) {
 361     assert((rd->encoding() & 1) == 0, "must be even");
 362     assert(!addr.index()->is_valid() ||
 363            (addr.index()->encoding() != rd->encoding() &&
 364             addr.index()->encoding() != (rd->encoding()+1)), "encoding constraint");
 365     emit_int32(cond << 28 | rd->encoding() << 12 | 0xD /* 0b1101 */ << 4 | addr.encoding3());
 366   }
 367 
 368 #define F(mnemonic, l, pu) \
 369   void mnemonic(Register rn, RegisterSet reg_set,                        \
 370                 AsmWriteback w = no_writeback, AsmCondition cond = al) { \
 371     assert(reg_set.encoding() != 0 && (w == no_writeback ||              \
 372            (reg_set.encoding() & (1 << rn->encoding())) == 0),           \
 373            "unpredictable instruction");                                 \
 374     emit_int32(cond << 28 | 4 << 25 | pu << 23 | w << 21 | l << 20 |     \
 375               rn->encoding() << 16 | reg_set.encoding());                \
 376   }
 377 
 378   F(ldmda, 1, 0)    F(ldmfa, 1, 0)
 379   F(ldmia, 1, 1)    F(ldmfd, 1, 1)
 380   F(ldmdb, 1, 2)    F(ldmea, 1, 2)
 381   F(ldmib, 1, 3)    F(ldmed, 1, 3)
 382   F(stmda, 0, 0)    F(stmed, 0, 0)
 383   F(stmia, 0, 1)    F(stmea, 0, 1)
 384   F(stmdb, 0, 2)    F(stmfd, 0, 2)
 385   F(stmib, 0, 3)    F(stmfa, 0, 3)
 386 #undef F
 387 
 388   void ldrex(Register rd, Address addr, AsmCondition cond = al) {
 389     assert(rd != PC, "unpredictable instruction");
 390     emit_int32(cond << 28 | 0x19 << 20 | addr.encoding_ex() |
 391               rd->encoding()  << 12 | 0xf9f);
 392   }
 393 
 394   void strex(Register rs, Register rd, Address addr, AsmCondition cond = al) {
 395     assert(rd != PC && rs != PC &&
 396            rs != rd && rs != addr.base(), "unpredictable instruction");
 397     emit_int32(cond << 28 | 0x18 << 20 | addr.encoding_ex() |
 398               rs->encoding()  << 12 | 0xf90 | rd->encoding());
 399   }
 400 
 401   void ldrexd(Register rd, Address addr, AsmCondition cond = al) {
 402     assert(rd != PC, "unpredictable instruction");
 403     emit_int32(cond << 28 | 0x1B << 20 | addr.encoding_ex() |
 404               rd->encoding()  << 12 | 0xf9f);
 405   }
 406 
 407   void strexd(Register rs, Register rd, Address addr, AsmCondition cond = al) {
 408     assert(rd != PC && rs != PC &&
 409            rs != rd && rs != addr.base(), "unpredictable instruction");
 410     emit_int32(cond << 28 | 0x1A << 20 | addr.encoding_ex() |
 411               rs->encoding()  << 12 | 0xf90 | rd->encoding());
 412   }
 413 
 414   void clrex() {
 415     emit_int32(0xF << 28 | 0x57 << 20 | 0xFF  << 12 | 0x01f);
 416   }
 417 
 418   // Miscellaneous instructions
 419 
 420   void clz(Register rd, Register rm, AsmCondition cond = al) {
 421     emit_int32(cond << 28 | 0x016f0f10 | rd->encoding() << 12 | rm->encoding());
 422   }
 423 
 424   void rev(Register rd, Register rm, AsmCondition cond = al) {
 425     emit_int32(cond << 28 | 0x06bf0f30 | rd->encoding() << 12 | rm->encoding());
 426   }
 427 
 428   void rev16(Register rd, Register rm, AsmCondition cond = al) {
 429     emit_int32(cond << 28 | 0x6bf0fb0 | rd->encoding() << 12 | rm->encoding());
 430   }
 431 
 432   void revsh(Register rd, Register rm, AsmCondition cond = al) {
 433     emit_int32(cond << 28 | 0x6ff0fb0 | rd->encoding() << 12 | rm->encoding());
 434   }
 435 
 436   void rbit(Register rd, Register rm, AsmCondition cond = al) {
 437     emit_int32(cond << 28 | 0x6ff0f30 | rd->encoding() << 12 | rm->encoding());
 438   }
 439 
 440   void pld(Address addr) {
 441     emit_int32(0xf550f000 | addr.encoding2());
 442   }
 443 
 444   void pldw(Address addr) {
 445     assert(!VM_Version::is_initialized() ||
 446            (VM_Version::arm_arch() >= 7 && VM_Version::has_multiprocessing_extensions()),
 447            "PLDW is available on ARMv7 with Multiprocessing Extensions only");
 448     emit_int32(0xf510f000 | addr.encoding2());
 449   }
 450 
 451   void svc(int imm_24, AsmCondition cond = al) {
 452     assert((imm_24 >> 24) == 0, "encoding constraint");
 453     emit_int32(cond << 28 | 0xf << 24 | imm_24);
 454   }
 455 
 456   void ubfx(Register rd, Register rn, unsigned int lsb, unsigned int width, AsmCondition cond = al) {
 457     assert(VM_Version::arm_arch() >= 7, "no ubfx on this processor");
 458     assert(width > 0, "must be");
 459     assert(lsb < 32, "must be");
 460     emit_int32(cond << 28 | 0x3f << 21 | (width - 1)  << 16 | rd->encoding() << 12 |
 461               lsb << 7 | 0x5 << 4 | rn->encoding());
 462   }
 463 
 464   void uxtb(Register rd, Register rm, unsigned int rotation = 0, AsmCondition cond = al) {
 465     assert(VM_Version::arm_arch() >= 7, "no uxtb on this processor");
 466     assert((rotation % 8) == 0 && (rotation <= 24), "encoding constraint");
 467     emit_int32(cond << 28 | 0x6e << 20 | 0xf << 16 | rd->encoding() << 12 |
 468               (rotation >> 3) << 10 | 0x7 << 4 | rm->encoding());
 469   }
 470 
 471   // ARM Memory Barriers
 472   //
 473   // There are two types of memory barriers defined for the ARM processor
 474   // DataSynchronizationBarrier and DataMemoryBarrier
 475   //
 476   // The Linux kernel uses the DataMemoryBarrier for all of it's
 477   // memory barrier operations (smp_mb, smp_rmb, smp_wmb)
 478   //
 479   // There are two forms of each barrier instruction.
 480   // The mcr forms are supported on armv5 and newer architectures
 481   //
 482   // The dmb, dsb instructions were added in armv7
 483   // architectures and are compatible with their mcr
 484   // predecessors.
 485   //
 486   // Here are the encodings for future reference:
 487   //
 488   // DataSynchronizationBarrier (dsb)
 489   // on ARMv7 - emit_int32(0xF57FF04F)
 490   //
 491   // on ARMv5+ - mcr p15, 0, Rtmp, c7, c10, 4  on earlier processors
 492   //             emit_int32(0xe << 28 | 0xe << 24 | 0x7 << 16 | Rtmp->encoding() << 12  |
 493   //                       0xf << 8  | 0x9 << 4  | 0xa);
 494   //
 495   // DataMemoryBarrier (dmb)
 496   // on ARMv7 - emit_int32(0xF57FF05F)
 497   //
 498   // on ARMv5+ - mcr p15, 0, Rtmp, c7, c10, 5 on earlier processors
 499   //             emit_int32(0xe << 28 | 0xe << 24 | 0x7 << 16 | Rtmp->encoding() << 12  |
 500   //                       0xf << 8  | 0xb << 4  | 0xa);
 501   //
 502 
 503   enum DMB_Opt {
 504     DMB_all = 0xf,
 505     DMB_st  = 0xe,
 506   };
 507 
 508   void dmb(DMB_Opt opt, Register reg) {
 509     if (VM_Version::arm_arch() >= 7) {
 510       emit_int32(0xF57FF050 | opt);
 511     } else if (VM_Version::arm_arch() == 6) {
 512       bool preserve_tmp = (reg == noreg);
 513       if(preserve_tmp) {
 514         reg = Rtemp;
 515         str(reg, Address(SP, -wordSize, pre_indexed));
 516       }
 517       mov(reg, 0);
 518       // DataMemoryBarrier
 519       emit_int32(0xe << 28 |
 520                 0xe << 24 |
 521                 0x7 << 16 |
 522                 reg->encoding() << 12  |
 523                 0xf << 8  |
 524                 0xb << 4  |
 525                 0xa);
 526       if(preserve_tmp) {
 527         ldr(reg, Address(SP, wordSize, post_indexed));
 528       }
 529     }
 530   }
 531 
 532   void dsb(Register reg) {
 533     if (VM_Version::arm_arch() >= 7) {
 534       emit_int32(0xF57FF04F);
 535     } else {
 536       bool preserve_tmp = (reg == noreg);
 537       if(preserve_tmp) {
 538         reg = Rtemp;
 539         str(reg, Address(SP, -wordSize, pre_indexed));
 540       }
 541       mov(reg, 0);
 542       // DataSynchronizationBarrier
 543       emit_int32(0xe << 28 |
 544                 0xe << 24 |
 545                 0x7 << 16 |
 546                 reg->encoding() << 12  |
 547                 0xf << 8  |
 548                 0x9 << 4  |
 549                 0xa);
 550       if(preserve_tmp) {
 551         ldr(reg, Address(SP, wordSize, post_indexed));
 552       }
 553     }
 554   }
 555 
 556 
 557 #define F(mnemonic, b) \
 558   void mnemonic(Register rd, Register rm, Register rn, AsmCondition cond = al) { \
 559     assert(rn != rm && rn != rd, "unpredictable instruction");                   \
 560     emit_int32(cond << 28 | 0x2 << 23 | b << 22 | rn->encoding() << 16 |         \
 561               rd->encoding() << 12 | 9 << 4 | rm->encoding());                   \
 562   }
 563 
 564   F(swp,  0)
 565   F(swpb, 1)
 566 #undef F
 567 
 568   // Branches
 569 
 570 #define F(mnemonic, l) \
 571   void mnemonic(Register rm, AsmCondition cond = al) {            \
 572     emit_int32(cond << 28 | 0x012fff10 | l << 5 | rm->encoding()); \
 573   }
 574 
 575   F(bx,  0)
 576   F(blx, 1)
 577 #undef F
 578 
 579 #define F(mnemonic, l)                                                  \
 580   void mnemonic(address target, AsmCondition cond = al) {               \
 581     unsigned int offset = (unsigned int)(target - pc() - 8);            \
 582     assert((offset & 3) == 0, "bad alignment");                         \
 583     assert((offset >> 25) == 0 || ((int)offset >> 25) == -1, "offset is too large"); \
 584     emit_int32(cond << 28 | l << 24 | offset << 6 >> 8);                \
 585   }
 586 
 587   F(b,  0xa)
 588   F(bl, 0xb)
 589 #undef F
 590 
 591   void udf(int imm_16) {
 592     assert((imm_16 >> 16) == 0, "encoding constraint");
 593     emit_int32(0xe7f000f0 | (imm_16 & 0xfff0) << 8 | (imm_16 & 0xf));
 594   }
 595 
 596   // ARMv7 instructions
 597 
 598 #define F(mnemonic, wt) \
 599   void mnemonic(Register rd, int imm_16, AsmCondition cond = al) { \
 600     assert((imm_16 >> 16) == 0, "encoding constraint");            \
 601     emit_int32(cond << 28 | wt << 20 | rd->encoding() << 12 |      \
 602               (imm_16 & 0xf000) << 4 | (imm_16 & 0xfff));          \
 603   }
 604 
 605   F(movw, 0x30)
 606   F(movt, 0x34)
 607 #undef F
 608 
 609   // VFP Support
 610 
 611 // Checks that VFP instructions are not used in SOFTFP mode.
 612 #ifdef __SOFTFP__
 613 #define CHECK_VFP_PRESENT ShouldNotReachHere()
 614 #else
 615 #define CHECK_VFP_PRESENT
 616 #endif // __SOFTFP__
 617 
 618   static const int single_cp_num = 0xa00;
 619   static const int double_cp_num = 0xb00;
 620 
 621   // Bits P, Q, R, S collectively form the opcode
 622 #define F(mnemonic, P, Q, R, S) \
 623   void mnemonic##d(FloatRegister fd, FloatRegister fn, FloatRegister fm, \
 624                    AsmCondition cond = al) {                             \
 625     CHECK_VFP_PRESENT;                                                   \
 626     assert(fn->lo_bit() == 0 && fd->lo_bit() == 0 && fm->lo_bit() == 0, "single precision register?"); \
 627     emit_int32(cond << 28 | 0x7 << 25 | double_cp_num |                  \
 628               P << 23 | Q << 21 | R << 20 | S << 6 |                     \
 629               fn->hi_bits() << 16 | fn->hi_bit() << 7 |                  \
 630               fd->hi_bits() << 12 | fd->hi_bit() << 22 |                 \
 631               fm->hi_bits()       | fm->hi_bit() << 5);                  \
 632   }                                                                      \
 633   void mnemonic##s(FloatRegister fd, FloatRegister fn, FloatRegister fm, \
 634                    AsmCondition cond = al) {                             \
 635     assert(fn->hi_bit() == 0 && fd->hi_bit() == 0 && fm->hi_bit() == 0, "double precision register?"); \
 636     CHECK_VFP_PRESENT;                                                   \
 637     emit_int32(cond << 28 | 0x7 << 25 | single_cp_num |                  \
 638               P << 23 | Q << 21 | R << 20 | S << 6 |                     \
 639               fn->hi_bits() << 16 | fn->lo_bit() << 7 |                  \
 640               fd->hi_bits() << 12 | fd->lo_bit() << 22 |                 \
 641               fm->hi_bits()       | fm->lo_bit() << 5);                  \
 642   }
 643 
 644   F(fmac,  0, 0, 0, 0)  // Fd = Fd + (Fn * Fm)
 645   F(fnmac, 0, 0, 0, 1)  // Fd = Fd - (Fn * Fm)
 646   F(fmsc,  0, 0, 1, 0)  // Fd = -Fd + (Fn * Fm)
 647   F(fnmsc, 0, 0, 1, 1)  // Fd = -Fd - (Fn * Fm)
 648 
 649   F(fmul,  0, 1, 0, 0)  // Fd = Fn * Fm
 650   F(fnmul, 0, 1, 0, 1)  // Fd = -(Fn * Fm)
 651   F(fadd,  0, 1, 1, 0)  // Fd = Fn + Fm
 652   F(fsub,  0, 1, 1, 1)  // Fd = Fn - Fm
 653   F(fdiv,  1, 0, 0, 0)  // Fd = Fn / Fm
 654 #undef F
 655 
 656   enum VElem_Size {
 657     VELEM_SIZE_8  = 0x00,
 658     VELEM_SIZE_16 = 0x01,
 659     VELEM_SIZE_32 = 0x02,
 660     VELEM_SIZE_64 = 0x03
 661   };
 662 
 663   enum VLD_Type {
 664     VLD1_TYPE_1_REG  = 0x7 /* 0b0111 */,
 665     VLD1_TYPE_2_REGS = 0xA /* 0b1010 */,
 666     VLD1_TYPE_3_REGS = 0x6 /* 0b0110 */,
 667     VLD1_TYPE_4_REGS = 0x2 /* 0b0010 */
 668   };
 669 
 670   enum VFloat_Arith_Size {
 671     VFA_SIZE_F32 = 0x0 /* 0b0 */,
 672   };
 673 
 674   // Bits P, Q, R, S collectively form the opcode
 675 #define F(mnemonic, P, Q, R, S) \
 676   void mnemonic(FloatRegister fd, FloatRegister fn, FloatRegister fm,    \
 677                 int size, int quad) {                                    \
 678     CHECK_VFP_PRESENT;                                                   \
 679     assert(VM_Version::has_simd(), "simd instruction");                  \
 680     assert(fn->lo_bit() == 0 && fd->lo_bit() == 0 && fm->lo_bit() == 0,  \
 681            "single precision register?");                                \
 682     assert(!quad || ((fn->hi_bits() | fd->hi_bits() | fm->hi_bits()) & 1) == 0, \
 683            "quad precision register?");                                  \
 684     emit_int32(0xf << 28 | P << 23 | Q << 8 | R << 4 |                   \
 685               S << 21 | size << 20 | quad << 6 |                         \
 686               fn->hi_bits() << 16 | fn->hi_bit() << 7 |                  \
 687               fd->hi_bits() << 12 | fd->hi_bit() << 22 |                 \
 688               fm->hi_bits()       | fm->hi_bit() << 5);                  \
 689   }
 690 
 691   F(vmulI,  0x4 /* 0b0100 */, 0x9 /* 0b1001 */, 1, 0)  // Vd = Vn * Vm (int)
 692   F(vaddI,  0x4 /* 0b0100 */, 0x8 /* 0b1000 */, 0, 0)  // Vd = Vn + Vm (int)
 693   F(vsubI,  0x6 /* 0b0110 */, 0x8 /* 0b1000 */, 0, 0)  // Vd = Vn - Vm (int)
 694   F(vaddF,  0x4 /* 0b0100 */, 0xD /* 0b1101 */, 0, 0)  // Vd = Vn + Vm (float)
 695   F(vsubF,  0x4 /* 0b0100 */, 0xD /* 0b1101 */, 0, 1)  // Vd = Vn - Vm (float)
 696   F(vmulF,  0x6 /* 0b0110 */, 0xD /* 0b1101 */, 1, 0)  // Vd = Vn * Vm (float)
 697   F(vshlSI, 0x4 /* 0b0100 */, 0x4 /* 0b0100 */, 0, 0)  // Vd = ashift(Vm,Vn) (int)
 698   F(vshlUI, 0x6 /* 0b0110 */, 0x4 /* 0b0100 */, 0, 0)  // Vd = lshift(Vm,Vn) (int)
 699   F(_vandI, 0x4 /* 0b0100 */, 0x1 /* 0b0001 */, 1, 0)  // Vd = Vn & Vm (int)
 700   F(_vorI,  0x4 /* 0b0100 */, 0x1 /* 0b0001 */, 1, 1)  // Vd = Vn | Vm (int)
 701   F(_vxorI, 0x6 /* 0b0110 */, 0x1 /* 0b0001 */, 1, 0)  // Vd = Vn ^ Vm (int)
 702 #undef F
 703 
 704   void vandI(FloatRegister fd, FloatRegister fn, FloatRegister fm, int quad) {
 705     _vandI(fd, fn, fm, 0, quad);
 706   }
 707   void vorI(FloatRegister fd, FloatRegister fn, FloatRegister fm, int quad) {
 708     _vorI(fd, fn, fm, 0, quad);
 709   }
 710   void vxorI(FloatRegister fd, FloatRegister fn, FloatRegister fm, int quad) {
 711     _vxorI(fd, fn, fm, 0, quad);
 712   }
 713 
 714   void vneg(FloatRegister fd, FloatRegister fm, int size, int flt, int quad) {
 715     CHECK_VFP_PRESENT;
 716     assert(VM_Version::has_simd(), "simd instruction");
 717     assert(fd->lo_bit() == 0 && fm->lo_bit() == 0,
 718            "single precision register?");
 719     assert(!quad || ((fd->hi_bits() | fm->hi_bits()) & 1) == 0,
 720            "quad precision register?");
 721     emit_int32(0xf << 28 | 0x3B /* 0b00111011 */ << 20 | 0x1 /* 0b01 */ << 16 | 0x7 /* 0b111 */ << 7 |
 722                size << 18 | quad << 6 | flt << 10 |
 723                fd->hi_bits() << 12 | fd->hi_bit() << 22 |
 724                fm->hi_bits() <<  0 | fm->hi_bit() << 5);
 725   }
 726 
 727   void vnegI(FloatRegister fd, FloatRegister fm, int size, int quad) {
 728     int flt = 0;
 729     vneg(fd, fm, size, flt, quad);
 730   }
 731 
 732   void vshli(FloatRegister fd, FloatRegister fm, int size, int imm, int quad) {
 733     CHECK_VFP_PRESENT;
 734     assert(VM_Version::has_simd(), "simd instruction");
 735     assert(fd->lo_bit() == 0 && fm->lo_bit() == 0,
 736            "single precision register?");
 737     assert(!quad || ((fd->hi_bits() | fm->hi_bits()) & 1) == 0,
 738            "quad precision register?");
 739 
 740     if (imm >= size) {
 741       // maximum shift gives all zeroes, direction doesn't matter,
 742       // but only available for shift right
 743       vshri(fd, fm, size, size, true /* unsigned */, quad);
 744       return;
 745     }
 746     assert(imm >= 0 && imm < size, "out of range");
 747 
 748     int imm6 = 0;
 749     int L = 0;
 750     switch (size) {
 751     case 8:
 752     case 16:
 753     case 32:
 754       imm6 = size + imm ;
 755       break;
 756     case 64:
 757       L = 1;
 758       imm6 = imm ;
 759       break;
 760     default:
 761       ShouldNotReachHere();
 762     }
 763     emit_int32(0xf << 28 | 0x5 /* 0b00101 */ << 23 | 0x51 /* 0b01010001 */ << 4 |
 764                imm6 << 16 | L << 7 | quad << 6 |
 765                fd->hi_bits() << 12 | fd->hi_bit() << 22 |
 766                fm->hi_bits() <<  0 | fm->hi_bit() << 5);
 767   }
 768 
 769   void vshri(FloatRegister fd, FloatRegister fm, int size, int imm,
 770              bool U /* unsigned */, int quad) {
 771     CHECK_VFP_PRESENT;
 772     assert(VM_Version::has_simd(), "simd instruction");
 773     assert(fd->lo_bit() == 0 && fm->lo_bit() == 0,
 774            "single precision register?");
 775     assert(!quad || ((fd->hi_bits() | fm->hi_bits()) & 1) == 0,
 776            "quad precision register?");
 777     assert(imm > 0, "out of range");
 778     if (imm >= size) {
 779       // maximum shift (all zeroes)
 780       imm = size;
 781     }
 782     int imm6 = 0;
 783     int L = 0;
 784     switch (size) {
 785     case 8:
 786     case 16:
 787     case 32:
 788       imm6 = 2 * size - imm ;
 789       break;
 790     case 64:
 791       L = 1;
 792       imm6 = 64 - imm ;
 793       break;
 794     default:
 795       ShouldNotReachHere();
 796     }
 797     emit_int32(0xf << 28 | 0x5 /* 0b00101 */ << 23 | 0x1 /* 0b00000001 */ << 4 |
 798                imm6 << 16 | L << 7 | quad << 6 | U << 24 |
 799                fd->hi_bits() << 12 | fd->hi_bit() << 22 |
 800                fm->hi_bits() <<  0 | fm->hi_bit() << 5);
 801   }
 802   void vshrUI(FloatRegister fd, FloatRegister fm, int size, int imm, int quad) {
 803     vshri(fd, fm, size, imm, true /* unsigned */, quad);
 804   }
 805   void vshrSI(FloatRegister fd, FloatRegister fm, int size, int imm, int quad) {
 806     vshri(fd, fm, size, imm, false /* signed */, quad);
 807   }
 808 
 809   // Extension opcodes where P,Q,R,S = 1 opcode is in Fn
 810 #define F(mnemonic, N, opcode) \
 811   void mnemonic##d(FloatRegister fd, FloatRegister fm, AsmCondition cond = al) {  \
 812     CHECK_VFP_PRESENT;                                                            \
 813     assert(fd->lo_bit() == 0 && fm->hi_bit() == 0, "incorrect register?");        \
 814     emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |         \
 815               double_cp_num |                                                     \
 816               fd->hi_bits() << 12 | fd->hi_bit() << 22 |                          \
 817               fm->hi_bits()       | fm->lo_bit() << 5);                           \
 818   }                                                                               \
 819   void mnemonic##s(FloatRegister fd, FloatRegister fm, AsmCondition cond = al) {  \
 820     CHECK_VFP_PRESENT;                                                            \
 821     assert(fd->hi_bit() == 0 && fm->hi_bit() == 0, "double precision register?"); \
 822     emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |         \
 823               single_cp_num |                                                     \
 824               fd->hi_bits() << 12 | fd->lo_bit() << 22 |                          \
 825               fm->hi_bits()       | fm->lo_bit() << 5);                           \
 826   }
 827 
 828   F(fuito,  0, 0x8)  // Unsigned integer to floating point conversion
 829   F(fsito,  1, 0x8)  // Signed integer to floating point conversion
 830 #undef F
 831 
 832 #define F(mnemonic, N, opcode) \
 833   void mnemonic##d(FloatRegister fd, FloatRegister fm, AsmCondition cond = al) {  \
 834     CHECK_VFP_PRESENT;                                                            \
 835     assert(fd->hi_bit() == 0 && fm->lo_bit() == 0, "incorrect register?");        \
 836     emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |         \
 837               double_cp_num |                                                     \
 838               fd->hi_bits() << 12 | fd->lo_bit() << 22 |                          \
 839               fm->hi_bits()       | fm->hi_bit() << 5);                           \
 840   }                                                                               \
 841   void mnemonic##s(FloatRegister fd, FloatRegister fm, AsmCondition cond = al) {  \
 842     CHECK_VFP_PRESENT;                                                            \
 843     assert(fd->hi_bit() == 0 && fm->hi_bit() == 0, "double precision register?"); \
 844     emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |         \
 845               single_cp_num |                                                     \
 846               fd->hi_bits() << 12 | fd->lo_bit() << 22 |                          \
 847               fm->hi_bits()       | fm->lo_bit() << 5);                           \
 848   }
 849 
 850   F(ftoui,  0, 0xc)  // Float to unsigned int conversion
 851   F(ftouiz, 1, 0xc)  // Float to unsigned int conversion, RZ mode
 852   F(ftosi,  0, 0xd)  // Float to signed int conversion
 853   F(ftosiz, 1, 0xd)  // Float to signed int conversion, RZ mode
 854 #undef F
 855 
 856 #define F(mnemonic, N, opcode) \
 857   void mnemonic##d(FloatRegister fd, FloatRegister fm, AsmCondition cond = al) {  \
 858     CHECK_VFP_PRESENT;                                                            \
 859     assert(fd->hi_bit() == 0 && fm->lo_bit() == 0, "incorrect register?");        \
 860     emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |         \
 861               double_cp_num |                                                     \
 862               fd->hi_bits() << 12 | fd->lo_bit() << 22 |                          \
 863               fm->hi_bits()       | fm->hi_bit() << 5);                           \
 864   }                                                                               \
 865   void mnemonic##s(FloatRegister fd, FloatRegister fm, AsmCondition cond = al) {  \
 866     CHECK_VFP_PRESENT;                                                            \
 867     assert(fd->lo_bit() == 0 && fm->hi_bit() == 0, "incorrect register?");        \
 868     emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |         \
 869               single_cp_num |                                                     \
 870               fd->hi_bits() << 12 | fd->hi_bit() << 22 |                          \
 871               fm->hi_bits()       | fm->lo_bit() << 5);                           \
 872   }
 873 
 874   F(fcvtd,  1, 0x7)  // Single->Double conversion
 875   F(fcvts,  1, 0x7)  // Double->Single conversion
 876 #undef F
 877 
 878 #define F(mnemonic, N, opcode) \
 879   void mnemonic##d(FloatRegister fd, FloatRegister fm, AsmCondition cond = al) {  \
 880     CHECK_VFP_PRESENT;                                                            \
 881     assert(fd->lo_bit() == 0 && fm->lo_bit() == 0, "single precision register?"); \
 882     emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |         \
 883               double_cp_num |                                                     \
 884               fd->hi_bits() << 12 | fd->hi_bit() << 22 |                          \
 885               fm->hi_bits()       | fm->hi_bit() << 5);                           \
 886   }                                                                               \
 887   void mnemonic##s(FloatRegister fd, FloatRegister fm, AsmCondition cond = al) {  \
 888     CHECK_VFP_PRESENT;                                                            \
 889     assert(fd->hi_bit() == 0 && fm->hi_bit() == 0, "double precision register?"); \
 890     emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |         \
 891               single_cp_num |                                                     \
 892               fd->hi_bits() << 12 | fd->lo_bit() << 22 |                          \
 893               fm->hi_bits()       | fm->lo_bit() << 5);                           \
 894   }
 895 
 896   F(fcpy,   0, 0x0)  // Fd = Fm
 897   F(fabs,   1, 0x0)  // Fd = abs(Fm)
 898   F(fneg,   0, 0x1)  // Fd = -Fm
 899   F(fsqrt,  1, 0x1)  // Fd = sqrt(Fm)
 900   F(fcmp,   0, 0x4)  // Compare Fd with Fm no exceptions on quiet NANs
 901   F(fcmpe,  1, 0x4)  // Compare Fd with Fm with exceptions on quiet NANs
 902 #undef F
 903 
 904   // Opcodes with one operand only
 905 #define F(mnemonic, N, opcode) \
 906   void mnemonic##d(FloatRegister fd, AsmCondition cond = al) {               \
 907     CHECK_VFP_PRESENT;                                                       \
 908     assert(fd->lo_bit() == 0, "single precision register?");                 \
 909     emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |    \
 910               double_cp_num | fd->hi_bits() << 12 | fd->hi_bit() << 22);     \
 911   }                                                                          \
 912   void mnemonic##s(FloatRegister fd, AsmCondition cond = al) {               \
 913     CHECK_VFP_PRESENT;                                                       \
 914     assert(fd->hi_bit() == 0, "double precision register?");                 \
 915     emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |    \
 916               single_cp_num | fd->hi_bits() << 12 | fd->lo_bit() << 22);     \
 917   }
 918 
 919   F(fcmpz,  0, 0x5)  // Compare Fd with 0, no exceptions quiet NANs
 920   F(fcmpez, 1, 0x5)  // Compare Fd with 0, with exceptions quiet NANs
 921 #undef F
 922 
 923   // Float loads (L==1) and stores (L==0)
 924 #define F(mnemonic, L) \
 925   void mnemonic##d(FloatRegister fd, Address addr, AsmCondition cond = al) { \
 926     CHECK_VFP_PRESENT;                                                       \
 927     assert(fd->lo_bit() == 0, "single precision register?");                 \
 928     emit_int32(cond << 28 | 0xd << 24 | L << 20 |                            \
 929               fd->hi_bits() << 12 | fd->hi_bit() << 22 |                     \
 930               double_cp_num | addr.encoding_vfp());                          \
 931   }                                                                          \
 932   void mnemonic##s(FloatRegister fd, Address addr, AsmCondition cond = al) { \
 933     CHECK_VFP_PRESENT;                                                       \
 934     assert(fd->hi_bit() == 0, "double precision register?");                 \
 935     emit_int32(cond << 28 | 0xd << 24 | L << 20 |                            \
 936               fd->hi_bits() << 12 | fd->lo_bit() << 22 |                     \
 937               single_cp_num | addr.encoding_vfp());                          \
 938   }
 939 
 940   F(fst, 0)  // Store 1 register
 941   F(fld, 1)  // Load 1 register
 942 #undef F
 943 
 944   // Float load and store multiple
 945 #define F(mnemonic, l, pu) \
 946   void mnemonic##d(Register rn, FloatRegisterSet reg_set,                    \
 947                    AsmWriteback w = no_writeback, AsmCondition cond = al) {  \
 948     CHECK_VFP_PRESENT;                                                       \
 949     assert(w == no_writeback || rn != PC, "unpredictable instruction");      \
 950     assert(!(w == no_writeback && pu == 2), "encoding constraint");          \
 951     assert((reg_set.encoding_d() & 1) == 0, "encoding constraint");          \
 952     emit_int32(cond << 28 | 6 << 25 | pu << 23 | w << 21 | l << 20 |         \
 953               rn->encoding() << 16 | reg_set.encoding_d() | double_cp_num);  \
 954   }                                                                          \
 955   void mnemonic##s(Register rn, FloatRegisterSet reg_set,                    \
 956                    AsmWriteback w = no_writeback, AsmCondition cond = al) {  \
 957     CHECK_VFP_PRESENT;                                                       \
 958     assert(w == no_writeback || rn != PC, "unpredictable instruction");      \
 959     assert(!(w == no_writeback && pu == 2), "encoding constraint");          \
 960     emit_int32(cond << 28 | 6 << 25 | pu << 23 | w << 21 | l << 20 |         \
 961               rn->encoding() << 16 | reg_set.encoding_s() | single_cp_num);  \
 962   }
 963 
 964   F(fldmia, 1, 1)    F(fldmfd, 1, 1)
 965   F(fldmdb, 1, 2)    F(fldmea, 1, 2)
 966   F(fstmia, 0, 1)    F(fstmfd, 0, 1)
 967   F(fstmdb, 0, 2)    F(fstmea, 0, 2)
 968 #undef F
 969 
 970   // fconst{s,d} encoding:
 971   //  31  28 27   23 22  21 20 19   16 15 12 10  9  8   7    4 3     0
 972   // | cond | 11101 | D | 11  | imm4H | Vd  | 101 | sz | 0000 | imm4L |
 973   // sz = 0 for single precision, 1 otherwise
 974   // Register number is Vd:D for single precision, D:Vd otherwise
 975   // immediate value is imm4H:imm4L
 976 
 977   void fconsts(FloatRegister fd, unsigned char imm_8, AsmCondition cond = al) {
 978     CHECK_VFP_PRESENT;
 979     assert(fd->hi_bit() == 0, "double precision register?");
 980     emit_int32(cond << 28 | 0xeb << 20 | single_cp_num |
 981               fd->hi_bits() << 12 | fd->lo_bit() << 22 | (imm_8 & 0xf) | (imm_8 >> 4) << 16);
 982   }
 983 
 984   void fconstd(FloatRegister fd, unsigned char imm_8, AsmCondition cond = al) {
 985     CHECK_VFP_PRESENT;
 986     assert(fd->lo_bit() == 0, "double precision register?");
 987     emit_int32(cond << 28 | 0xeb << 20 | double_cp_num |
 988               fd->hi_bits() << 12 | fd->hi_bit() << 22 | (imm_8 & 0xf) | (imm_8 >> 4) << 16);
 989   }
 990 
 991   // GPR <-> FPR transfers
 992   void fmsr(FloatRegister fd, Register rd, AsmCondition cond = al) {
 993     CHECK_VFP_PRESENT;
 994     assert(fd->hi_bit() == 0, "double precision register?");
 995     emit_int32(cond << 28 | 0xe0 << 20 | single_cp_num | 1 << 4 |
 996               fd->hi_bits() << 16 | fd->lo_bit() << 7 | rd->encoding() << 12);
 997   }
 998 
 999   void fmrs(Register rd, FloatRegister fd, AsmCondition cond = al) {
1000     CHECK_VFP_PRESENT;
1001     assert(fd->hi_bit() == 0, "double precision register?");
1002     emit_int32(cond << 28 | 0xe1 << 20 | single_cp_num | 1 << 4 |
1003               fd->hi_bits() << 16 | fd->lo_bit() << 7 | rd->encoding() << 12);
1004   }
1005 
1006   void fmdrr(FloatRegister fd, Register rd, Register rn, AsmCondition cond = al) {
1007     CHECK_VFP_PRESENT;
1008     assert(fd->lo_bit() == 0, "single precision register?");
1009     emit_int32(cond << 28 | 0xc4 << 20 | double_cp_num | 1 << 4 |
1010               fd->hi_bits() | fd->hi_bit() << 5 |
1011               rn->encoding() << 16 | rd->encoding() << 12);
1012   }
1013 
1014   void fmrrd(Register rd, Register rn, FloatRegister fd, AsmCondition cond = al) {
1015     CHECK_VFP_PRESENT;
1016     assert(fd->lo_bit() == 0, "single precision register?");
1017     emit_int32(cond << 28 | 0xc5 << 20 | double_cp_num | 1 << 4 |
1018               fd->hi_bits() | fd->hi_bit() << 5 |
1019               rn->encoding() << 16 | rd->encoding() << 12);
1020   }
1021 
1022   void fmstat(AsmCondition cond = al) {
1023     CHECK_VFP_PRESENT;
1024     emit_int32(cond << 28 | 0xef1fa10);
1025   }
1026 
1027   void vmrs(Register rt, VFPSystemRegister sr, AsmCondition cond = al) {
1028     assert((sr->encoding() & (~0xf)) == 0, "what system register is that?");
1029     emit_int32(cond << 28 | rt->encoding() << 12 | sr->encoding() << 16 | 0xef00a10);
1030   }
1031 
1032   void vmsr(VFPSystemRegister sr, Register rt, AsmCondition cond = al) {
1033     assert((sr->encoding() & (~0xf)) == 0, "what system register is that?");
1034     emit_int32(cond << 28 | rt->encoding() << 12 | sr->encoding() << 16 | 0xee00a10);
1035   }
1036 
1037   void vcnt(FloatRegister Dd, FloatRegister Dm) {
1038     CHECK_VFP_PRESENT;
1039     // emitted at VM startup to detect whether the instruction is available
1040     assert(!VM_Version::is_initialized() || VM_Version::has_simd(), "simd instruction");
1041     assert(Dd->lo_bit() == 0 && Dm->lo_bit() == 0, "single precision registers?");
1042     emit_int32(0xf3b00500 | Dd->hi_bit() << 22 | Dd->hi_bits() << 12 | Dm->hi_bit() << 5 | Dm->hi_bits());
1043   }
1044 
1045   void vpaddl(FloatRegister Dd, FloatRegister Dm, int size, bool s) {
1046     CHECK_VFP_PRESENT;
1047     assert(VM_Version::has_simd(), "simd instruction");
1048     assert(Dd->lo_bit() == 0 && Dm->lo_bit() == 0, "single precision registers?");
1049     assert(size == 8 || size == 16 || size == 32, "unexpected size");
1050     emit_int32(0xf3b00200 | Dd->hi_bit() << 22 | (size >> 4) << 18 | Dd->hi_bits() << 12 | (s ? 0 : 1) << 7 | Dm->hi_bit() << 5 | Dm->hi_bits());
1051   }
1052 
1053   void vld1(FloatRegister Dd, Address addr, VElem_Size size, int bits) {
1054     CHECK_VFP_PRESENT;
1055     assert(VM_Version::has_simd(), "simd instruction");
1056     assert(Dd->lo_bit() == 0, "single precision registers?");
1057     int align = 0;
1058     assert(bits == 128, "code assumption");
1059     VLD_Type type = VLD1_TYPE_2_REGS; // 2x64
1060     emit_int32(0xf4200000 | Dd->hi_bit() << 22 | Dd->hi_bits() << 12 | type << 8 | size << 6 | align << 4 | addr.encoding_simd());
1061   }
1062 
1063   void vst1(FloatRegister Dd, Address addr, VElem_Size size, int bits) {
1064     CHECK_VFP_PRESENT;
1065     assert(VM_Version::has_simd(), "simd instruction");
1066     assert(Dd->lo_bit() == 0, "single precision registers?");
1067     int align = 0;
1068     assert(bits == 128, "code assumption");
1069     VLD_Type type = VLD1_TYPE_2_REGS; // 2x64
1070     emit_int32(0xf4000000 | Dd->hi_bit() << 22 | Dd->hi_bits() << 12 | type << 8 | size << 6 | align << 4 | addr.encoding_simd());
1071   }
1072 
1073   void vmovI(FloatRegister Dd, int imm8, VElem_Size size, int quad) {
1074     CHECK_VFP_PRESENT;
1075     assert(VM_Version::has_simd(), "simd instruction");
1076     assert(Dd->lo_bit() == 0, "single precision register?");
1077     assert(!quad || (Dd->hi_bits() & 1) == 0, "quad precision register?");
1078     assert(imm8 >= 0 && imm8 < 256, "out of range");
1079     int op;
1080     int cmode;
1081     switch (size) {
1082     case VELEM_SIZE_8:
1083       op = 0;
1084       cmode = 0xE /* 0b1110 */;
1085       break;
1086     case VELEM_SIZE_16:
1087       op = 0;
1088       cmode = 0x8 /* 0b1000 */;
1089       break;
1090     case VELEM_SIZE_32:
1091       op = 0;
1092       cmode = 0x0 /* 0b0000 */;
1093       break;
1094     default:
1095       ShouldNotReachHere();
1096       return;
1097     }
1098     emit_int32(0xf << 28 | 0x1 << 25 | 0x1 << 23 | 0x1 << 4 |
1099               (imm8 >> 7) << 24 | ((imm8 & 0x70) >> 4) << 16 | (imm8 & 0xf) |
1100               quad << 6 | op << 5 | cmode << 8 |
1101               Dd->hi_bits() << 12 | Dd->hi_bit() << 22);
1102   }
1103 
1104   void vdupI(FloatRegister Dd, Register Rs, VElem_Size size, int quad,
1105              AsmCondition cond = al) {
1106     CHECK_VFP_PRESENT;
1107     assert(VM_Version::has_simd(), "simd instruction");
1108     assert(Dd->lo_bit() == 0, "single precision register?");
1109     assert(!quad || (Dd->hi_bits() & 1) == 0, "quad precision register?");
1110     int b;
1111     int e;
1112     switch (size) {
1113     case VELEM_SIZE_8:
1114       b = 1;
1115       e = 0;
1116       break;
1117     case VELEM_SIZE_16:
1118       b = 0;
1119       e = 1;
1120       break;
1121     case VELEM_SIZE_32:
1122       b = 0;
1123       e = 0;
1124       break;
1125     default:
1126       ShouldNotReachHere();
1127       return;
1128     }
1129     emit_int32(cond << 28 | 0x1D /* 0b11101 */ << 23 | 0xB /* 0b1011 */ << 8 | 0x1 << 4 |
1130               quad << 21 | b << 22 |  e << 5 | Rs->encoding() << 12 |
1131               Dd->hi_bits() << 16 | Dd->hi_bit() << 7);
1132   }
1133 
1134   void vdup(FloatRegister Dd, FloatRegister Ds, int index, int size, int quad) {
1135     CHECK_VFP_PRESENT;
1136     assert(VM_Version::has_simd(), "simd instruction");
1137     assert(Dd->lo_bit() == 0, "single precision register?");
1138     assert(Ds->lo_bit() == 0, "single precision register?");
1139     assert(!quad || (Dd->hi_bits() & 1) == 0, "quad precision register?");
1140     int range = 64 / size;
1141     assert(index < range, "overflow");
1142     int imm4;
1143     switch (size) {
1144     case 8:
1145       assert((index & 0x7 /* 0b111 */) == index, "overflow");
1146       imm4 = index << 1 | 0x1 /* 0b0001 */;
1147       break;
1148     case 16:
1149       assert((index & 0x3 /* 0b11 */) == index, "overflow");
1150       imm4 = index << 2 | 0x2 /* 0b0010 */;
1151       break;
1152     case 32:
1153       assert((index & 0x1 /* 0b1 */) == index, "overflow");
1154       imm4 = index << 3 | 0x4 /* 0b0100 */;
1155       break;
1156     default:
1157       ShouldNotReachHere();
1158       return;
1159     }
1160     emit_int32(0xF /* 0b1111 */ << 28 | 0x3B /* 0b00111011 */ << 20 | 0x6 /* 0b110 */ << 9 |
1161                quad << 6 | imm4 << 16 |
1162                Dd->hi_bits() << 12 | Dd->hi_bit() << 22 |
1163                Ds->hi_bits() << 00 | Ds->hi_bit() << 5);
1164   }
1165 
1166   void vdupF(FloatRegister Dd, FloatRegister Ss, int quad) {
1167     int index = 0;
1168     FloatRegister Ds = as_FloatRegister(Ss->encoding() & ~1);
1169     if (Ss->lo_bit() != 0) {
1170       /* odd S register */
1171       assert(Ds->successor() == Ss, "bad reg");
1172       index = 1;
1173     } else {
1174       /* even S register */
1175       assert(Ds == Ss, "bad reg");
1176     }
1177     vdup(Dd, Ds, index, 32, quad);
1178   }
1179 
1180   void vrev(FloatRegister Dd, FloatRegister Dm, int quad, int region_size, VElem_Size size) {
1181     CHECK_VFP_PRESENT;
1182     assert(VM_Version::has_simd(), "simd instruction");
1183     assert(Dd->lo_bit() == 0, "single precision register?");
1184     assert(Dm->lo_bit() == 0, "single precision register?");
1185     assert(!quad || ((Dd->hi_bits() | Dm->hi_bits()) & 1) == 0,
1186            "quad precision register?");
1187     unsigned int op = 0;
1188     switch (region_size) {
1189       case 16: op = 0x2; /*0b10*/ break;
1190       case 32: op = 0x1; /*0b01*/ break;
1191       case 64: op = 0x0; /*0b00*/ break;
1192       default: assert(false, "encoding constraint");
1193     }
1194     emit_int32(0xf << 28 | 0x7 << 23 | Dd->hi_bit() << 22 | 0x3 << 20 |
1195                size << 18 | Dd->hi_bits() << 12 | op  << 7 | quad << 6 | Dm->hi_bit() << 5 |
1196                Dm->hi_bits());
1197   }
1198 
1199   void veor(FloatRegister Dd, FloatRegister Dn, FloatRegister Dm, int quad) {
1200     CHECK_VFP_PRESENT;
1201     assert(VM_Version::has_simd(), "simd instruction");
1202     assert(Dd->lo_bit() == 0, "single precision register?");
1203     assert(Dm->lo_bit() == 0, "single precision register?");
1204     assert(Dn->lo_bit() == 0, "single precision register?");
1205     assert(!quad || ((Dd->hi_bits() | Dm->hi_bits() | Dn->hi_bits()) & 1) == 0,
1206            "quad precision register?");
1207 
1208     emit_int32(0xf << 28 | 0x3 << 24 | Dd->hi_bit() << 22 | Dn->hi_bits() << 16 |
1209                Dd->hi_bits() << 12 | 0x1 << 8 | Dn->hi_bit() << 7 | quad << 6 |
1210                Dm->hi_bit() << 5 | 0x1 << 4 | Dm->hi_bits());
1211   }
1212 
1213 
1214   Assembler(CodeBuffer* code) : AbstractAssembler(code) {}
1215 
1216 #ifdef COMPILER2
1217   typedef VFP::double_num double_num;
1218   typedef VFP::float_num  float_num;
1219 #endif
1220 };
1221 
1222 #ifdef __SOFTFP__
1223 // Soft float function declarations
1224 extern "C" {
1225 extern float  __aeabi_fadd(float, float);
1226 extern float  __aeabi_fmul(float, float);
1227 extern float  __aeabi_fsub(float, float);
1228 extern float  __aeabi_fdiv(float, float);
1229 
1230 extern double __aeabi_dadd(double, double);
1231 extern double __aeabi_dmul(double, double);
1232 extern double __aeabi_dsub(double, double);
1233 extern double __aeabi_ddiv(double, double);
1234 
1235 extern double __aeabi_f2d(float);
1236 extern float  __aeabi_d2f(double);
1237 extern float  __aeabi_i2f(int);
1238 extern double __aeabi_i2d(int);
1239 extern int    __aeabi_f2iz(float);
1240 
1241 extern int  __aeabi_fcmpeq(float, float);
1242 extern int  __aeabi_fcmplt(float, float);
1243 extern int  __aeabi_fcmple(float, float);
1244 extern int  __aeabi_fcmpge(float, float);
1245 extern int  __aeabi_fcmpgt(float, float);
1246 
1247 extern int  __aeabi_dcmpeq(double, double);
1248 extern int  __aeabi_dcmplt(double, double);
1249 extern int  __aeabi_dcmple(double, double);
1250 extern int  __aeabi_dcmpge(double, double);
1251 extern int  __aeabi_dcmpgt(double, double);
1252 
1253 // Imported code from glibc soft-fp bundle for
1254 // calculation accuracy improvement. See CR 6757269.
1255 extern double __aeabi_fadd_glibc(float, float);
1256 extern double __aeabi_fsub_glibc(float, float);
1257 extern double __aeabi_dadd_glibc(double, double);
1258 extern double __aeabi_dsub_glibc(double, double);
1259 };
1260 #endif // __SOFTFP__
1261 
1262 
1263 #endif // CPU_ARM_ASSEMBLER_ARM_32_HPP