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