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::arm_arch() >= 7 && os::is_MP(), "no pldw on this processor");
 446     emit_int32(0xf510f000 | addr.encoding2());
 447   }
 448 
 449   void svc(int imm_24, AsmCondition cond = al) {
 450     assert((imm_24 >> 24) == 0, "encoding constraint");
 451     emit_int32(cond << 28 | 0xf << 24 | imm_24);
 452   }
 453 
 454   void ubfx(Register rd, Register rn, unsigned int lsb, unsigned int width, AsmCondition cond = al) {
 455     assert(VM_Version::arm_arch() >= 7, "no ubfx on this processor");
 456     assert(width > 0, "must be");
 457     assert(lsb < 32, "must be");
 458     emit_int32(cond << 28 | 0x3f << 21 | (width - 1)  << 16 | rd->encoding() << 12 |
 459               lsb << 7 | 0x5 << 4 | rn->encoding());
 460   }
 461 
 462   void uxtb(Register rd, Register rm, unsigned int rotation = 0, AsmCondition cond = al) {
 463     assert(VM_Version::arm_arch() >= 7, "no uxtb on this processor");
 464     assert((rotation % 8) == 0 && (rotation <= 24), "encoding constraint");
 465     emit_int32(cond << 28 | 0x6e << 20 | 0xf << 16 | rd->encoding() << 12 |
 466               (rotation >> 3) << 10 | 0x7 << 4 | rm->encoding());
 467   }
 468 
 469   // ARM Memory Barriers
 470   //
 471   // There are two types of memory barriers defined for the ARM processor
 472   // DataSynchronizationBarrier and DataMemoryBarrier
 473   //
 474   // The Linux kernel uses the DataMemoryBarrier for all of it's
 475   // memory barrier operations (smp_mb, smp_rmb, smp_wmb)
 476   //
 477   // There are two forms of each barrier instruction.
 478   // The mcr forms are supported on armv5 and newer architectures
 479   //
 480   // The dmb, dsb instructions were added in armv7
 481   // architectures and are compatible with their mcr
 482   // predecessors.
 483   //
 484   // Here are the encodings for future reference:
 485   //
 486   // DataSynchronizationBarrier (dsb)
 487   // on ARMv7 - emit_int32(0xF57FF04F)
 488   //
 489   // on ARMv5+ - mcr p15, 0, Rtmp, c7, c10, 4  on earlier processors
 490   //             emit_int32(0xe << 28 | 0xe << 24 | 0x7 << 16 | Rtmp->encoding() << 12  |
 491   //                       0xf << 8  | 0x9 << 4  | 0xa);
 492   //
 493   // DataMemoryBarrier (dmb)
 494   // on ARMv7 - emit_int32(0xF57FF05F)
 495   //
 496   // on ARMv5+ - mcr p15, 0, Rtmp, c7, c10, 5 on earlier processors
 497   //             emit_int32(0xe << 28 | 0xe << 24 | 0x7 << 16 | Rtmp->encoding() << 12  |
 498   //                       0xf << 8  | 0xb << 4  | 0xa);
 499   //
 500 
 501   enum DMB_Opt {
 502     DMB_all = 0xf,
 503     DMB_st  = 0xe,
 504   };
 505 
 506   void dmb(DMB_Opt opt, Register reg) {
 507     if (VM_Version::arm_arch() >= 7) {
 508       emit_int32(0xF57FF050 | opt);
 509     } else if (VM_Version::arm_arch() == 6) {
 510       bool preserve_tmp = (reg == noreg);
 511       if(preserve_tmp) {
 512         reg = Rtemp;
 513         str(reg, Address(SP, -wordSize, pre_indexed));
 514       }
 515       mov(reg, 0);
 516       // DataMemoryBarrier
 517       emit_int32(0xe << 28 |
 518                 0xe << 24 |
 519                 0x7 << 16 |
 520                 reg->encoding() << 12  |
 521                 0xf << 8  |
 522                 0xb << 4  |
 523                 0xa);
 524       if(preserve_tmp) {
 525         ldr(reg, Address(SP, wordSize, post_indexed));
 526       }
 527     }
 528   }
 529 
 530   void dsb(Register reg) {
 531     if (VM_Version::arm_arch() >= 7) {
 532       emit_int32(0xF57FF04F);
 533     } else {
 534       bool preserve_tmp = (reg == noreg);
 535       if(preserve_tmp) {
 536         reg = Rtemp;
 537         str(reg, Address(SP, -wordSize, pre_indexed));
 538       }
 539       mov(reg, 0);
 540       // DataSynchronizationBarrier
 541       emit_int32(0xe << 28 |
 542                 0xe << 24 |
 543                 0x7 << 16 |
 544                 reg->encoding() << 12  |
 545                 0xf << 8  |
 546                 0x9 << 4  |
 547                 0xa);
 548       if(preserve_tmp) {
 549         ldr(reg, Address(SP, wordSize, post_indexed));
 550       }
 551     }
 552   }
 553 
 554 
 555 #define F(mnemonic, b) \
 556   void mnemonic(Register rd, Register rm, Register rn, AsmCondition cond = al) { \
 557     assert(rn != rm && rn != rd, "unpredictable instruction");                   \
 558     emit_int32(cond << 28 | 0x2 << 23 | b << 22 | rn->encoding() << 16 |         \
 559               rd->encoding() << 12 | 9 << 4 | rm->encoding());                   \
 560   }
 561 
 562   F(swp,  0)
 563   F(swpb, 1)
 564 #undef F
 565 
 566   // Branches
 567 
 568 #define F(mnemonic, l) \
 569   void mnemonic(Register rm, AsmCondition cond = al) {            \
 570     emit_int32(cond << 28 | 0x012fff10 | l << 5 | rm->encoding()); \
 571   }
 572 
 573   F(bx,  0)
 574   F(blx, 1)
 575 #undef F
 576 
 577 #define F(mnemonic, l)                                                  \
 578   void mnemonic(address target, AsmCondition cond = al) {               \
 579     unsigned int offset = (unsigned int)(target - pc() - 8);            \
 580     assert((offset & 3) == 0, "bad alignment");                         \
 581     assert((offset >> 25) == 0 || ((int)offset >> 25) == -1, "offset is too large"); \
 582     emit_int32(cond << 28 | l << 24 | offset << 6 >> 8);                \
 583   }
 584 
 585   F(b,  0xa)
 586   F(bl, 0xb)
 587 #undef F
 588 
 589   void udf(int imm_16) {
 590     assert((imm_16 >> 16) == 0, "encoding constraint");
 591     emit_int32(0xe7f000f0 | (imm_16 & 0xfff0) << 8 | (imm_16 & 0xf));
 592   }
 593 
 594   // ARMv7 instructions
 595 
 596 #define F(mnemonic, wt) \
 597   void mnemonic(Register rd, int imm_16, AsmCondition cond = al) { \
 598     assert((imm_16 >> 16) == 0, "encoding constraint");            \
 599     emit_int32(cond << 28 | wt << 20 | rd->encoding() << 12 |      \
 600               (imm_16 & 0xf000) << 4 | (imm_16 & 0xfff));          \
 601   }
 602 
 603   F(movw, 0x30)
 604   F(movt, 0x34)
 605 #undef F
 606 
 607   // VFP Support
 608 
 609 // Checks that VFP instructions are not used in SOFTFP mode.
 610 #ifdef __SOFTFP__
 611 #define CHECK_VFP_PRESENT ShouldNotReachHere()
 612 #else
 613 #define CHECK_VFP_PRESENT
 614 #endif // __SOFTFP__
 615 
 616   static const int single_cp_num = 0xa00;
 617   static const int double_cp_num = 0xb00;
 618 
 619   // Bits P, Q, R, S collectively form the opcode
 620 #define F(mnemonic, P, Q, R, S) \
 621   void mnemonic##d(FloatRegister fd, FloatRegister fn, FloatRegister fm, \
 622                    AsmCondition cond = al) {                             \
 623     CHECK_VFP_PRESENT;                                                   \
 624     assert(fn->lo_bit() == 0 && fd->lo_bit() == 0 && fm->lo_bit() == 0, "single precision register?"); \
 625     emit_int32(cond << 28 | 0x7 << 25 | double_cp_num |                  \
 626               P << 23 | Q << 21 | R << 20 | S << 6 |                     \
 627               fn->hi_bits() << 16 | fn->hi_bit() << 7 |                  \
 628               fd->hi_bits() << 12 | fd->hi_bit() << 22 |                 \
 629               fm->hi_bits()       | fm->hi_bit() << 5);                  \
 630   }                                                                      \
 631   void mnemonic##s(FloatRegister fd, FloatRegister fn, FloatRegister fm, \
 632                    AsmCondition cond = al) {                             \
 633     assert(fn->hi_bit() == 0 && fd->hi_bit() == 0 && fm->hi_bit() == 0, "double precision register?"); \
 634     CHECK_VFP_PRESENT;                                                   \
 635     emit_int32(cond << 28 | 0x7 << 25 | single_cp_num |                  \
 636               P << 23 | Q << 21 | R << 20 | S << 6 |                     \
 637               fn->hi_bits() << 16 | fn->lo_bit() << 7 |                  \
 638               fd->hi_bits() << 12 | fd->lo_bit() << 22 |                 \
 639               fm->hi_bits()       | fm->lo_bit() << 5);                  \
 640   }
 641 
 642   F(fmac,  0, 0, 0, 0)  // Fd = Fd + (Fn * Fm)
 643   F(fnmac, 0, 0, 0, 1)  // Fd = Fd - (Fn * Fm)
 644   F(fmsc,  0, 0, 1, 0)  // Fd = -Fd + (Fn * Fm)
 645   F(fnmsc, 0, 0, 1, 1)  // Fd = -Fd - (Fn * Fm)
 646 
 647   F(fmul,  0, 1, 0, 0)  // Fd = Fn * Fm
 648   F(fnmul, 0, 1, 0, 1)  // Fd = -(Fn * Fm)
 649   F(fadd,  0, 1, 1, 0)  // Fd = Fn + Fm
 650   F(fsub,  0, 1, 1, 1)  // Fd = Fn - Fm
 651   F(fdiv,  1, 0, 0, 0)  // Fd = Fn / Fm
 652 #undef F
 653 
 654   enum VElem_Size {
 655     VELEM_SIZE_8  = 0x00,
 656     VELEM_SIZE_16 = 0x01,
 657     VELEM_SIZE_32 = 0x02,
 658     VELEM_SIZE_64 = 0x03
 659   };
 660 
 661   enum VLD_Type {
 662     VLD1_TYPE_1_REG  = 0x7 /* 0b0111 */,
 663     VLD1_TYPE_2_REGS = 0xA /* 0b1010 */,
 664     VLD1_TYPE_3_REGS = 0x6 /* 0b0110 */,
 665     VLD1_TYPE_4_REGS = 0x2 /* 0b0010 */
 666   };
 667 
 668   enum VFloat_Arith_Size {
 669     VFA_SIZE_F32 = 0x0 /* 0b0 */,
 670   };
 671 
 672   // Bits P, Q, R, S collectively form the opcode
 673 #define F(mnemonic, P, Q, R, S) \
 674   void mnemonic(FloatRegister fd, FloatRegister fn, FloatRegister fm,    \
 675                 int size, int quad) {                                    \
 676     CHECK_VFP_PRESENT;                                                   \
 677     assert(VM_Version::has_simd(), "simd instruction");                  \
 678     assert(fn->lo_bit() == 0 && fd->lo_bit() == 0 && fm->lo_bit() == 0,  \
 679            "single precision register?");                                \
 680     assert(!quad || ((fn->hi_bits() | fd->hi_bits() | fm->hi_bits()) & 1) == 0, \
 681            "quad precision register?");                                  \
 682     emit_int32(0xf << 28 | P << 23 | Q << 8 | R << 4 |                   \
 683               S << 21 | size << 20 | quad << 6 |                         \
 684               fn->hi_bits() << 16 | fn->hi_bit() << 7 |                  \
 685               fd->hi_bits() << 12 | fd->hi_bit() << 22 |                 \
 686               fm->hi_bits()       | fm->hi_bit() << 5);                  \
 687   }
 688 
 689   F(vmulI,  0x4 /* 0b0100 */, 0x9 /* 0b1001 */, 1, 0)  // Vd = Vn * Vm (int)
 690   F(vaddI,  0x4 /* 0b0100 */, 0x8 /* 0b1000 */, 0, 0)  // Vd = Vn + Vm (int)
 691   F(vsubI,  0x6 /* 0b0110 */, 0x8 /* 0b1000 */, 0, 0)  // Vd = Vn - Vm (int)
 692   F(vaddF,  0x4 /* 0b0100 */, 0xD /* 0b1101 */, 0, 0)  // Vd = Vn + Vm (float)
 693   F(vsubF,  0x4 /* 0b0100 */, 0xD /* 0b1101 */, 0, 1)  // Vd = Vn - Vm (float)
 694   F(vmulF,  0x6 /* 0b0110 */, 0xD /* 0b1101 */, 1, 0)  // Vd = Vn * Vm (float)
 695   F(vshlSI, 0x4 /* 0b0100 */, 0x4 /* 0b0100 */, 0, 0)  // Vd = ashift(Vm,Vn) (int)
 696   F(vshlUI, 0x6 /* 0b0110 */, 0x4 /* 0b0100 */, 0, 0)  // Vd = lshift(Vm,Vn) (int)
 697   F(_vandI, 0x4 /* 0b0100 */, 0x1 /* 0b0001 */, 1, 0)  // Vd = Vn & Vm (int)
 698   F(_vorI,  0x4 /* 0b0100 */, 0x1 /* 0b0001 */, 1, 1)  // Vd = Vn | Vm (int)
 699   F(_vxorI, 0x6 /* 0b0110 */, 0x1 /* 0b0001 */, 1, 0)  // Vd = Vn ^ Vm (int)
 700 #undef F
 701 
 702   void vandI(FloatRegister fd, FloatRegister fn, FloatRegister fm, int quad) {
 703     _vandI(fd, fn, fm, 0, quad);
 704   }
 705   void vorI(FloatRegister fd, FloatRegister fn, FloatRegister fm, int quad) {
 706     _vorI(fd, fn, fm, 0, quad);
 707   }
 708   void vxorI(FloatRegister fd, FloatRegister fn, FloatRegister fm, int quad) {
 709     _vxorI(fd, fn, fm, 0, quad);
 710   }
 711 
 712   void vneg(FloatRegister fd, FloatRegister fm, int size, int flt, int quad) {
 713     CHECK_VFP_PRESENT;
 714     assert(VM_Version::has_simd(), "simd instruction");
 715     assert(fd->lo_bit() == 0 && fm->lo_bit() == 0,
 716            "single precision register?");
 717     assert(!quad || ((fd->hi_bits() | fm->hi_bits()) & 1) == 0,
 718            "quad precision register?");
 719     emit_int32(0xf << 28 | 0x3B /* 0b00111011 */ << 20 | 0x1 /* 0b01 */ << 16 | 0x7 /* 0b111 */ << 7 |
 720                size << 18 | quad << 6 | flt << 10 |
 721                fd->hi_bits() << 12 | fd->hi_bit() << 22 |
 722                fm->hi_bits() <<  0 | fm->hi_bit() << 5);
 723   }
 724 
 725   void vnegI(FloatRegister fd, FloatRegister fm, int size, int quad) {
 726     int flt = 0;
 727     vneg(fd, fm, size, flt, quad);
 728   }
 729 
 730   void vshli(FloatRegister fd, FloatRegister fm, int size, int imm, int quad) {
 731     CHECK_VFP_PRESENT;
 732     assert(VM_Version::has_simd(), "simd instruction");
 733     assert(fd->lo_bit() == 0 && fm->lo_bit() == 0,
 734            "single precision register?");
 735     assert(!quad || ((fd->hi_bits() | fm->hi_bits()) & 1) == 0,
 736            "quad precision register?");
 737 
 738     if (imm >= size) {
 739       // maximum shift gives all zeroes, direction doesn't matter,
 740       // but only available for shift right
 741       vshri(fd, fm, size, size, true /* unsigned */, quad);
 742       return;
 743     }
 744     assert(imm >= 0 && imm < size, "out of range");
 745 
 746     int imm6 = 0;
 747     int L = 0;
 748     switch (size) {
 749     case 8:
 750     case 16:
 751     case 32:
 752       imm6 = size + imm ;
 753       break;
 754     case 64:
 755       L = 1;
 756       imm6 = imm ;
 757       break;
 758     default:
 759       ShouldNotReachHere();
 760     }
 761     emit_int32(0xf << 28 | 0x5 /* 0b00101 */ << 23 | 0x51 /* 0b01010001 */ << 4 |
 762                imm6 << 16 | L << 7 | quad << 6 |
 763                fd->hi_bits() << 12 | fd->hi_bit() << 22 |
 764                fm->hi_bits() <<  0 | fm->hi_bit() << 5);
 765   }
 766 
 767   void vshri(FloatRegister fd, FloatRegister fm, int size, int imm,
 768              bool U /* unsigned */, int quad) {
 769     CHECK_VFP_PRESENT;
 770     assert(VM_Version::has_simd(), "simd instruction");
 771     assert(fd->lo_bit() == 0 && fm->lo_bit() == 0,
 772            "single precision register?");
 773     assert(!quad || ((fd->hi_bits() | fm->hi_bits()) & 1) == 0,
 774            "quad precision register?");
 775     assert(imm > 0, "out of range");
 776     if (imm >= size) {
 777       // maximum shift (all zeroes)
 778       imm = size;
 779     }
 780     int imm6 = 0;
 781     int L = 0;
 782     switch (size) {
 783     case 8:
 784     case 16:
 785     case 32:
 786       imm6 = 2 * size - imm ;
 787       break;
 788     case 64:
 789       L = 1;
 790       imm6 = 64 - imm ;
 791       break;
 792     default:
 793       ShouldNotReachHere();
 794     }
 795     emit_int32(0xf << 28 | 0x5 /* 0b00101 */ << 23 | 0x1 /* 0b00000001 */ << 4 |
 796                imm6 << 16 | L << 7 | quad << 6 | U << 24 |
 797                fd->hi_bits() << 12 | fd->hi_bit() << 22 |
 798                fm->hi_bits() <<  0 | fm->hi_bit() << 5);
 799   }
 800   void vshrUI(FloatRegister fd, FloatRegister fm, int size, int imm, int quad) {
 801     vshri(fd, fm, size, imm, true /* unsigned */, quad);
 802   }
 803   void vshrSI(FloatRegister fd, FloatRegister fm, int size, int imm, int quad) {
 804     vshri(fd, fm, size, imm, false /* signed */, quad);
 805   }
 806 
 807   // Extension opcodes where P,Q,R,S = 1 opcode is in Fn
 808 #define F(mnemonic, N, opcode) \
 809   void mnemonic##d(FloatRegister fd, FloatRegister fm, AsmCondition cond = al) {  \
 810     CHECK_VFP_PRESENT;                                                            \
 811     assert(fd->lo_bit() == 0 && fm->hi_bit() == 0, "incorrect register?");        \
 812     emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |         \
 813               double_cp_num |                                                     \
 814               fd->hi_bits() << 12 | fd->hi_bit() << 22 |                          \
 815               fm->hi_bits()       | fm->lo_bit() << 5);                           \
 816   }                                                                               \
 817   void mnemonic##s(FloatRegister fd, FloatRegister fm, AsmCondition cond = al) {  \
 818     CHECK_VFP_PRESENT;                                                            \
 819     assert(fd->hi_bit() == 0 && fm->hi_bit() == 0, "double precision register?"); \
 820     emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |         \
 821               single_cp_num |                                                     \
 822               fd->hi_bits() << 12 | fd->lo_bit() << 22 |                          \
 823               fm->hi_bits()       | fm->lo_bit() << 5);                           \
 824   }
 825 
 826   F(fuito,  0, 0x8)  // Unsigned integer to floating point conversion
 827   F(fsito,  1, 0x8)  // Signed integer to floating point conversion
 828 #undef F
 829 
 830 #define F(mnemonic, N, opcode) \
 831   void mnemonic##d(FloatRegister fd, FloatRegister fm, AsmCondition cond = al) {  \
 832     CHECK_VFP_PRESENT;                                                            \
 833     assert(fd->hi_bit() == 0 && fm->lo_bit() == 0, "incorrect register?");        \
 834     emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |         \
 835               double_cp_num |                                                     \
 836               fd->hi_bits() << 12 | fd->lo_bit() << 22 |                          \
 837               fm->hi_bits()       | fm->hi_bit() << 5);                           \
 838   }                                                                               \
 839   void mnemonic##s(FloatRegister fd, FloatRegister fm, AsmCondition cond = al) {  \
 840     CHECK_VFP_PRESENT;                                                            \
 841     assert(fd->hi_bit() == 0 && fm->hi_bit() == 0, "double precision register?"); \
 842     emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |         \
 843               single_cp_num |                                                     \
 844               fd->hi_bits() << 12 | fd->lo_bit() << 22 |                          \
 845               fm->hi_bits()       | fm->lo_bit() << 5);                           \
 846   }
 847 
 848   F(ftoui,  0, 0xc)  // Float to unsigned int conversion
 849   F(ftouiz, 1, 0xc)  // Float to unsigned int conversion, RZ mode
 850   F(ftosi,  0, 0xd)  // Float to signed int conversion
 851   F(ftosiz, 1, 0xd)  // Float to signed int conversion, RZ mode
 852 #undef F
 853 
 854 #define F(mnemonic, N, opcode) \
 855   void mnemonic##d(FloatRegister fd, FloatRegister fm, AsmCondition cond = al) {  \
 856     CHECK_VFP_PRESENT;                                                            \
 857     assert(fd->hi_bit() == 0 && fm->lo_bit() == 0, "incorrect register?");        \
 858     emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |         \
 859               double_cp_num |                                                     \
 860               fd->hi_bits() << 12 | fd->lo_bit() << 22 |                          \
 861               fm->hi_bits()       | fm->hi_bit() << 5);                           \
 862   }                                                                               \
 863   void mnemonic##s(FloatRegister fd, FloatRegister fm, AsmCondition cond = al) {  \
 864     CHECK_VFP_PRESENT;                                                            \
 865     assert(fd->lo_bit() == 0 && fm->hi_bit() == 0, "incorrect register?");        \
 866     emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |         \
 867               single_cp_num |                                                     \
 868               fd->hi_bits() << 12 | fd->hi_bit() << 22 |                          \
 869               fm->hi_bits()       | fm->lo_bit() << 5);                           \
 870   }
 871 
 872   F(fcvtd,  1, 0x7)  // Single->Double conversion
 873   F(fcvts,  1, 0x7)  // Double->Single conversion
 874 #undef F
 875 
 876 #define F(mnemonic, N, opcode) \
 877   void mnemonic##d(FloatRegister fd, FloatRegister fm, AsmCondition cond = al) {  \
 878     CHECK_VFP_PRESENT;                                                            \
 879     assert(fd->lo_bit() == 0 && fm->lo_bit() == 0, "single precision register?"); \
 880     emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |         \
 881               double_cp_num |                                                     \
 882               fd->hi_bits() << 12 | fd->hi_bit() << 22 |                          \
 883               fm->hi_bits()       | fm->hi_bit() << 5);                           \
 884   }                                                                               \
 885   void mnemonic##s(FloatRegister fd, FloatRegister fm, AsmCondition cond = al) {  \
 886     CHECK_VFP_PRESENT;                                                            \
 887     assert(fd->hi_bit() == 0 && fm->hi_bit() == 0, "double precision register?"); \
 888     emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |         \
 889               single_cp_num |                                                     \
 890               fd->hi_bits() << 12 | fd->lo_bit() << 22 |                          \
 891               fm->hi_bits()       | fm->lo_bit() << 5);                           \
 892   }
 893 
 894   F(fcpy,   0, 0x0)  // Fd = Fm
 895   F(fabs,   1, 0x0)  // Fd = abs(Fm)
 896   F(fneg,   0, 0x1)  // Fd = -Fm
 897   F(fsqrt,  1, 0x1)  // Fd = sqrt(Fm)
 898   F(fcmp,   0, 0x4)  // Compare Fd with Fm no exceptions on quiet NANs
 899   F(fcmpe,  1, 0x4)  // Compare Fd with Fm with exceptions on quiet NANs
 900 #undef F
 901 
 902   // Opcodes with one operand only
 903 #define F(mnemonic, N, opcode) \
 904   void mnemonic##d(FloatRegister fd, AsmCondition cond = al) {               \
 905     CHECK_VFP_PRESENT;                                                       \
 906     assert(fd->lo_bit() == 0, "single precision register?");                 \
 907     emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |    \
 908               double_cp_num | fd->hi_bits() << 12 | fd->hi_bit() << 22);     \
 909   }                                                                          \
 910   void mnemonic##s(FloatRegister fd, AsmCondition cond = al) {               \
 911     CHECK_VFP_PRESENT;                                                       \
 912     assert(fd->hi_bit() == 0, "double precision register?");                 \
 913     emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |    \
 914               single_cp_num | fd->hi_bits() << 12 | fd->lo_bit() << 22);     \
 915   }
 916 
 917   F(fcmpz,  0, 0x5)  // Compare Fd with 0, no exceptions quiet NANs
 918   F(fcmpez, 1, 0x5)  // Compare Fd with 0, with exceptions quiet NANs
 919 #undef F
 920 
 921   // Float loads (L==1) and stores (L==0)
 922 #define F(mnemonic, L) \
 923   void mnemonic##d(FloatRegister fd, Address addr, AsmCondition cond = al) { \
 924     CHECK_VFP_PRESENT;                                                       \
 925     assert(fd->lo_bit() == 0, "single precision register?");                 \
 926     emit_int32(cond << 28 | 0xd << 24 | L << 20 |                            \
 927               fd->hi_bits() << 12 | fd->hi_bit() << 22 |                     \
 928               double_cp_num | addr.encoding_vfp());                          \
 929   }                                                                          \
 930   void mnemonic##s(FloatRegister fd, Address addr, AsmCondition cond = al) { \
 931     CHECK_VFP_PRESENT;                                                       \
 932     assert(fd->hi_bit() == 0, "double precision register?");                 \
 933     emit_int32(cond << 28 | 0xd << 24 | L << 20 |                            \
 934               fd->hi_bits() << 12 | fd->lo_bit() << 22 |                     \
 935               single_cp_num | addr.encoding_vfp());                          \
 936   }
 937 
 938   F(fst, 0)  // Store 1 register
 939   F(fld, 1)  // Load 1 register
 940 #undef F
 941 
 942   // Float load and store multiple
 943 #define F(mnemonic, l, pu) \
 944   void mnemonic##d(Register rn, FloatRegisterSet reg_set,                    \
 945                    AsmWriteback w = no_writeback, AsmCondition cond = al) {  \
 946     CHECK_VFP_PRESENT;                                                       \
 947     assert(w == no_writeback || rn != PC, "unpredictable instruction");      \
 948     assert(!(w == no_writeback && pu == 2), "encoding constraint");          \
 949     assert((reg_set.encoding_d() & 1) == 0, "encoding constraint");          \
 950     emit_int32(cond << 28 | 6 << 25 | pu << 23 | w << 21 | l << 20 |         \
 951               rn->encoding() << 16 | reg_set.encoding_d() | double_cp_num);  \
 952   }                                                                          \
 953   void mnemonic##s(Register rn, FloatRegisterSet reg_set,                    \
 954                    AsmWriteback w = no_writeback, AsmCondition cond = al) {  \
 955     CHECK_VFP_PRESENT;                                                       \
 956     assert(w == no_writeback || rn != PC, "unpredictable instruction");      \
 957     assert(!(w == no_writeback && pu == 2), "encoding constraint");          \
 958     emit_int32(cond << 28 | 6 << 25 | pu << 23 | w << 21 | l << 20 |         \
 959               rn->encoding() << 16 | reg_set.encoding_s() | single_cp_num);  \
 960   }
 961 
 962   F(fldmia, 1, 1)    F(fldmfd, 1, 1)
 963   F(fldmdb, 1, 2)    F(fldmea, 1, 2)
 964   F(fstmia, 0, 1)    F(fstmfd, 0, 1)
 965   F(fstmdb, 0, 2)    F(fstmea, 0, 2)
 966 #undef F
 967 
 968   // fconst{s,d} encoding:
 969   //  31  28 27   23 22  21 20 19   16 15 12 10  9  8   7    4 3     0
 970   // | cond | 11101 | D | 11  | imm4H | Vd  | 101 | sz | 0000 | imm4L |
 971   // sz = 0 for single precision, 1 otherwise
 972   // Register number is Vd:D for single precision, D:Vd otherwise
 973   // immediate value is imm4H:imm4L
 974 
 975   void fconsts(FloatRegister fd, unsigned char imm_8, AsmCondition cond = al) {
 976     CHECK_VFP_PRESENT;
 977     assert(fd->hi_bit() == 0, "double precision register?");
 978     emit_int32(cond << 28 | 0xeb << 20 | single_cp_num |
 979               fd->hi_bits() << 12 | fd->lo_bit() << 22 | (imm_8 & 0xf) | (imm_8 >> 4) << 16);
 980   }
 981 
 982   void fconstd(FloatRegister fd, unsigned char imm_8, AsmCondition cond = al) {
 983     CHECK_VFP_PRESENT;
 984     assert(fd->lo_bit() == 0, "double precision register?");
 985     emit_int32(cond << 28 | 0xeb << 20 | double_cp_num |
 986               fd->hi_bits() << 12 | fd->hi_bit() << 22 | (imm_8 & 0xf) | (imm_8 >> 4) << 16);
 987   }
 988 
 989   // GPR <-> FPR transfers
 990   void fmsr(FloatRegister fd, Register rd, AsmCondition cond = al) {
 991     CHECK_VFP_PRESENT;
 992     assert(fd->hi_bit() == 0, "double precision register?");
 993     emit_int32(cond << 28 | 0xe0 << 20 | single_cp_num | 1 << 4 |
 994               fd->hi_bits() << 16 | fd->lo_bit() << 7 | rd->encoding() << 12);
 995   }
 996 
 997   void fmrs(Register rd, FloatRegister fd, AsmCondition cond = al) {
 998     CHECK_VFP_PRESENT;
 999     assert(fd->hi_bit() == 0, "double precision register?");
1000     emit_int32(cond << 28 | 0xe1 << 20 | single_cp_num | 1 << 4 |
1001               fd->hi_bits() << 16 | fd->lo_bit() << 7 | rd->encoding() << 12);
1002   }
1003 
1004   void fmdrr(FloatRegister fd, Register rd, Register rn, AsmCondition cond = al) {
1005     CHECK_VFP_PRESENT;
1006     assert(fd->lo_bit() == 0, "single precision register?");
1007     emit_int32(cond << 28 | 0xc4 << 20 | double_cp_num | 1 << 4 |
1008               fd->hi_bits() | fd->hi_bit() << 5 |
1009               rn->encoding() << 16 | rd->encoding() << 12);
1010   }
1011 
1012   void fmrrd(Register rd, Register rn, FloatRegister fd, AsmCondition cond = al) {
1013     CHECK_VFP_PRESENT;
1014     assert(fd->lo_bit() == 0, "single precision register?");
1015     emit_int32(cond << 28 | 0xc5 << 20 | double_cp_num | 1 << 4 |
1016               fd->hi_bits() | fd->hi_bit() << 5 |
1017               rn->encoding() << 16 | rd->encoding() << 12);
1018   }
1019 
1020   void fmstat(AsmCondition cond = al) {
1021     CHECK_VFP_PRESENT;
1022     emit_int32(cond << 28 | 0xef1fa10);
1023   }
1024 
1025   void vmrs(Register rt, VFPSystemRegister sr, AsmCondition cond = al) {
1026     assert((sr->encoding() & (~0xf)) == 0, "what system register is that?");
1027     emit_int32(cond << 28 | rt->encoding() << 12 | sr->encoding() << 16 | 0xef00a10);
1028   }
1029 
1030   void vmsr(VFPSystemRegister sr, Register rt, AsmCondition cond = al) {
1031     assert((sr->encoding() & (~0xf)) == 0, "what system register is that?");
1032     emit_int32(cond << 28 | rt->encoding() << 12 | sr->encoding() << 16 | 0xee00a10);
1033   }
1034 
1035   void vcnt(FloatRegister Dd, FloatRegister Dm) {
1036     CHECK_VFP_PRESENT;
1037     // emitted at VM startup to detect whether the instruction is available
1038     assert(!VM_Version::is_initialized() || VM_Version::has_simd(), "simd instruction");
1039     assert(Dd->lo_bit() == 0 && Dm->lo_bit() == 0, "single precision registers?");
1040     emit_int32(0xf3b00500 | Dd->hi_bit() << 22 | Dd->hi_bits() << 12 | Dm->hi_bit() << 5 | Dm->hi_bits());
1041   }
1042 
1043   void vpaddl(FloatRegister Dd, FloatRegister Dm, int size, bool s) {
1044     CHECK_VFP_PRESENT;
1045     assert(VM_Version::has_simd(), "simd instruction");
1046     assert(Dd->lo_bit() == 0 && Dm->lo_bit() == 0, "single precision registers?");
1047     assert(size == 8 || size == 16 || size == 32, "unexpected size");
1048     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());
1049   }
1050 
1051   void vld1(FloatRegister Dd, Address addr, VElem_Size size, int bits) {
1052     CHECK_VFP_PRESENT;
1053     assert(VM_Version::has_simd(), "simd instruction");
1054     assert(Dd->lo_bit() == 0, "single precision registers?");
1055     int align = 0;
1056     assert(bits == 128, "code assumption");
1057     VLD_Type type = VLD1_TYPE_2_REGS; // 2x64
1058     emit_int32(0xf4200000 | Dd->hi_bit() << 22 | Dd->hi_bits() << 12 | type << 8 | size << 6 | align << 4 | addr.encoding_simd());
1059   }
1060 
1061   void vst1(FloatRegister Dd, Address addr, VElem_Size size, int bits) {
1062     CHECK_VFP_PRESENT;
1063     assert(VM_Version::has_simd(), "simd instruction");
1064     assert(Dd->lo_bit() == 0, "single precision registers?");
1065     int align = 0;
1066     assert(bits == 128, "code assumption");
1067     VLD_Type type = VLD1_TYPE_2_REGS; // 2x64
1068     emit_int32(0xf4000000 | Dd->hi_bit() << 22 | Dd->hi_bits() << 12 | type << 8 | size << 6 | align << 4 | addr.encoding_simd());
1069   }
1070 
1071   void vmovI(FloatRegister Dd, int imm8, VElem_Size size, int quad) {
1072     CHECK_VFP_PRESENT;
1073     assert(VM_Version::has_simd(), "simd instruction");
1074     assert(Dd->lo_bit() == 0, "single precision register?");
1075     assert(!quad || (Dd->hi_bits() & 1) == 0, "quad precision register?");
1076     assert(imm8 >= 0 && imm8 < 256, "out of range");
1077     int op;
1078     int cmode;
1079     switch (size) {
1080     case VELEM_SIZE_8:
1081       op = 0;
1082       cmode = 0xE /* 0b1110 */;
1083       break;
1084     case VELEM_SIZE_16:
1085       op = 0;
1086       cmode = 0x8 /* 0b1000 */;
1087       break;
1088     case VELEM_SIZE_32:
1089       op = 0;
1090       cmode = 0x0 /* 0b0000 */;
1091       break;
1092     default:
1093       ShouldNotReachHere();
1094       return;
1095     }
1096     emit_int32(0xf << 28 | 0x1 << 25 | 0x1 << 23 | 0x1 << 4 |
1097               (imm8 >> 7) << 24 | ((imm8 & 0x70) >> 4) << 16 | (imm8 & 0xf) |
1098               quad << 6 | op << 5 | cmode << 8 |
1099               Dd->hi_bits() << 12 | Dd->hi_bit() << 22);
1100   }
1101 
1102   void vdupI(FloatRegister Dd, Register Rs, VElem_Size size, int quad,
1103              AsmCondition cond = al) {
1104     CHECK_VFP_PRESENT;
1105     assert(VM_Version::has_simd(), "simd instruction");
1106     assert(Dd->lo_bit() == 0, "single precision register?");
1107     assert(!quad || (Dd->hi_bits() & 1) == 0, "quad precision register?");
1108     int b;
1109     int e;
1110     switch (size) {
1111     case VELEM_SIZE_8:
1112       b = 1;
1113       e = 0;
1114       break;
1115     case VELEM_SIZE_16:
1116       b = 0;
1117       e = 1;
1118       break;
1119     case VELEM_SIZE_32:
1120       b = 0;
1121       e = 0;
1122       break;
1123     default:
1124       ShouldNotReachHere();
1125       return;
1126     }
1127     emit_int32(cond << 28 | 0x1D /* 0b11101 */ << 23 | 0xB /* 0b1011 */ << 8 | 0x1 << 4 |
1128               quad << 21 | b << 22 |  e << 5 | Rs->encoding() << 12 |
1129               Dd->hi_bits() << 16 | Dd->hi_bit() << 7);
1130   }
1131 
1132   void vdup(FloatRegister Dd, FloatRegister Ds, int index, int size, int quad) {
1133     CHECK_VFP_PRESENT;
1134     assert(VM_Version::has_simd(), "simd instruction");
1135     assert(Dd->lo_bit() == 0, "single precision register?");
1136     assert(Ds->lo_bit() == 0, "single precision register?");
1137     assert(!quad || (Dd->hi_bits() & 1) == 0, "quad precision register?");
1138     int range = 64 / size;
1139     assert(index < range, "overflow");
1140     int imm4;
1141     switch (size) {
1142     case 8:
1143       assert((index & 0x7 /* 0b111 */) == index, "overflow");
1144       imm4 = index << 1 | 0x1 /* 0b0001 */;
1145       break;
1146     case 16:
1147       assert((index & 0x3 /* 0b11 */) == index, "overflow");
1148       imm4 = index << 2 | 0x2 /* 0b0010 */;
1149       break;
1150     case 32:
1151       assert((index & 0x1 /* 0b1 */) == index, "overflow");
1152       imm4 = index << 3 | 0x4 /* 0b0100 */;
1153       break;
1154     default:
1155       ShouldNotReachHere();
1156       return;
1157     }
1158     emit_int32(0xF /* 0b1111 */ << 28 | 0x3B /* 0b00111011 */ << 20 | 0x6 /* 0b110 */ << 9 |
1159                quad << 6 | imm4 << 16 |
1160                Dd->hi_bits() << 12 | Dd->hi_bit() << 22 |
1161                Ds->hi_bits() << 00 | Ds->hi_bit() << 5);
1162   }
1163 
1164   void vdupF(FloatRegister Dd, FloatRegister Ss, int quad) {
1165     int index = 0;
1166     FloatRegister Ds = as_FloatRegister(Ss->encoding() & ~1);
1167     if (Ss->lo_bit() != 0) {
1168       /* odd S register */
1169       assert(Ds->successor() == Ss, "bad reg");
1170       index = 1;
1171     } else {
1172       /* even S register */
1173       assert(Ds == Ss, "bad reg");
1174     }
1175     vdup(Dd, Ds, index, 32, quad);
1176   }
1177 
1178   void vrev(FloatRegister Dd, FloatRegister Dm, int quad, int region_size, VElem_Size size) {
1179     CHECK_VFP_PRESENT;
1180     assert(VM_Version::has_simd(), "simd instruction");
1181     assert(Dd->lo_bit() == 0, "single precision register?");
1182     assert(Dm->lo_bit() == 0, "single precision register?");
1183     assert(!quad || ((Dd->hi_bits() | Dm->hi_bits()) & 1) == 0,
1184            "quad precision register?");
1185     unsigned int op = 0;
1186     switch (region_size) {
1187       case 16: op = 0x2; /*0b10*/ break;
1188       case 32: op = 0x1; /*0b01*/ break;
1189       case 64: op = 0x0; /*0b00*/ break;
1190       default: assert(false, "encoding constraint");
1191     }
1192     emit_int32(0xf << 28 | 0x7 << 23 | Dd->hi_bit() << 22 | 0x3 << 20 |
1193                size << 18 | Dd->hi_bits() << 12 | op  << 7 | quad << 6 | Dm->hi_bit() << 5 |
1194                Dm->hi_bits());
1195   }
1196 
1197   void veor(FloatRegister Dd, FloatRegister Dn, FloatRegister Dm, int quad) {
1198     CHECK_VFP_PRESENT;
1199     assert(VM_Version::has_simd(), "simd instruction");
1200     assert(Dd->lo_bit() == 0, "single precision register?");
1201     assert(Dm->lo_bit() == 0, "single precision register?");
1202     assert(Dn->lo_bit() == 0, "single precision register?");
1203     assert(!quad || ((Dd->hi_bits() | Dm->hi_bits() | Dn->hi_bits()) & 1) == 0,
1204            "quad precision register?");
1205 
1206     emit_int32(0xf << 28 | 0x3 << 24 | Dd->hi_bit() << 22 | Dn->hi_bits() << 16 |
1207                Dd->hi_bits() << 12 | 0x1 << 8 | Dn->hi_bit() << 7 | quad << 6 |
1208                Dm->hi_bit() << 5 | 0x1 << 4 | Dm->hi_bits());
1209   }
1210 
1211 
1212   Assembler(CodeBuffer* code) : AbstractAssembler(code) {}
1213 
1214 #ifdef COMPILER2
1215   typedef VFP::double_num double_num;
1216   typedef VFP::float_num  float_num;
1217 #endif
1218 };
1219 
1220 #ifdef __SOFTFP__
1221 // Soft float function declarations
1222 extern "C" {
1223 extern float  __aeabi_fadd(float, float);
1224 extern float  __aeabi_fmul(float, float);
1225 extern float  __aeabi_fsub(float, float);
1226 extern float  __aeabi_fdiv(float, float);
1227 
1228 extern double __aeabi_dadd(double, double);
1229 extern double __aeabi_dmul(double, double);
1230 extern double __aeabi_dsub(double, double);
1231 extern double __aeabi_ddiv(double, double);
1232 
1233 extern double __aeabi_f2d(float);
1234 extern float  __aeabi_d2f(double);
1235 extern float  __aeabi_i2f(int);
1236 extern double __aeabi_i2d(int);
1237 extern int    __aeabi_f2iz(float);
1238 
1239 extern int  __aeabi_fcmpeq(float, float);
1240 extern int  __aeabi_fcmplt(float, float);
1241 extern int  __aeabi_fcmple(float, float);
1242 extern int  __aeabi_fcmpge(float, float);
1243 extern int  __aeabi_fcmpgt(float, float);
1244 
1245 extern int  __aeabi_dcmpeq(double, double);
1246 extern int  __aeabi_dcmplt(double, double);
1247 extern int  __aeabi_dcmple(double, double);
1248 extern int  __aeabi_dcmpge(double, double);
1249 extern int  __aeabi_dcmpgt(double, double);
1250 
1251 // Imported code from glibc soft-fp bundle for
1252 // calculation accuracy improvement. See CR 6757269.
1253 extern double __aeabi_fadd_glibc(float, float);
1254 extern double __aeabi_fsub_glibc(float, float);
1255 extern double __aeabi_dadd_glibc(double, double);
1256 extern double __aeabi_dsub_glibc(double, double);
1257 };
1258 #endif // __SOFTFP__
1259 
1260 
1261 #endif // CPU_ARM_ASSEMBLER_ARM_32_HPP