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