1 /*
   2  * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
   4  * Copyright (c) 2015, Linaro Ltd. All rights reserved.
   5  * Copyright (c) 2015-2018, Azul Systems, Inc. All rights reserved.
   6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   7  *
   8  * This code is free software; you can redistribute it and/or modify it
   9  * under the terms of the GNU General Public License version 2 only, as
  10  * published by the Free Software Foundation.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  23  * or visit www.oracle.com if you need additional information or have any
  24  * questions.
  25  *
  26  */
  27 
  28 #ifndef CPU_AARCH32_VM_ASSEMBLER_AARCH32_HPP
  29 #define CPU_AARCH32_VM_ASSEMBLER_AARCH32_HPP
  30 
  31 #include "asm/register.hpp"
  32 #include "vm_version_aarch32.hpp"
  33 
  34 // Definitions of various symbolic names for machine registers
  35 
  36 // Here we define how many integer and double precision floating point
  37 // registers are used for passing parameters by the C and Java calling
  38 // conventions. Each double precision floating point register can be used
  39 // as two single precision registers.
  40 
  41 class Argument {
  42  public:
  43   enum {
  44     n_int_register_parameters_c = 4,   // c_rarg0, c_rarg1, c_rarg2, c_rarg3
  45 #ifdef HARD_FLOAT_CC
  46     n_float_register_parameters_c = 8, // c_farg0, c_farg1, ..., c_farg7
  47 #else // HARD_FLOAT_CC
  48     n_float_register_parameters_c = 0, // 0 registers used to pass arguments
  49 #endif // HARD_FLOAT_CC
  50     n_int_register_parameters_j = 4,   // j_rarg0, j_rarg1, j_rarg2, j_rarg3
  51 #ifdef HARD_FLOAT_CC
  52     n_float_register_parameters_j = 8  // j_farg0, j_farg1, ..., j_farg7
  53 #else // HARD_FLOAT_CC
  54     n_float_register_parameters_j = 0  // 0 registers used to pass arguments
  55 #endif // HARD_FLOAT_CC
  56   };
  57 };
  58 
  59 // Symbolic names for the register arguments used by the C calling convention
  60 // (the calling convention for C runtime calls and calls to JNI native
  61 // methods)
  62 
  63 REGISTER_DECLARATION(Register, c_rarg0, r0);
  64 REGISTER_DECLARATION(Register, c_rarg1, r1);
  65 REGISTER_DECLARATION(Register, c_rarg2, r2);
  66 REGISTER_DECLARATION(Register, c_rarg3, r3);
  67 
  68 // Symbolic names for the register arguments used by the Java calling
  69 // convention (the calling convention for calls to compiled Java methods)
  70 
  71 // In contrary to most ports we don't shift java argument registers by 1. Although
  72 // it helps to avoid extra argument copy when invoking JNI methods it brings a
  73 // lot more complexity into C2 port and prevents from using ldrd/strd instructions
  74 // when dealing with jlong values.
  75 //
  76 //  |-----------------------------------|
  77 //  | c_rarg0  c_rarg1  c_rarg2 c_rarg3 |
  78 //  |-----------------------------------|
  79 //  | r0       r1       r2      r3      |
  80 //  |-----------------------------------|
  81 //  | j_rarg0  j_rarg1  j_rarg2 j_rarg3 |
  82 //  |-----------------------------------|
  83 
  84 REGISTER_DECLARATION(Register, j_rarg0, c_rarg0);
  85 REGISTER_DECLARATION(Register, j_rarg1, c_rarg1);
  86 REGISTER_DECLARATION(Register, j_rarg2, c_rarg2);
  87 REGISTER_DECLARATION(Register, j_rarg3, c_rarg3);
  88 
  89 // Common register aliases used in assembler code
  90 
  91 // These registers are used to hold VM data either temporarily within a method
  92 // or across method calls. According to AAPCS, r0-r3 and r12 are caller-saved,
  93 // the rest are callee-saved.
  94 
  95 // These 4 aliases are used in the template interpreter only.
  96 
  97 REGISTER_DECLARATION(Register, rdispatch, r4);  // Address of dispatch table
  98 REGISTER_DECLARATION(Register, rbcp,      r5);  // Bytecode pointer
  99 REGISTER_DECLARATION(Register, rlocals,   r6);  // Address of local variables section of current frame
 100 REGISTER_DECLARATION(Register, rcpool,    r7);  // Address of constant pool cache
 101 
 102 // The following aliases are used in all VM components.
 103 
 104 REGISTER_DECLARATION(Register, rmethod,   r8);  // Address of current method
 105 REGISTER_DECLARATION(Register, rscratch1, r9);  // Scratch register
 106 REGISTER_DECLARATION(Register, rthread,   r10); // Address of current thread
 107 REGISTER_DECLARATION(Register, rfp,       r11); // Frame pointer
 108 REGISTER_DECLARATION(Register, rscratch2, r12); // Scratch register
 109 REGISTER_DECLARATION(Register, sp,        r13); // Stack pointer
 110 REGISTER_DECLARATION(Register, lr,        r14); // Link register
 111 REGISTER_DECLARATION(Register, r15_pc,    r15); // Program counter
 112 
 113 
 114 extern "C" void entry(CodeBuffer *cb);
 115 
 116 
 117 #define assert_cond(ARG1) assert(ARG1, #ARG1)
 118 
 119 class Assembler;
 120 
 121 class Instruction_aarch32 {
 122   unsigned insn;
 123 #ifdef ASSERT
 124   unsigned bits;
 125 #endif
 126   Assembler *assem;
 127 
 128 public:
 129 
 130   Instruction_aarch32(class Assembler *as) {
 131 #ifdef ASSERT
 132     bits = 0;
 133 #endif
 134     insn = 0;
 135     assem = as;
 136   }
 137 
 138   inline ~Instruction_aarch32();
 139 
 140   unsigned &get_insn() { return insn; }
 141 #ifdef ASSERT
 142   unsigned &get_bits() { return bits; }
 143 #endif
 144 
 145   static inline int32_t extend(unsigned val, int hi = 31, int lo = 0) {
 146     union {
 147       unsigned u;
 148       int n;
 149     };
 150 
 151     u = val << (31 - hi);
 152     n = n >> (31 - hi + lo);
 153     return n;
 154   }
 155 
 156   static inline uint32_t extract(uint32_t val, int msb, int lsb) {
 157     int nbits = msb - lsb + 1;
 158     assert_cond(msb >= lsb);
 159     uint32_t mask = (1U << nbits) - 1;
 160     uint32_t result = val >> lsb;
 161     result &= mask;
 162     return result;
 163   }
 164 
 165   static inline int32_t sextract(uint32_t val, int msb, int lsb) {
 166     uint32_t uval = extract(val, msb, lsb);
 167     return extend(uval, msb - lsb);
 168   }
 169 
 170   static void patch(address a, int msb, int lsb, unsigned long val) {
 171     int nbits = msb - lsb + 1;
 172     guarantee(val < (1U << nbits), "Field too big for insn");
 173     assert_cond(msb >= lsb);
 174     unsigned mask = (1U << nbits) - 1;
 175     val <<= lsb;
 176     mask <<= lsb;
 177     unsigned target = *(unsigned *)a;
 178     target &= ~mask;
 179     target |= val;
 180     *(unsigned *)a = target;
 181   }
 182 
 183   static void spatch(address a, int msb, int lsb, long val) {
 184     int nbits = msb - lsb + 1;
 185     long chk = val >> (nbits - 1);
 186     guarantee (chk == -1 || chk == 0, "Field too big for insn");
 187     unsigned uval = val;
 188     unsigned mask = (1U << nbits) - 1;
 189     uval &= mask;
 190     uval <<= lsb;
 191     mask <<= lsb;
 192     unsigned target = *(unsigned *)a;
 193     target &= ~mask;
 194     target |= uval;
 195     *(unsigned *)a = target;
 196   }
 197 
 198 /*  void f(unsigned val, int msb, int lsb) {
 199     int nbits = msb - lsb + 1;
 200     guarantee(val < (1U << nbits), "Field too big for insn");
 201     assert_cond(msb >= lsb);
 202     unsigned mask = (1U << nbits) - 1;
 203     val <<= lsb;
 204     mask <<= lsb;
 205     insn |= val;
 206     assert_cond((bits & mask) == 0);
 207 #ifdef ASSERT
 208     bits |= mask;
 209 #endif
 210   }*/
 211 
 212   void f(unsigned val, int msb, int lsb) {
 213     int nbits = msb - lsb + 1;
 214     guarantee(val < (1U << nbits), "Field too big for insn");
 215     assert_cond(msb >= lsb);
 216     unsigned mask = (1U << nbits) - 1;
 217     val <<= lsb;
 218     mask <<= lsb;
 219     insn &= ~mask;
 220     insn |= val;
 221 #ifdef ASSERT
 222     bits |= mask;
 223 #endif
 224   }
 225 
 226   void f(unsigned val, int bit) {
 227     f(val, bit, bit);
 228   }
 229 
 230   void sf(long val, int msb, int lsb) {
 231     int nbits = msb - lsb + 1;
 232     long chk = val >> (nbits - 1);
 233     guarantee (chk == -1 || chk == 0, "Field too big for insn");
 234     unsigned uval = val;
 235     unsigned mask = (1U << nbits) - 1;
 236     uval &= mask;
 237     f(uval, lsb + nbits - 1, lsb);
 238   }
 239 
 240   void rf(Register r, int lsb) {
 241     f(r->encoding_nocheck(), lsb + 3, lsb);
 242   }
 243 
 244   void rf(FloatRegister r, int lsb) {
 245     f(r->encoding_nocheck(), lsb + 4, lsb);
 246   }
 247 
 248   unsigned get(int msb = 31, int lsb = 0) {
 249     int nbits = msb - lsb + 1;
 250     unsigned mask = ((1U << nbits) - 1) << lsb;
 251     assert_cond((bits & mask) == mask);
 252     return (insn & mask) >> lsb;
 253   }
 254 
 255   void fixed(unsigned value, unsigned mask) {
 256     assert_cond ((mask & bits) == 0);
 257 #ifdef ASSERT
 258     bits |= mask;
 259 #endif
 260     insn |= value;
 261   }
 262 };
 263 
 264 #define starti Instruction_aarch32 do_not_use(this); set_current(&do_not_use)
 265 
 266 // abs methods which cannot overflow and so are well-defined across
 267 // the entire domain of integer types.
 268 static inline unsigned int uabs(unsigned int n) {
 269   union {
 270     unsigned int result;
 271     int value;
 272   };
 273   result = n;
 274   if (value < 0) result = -result;
 275   return result;
 276 }
 277 static inline unsigned long uabs(unsigned long n) {
 278   union {
 279     unsigned long result;
 280     long value;
 281   };
 282   result = n;
 283   if (value < 0) result = -result;
 284   return result;
 285 }
 286 static inline unsigned long uabs(long n) { return uabs((unsigned long)n); }
 287 static inline unsigned long uabs(int n) { return uabs((unsigned int)n); }
 288 
 289 #define S_DFLT ::lsl()
 290 #define C_DFLT AL
 291 
 292 
 293 // Shift for base reg + reg offset addressing
 294 class shift_op {
 295  public:
 296   enum shift_kind { LSL, LSR, ASR, ROR };
 297  private:
 298   enum shift_source { imm_s, reg_s };
 299   enum shift_source _source;
 300   enum shift_kind _op;
 301   int _shift;
 302   Register _reg;
 303 
 304   bool check_valid() {
 305     if(imm_s == _source) {
 306       switch(_op) {
 307         case LSL: return _shift >= 0 && _shift <= 31;
 308         case ROR: return _shift >= 1 && _shift <= 32;
 309         default:  return _shift >= 1 && _shift <= 32;
 310       }
 311     }
 312     return true; //Don't check register shifts
 313   }
 314  public:
 315   // Default shift is lsl(0)
 316   shift_op()
 317     : _source(imm_s), _op(LSL), _shift(0) { }
 318   shift_op(enum shift_kind op, int shift)
 319     : _source(imm_s), _op(op), _shift(shift) {
 320     if(!shift) {
 321       // All zero shift encodings map to LSL 0
 322       _shift = 0;
 323       _op = LSL;
 324     }
 325     int pshift = _shift;
 326     if(-1 == _shift && ROR == _op) {
 327       // This is an RRX, make shift valid for the check
 328       _shift = 1;
 329       pshift = 0; //set to zero
 330     }
 331     assert(check_valid(), "Invalid shift quantity");
 332     _shift = pshift; //restore shift
 333   }
 334   shift_op(enum shift_kind op, Register r)
 335     : _source(reg_s), _op(op), _reg(r) {}
 336 
 337   shift_kind kind() const {
 338     return _op;
 339   }
 340 
 341   int shift() const {
 342     assert(imm_s == _source, "Not an immediate shift");
 343     return _shift % 32;
 344   }
 345   Register reg() const {
 346     assert(reg_s == _source, "Not a register shift");
 347     return _reg;
 348   }
 349   bool is_register() {
 350     return reg_s == _source;
 351   }
 352   bool operator==(const shift_op& other) const {
 353     if(imm_s == _source && imm_s == other._source) {
 354       return _op == other._op && _shift == other._shift;
 355     } else if (reg_s == _source && imm_s == _source) {
 356       return _op == other._op && _reg == other._reg;
 357     }
 358     return false;
 359   }
 360   bool operator!=(const shift_op& other) const {
 361     return !( *this == other);
 362   }
 363 };
 364 class lsl : public shift_op {
 365  public:
 366   lsl(int sft = 0): shift_op(LSL, sft) { }
 367   lsl(Register r): shift_op(LSL, r) { }
 368 };
 369 class lsr : public shift_op {
 370  public:
 371   lsr(int sft = 0): shift_op(LSR, sft) { }
 372   lsr(Register r): shift_op(LSR, r) { }
 373 };
 374 class asr : public shift_op {
 375  public:
 376   asr(int sft = 0): shift_op(ASR, sft) { }
 377   asr(Register r): shift_op(ASR, r) { }
 378 };
 379 class ror : public shift_op {
 380  public:
 381   ror(int sft = 0): shift_op(ROR, sft) {}
 382   ror(Register r): shift_op(ROR, r) { }
 383 };
 384 class rrx : public shift_op {
 385  public:
 386   rrx(): shift_op(ROR, -1) {}
 387 };
 388 
 389 
 390 // Addressing modes
 391 class Address {
 392  public:
 393   enum access_mode { no_mode, imm, reg, lit };
 394   //literal is class of imm? -> potentially have to split later if some instructions work
 395   // with one but not other although can be determined from registers.
 396   enum wb_mode { off, pre, post };
 397 
 398   enum reg_op { ADD, SUB };
 399 
 400  private:
 401   Register _base;
 402   Register _index;
 403   int _offset;
 404   enum access_mode _acc_mode;
 405   enum wb_mode _wb_mode;
 406   enum reg_op _as_op;
 407   shift_op _shift;
 408 
 409   RelocationHolder _rspec;
 410 
 411   // Typically we use AddressLiterals we want to use their rval
 412   // However in some situations we want the lval (effect address) of
 413   // the item.  We provide a special factory for making those lvals.
 414   bool _is_lval;
 415 
 416   // If the target is far we'll need to load the ea of this to a
 417   // register to reach it. Otherwise if near we can do PC-relative
 418   // addressing.
 419   address _target;
 420 
 421  public:
 422   Address()
 423     : _acc_mode(no_mode) { }
 424   //immediate & literal
 425   Address(Register r, enum wb_mode mode = off)
 426     : _base(r), _index(noreg), _offset(0), _acc_mode(imm), _wb_mode(mode),
 427       _shift(lsl()), _target(0) {
 428     assert(!(r == r15_pc && _wb_mode == pre), "The PC can't be pre-indexed.");
 429   }
 430   Address(Register r, int o, enum wb_mode mode = off)
 431     : _base(r), _index(noreg), _offset(o), _acc_mode(imm), _wb_mode(mode),
 432       _shift(lsl()), _target(0) {
 433     assert(!(r == r15_pc && _wb_mode == pre), "The PC can't be pre-indexed.");
 434   }
 435   Address(Register r, long o, enum wb_mode mode = off)
 436     : _base(r), _index(noreg), _offset(o), _acc_mode(imm), _wb_mode(mode),
 437       _shift(lsl()), _target(0) {
 438     assert(!(r == r15_pc && _wb_mode == pre), "The PC can't be pre-indexed.");
 439   }
 440   Address(Register r, unsigned long o, enum wb_mode mode = off)
 441     : _base(r), _index(noreg), _offset(o), _acc_mode(imm), _wb_mode(mode),
 442       _shift(lsl()), _target(0) {
 443     assert(!(r == r15_pc && _wb_mode == pre), "The PC can't be pre-indexed.");
 444   }
 445   Address(Register r, unsigned int o, enum wb_mode mode = off)
 446     : _base(r), _index(noreg), _offset(o), _acc_mode(imm), _wb_mode(mode),
 447       _shift(lsl()), _target(0) {
 448     assert(!(r == r15_pc && _wb_mode == pre), "The PC can't be pre-indexed.");
 449   }
 450 #ifdef ASSERT
 451   Address(Register r, ByteSize disp)
 452     : _base(r), _index(noreg), _offset(in_bytes(disp)), _acc_mode(imm), _wb_mode(off),
 453       _shift(lsl()), _target(0) {
 454     assert(!(r == r15_pc && _wb_mode == pre), "The PC can't be pre-indexed.");
 455   }
 456 #endif
 457 
 458 
 459   //Register-offset
 460   Address(Register r, Register r1, shift_op shift = lsl(), enum reg_op op = ADD,
 461           enum wb_mode wbm = off)
 462     : _base(r), _index(r1), _offset(0), _acc_mode(reg), _wb_mode(wbm), _as_op(op),
 463       _shift(shift), _target(0) {
 464         assert(!shift.is_register(), "Can't shift a register-offset address by a register");
 465   }
 466 
 467   Address(address target, RelocationHolder const& rspec)
 468     : _acc_mode(lit),
 469       _base(sp),
 470       _wb_mode(off),
 471       _rspec(rspec),
 472       _is_lval(false),
 473       _target(target)
 474       { }
 475   Address(address target, relocInfo::relocType rtype = relocInfo::external_word_type);
 476 
 477 #ifdef COMPILER2
 478   static Address make_raw(int base, int index, int scale, unsigned long o, relocInfo::relocType disp_reloc);
 479 #endif
 480 
 481  private:
 482   //Could be either
 483   void AddressConstruct(Register base, RegisterOrConstant index, enum reg_op op, shift_op shift,
 484                         enum wb_mode mode);
 485  public:
 486 
 487   Address(Register base, RegisterOrConstant index, enum reg_op op, enum wb_mode mode) {
 488     AddressConstruct(base, index, op, lsl(), mode);
 489   }
 490   Address(Register base, RegisterOrConstant index, shift_op shift = lsl(), enum reg_op op = ADD,
 491           enum wb_mode mode = off) {
 492     if(shift.kind() != lsl().kind()) {
 493       assert(index.is_register(), "should be");
 494     }
 495     AddressConstruct(base, index, op, shift, mode);
 496   }
 497 
 498 
 499   Register base() const {
 500     //in aarch64 this didn't apply to preindex mode -> why?
 501     guarantee(_acc_mode == imm || _acc_mode == reg, "wrong mode");
 502     return _base;
 503   }
 504   long offset() const {
 505     return _offset;
 506   }
 507   Register index() const {
 508     return _index;
 509   }
 510   shift_op shift() const {
 511     return _shift;
 512   }
 513   reg_op op() const {
 514     return _as_op;
 515   }
 516   access_mode get_mode() const {
 517     return _acc_mode;
 518   }
 519   wb_mode get_wb_mode() const {
 520     return _wb_mode;
 521   }
 522   bool uses(Register reg) const { return _base == reg || _index == reg; }
 523   unsigned reg_bits() { return _base->bit(_acc_mode != no_mode) | _index->bit(_acc_mode == reg); }
 524   address target() const { return _target; }
 525   const RelocationHolder& rspec() const { return _rspec; }
 526 
 527   void encode(Instruction_aarch32 *i, CodeSection *sec, address pc) const;
 528 
 529   void fp_encode(Instruction_aarch32 *i, CodeSection *sec, address pc) const;
 530 
 531   void lea(MacroAssembler *, Register) const;
 532 
 533   typedef enum {
 534     IDT_BOOLEAN     = T_BOOLEAN,
 535     IDT_CHAR        = T_CHAR,
 536     IDT_FLOAT       = T_FLOAT,
 537     IDT_DOUBLE      = T_DOUBLE,
 538     IDT_BYTE        = T_BYTE,
 539     IDT_SHORT       = T_SHORT,
 540     IDT_INT         = T_INT,
 541     IDT_LONG        = T_LONG,
 542     IDT_OBJECT      = T_OBJECT,
 543     IDT_ARRAY       = T_ARRAY,
 544     IDT_ADDRESS     = T_ADDRESS,
 545     IDT_METADATA    = T_METADATA,
 546     // not really a data type, denotes the use when address value is needed
 547     // itself, and Address instance is not used to fetch actual data from memory
 548     IDT_LEA         = 100,
 549     // ldrex*/strex*
 550     IDT_ATOMIC      = 101,
 551     // multi-word memory access insn (ldmia/stmia etc)
 552     IDT_MULTIWORD
 553   } InsnDataType;
 554 
 555   inline static InsnDataType toInsnDataType(BasicType type) {
 556     return (InsnDataType)type;
 557   }
 558 
 559   Address safe_for(InsnDataType type, MacroAssembler *, Register temp);
 560   bool is_safe_for(InsnDataType);
 561 
 562   static bool offset_ok_for_immed(long offset, InsnDataType type);
 563   static bool shift_ok_for_index(shift_op shift, InsnDataType type);
 564 };
 565 
 566 // Convience classes
 567 class RuntimeAddress: public Address {
 568   public:
 569     RuntimeAddress(address target) : Address(target, relocInfo::runtime_call_type) {}
 570 };
 571 
 572 class OopAddress: public Address {
 573   public:
 574     OopAddress(address target) : Address(target, relocInfo::oop_type){}
 575 };
 576 
 577 class ExternalAddress: public Address {
 578  private:
 579   static relocInfo::relocType reloc_for_target(address target) {
 580     // Sometimes ExternalAddress is used for values which aren't
 581     // exactly addresses, like the card table base.
 582     // external_word_type can't be used for values in the first page
 583     // so just skip the reloc in that case.
 584     return external_word_Relocation::can_be_relocated(target) ? relocInfo::external_word_type : relocInfo::none;
 585   }
 586 
 587  public:
 588     ExternalAddress(address target) : Address(target, reloc_for_target(target)) {}
 589 };
 590 
 591 class InternalAddress: public Address {
 592   public:
 593     InternalAddress(address target) : Address(target, relocInfo::internal_word_type) {}
 594 };
 595 
 596 
 597 const int FPUStateSizeInWords = FloatRegisterImpl::number_of_registers;
 598 
 599 class Assembler : public AbstractAssembler {
 600   void emit_long(jint x) {
 601     AbstractAssembler::emit_int32(x);
 602   }
 603 
 604 public:
 605   //TODO REMOVE shift_kind from here once done
 606   enum shift_kind { LSL, LSR, ASR, ROR };
 607   // NOTE RRX is a special case of ROR with shift = 0#
 608 
 609   // Helper functions for shifts
 610   // Here to allow compiler to find global shift_op without :: prefix as lsl is a
 611   // standalone instruction
 612 #define HELPER(NAME)                                                                \
 613   shift_op NAME(int sft = 0) { return ::NAME(sft); }                                \
 614   shift_op NAME(Register r) { return ::NAME(r); }
 615   HELPER(lsl);
 616   HELPER(lsr);
 617   HELPER(asr);
 618   HELPER(ror);
 619   shift_op rrx() { return ::rrx(); }
 620 #undef HELPER
 621 
 622   typedef enum {
 623     EQ, NE, HS, CS=HS, LO, CC=LO, MI, PL, VS, VC, HI, LS, GE, LT, GT, LE, AL, NV
 624   } Condition;
 625 
 626   enum { instruction_size = 4 };
 627 
 628   static const uint32_t nop_insn = 0xe1a00000;
 629 
 630   Address adjust(Register base, int offset, bool preIncrement) {
 631     if (preIncrement)
 632       return Address(base, offset, Address::pre);
 633     else
 634       return Address(base, offset, Address::post);
 635   }
 636 
 637   Address adjust(Register base, Register index, shift_op shift,
 638       enum Address::reg_op op, bool preIncrement) {
 639     return Address(base, index, shift, op, preIncrement ? Address::pre : Address::post);
 640   }
 641 
 642   Address pre(Register base, int offset) {
 643     return adjust(base, offset, true);
 644   }
 645 
 646   Address pre(Register base, Register index, shift_op shift, enum Address::reg_op op) {
 647     return adjust(base, index, shift, op, true);
 648   }
 649 
 650   Address post (Register base, int offset) {
 651     return adjust(base, offset, false);
 652   }
 653 
 654   Instruction_aarch32* current;
 655 
 656   void set_current(Instruction_aarch32* i) { current = i; }
 657 
 658   void f(unsigned val, int msb, int lsb) {
 659     current->f(val, msb, lsb);
 660   }
 661   void f(unsigned val, int msb) {
 662     current->f(val, msb, msb);
 663   }
 664   void sf(long val, int msb, int lsb) {
 665     current->sf(val, msb, lsb);
 666   }
 667   void rf(Register reg, int lsb) {
 668     current->rf(reg, lsb);
 669   }
 670   void rf(FloatRegister reg, int lsb) {
 671     current->rf(reg, lsb);
 672   }
 673   void fixed(unsigned value, unsigned mask) {
 674     current->fixed(value, mask);
 675   }
 676 
 677   void emit() {
 678     emit_long(current->get_insn());
 679     assert_cond(current->get_bits() == 0xffffffff);
 680     current = NULL;
 681   }
 682 
 683   typedef void (Assembler::* uncond_branch_insn)(address dest);
 684   typedef void (Assembler::* cond_branch_insn)(address dest, Condition cond);
 685   typedef void (Assembler::* cond_ldst_insn)(Register Rt, address dest, Condition cond);
 686   typedef void (Assembler::* cond_fp_ldst_insn)(FloatRegister Vd, address dest, Condition cond);
 687 
 688   void wrap_label(Label &L, uncond_branch_insn insn);
 689   void wrap_label(Label &L, Condition cond, cond_branch_insn insn);
 690   void wrap_label(Register r, Label &L, Condition cond, cond_ldst_insn insn);
 691   void wrap_label(FloatRegister r, Label &L, Condition cond, cond_fp_ldst_insn insn);
 692 
 693 #undef INSN
 694 
 695 // AARCH32 Instructions
 696 // Defined roughly in the order they are found in
 697 // ARM Archicture Reference Manual, section 5
 698 
 699 #define ZERO_ADDR_REG r0
 700 #define ONES_ADDR_REG r15
 701 
 702 // Data processing (register & register-shifted-register)
 703   void reg_instr(int decode, shift_op shift, Condition cond, bool s) {
 704     f(cond, 31, 28), f(0b000, 27, 25), f(decode, 24, 21), f(s, 20);
 705     f(shift.shift(), 11, 7), f(shift.kind(), 6, 5), f(0, 4);
 706   }
 707   void reg_shift_reg_instr(int decode, enum shift_op::shift_kind kind,
 708                            Condition cond, bool s) {
 709     f(cond, 31, 28), f(0b000, 27, 25), f(decode, 24, 21), f(s, 20);
 710     f(0, 7), f(kind, 6, 5), f(1, 4);
 711   }
 712 
 713 #define INSN(NAME, decode, s_flg)                                                   \
 714   void NAME(Register Rd, Register Rn, Register Rm, shift_op shift = S_DFLT,         \
 715             Condition cond = C_DFLT) {                                              \
 716     starti;                                                                         \
 717     if(shift.is_register()) {                                                       \
 718       reg_shift_reg_instr(decode, shift.kind(), cond, s_flg);                       \
 719       rf(Rn, 16), rf(Rd, 12), rf(shift.reg(), 8), rf(Rm, 0);                        \
 720     } else {                                                                        \
 721       reg_instr(decode, shift, cond, s_flg);                                        \
 722       rf(Rn, 16), rf(Rd, 12), rf(Rm, 0);                                            \
 723     }                                                                               \
 724   }
 725   INSN(andr, 0b0000, 0);
 726   INSN(eor,  0b0001, 0);
 727   INSN(sub,  0b0010, 0);
 728   INSN(rsb,  0b0011, 0);
 729   INSN(add,  0b0100, 0);
 730   INSN(adc,  0b0101, 0);
 731   INSN(sbc,  0b0110, 0);
 732   INSN(rsc,  0b0111, 0);
 733   INSN(orr,  0b1100, 0);
 734   INSN(bic,  0b1110, 0);
 735 
 736   INSN(ands, 0b0000, 1);
 737   INSN(eors, 0b0001, 1);
 738   INSN(subs, 0b0010, 1);
 739   INSN(rsbs, 0b0011, 1);
 740   INSN(adds, 0b0100, 1);
 741   INSN(adcs, 0b0101, 1);
 742   INSN(sbcs, 0b0110, 1);
 743   INSN(rscs, 0b0111, 1);
 744   INSN(orrs, 0b1100, 1);
 745   INSN(bics, 0b1110, 1);
 746 
 747 #undef INSN
 748 
 749 #define INSN(NAME, decode)                                                           \
 750   void NAME(Register Rn, Register Rm, Condition cond) {                              \
 751     NAME(Rn, Rm, S_DFLT, cond);                                                      \
 752   }                                                                                  \
 753   void NAME(Register Rn, Register Rm, shift_op shift = S_DFLT,                       \
 754             Condition cond = C_DFLT) {                                               \
 755     starti;                                                                          \
 756     if(shift.is_register()) {                                                        \
 757         reg_shift_reg_instr(decode, shift.kind(), cond, true);                       \
 758     rf(Rn, 16), f(0b0000, 15, 12), rf(shift.reg(), 8), rf(Rm, 0);                    \
 759     } else {                                                                         \
 760       reg_instr(decode, shift, cond, true);                                          \
 761       rf(Rn, 16), f(0, 15, 12), rf(Rm, 0);                                           \
 762     }                                                                                \
 763   }
 764   INSN(tst, 0b1000);
 765   INSN(teq, 0b1001);
 766   INSN(cmp, 0b1010);
 767   INSN(cmn, 0b1011);
 768 #undef INSN
 769 
 770 // TODO appears that if Rd = 15 and s flag set then perhaps different method
 771 void mov_internal(int decode, Register Rd, Register Rnm, shift_op shift, bool s, Condition cond) {
 772   starti;
 773   if(shift.is_register()) {
 774     reg_shift_reg_instr(decode, shift.kind(), cond, s);
 775     f(0b0000, 19, 16), rf(Rd, 12), rf(shift.reg(), 8), rf(Rnm, 0);
 776   } else {
 777     reg_instr(decode, shift, cond, s);
 778     f(0, 19, 16), rf(Rd, 12), rf(Rnm, 0);
 779   }
 780 }
 781 void mov(Register Rd, Register Rm, shift_op shift, Condition cond = C_DFLT) {
 782   mov_internal(0b1101, Rd, Rm, shift, false, cond);
 783 }
 784 void movs(Register Rd, Register Rm, shift_op shift, Condition cond = C_DFLT) {
 785   mov_internal(0b1101, Rd, Rm, shift, true, cond);
 786 }
 787 void mov(Register Rd, Register Rm, Condition cond = C_DFLT) {
 788   mov_internal(0b1101, Rd, Rm, S_DFLT, false, cond);
 789 }
 790 void movs(Register Rd, Register Rm, Condition cond = C_DFLT) {
 791   mov_internal(0b1101, Rd, Rm, S_DFLT, true, cond);
 792 }
 793 
 794 void mvn(Register Rd, Register Rm, shift_op shift, Condition cond = C_DFLT) {
 795   mov_internal(0b1111, Rd, Rm, shift, false, cond);
 796 }
 797 void mvns(Register Rd, Register Rm, shift_op shift, Condition cond = C_DFLT) {
 798   mov_internal(0b1111, Rd, Rm, shift, true, cond);
 799 }
 800 void mvn(Register Rd, Register Rm, Condition cond = C_DFLT) {
 801   mov_internal(0b1111, Rd, Rm, S_DFLT, false, cond);
 802 }
 803 void mvns(Register Rd, Register Rm, Condition cond = C_DFLT) {
 804   mov_internal(0b1111, Rd, Rm, S_DFLT, true, cond);
 805 }
 806 
 807 #define INSN(NAME, type, s_flg, ASSERTION)                                           \
 808   void NAME(Register Rd, Register Rm, unsigned shift, Condition cond = C_DFLT) {     \
 809     assert_cond(ASSERTION);                                                          \
 810     if(s_flg) movs(Rd, Rm, shift_op(type, shift), cond);                             \
 811     else       mov(Rd, Rm, shift_op(type, shift), cond);                             \
 812   }
 813   INSN(lsl, shift_op::LSL, 0, true);
 814   INSN(lsr, shift_op::LSR, 0, true);
 815   INSN(asr, shift_op::ASR, 0, true);
 816   INSN(ror, shift_op::ROR, 0, shift != 0); //shift == 0 => RRX
 817 
 818   INSN(lsls, shift_op::LSL, 1, true);
 819   INSN(lsrs, shift_op::LSR, 1, true);
 820   INSN(asrs, shift_op::ASR, 1, true);
 821   INSN(rors, shift_op::ROR, 1, shift != 0); //shift == 0 => RRX
 822 #undef INSN
 823 
 824 #define INSN(NAME, type, s_flg)                                                      \
 825   void NAME(Register Rd, Register Rm, Condition cond = C_DFLT) {                     \
 826     if(s_flg) movs(Rd, Rm, shift_op(type, 0), cond);                                 \
 827     else       mov(Rd, Rm, shift_op(type, 0), cond);                                 \
 828   }
 829   INSN(rrx,  shift_op::LSR, 0);
 830   INSN(rrxs, shift_op::LSR, 1);
 831 #undef INSN
 832 
 833 //Data processing (register-shifted-register)
 834 #define INSN(NAME, type, s_flg)                                                      \
 835   void NAME(Register Rd, Register Rn, Register Rm, Condition cond = C_DFLT) {        \
 836     if(s_flg) movs(Rd, Rn, shift_op(type, Rm), cond);                                \
 837     else       mov(Rd, Rn, shift_op(type, Rm), cond);                                \
 838   }
 839   INSN(lsl, shift_op::LSL, 0);
 840   INSN(lsr, shift_op::LSR, 0);
 841   INSN(asr, shift_op::ASR, 0);
 842   INSN(ror, shift_op::ROR, 0);
 843 
 844   INSN(lsls, shift_op::LSL, 1);
 845   INSN(lsrs, shift_op::LSR, 1);
 846   INSN(asrs, shift_op::ASR, 1);
 847   INSN(rors, shift_op::ROR, 1);
 848 #undef INSN
 849 
 850   bool imm_instr(int decode, Register Rd, Register Rn, int imm, Condition cond,
 851                  bool s) {
 852     if(!is_valid_for_imm12(imm))
 853       return false;
 854     {
 855       starti;
 856       f(cond, 31, 28), f(0b001, 27, 25), f(decode, 24, 21), f(s, 20), rf(Rn, 16);
 857       int imm12 = encode_imm12(imm);
 858       rf(Rd, 12), f(imm12, 11, 0);
 859     }
 860     return true;
 861   }
 862 
 863 #define INSN(NAME, decode, s_flg)                                                    \
 864   inline void NAME(Register Rd, Register Rn, unsigned imm, Condition cond = C_DFLT) {\
 865     bool status = imm_instr(decode, Rd, Rn, imm, cond, s_flg);                       \
 866     assert(status, "invalid imm");                                                   \
 867   }
 868   INSN(andr, 0b0000, 0);
 869   INSN(eor,  0b0001, 0);
 870   INSN(orr,  0b1100, 0);
 871   INSN(bic,  0b1110, 0);
 872 
 873   INSN(ands, 0b0000, 1);
 874   INSN(eors, 0b0001, 1);
 875   INSN(orrs, 0b1100, 1);
 876   INSN(bics, 0b1110, 1);
 877   //NOTE: arithmetic immediate instructions are defined below to allow dispatch.
 878 #undef INSN
 879  protected:
 880   // Mov data to destination register in the shortest number of instructions
 881   // possible.
 882   void mov_immediate(Register dst, uint32_t imm32, Condition cond, bool s);
 883   // Mov data to destination register but always emit enough instructions that would
 884   // permit any 32-bit constant to be loaded. (Allow for rewriting later).
 885   void mov_immediate32(Register dst, uint32_t imm32, Condition cond, bool s);
 886 
 887    void add_sub_imm(int decode, Register Rd, Register Rn, int imm,
 888                    Condition cond, bool s);
 889 
 890  public:
 891 #define INSN(NAME, decode, s_flg)                                                    \
 892   inline void NAME(Register Rd, Register Rn, int imm, Condition cond = C_DFLT) {     \
 893     add_sub_imm(decode, Rd, Rn, imm, cond, s_flg);                                   \
 894   }                                                                                  \
 895   inline void NAME(Register Rd, Register Rn, unsigned imm,                           \
 896                    Condition cond = C_DFLT) {                                        \
 897     add_sub_imm(decode, Rd, Rn, imm, cond, s_flg);                                   \
 898   }                                                                                  \
 899   inline void NAME(Register Rd, Register Rn, long imm, Condition cond = C_DFLT) {    \
 900     add_sub_imm(decode, Rd, Rn, imm, cond, s_flg);                                   \
 901   }                                                                                  \
 902   inline void NAME(Register Rd, Register Rn, unsigned long imm,                      \
 903                    Condition cond = C_DFLT) {                                        \
 904     add_sub_imm(decode, Rd, Rn, imm, cond, s_flg);                                   \
 905   }                                                                                  \
 906   /*Addition dispatch - place in macroassembler?*/                                   \
 907   void NAME(Register Rd, Register Rn, RegisterOrConstant operand,                    \
 908            Condition cond = C_DFLT) {                                                \
 909     if(operand.is_register()) {                                                      \
 910       NAME(Rd, Rn, (Register)operand.as_register(), lsl(), cond);                    \
 911     } else {                                                                         \
 912       NAME(Rd, Rn, (unsigned)operand.as_constant(), cond);                           \
 913     }                                                                                \
 914   }                                                                                  \
 915   inline void NAME(Register Rd, Register Rn, unsigned imm, Register Rtmp,            \
 916       Condition cond = C_DFLT) {                                                     \
 917     if (Assembler::operand_valid_for_add_sub_immediate(imm))                         \
 918       NAME(Rd, Rn, imm, cond);                                                       \
 919     else {                                                                           \
 920       mov_immediate(Rtmp, imm, cond, false);                                         \
 921       NAME(Rd, Rn, Rtmp, cond);                                                      \
 922     }                                                                                \
 923   }                                                                                  \
 924   //Note that the RegisterOrConstant version can't take a shift even though
 925   // one of the instructions dispatched to can
 926   INSN(sub,  0b0010, 0);
 927   INSN(rsb,  0b0011, 0);
 928   INSN(add,  0b0100, 0);
 929   INSN(adc,  0b0101, 0);
 930   INSN(sbc,  0b0110, 0);
 931   INSN(rsc,  0b0111, 0);
 932 
 933   INSN(subs, 0b0010, 1);
 934   INSN(rsbs, 0b0011, 1);
 935   INSN(adds, 0b0100, 1);
 936   INSN(adcs, 0b0101, 1);
 937   INSN(sbcs, 0b0110, 1);
 938   INSN(rscs, 0b0111, 1);
 939 #undef INSN
 940   //No need to do reverse as register subtracted from immediate
 941 
 942   // alias for mvn
 943   void inv(Register Rd, Register Rn, Condition cond = C_DFLT) {
 944       mvn(Rd, Rn, cond);
 945   }
 946   //alias for rsb
 947   void neg(Register Rd, Register Rn, Condition cond = C_DFLT) {
 948     rsb(Rd, Rn, 0, cond);
 949   }
 950   void negs(Register Rd, Register Rn, Condition cond = C_DFLT) {
 951     rsbs(Rd, Rn, 0, cond);
 952   }
 953 
 954   // PC-rel. addressing
 955   void adr_encode(Register Rd, int imm, Condition cond) {
 956     if (is_valid_for_imm12(imm) || is_valid_for_imm12(-imm)) {
 957       add_sub_imm(0b0100, Rd, r15_pc, imm, cond, false); //opcode for add
 958     } else {
 959       int adjust = 0;
 960       if (VM_Version::features() & (FT_ARMV7 | FT_ARMV6T2))  {
 961         adjust = 8; // mov_w/mov_t
 962       } else {
 963         adjust = 16; // mov and 3 orr
 964       }
 965       mov_immediate32(Rd, imm - adjust, cond, false);
 966       add(Rd, r15_pc, Rd, cond);
 967     }
 968   }
 969 
 970   void adr(Register Rd, address dest, Condition cond = C_DFLT);
 971 
 972   void adr(Register Rd, const Address &dest, Condition cond = C_DFLT);
 973 
 974   void adr(Register Rd, Label &L, Condition cond = C_DFLT) {
 975     wrap_label(Rd, L, cond, &Assembler::Assembler::adr);
 976   }
 977 
 978 private:
 979   friend void entry(CodeBuffer *cb);
 980 #define INSN(NAME, decode, s_flg)                                                    \
 981   inline void NAME(Register Rd, unsigned imm, Condition cond = C_DFLT) {             \
 982     bool status = imm_instr(decode, Rd, ZERO_ADDR_REG, imm, cond, s_flg);            \
 983     assert(status, "invalid imm");                                                   \
 984   }                                                                                  \
 985   inline void NAME(Register Rd, int imm, Condition cond = C_DFLT) {                  \
 986    bool status = imm_instr(decode, Rd, ZERO_ADDR_REG, imm, cond, s_flg);             \
 987    assert(status, "invalid imm");                                                    \
 988   }
 989 public:
 990 
 991   INSN(mov_i, 0b1101, 0);
 992   INSN(mvn_i, 0b1111, 0);
 993 
 994   INSN(movs_i, 0b1101, 1);
 995   INSN(mvns_i, 0b1111, 1);
 996 #undef INSN
 997 
 998   void movw_i(Register Rd, unsigned imm, Condition cond = C_DFLT) {
 999     starti;
1000     assert(imm < (1 << 16), "Immediate too big for movw");
1001     f(cond, 31, 28), f(0b00110000, 27, 20), f(imm >> 12, 19, 16);
1002     rf(Rd, 12), f(imm & 0xfff, 11, 0);
1003   }
1004 
1005   void movt_i(Register Rd, unsigned imm, Condition cond = C_DFLT) {
1006     starti;
1007     assert(imm < (1 << 16), "Immediate too big for movt");
1008     f(cond, 31, 28), f(0b00110100, 27, 20), f(imm >> 12, 19, 16);
1009     rf(Rd, 12), f(imm & 0xfff, 11, 0);
1010   }
1011 
1012 #define INSN(NAME, decode)                                                              \
1013   inline void NAME(Register Rn, int imm, Condition cond = C_DFLT) {                     \
1014     bool status = imm_instr(decode, ZERO_ADDR_REG, Rn, imm, cond, true);                \
1015     assert(status, "invalid imm");                                                      \
1016   }                                                                                     \
1017   inline void NAME(Register Rn, unsigned imm, Condition cond = C_DFLT) {                \
1018     bool status = imm_instr(decode, ZERO_ADDR_REG, Rn, imm, cond, true);                \
1019     assert(status, "invalid imm");                                                      \
1020   }                                                                                     \
1021   inline void NAME(Register Rn, int imm, Register Rtmp, Condition cond = C_DFLT) {      \
1022     if (Assembler::operand_valid_for_add_sub_immediate(imm))                            \
1023       NAME(Rn, imm, cond);                                                              \
1024     else {                                                                              \
1025       mov_immediate(Rtmp, imm, cond, false);                                            \
1026       NAME(Rn, Rtmp, cond);                                                             \
1027     }                                                                                   \
1028   }                                                                                     \
1029   inline void NAME(Register Rn, unsigned imm, Register Rtmp, Condition cond = C_DFLT) { \
1030     if (Assembler::operand_valid_for_add_sub_immediate(imm))                            \
1031       NAME(Rn, imm, cond);                                                              \
1032     else {                                                                              \
1033       mov_immediate(Rtmp, imm, cond, false);                                            \
1034       NAME(Rn, Rtmp, cond);                                                             \
1035     }                                                                                   \
1036   }
1037   INSN(tst, 0b1000);
1038   INSN(teq, 0b1001);
1039   INSN(cmp, 0b1010);
1040   INSN(cmn, 0b1011);
1041 #undef INSN
1042 
1043 
1044 // Multiply and multiply accumulate
1045   void mult_instr(int decode, Register a, Register b, Register c,
1046                   Register d, Condition cond, bool s) {
1047     starti;
1048     f(cond, 31, 28), f(0b0000, 27, 24), f(decode, 23, 21), f(s, 20);
1049     rf(a, 16), rf(b, 12), rf(c, 8), rf(d, 0), f(0b1001, 7, 4);
1050   }
1051 
1052   void mul(Register Rd, Register Rn, Register Rm, Condition cond = C_DFLT) {
1053     mult_instr(0b000, Rd, ZERO_ADDR_REG, Rm, Rn, cond, false);
1054   }
1055   void muls(Register Rd, Register Rn, Register Rm, Condition cond = C_DFLT) {
1056     mult_instr(0b000, Rd, ZERO_ADDR_REG, Rm, Rn, cond, true);
1057   }
1058 
1059   void mla(Register Rd, Register Rn, Register Rm, Register Ra, Condition cond = C_DFLT) {
1060     mult_instr(0b001, Rd, Ra, Rm, Rn, cond, false);
1061   }
1062   void mlas(Register Rd, Register Rn, Register Rm, Register Ra, Condition cond = C_DFLT) {
1063     mult_instr(0b001, Rd, Ra, Rm, Rn, cond, true);
1064   }
1065 
1066   void mls(Register Rd, Register Rn, Register Rm, Register Ra, Condition cond = C_DFLT) {
1067     mult_instr(0b011, Rd, Ra, Rm, Rn, cond, false);
1068   }
1069 
1070   void umaal(Register RdLo, Register RdHi, Register Rn, Register Rm, Condition cond = C_DFLT) {
1071     mult_instr(0b010, RdHi, RdLo, Rm, Rn, cond, false);
1072   }
1073 
1074 #define INSN(NAME, decode, s_flg)                                                    \
1075   void NAME(Register RdLo, Register RdHi, Register Rn, Register Rm,                  \
1076             Condition cond = C_DFLT) {                                               \
1077     mult_instr(decode, RdHi, RdLo, Rm, Rn, cond, s_flg);                             \
1078   }
1079   INSN(umull, 0b100, 0);
1080   INSN(umlal, 0b101, 0);
1081   INSN(smull, 0b110, 0);
1082   INSN(smlal, 0b111, 0);
1083 
1084   INSN(umulls, 0b100, 1);
1085   INSN(umlals, 0b101, 1);
1086   INSN(smulls, 0b110, 1);
1087   INSN(smlals, 0b111, 1);
1088 
1089 #undef INSN
1090 
1091 //Saturating addition and subtraction
1092 #define INSN(NAME, decode)                                                           \
1093   void NAME(Register Rd, Register Rm, Register Rn, Condition cond = C_DFLT) {        \
1094     starti;                                                                          \
1095     f(cond, 31, 28), f( 0b00010, 27, 23), f(decode, 22, 21), f(0, 20);               \
1096     rf(Rn, 16), rf(Rd, 12), f( 0b00000101, 11, 4),  rf(Rm, 0);                       \
1097   }
1098   INSN(qadd,  0b00);
1099   INSN(qsub,  0b01);
1100   INSN(qdadd, 0b10);
1101   INSN(qdsub, 0b11);
1102 #undef INSN
1103 
1104 // Halfword multiply and multiply accumulate
1105   void mul_instr(int decode, Register Ra, Register Rb, Register Rc, Register Rd,
1106                  bool N, bool M, Condition cond) {
1107       starti;
1108       f(cond, 31, 28), f(0b00010, 27, 23), f(decode, 22, 21), f(0, 20);
1109       rf(Ra, 16), rf(Rb, 12), rf(Rc, 8), f(1, 7), f(M, 6), f(N, 5), f(0, 4);
1110       rf(Rd, 0);
1111   }
1112 
1113 #define INSN(NAME, decode, N, M)                                                     \
1114   void NAME(Register Rd, Register Rn, Register Rm, Register Ra,                      \
1115             Condition cond = C_DFLT) {                                               \
1116     mul_instr(decode, Rd, Ra, Rm, Rn, N, M, cond);                                   \
1117   }
1118   INSN(smlabb, 0b00, 0, 0);
1119   INSN(smlabt, 0b00, 0, 1)
1120   INSN(smlatb, 0b00, 1, 0)
1121   INSN(smlatt, 0b00, 1, 1)
1122 
1123   INSN(smlawb, 0b01, 0, 0);
1124   INSN(smlawt, 0b01, 0, 1);
1125 #undef INSN
1126 
1127 #define INSN(NAME, decode, N, M)                                                     \
1128   void NAME(Register RdLo, Register RdHi, Register Rn, Register Rm,                  \
1129             Condition cond = C_DFLT) {                                               \
1130     mul_instr(decode, RdHi, RdLo, Rm, Rn, N, M, cond);                               \
1131   }
1132   INSN(smlalbb, 0b10, 0, 0);
1133   INSN(smlalbt, 0b10, 0, 1);
1134   INSN(smlaltb, 0b10, 1, 0);
1135   INSN(smlaltt, 0b10, 1, 1);
1136 #undef INSN
1137 
1138 #define INSN(NAME, decode, N, M)                                                     \
1139   void NAME(Register Rd, Register Rn, Register Rm, Condition cond = C_DFLT) {        \
1140     mul_instr(decode, Rd, ZERO_ADDR_REG, Rm, Rn, N, M, cond);                        \
1141   }
1142   INSN(smulwb, 0b01, 1, 0);
1143   INSN(smulwt, 0b01, 1, 1);
1144 
1145   INSN(smulbb, 0b11, 0, 0);
1146   INSN(smulbt, 0b11, 0, 1);
1147   INSN(smultb, 0b11, 1, 0);
1148   INSN(smultt, 0b11, 1, 1);
1149 #undef INSN
1150 
1151 // For Extra load/store instructions, see load/store section
1152 // For Synchronization primitives, see load/store section
1153 
1154 // MSR(immediate), and hints
1155 #define INSN(NAME, decode)                                                           \
1156   void NAME(Condition cond = C_DFLT) {                                               \
1157     starti;                                                                          \
1158     f(cond, 31, 28), f(0b001100100000, 27, 16), f(0b11110000, 15, 8);                \
1159     f(decode, 7, 0);                                                                 \
1160   }
1161   INSN(nop,   0b000);
1162   INSN(yield, 0b001);
1163   INSN(wfe,   0b010);
1164   INSN(wfi,   0b011);
1165   INSN(sev,   0b100);
1166   void dbg(int dbg_hint, Condition cond = C_DFLT) {
1167     f(cond, 31, 28), f(0b001100100000, 27, 16), f(0b11110000, 15, 8);
1168     f(0b1111, 7, 4); f(dbg_hint, 3, 0);
1169   }
1170 #undef INSN
1171 
1172   //TODO Misc instructions
1173   void bkpt(unsigned imm) {
1174     starti;
1175     f(AL, 31, 28), f(0b00010010, 27, 20);
1176     f(imm >> 4, 19, 8), f(0b0111, 7, 4), f(imm & 0xf, 3, 0);
1177   }
1178   void hlt(unsigned imm) {
1179     bkpt(imm);
1180     // FIXME This seemed like the best option!
1181   }
1182 
1183   // Load/store register (all modes)
1184   void load_store_instr(Register Rt, const Address &adr, int op, int op2, int a, int b,
1185                         Condition cond) {
1186     starti;
1187     f(cond, 31, 28), f(op, 27, 25), f(a, 22), f(b, 20);
1188     if(op2 >= 0)
1189       f(op2, 7, 4);
1190     //Destination
1191     rf(Rt, 12);
1192     adr.encode(current, code_section(), pc());
1193   }
1194 
1195   bool encodeable(int decode, address dest) {
1196     long offset = dest - pc();
1197     switch(decode) {
1198       case 0b010:
1199         // LDR, LDRB, STR, STRB
1200         return uabs(offset) < (1 << 12);
1201       case 0b000:
1202         //LDRD, LDRH, LDRSB, LDRSH, STRH, STRD
1203         return uabs(offset) < (1 << 8);
1204       default:
1205         ShouldNotReachHere();
1206     }
1207     return false;
1208   }
1209 
1210 
1211 #define INSN_INT(NAME, op, op2, a, b, isload)                                        \
1212   void NAME(Register Rt, address dest, Condition cond = C_DFLT) {                    \
1213     if(encodeable(op, dest)) { /* Plan A */                                          \
1214       long offset = dest - pc();                                                     \
1215       NAME(Rt, Address(r15_pc, offset), cond);                                       \
1216     } else if(isload){ /* Plan B */                                                  \
1217       /* TODO check we don't have to relocate this*/                                 \
1218       mov_immediate(Rt, (uint32_t)dest, cond, false);                                \
1219       NAME(Rt, Address(Rt, 0), cond);                                                \
1220     } else { /* There is no plan C */                                                \
1221       ShouldNotReachHere();                                                          \
1222     }                                                                                \
1223   }                                                                                  \
1224   void NAME(Register Rt, address dest, relocInfo::relocType rtype,                   \
1225             Condition cond = C_DFLT) {                                               \
1226     guarantee(rtype == relocInfo::internal_word_type,                                \
1227               "only internal_word_type relocs make sense here");                     \
1228     NAME(Rt, InternalAddress(dest), cond);                                           \
1229   }                                                                                  \
1230   void NAME(Register Rt, Label &L, Condition cond = C_DFLT) {                        \
1231     wrap_label(Rt, L, cond, &Assembler::NAME);                                       \
1232   }
1233 
1234 #define INSN(NAME, op, op2, a, b, isload)                                            \
1235   void NAME(Register Rt, const Address &adr, Condition cond = C_DFLT) {              \
1236     load_store_instr(Rt, adr, op, op2, a, b, cond);                                  \
1237   }                                                                                  \
1238   INSN_INT(NAME, op, op2, a, b, isload);
1239   INSN(ldr,   0b010,     -1, 0, 1, 1);
1240   INSN(ldrb,  0b010,     -1, 1, 1, 1);
1241 
1242   INSN(ldrsb, 0b000, 0b1101, 0, 1, 1);
1243   INSN(ldrh,  0b000, 0b1011, 0, 1, 1);
1244   INSN(ldrsh, 0b000, 0b1111, 0, 1, 1);
1245 
1246   INSN(str,   0b010,     -1, 0, 0, 0);
1247   INSN(strb,  0b010,     -1, 1, 0, 0);
1248   INSN(strh,  0b000, 0b1011, 0, 0, 0);
1249   //Note LDRD & STRD are defined with the load/store multiple instructions
1250 
1251   //TODO Need to introduce ldrsb ldrsh - then check that the encoding works properly!
1252 #undef INSN
1253 
1254 
1255   //Synchronization primitives
1256   void sync_instr(int decode, Register Ra, Register Rb, Register Rc, Register Rd,
1257              Condition cond) {
1258     starti;
1259     f(cond, 31, 28), f(0b0001, 27, 24), f(decode, 23, 20), rf(Ra, 16), rf(Rb, 12);
1260     rf(Rc, 8), f(0b1001, 7, 4), rf(Rd, 0);
1261   }
1262 
1263 #define INSN(NAME, decode)                                                           \
1264   void NAME(Register Rd, Register Rt, Register Rn, Condition cond = C_DFLT) {        \
1265     assert(r15_pc != Rn, "Unpredictable");                                           \
1266     sync_instr(decode, Rn, Rd, ONES_ADDR_REG, Rt, cond);                             \
1267   }                                                                                  \
1268   void NAME(Register Rd, Register Rt, Address a, Condition cond = C_DFLT) {          \
1269     assert(a.get_mode() == Address::imm, "must be");                                 \
1270     assert(a.offset() == 0, "unsupported");                                          \
1271     NAME(Rd, Rt, a.base(), cond);                                                    \
1272   }
1273   INSN( strex, 0b1000);
1274   INSN(strexd, 0b1010);
1275   INSN(strexb, 0b1100);
1276   INSN(strexh, 0b1110);
1277 #undef INSN
1278 
1279 #define INSN(NAME, decode)                                                           \
1280   void NAME(Register Rt, Register Rn, Condition cond = C_DFLT) {                     \
1281     assert(r15_pc != Rn, "Unpredictable");                                           \
1282     sync_instr(decode, Rn, Rt, ONES_ADDR_REG, ONES_ADDR_REG, cond);                  \
1283   }                                                                                  \
1284   void NAME(Register Rt, Address a, Condition cond = C_DFLT) {                       \
1285     assert(a.get_mode() == Address::imm, "must be");                                 \
1286     assert(a.offset() == 0, "unsupported");                                          \
1287     NAME(Rt, a.base(), cond);                                                        \
1288     }
1289   INSN(ldrex,  0b1001);
1290   INSN(ldrexd, 0b1011);
1291   INSN(ldrexb, 0b1101);
1292   INSN(ldrexh, 0b1111);
1293 #undef INSN
1294 
1295 // Media instructions
1296 void media_instr(int decode, int decode2, Condition cond) {
1297   f(cond, 31, 28), f(0b011, 27, 25), f(decode, 24, 20);
1298   f(decode2, 7, 5), f(1, 4);
1299 }
1300 
1301 #define INSN(NAME, decode, decode2)                                                  \
1302   void NAME(Register Rd, Register Rn, Register Rm, Condition cond = C_DFLT) {        \
1303     starti;                                                                          \
1304     media_instr(0b00000 | decode, decode2, cond);                                    \
1305     rf(Rn, 16), rf(Rd, 12), f(0b1111, 11, 8), rf(Rm, 0);                             \
1306   }
1307   INSN(sadd16, 0b01, 0b000);
1308   INSN(sasx,   0b01, 0b001);
1309   INSN(ssax,   0b01, 0b010);
1310   INSN(ssub16, 0b01, 0b011);
1311   INSN(sadd8,  0b01, 0b100);
1312   INSN(ssub8,  0b01, 0b111);
1313   //Saturating
1314   INSN(qadd16, 0b10, 0b000);
1315   INSN(qasx,   0b10, 0b001);
1316   INSN(qsax,   0b10, 0b010);
1317   INSN(qsub16, 0b10, 0b011);
1318   INSN(qadd8,  0b10, 0b100);
1319   INSN(qsub8,  0b10, 0b111);
1320   //Halving
1321   INSN(shadd16, 0b11, 0b000);
1322   INSN(shasx,   0b11, 0b001);
1323   INSN(shsax,   0b11, 0b010);
1324   INSN(shsub16, 0b11, 0b011);
1325   INSN(shadd8,  0b11, 0b100);
1326   INSN(shsub8,  0b11, 0b111);
1327 
1328   //Now unsigned
1329   INSN(uadd16, 0b101, 0b000);
1330   INSN(uasx,   0b101, 0b001);
1331   INSN(usax,   0b101, 0b010);
1332   INSN(usub16, 0b101, 0b011);
1333   INSN(uadd8,  0b101, 0b100);
1334   INSN(usub8,  0b101, 0b111);
1335   //Saturating
1336   INSN(uqadd16, 0b110, 0b000);
1337   INSN(uqasx,   0b110, 0b001);
1338   INSN(uqsax,   0b110, 0b010);
1339   INSN(uqsub16, 0b110, 0b011);
1340   INSN(uqadd8,  0b110, 0b100);
1341   INSN(uqsub8,  0b110, 0b111);
1342   //Halving
1343   INSN(uhadd16, 0b111, 0b000);
1344   INSN(uhasx,   0b111, 0b001);
1345   INSN(uhsax,   0b111, 0b010);
1346   INSN(uhsub16, 0b111, 0b011);
1347   INSN(uhadd8,  0b111, 0b100);
1348   INSN(uhsub8,  0b111, 0b111);
1349 #undef INSN
1350 
1351 //Packing, unpacking, saturation and reversal
1352 // Note rotation can only be one of ROR #0 ROR #8 ROR #16 ROR #24
1353 void extend_instr(int decode, int decode2, int decode3, Register Rd, Register Rn,
1354                   Register Rm, shift_op shift, Condition cond) {
1355   starti;
1356   assert(0 == shift.shift() ||
1357          shift_op::ROR == shift.kind(), "Only ROR may be used for op");
1358   // All zero shifts are mapped to LSL #0
1359   int shift_enc = 0;
1360   switch(shift.shift()) {
1361     case 0:                 break;
1362     case 8:  shift_enc = 1; break;
1363     case 16: shift_enc = 2; break;
1364     case 24: shift_enc = 3; break;
1365     default: assert(false, "Invalid shift quantity");
1366   }
1367   media_instr(0b01000 | decode, decode2, cond);
1368   rf(Rn, 16), rf(Rd, 12), f(shift_enc, 11, 10), f(decode3, 9, 8), rf(Rm, 0);
1369 }
1370 void extend_instr(int decode, int decode2, int decode3, Register Rd, Register Rn,
1371                   unsigned imm, Condition cond) {
1372   starti;
1373   media_instr(0b01000 | decode, decode2, cond);
1374   rf(Rn, 0), rf(Rd, 12), f(decode3, 11, 8), f(imm, 19, 16);
1375 }
1376 
1377 #define INSN(NAME, decode, decode2)                                                  \
1378   void NAME(Register Rd, Register Rn, Register Rm, shift_op shift = ::ror(),         \
1379             Condition cond = C_DFLT) {                                               \
1380     assert(0xf != Rn->encoding_nocheck(), "Rn = pc makes different instruction");    \
1381     extend_instr(decode, decode2, 0b00, Rd, Rn, Rm, shift, cond);                    \
1382   }
1383   INSN(sxtab16, 0b000, 0b011);
1384   INSN(sxtab,   0b010, 0b011);
1385   INSN(sxtah,   0b011, 0b011);
1386   INSN(uxtab16, 0b100, 0b011);
1387   INSN(uxtab,   0b110, 0b011);
1388   INSN(uxtah,   0b111, 0b011);
1389 #undef INSN
1390 
1391 #define INSN(NAME, decode, decode2)                                                  \
1392   void NAME(Register Rd, Register Rm, shift_op shift = ::ror(),                      \
1393             Condition cond = C_DFLT) {                                               \
1394     extend_instr(decode, decode2, 0b00, Rd, ONES_ADDR_REG, Rm, shift, cond);         \
1395   }
1396   INSN(sxtb16, 0b000, 0b011);
1397   INSN(sxtb,   0b010, 0b011);
1398   INSN(sxth,   0b011, 0b011);
1399   INSN(uxtb16, 0b100, 0b011);
1400   INSN(uxtb,   0b110, 0b011);
1401   INSN(uxth,   0b111, 0b011);
1402 #undef INSN
1403 
1404 #define INSN(NAME, decode, decode2) \
1405   void NAME(Register Rd, unsigned imm, Register Rn, Condition cond = C_DFLT) { \
1406     extend_instr(decode, decode2, 0b1111, Rd, Rn, imm, cond); \
1407   }
1408   INSN(usat16, 0b110, 0b001);
1409 #undef INSN
1410 
1411   //Reverse instructions
1412 #define INSN(NAME, decode, decode2)                                                  \
1413   void NAME(Register Rd, Register Rm, Condition cond = C_DFLT) {                     \
1414     extend_instr(decode, decode2, 0b11, Rd, ONES_ADDR_REG, Rm, ::ror(24), cond);     \
1415   }
1416   INSN(rev,   0b011, 0b001);
1417   INSN(rev16, 0b011, 0b101);
1418   INSN(rbit,  0b111, 0b001);
1419   INSN(revsh, 0b111, 0b101);
1420 #undef INSN
1421 
1422 // Signed multiply, signed and unsigned divide
1423 #define INSN(NAME, decode, decode2)                                                  \
1424   void NAME(Register Rd, Register Rn, Register Rm, Condition cond = C_DFLT) {        \
1425     starti;                                                                          \
1426     media_instr(0b10000 | decode, decode2, cond);                                    \
1427     rf(Rd, 16), f(0b1111, 15, 12), rf(Rm, 8), rf(Rn, 0);                             \
1428   }
1429   INSN(sdiv,   0b001, 0b000);
1430   INSN(udiv,   0b011, 0b000);
1431   INSN(smuad,  0b000, 0b000);
1432   INSN(smuadx, 0b000, 0b001);
1433   INSN(smusd,  0b000, 0b010);
1434   INSN(smusdx, 0b000, 0b011);
1435   INSN(smmul,  0b101, 0b000);
1436   INSN(smmulr, 0b101, 0b001);
1437   //TODO ALL THE REST!
1438 #undef INSN
1439 
1440 // Remainder of things
1441 #define INSN(NAME, decode, decode2)                                                  \
1442   void NAME(Register Rd, Register Rn, int lsb, int width,                            \
1443             Condition cond = C_DFLT) {                                               \
1444     starti;                                                                          \
1445     assert(lsb >= 0 && lsb < 32, "lsb out of range");                                \
1446     assert(width > 0 && width <= 32 - lsb, "width out of range");                    \
1447     media_instr(decode, decode2, cond);                                              \
1448     f(width - 1, 20, 16), rf(Rd, 12), f(lsb, 11, 7), rf(Rn, 0);                      \
1449   }
1450   INSN(sbfx, 0b11010, 0b010);
1451   INSN(ubfx, 0b11110, 0b010);
1452 #undef INSN
1453 
1454 void bfi(Register Rd, Register Rn, int lsb, int width, Condition cond = C_DFLT) {
1455   assert(VM_Version::features() & (FT_ARMV6T2 | FT_ARMV7), "unsupported on the cpu");
1456   int msb = lsb + width - 1;
1457   assert(lsb >= 0 && lsb < 32, "lsb out of range");
1458   assert(msb < 32 && msb >= lsb, "width out of range");
1459   starti;
1460   media_instr(0b11100, 0b000, cond);
1461   f(msb, 20, 16), rf(Rd, 12), f(lsb, 11, 7), rf(Rn, 0);
1462 }
1463 
1464 void bfc(Register Rd, int lsb, int width, Condition cond = C_DFLT) {
1465   assert(VM_Version::features() & (FT_ARMV6T2 | FT_ARMV7), "unsupported on the cpu");
1466   int msb = lsb + width - 1;
1467   assert(lsb >= 0 && lsb < 32, "lsb out of range");
1468   assert(msb < 32 && msb >= lsb, "width out of range");
1469   starti;
1470   media_instr(0b11100, 0b000, cond);
1471   f(msb, 20, 16), rf(Rd, 12), f(lsb, 11, 7), f(0b1111, 3, 0);
1472 }
1473 
1474 void clz(Register Rd, Register Rm, Condition cond = C_DFLT) {
1475   assert(Rd != r15_pc && Rm != r15_pc, "must be");
1476   starti;
1477   f(cond, 31, 28), f(0b000101101111, 27, 16), rf(Rd, 12);
1478   f(0b11110001, 11, 4), rf(Rm, 0);
1479 }
1480 
1481 //Branch, branch with link, and block data transfer
1482 
1483 void block_imm_instr(int decode, int w, Register Rn, unsigned regset,
1484                      Condition cond) {
1485   starti;
1486   f(cond, 31, 28), f(0b10, 27, 26), f(decode | (w << 1), 25, 20);
1487   rf(Rn, 16), f(regset, 15, 0);
1488 }
1489 #define INSN(NAME, decode)                                                           \
1490   void NAME(Register Rn, unsigned regset, bool wb = true, Condition cond = C_DFLT) { \
1491     block_imm_instr(decode, wb, Rn, regset, cond);                                   \
1492   }
1493   INSN(stmda, 0b000000);
1494   INSN(stmed, 0b000000);
1495 
1496   INSN(ldmda, 0b000001);
1497   INSN(ldmfa, 0b000001);
1498 
1499   //INSN(stm,   0b001000);
1500   INSN(stmia, 0b001000);
1501   INSN(stmea, 0b001000);
1502 
1503   //INSN(ldm,   0b001001);
1504   INSN(ldmia, 0b001001);
1505   INSN(ldmfd, 0b001001);
1506 
1507   INSN(stmdb, 0b010000);
1508   INSN(stmfd, 0b010000);
1509 
1510   INSN(ldmdb, 0b010001);
1511   INSN(ldmea, 0b010001);
1512 
1513   INSN(stmib, 0b011000);
1514   INSN(stmfa, 0b011000);
1515 
1516   INSN(ldmib, 0b011001);
1517   INSN(ldmed, 0b011001);
1518 #undef INSN
1519 
1520 unsigned count_bits(unsigned val);
1521 bool can_ldst_multiple( unsigned regset, const Address& adr);
1522 
1523 //NOTE!! Have repurposed stm and ldm for auto dispatch instructions
1524 #define INSN(NAME, PREFIX)                                                           \
1525   void NAME(unsigned regset, const Address& adr, Condition cond = C_DFLT) {          \
1526     assert(can_ldst_multiple(regset, adr), "Can't do anything with this!");          \
1527     int offset = adr.offset();                                                       \
1528     switch(adr.get_wb_mode()) {                                                      \
1529       case Address::pre:                                                             \
1530         if(offset > 0) PREFIX##mib(adr.base(), regset, true, cond);                  \
1531         else           PREFIX##mdb(adr.base(), regset, true, cond);                  \
1532         break;                                                                       \
1533       case Address::post:                                                            \
1534         if(offset > 0) PREFIX##mia(adr.base(), regset, true, cond);                  \
1535         else           PREFIX##mda(adr.base(), regset, offset != 0, cond);           \
1536         break;                                                                       \
1537       case Address::off:                                                             \
1538         if(offset > 0)   PREFIX##mib(adr.base(), regset, false, cond);               \
1539         else if(!offset) PREFIX##mia(adr.base(), regset, false, cond);               \
1540         else             PREFIX##mdb(adr.base(), regset, false, cond);               \
1541         break;                                                                       \
1542       default:                                                                       \
1543         ShouldNotReachHere();                                                        \
1544     }                                                                                \
1545   }
1546   INSN(ldm, ld);
1547   INSN(stm, st);
1548 #undef INSN
1549 
1550 //Made push and pop operate on full descending stacks
1551 #define INSN(NAME, CNAME)                                                            \
1552   inline void NAME(unsigned regset, Condition cond = C_DFLT) {                       \
1553     CNAME(r13, regset, true, cond);                                                  \
1554   }
1555   INSN(pop,  ldmia);
1556   INSN(push, stmdb);
1557 #undef INSN
1558 
1559  public:
1560 
1561 #define INSN(NAME, PREFIX, op, op2, a, b, isload)                                    \
1562   void NAME(Register Rt, const Address& adr, Condition cond = C_DFLT) {              \
1563     load_store_instr(Rt, adr, op, op2, a, b, cond);                                  \
1564   }                                                                                  \
1565   INSN_INT(NAME, op, op2, a, b, isload);
1566 
1567   INSN(ldrd, ld, 0b000, 0b1101, 0, 0, 1);
1568   INSN(strd, st, 0b000, 0b1111, 0, 0, 0);
1569 #undef INSN
1570 #undef INSN_INT
1571 
1572   // Branches
1573 
1574   // For immediate branches:
1575   // The maximum range of a branch is fixed for the aarch32
1576   // architecture.  In debug mode we shrink it in order to test
1577   // trampolines, but not so small that branches in the interpreter
1578   // are out of range. Compiler2 is ported in the assumption that code cache is
1579   // always reachable with immediate branch, so cannot restrict the size
1580   static const unsigned long branch_range =
1581       COMPILER2_PRESENT(32 * M) NOT_COMPILER2(NOT_DEBUG(32 * M) DEBUG_ONLY(2 * M));
1582   static bool reachable_from_branch_at(address branch, address target) {
1583     return uabs(target - branch) < branch_range;
1584   }
1585 
1586   void branch_imm_instr(int decode, address dest, Condition cond) {
1587     starti;
1588     // Correct PC for as it will be when executing this instruction
1589     int offset = (dest - (pc() + 8)) >> 2;
1590     assert(reachable_from_branch_at(pc(), dest), "branch target unreachable");
1591     f(cond, 31, 28), f(decode, 27, 24), sf(offset, 23, 0);
1592   }
1593 
1594   void branch_reg_instr(int decode, Register Rm, Condition cond) {
1595     starti;
1596     f(cond, 31, 28), f(0b00010010, 27, 20);
1597     f(0b111111111111, 19, 8), f(decode, 7, 4), rf(Rm, 0);
1598   }
1599 
1600 #define INSN(NAME, decode_imm, decode_reg)                                           \
1601   void NAME(Register Rm, Condition cond = C_DFLT) {                                  \
1602     branch_reg_instr(decode_reg, Rm, cond);                                          \
1603   }                                                                                  \
1604   void NAME(address dest, Condition cond = C_DFLT) {                                 \
1605     branch_imm_instr(decode_imm, dest, cond);                                        \
1606   }                                                                                  \
1607   void NAME(Label &L, Condition cond = C_DFLT) {                                     \
1608     wrap_label(L, cond, &Assembler::NAME);                                           \
1609   }                                                                                  \
1610   void NAME(const Address &dest, Condition cond = C_DFLT) {                          \
1611     code_section()->relocate(pc(), dest.rspec());                                    \
1612     NAME(dest.target(), cond);                                                       \
1613   }
1614   //TODO assert type of address
1615   INSN(b,  0b1010, 0b0001); // B & BX
1616   INSN(bl, 0b1011, 0b0011); // BL & BLX
1617 #undef INSN
1618 
1619 
1620 //TODO Coprocessor instructions, and Supervisor Call
1621 
1622 
1623 // Unconditional Instructions
1624   enum barrier {OSHST = 0b0010, OSH,
1625                 NSHST = 0b0110, NSH,
1626                 ISHST = 0b1010, ISH,
1627                    ST = 0b1110, SY};
1628 
1629   void sync_instr(int decode, enum barrier option) {
1630     starti;
1631     f(0b11110, 31, 27), f(0b1010111, 26, 20), f(0b111111110000, 19, 8);
1632     f(decode, 7, 4), f(option, 3, 0);
1633   }
1634   void clrex() {
1635     sync_instr(0b0001, SY);
1636   }
1637   void dsb(enum barrier option) {
1638     sync_instr(0b0100, option);
1639   }
1640   void dmb(enum barrier option) {
1641     sync_instr(0b0101, option);
1642   }
1643   void bkpt();
1644   void isb() {
1645     sync_instr(0b0110, SY);
1646   }
1647 
1648   void udf(int imm_16) {
1649     assert((imm_16 >> 16) == 0, "encoding constraint");
1650     emit_int32(0xe7f000f0 | (imm_16 & 0xfff0) << 8 | (imm_16 & 0xf));
1651   }
1652 
1653   // And the relevant instructions for ARMv6.
1654 
1655   // MCR<c> <coproc>, <opc1>, <Rt>, <CRn>, <CRm>{, <opc2>}
1656   void mcr(int cpc_dex, int opc1, Register Rt, int cpc_reg_dex1,
1657            int cpc_reg_dex2, int opc2, Condition cond = C_DFLT) {
1658     starti;
1659     f(cond, 31, 28), f(0b1110, 27, 24), f(opc1, 23, 21), f(0, 20);
1660     f(cpc_reg_dex1, 19, 16), rf(Rt, 12), f(cpc_dex, 11, 8);
1661     f(opc2, 7, 5), f(1, 4), f(cpc_reg_dex2, 3, 0);
1662   }
1663 
1664   // These instructions do not read the value of the register passed,
1665   // can be any. Chosen r0.
1666   void cp15dmb(Condition cond = C_DFLT) {
1667     mcr(15, 0, r0, 7, 10, 5, cond);
1668   }
1669 
1670   void cp15dsb(Condition cond = C_DFLT) {
1671     mcr(15, 0, r0, 7, 10, 4, cond);
1672   }
1673 
1674   void cp15isb(Condition cond = C_DFLT) {
1675     mcr(15, 0, r0, 7, 5, 4, cond);
1676   }
1677 
1678   enum Membar_mask_bits {
1679     // We can use ISH for a barrier because the ARM ARM says "This
1680     // architecture assumes that all Processing Elements that use the
1681     // same operating system or hypervisor are in the same Inner
1682     // Shareable shareability domain."
1683     StoreStore = ISHST,
1684     LoadStore  = ISH, //ISHLD, Changed to
1685     LoadLoad   = ISH, //ISHLD,
1686     StoreLoad  = ISH,
1687     AnyAny     = ISH
1688   };
1689 
1690   void mrs(Register Rd, Condition cond = C_DFLT) {
1691     starti;
1692     f(cond, 31, 28), f(0b00010, 27, 23), f(0, 22), f(0b00, 21, 20), f(0b1111, 19, 16);
1693     rf(Rd, 12), f(0b000000000000, 11, 0);
1694   }
1695 
1696   void msr(Register Rn, bool nzcvq = true, bool g = true, Condition cond = C_DFLT) {
1697     starti;
1698     f(cond, 31, 28), f(0b00010, 27, 23), f(0, 22), f(0b10, 21, 20);
1699     f(nzcvq ? 1 : 0, 19), f(g ? 1 : 0, 18), f(0b00, 17, 16);
1700     f(0b111100000000, 15, 4), rf(Rn, 0);
1701   }
1702 
1703 // Floating point operations
1704 
1705 enum fpscr_cond { FP_EQ = 0b0110 << 28,
1706                   FP_LT = 0b1000 << 28,
1707                   FP_GT = 0b0010 << 28,
1708                   FP_UN = 0b0011 << 28,
1709                   FP_MASK = 0b1111 << 28 };
1710 
1711   void fp_instr_base(bool is64bit, Condition cond) {
1712     f(cond, 31, 28), f(0b1110, 27, 24), f(0b101, 11, 9), f(is64bit, 8), f(0, 4);
1713   }
1714 
1715   void fp_rencode(FloatRegister reg, bool is64bit, int base, int bit) {
1716     int reg_val = reg->encoding_nocheck();
1717     if(!is64bit) {
1718       f( reg_val >> 1, base + 3, base);
1719       f( reg_val & 1, bit);
1720     } else {
1721       f( reg_val & 0xf, base + 3, base);
1722       f( reg_val >> 4, bit);
1723     }
1724   }
1725 
1726   void fp_instr(int decode, int op, bool is64bit, FloatRegister Rd, FloatRegister Rn,
1727                 FloatRegister Rm, Condition cond) {
1728     fp_instr_base(is64bit, cond);
1729     f(decode, 23, 20), f(op, 6);
1730     // Register encoding is a bit involved
1731     // double register passed (see 'd0'-'dN' encoding), not reencode it's number
1732     fp_rencode(Rn, false, 16, 7);
1733     fp_rencode(Rd, false, 12, 22);
1734     fp_rencode(Rm, false,  0, 5);
1735   }
1736 
1737 #define INSN(NAME, decode, op, is64bit)                                              \
1738   void NAME(FloatRegister Rd, FloatRegister Rn, FloatRegister Rm,                    \
1739             Condition cond = C_DFLT) {                                               \
1740     starti;                                                                          \
1741     fp_instr(decode, op, is64bit, Rd, Rn, Rm, cond);                                 \
1742   }
1743   INSN(vmla_f32,  0b0000, 0, 0);
1744   INSN(vmla_f64,  0b0000, 0, 1);
1745   INSN(vmls_f32,  0b0000, 1, 0);
1746   INSN(vmls_f64,  0b0000, 1, 1);
1747 
1748   INSN(vnmla_f32, 0b0001, 1, 0);
1749   INSN(vnmla_f64, 0b0001, 1, 1);
1750   INSN(vnmls_f32, 0b0001, 0, 0);
1751   INSN(vnmls_f64, 0b0001, 0, 1);
1752   INSN(vnmul_f32, 0b0010, 1, 0);
1753   INSN(vnmul_f64, 0b0010, 1, 1);
1754   INSN(vmul_f32,  0b0010, 0, 0);
1755   INSN(vmul_f64,  0b0010, 0, 1);
1756 
1757   INSN(vadd_f32,  0b0011, 0, 0);
1758   INSN(vadd_f64,  0b0011, 0, 1);
1759   INSN(vsub_f32,  0b0011, 1, 0);
1760   INSN(vsub_f64,  0b0011, 1, 1);
1761 
1762   INSN(vdiv_f32,  0b1000, 0, 0);
1763   INSN(vdiv_f64,  0b1000, 0, 1);
1764 
1765   INSN(vfnma_f32, 0b1001, 1, 0);
1766   INSN(vfnma_f64, 0b1001, 1, 1);
1767   INSN(vfnms_f32, 0b1001, 0, 0);
1768   INSN(vfnms_f64, 0b1001, 0, 1);
1769 
1770   INSN(vfma_f32,  0b1010, 0, 0);
1771   INSN(vfma_f64,  0b1010, 0, 1);
1772   INSN(vfms_f32,  0b1010, 1, 0);
1773   INSN(vfms_f64,  0b1010, 1, 1);
1774 #undef INSN
1775 
1776 
1777   void vmov_imm(FloatRegister Rd, unsigned imm, bool is64bit, Condition cond);
1778   void vmov_imm(FloatRegister Rd, unsigned imm);
1779   void vmov_imm_zero(FloatRegister Rd, bool is64bit, Condition cond);
1780 
1781   unsigned encode_float_fp_imm(float imm_f);
1782 
1783   void vmov_f32(FloatRegister Rd, float imm, Condition cond = C_DFLT) {
1784     vmov_imm(Rd, encode_float_fp_imm(imm), false, cond);
1785   }
1786 
1787   unsigned encode_double_fp_imm(double imm_f);
1788 
1789   void vmov_f64(FloatRegister Rd, double imm, Condition cond = C_DFLT) {
1790     bool positive_zero = (imm == 0.0) && !signbit(imm);
1791     if(positive_zero) vmov_imm_zero(Rd, true, cond);
1792     else              vmov_imm(Rd, encode_double_fp_imm(imm), true, cond);
1793   }
1794 
1795 #define INSN(NAME, decode, op, is64bit)                                              \
1796   void NAME(FloatRegister Rd, FloatRegister Rm, Condition cond = C_DFLT) {           \
1797     starti;                                                                          \
1798     fp_instr_base(is64bit, cond);                                                    \
1799     f(0b1011, 23, 20), f(decode, 19, 16), f(op, 7, 6), f(0b00, 5, 4);                \
1800     /* double register passed (see 'd0'-'dN' encoding), not reencode it's number */  \
1801     fp_rencode(Rd, false, 12, 22);                                                   \
1802     fp_rencode(Rm, false, 0, 5);                                                     \
1803   }
1804   INSN(vmov_f32,  0b0000, 0b01, 0);
1805   INSN(vmov_f64,  0b0000, 0b01, 1);
1806   INSN(vabs_f32,  0b0000, 0b11, 0);
1807   INSN(vabs_f64,  0b0000, 0b11, 1);
1808   INSN(vneg_f32,  0b0001, 0b01, 0);
1809   INSN(vneg_f64,  0b0001, 0b01, 1);
1810   INSN(vsqrt_f32, 0b0001, 0b11, 0);
1811   INSN(vsqrt_f64, 0b0001, 0b11, 1);
1812 #undef INSN
1813 
1814 //ARM -> FP, FP -> ARM
1815 // NOTE - Have only implemented the double precision variant as only operating on
1816 // double registers - can still be used to copy single precision
1817 void vmov64_instr_base(FloatRegister Rm, Register Rt, Register Rt2, int op,
1818                        Condition cond) {
1819   starti;
1820   f(cond, 31, 28), f(0b1100010, 27, 21), f(op, 20);
1821   rf(Rt2, 16), rf(Rt, 12), f(0b101100, 11, 6), f(1, 4);
1822   // double register passed (see 'd0'-'dN' encoding), not reencode it's number
1823   fp_rencode(Rm, false, 0, 5);
1824 }
1825 
1826 void vmov_f64(FloatRegister Rm, Register Rt, Register Rt2, Condition cond = C_DFLT) {
1827   vmov64_instr_base(Rm, Rt, Rt2, 0, cond);
1828 }
1829 void vmov_f64(Register Rt, Register Rt2, FloatRegister Rm, Condition cond = C_DFLT) {
1830   vmov64_instr_base(Rm, Rt, Rt2, 1, cond);
1831 }
1832 
1833 void vmov_f32(FloatRegister Rn, Register Rt, Condition cond = C_DFLT) {
1834   starti;
1835   fp_instr_base(false, cond);
1836   f(0b000, 23, 21), f(0, 20);
1837   rf(Rt, 12), f(0b101000010000, 11, 0);
1838   // double register passed (see 'd0'-'dN' encoding), not reencode it's number
1839   fp_rencode(Rn, false, 16, 7);
1840 }
1841 void vmov_f32(Register Rt, FloatRegister Rn, Condition cond = C_DFLT) {
1842   starti;
1843   fp_instr_base(false, cond);
1844   f(0b000, 23, 21), f(1, 20);
1845   rf(Rt, 12), f(0b101000010000, 11, 0);
1846   // double register passed (see 'd0'-'dN' encoding), not reencode it's number
1847   fp_rencode(Rn, false, 16, 7);
1848 }
1849 
1850 // Floating-point comparison
1851 #define INSN(NAME, E, is64bit)                                                       \
1852   void NAME(FloatRegister Rd, int imm, Condition cond = C_DFLT) {                    \
1853     assert(0 == imm, "vector compare can only be with another vector or zero");      \
1854     starti;                                                                          \
1855     fp_instr_base(is64bit, cond);                                                    \
1856     f(0b10110101, 23, 16), f(E, 7), f(0b1000000, 6, 0);                              \
1857     /* double register passed (see 'd0'-'dN' encoding), not reencode it's number */  \
1858     fp_rencode(Rd, false, 12, 22);                                                   \
1859   }                                                                                  \
1860   void NAME(FloatRegister Vd, FloatRegister Vm, Condition cond = C_DFLT) {           \
1861     starti;                                                                          \
1862     fp_instr_base(is64bit, cond);                                                    \
1863     f(0b10110100, 23, 16), f(E, 7), f(1, 6), f(0, 4);                                \
1864     /* double register passed (see 'd0'-'dN' encoding), not reencode it's number */  \
1865     fp_rencode(Vd, false, 12, 22), fp_rencode(Vm, false, 0, 5);                      \
1866   }
1867   INSN(vcmpe_f64, 1, 1);
1868   INSN(vcmpe_f32, 1, 0);
1869   INSN( vcmp_f64, 0, 1);
1870   INSN( vcmp_f32, 0, 0);
1871 #undef INSN
1872 
1873 //Move FPSCR to ARM register
1874 void vmrs(Register Rt, Condition cond = C_DFLT) {
1875   starti;
1876   f(cond, 31, 28), f(0b111011110001, 27, 16), rf(Rt, 12), f(0b101000010000, 11, 0);
1877 }
1878 
1879 //Move ARM register to FPSCR
1880 void vmsr(Register Rt, Condition cond = C_DFLT) {
1881   starti;
1882   f(cond, 31, 28), f(0b111011100001, 27, 16), rf(Rt, 12), f(0b101000010000, 11, 0);
1883 }
1884 
1885 // TODO These instructions use round towards zero mode. It is possible
1886 //  for the mode to be taken from the FPSCR however it doesn't do it currently
1887 #define INSN(NAME, decode2, b19, op, is64bitRd, is64bitRm, sz)                       \
1888   void NAME(FloatRegister Rd, FloatRegister Rm, Condition cond = C_DFLT) {           \
1889     starti;                                                                          \
1890     fp_instr_base(sz, cond);                                                         \
1891     f(0b1011, 23, 20), f(b19, 19), f(decode2, 18, 16), f(op, 7), f(0b100, 6, 4);     \
1892     /* double register passed (see 'd0'-'dN' encoding), not reencode it's number */  \
1893     fp_rencode(Rd, false, 12, 22);                                                   \
1894     fp_rencode(Rm, false, 0, 5);                                                     \
1895   }
1896   INSN(vcvt_s32_f32, 0b101, 1, 1, 0, 0, 0);
1897   INSN(vcvt_s32_f64, 0b101, 1, 1, 0, 1, 1);
1898   INSN(vcvt_u32_f32, 0b100, 1, 1, 0, 0, 0);
1899   INSN(vcvt_u32_f64, 0b100, 1, 1, 0, 1, 1);
1900 
1901   INSN(vcvt_f64_s32, 0b000, 1, 1, 1, 0, 1);
1902   INSN(vcvt_f64_u32, 0b000, 1, 0, 1, 0, 1);
1903   INSN(vcvt_f32_s32, 0b000, 1, 1, 0, 0, 0);
1904   INSN(vcvt_f32_u32, 0b000, 1, 0, 0, 0, 0);
1905 
1906   INSN(vcvt_f32_f64, 0b111, 0, 1, 0, 1, 1);
1907   INSN(vcvt_f64_f32, 0b111, 0, 1, 1, 0, 0);
1908 #undef INSN
1909 
1910 //Vector load/store
1911  private:
1912   void fp_ldst_instr(int decode, bool is64bit, const Address& adr, Condition cond);
1913  public:
1914 
1915 #define INSN(NAME, decode, is64bit)                                                  \
1916   void NAME(FloatRegister Vd, const Address &adr, Condition cond = C_DFLT) {         \
1917     starti;                                                                          \
1918     fp_ldst_instr(decode, is64bit, adr, cond);                                       \
1919     /* double register passed (see 'd0'-'dN' encoding), not reencode it's number */  \
1920     fp_rencode(Vd, false, 12, 22);                                                   \
1921   }                                                                                  \
1922   void NAME(FloatRegister Vd, address dest, Condition cond = C_DFLT) {               \
1923     long offset = dest - pc();                                                       \
1924     NAME(Vd, Address(r15_pc, offset), cond);                                         \
1925   }                                                                                  \
1926   void NAME(FloatRegister Vd, address dest, relocInfo::relocType rtype,              \
1927             Condition cond = C_DFLT) {                                               \
1928     guarantee(rtype == relocInfo::internal_word_type,                                \
1929               "only internal_word_type relocs make sense here");                     \
1930     NAME(Vd, InternalAddress(dest), cond);                                           \
1931   }                                                                                  \
1932   void NAME(FloatRegister Vd, Label &L, Condition cond = C_DFLT) {                   \
1933     wrap_label(Vd, L, cond, &Assembler::NAME);                                       \
1934   }
1935   INSN(vstr_f64, 0b10000, 1);
1936   INSN(vstr_f32, 0b10000, 0);
1937   INSN(vldr_f64, 0b10001, 1);
1938   INSN(vldr_f32, 0b10001, 0);
1939 #undef INSN
1940 
1941  private:
1942   enum fp_mode { ia_wb, ia, db_wb };
1943   void fp_ldst_mul(Register Rn, uint32_t regset, bool load, bool is64bit, enum fp_mode mode, Condition cond);
1944  public:
1945 #define INSN(NAME, EXT, is64bit, load)                                               \
1946   inline void NAME##ia##EXT(Register Rn, unsigned regset, bool wb = true,            \
1947                             Condition cond = C_DFLT) {                               \
1948     fp_ldst_mul(Rn, regset, load, is64bit,                                           \
1949                 (enum fp_mode)( ia_wb + ( wb?0:1 )), cond);                          \
1950   }                                                                                  \
1951   inline void NAME##db##EXT(Register Rn, unsigned regset, Condition cond = C_DFLT) { \
1952     fp_ldst_mul(Rn, regset, load, is64bit, db_wb, cond);                             \
1953   }
1954   INSN(vldm, _f32, 0, 1);
1955   INSN(vldm, _f64, 1, 1);
1956   INSN(vstm, _f32, 0, 0);
1957   INSN(vstm, _f64, 1, 0);
1958 #undef INSN
1959 
1960 #undef ZERO_ADDR_REG
1961 #undef ONES_ADDR_REG
1962 
1963 /* SIMD extensions
1964  *
1965  * We just use FloatRegister in the following. They are exactly the same
1966  * as SIMD registers.
1967  */
1968  public:
1969   enum SIMD_Align {
1970     ALIGN_STD = 0b00, ALIGN_64 = 0b01, ALIGN_128 = 0b10, ALIGN_256 = 0b11
1971   };
1972   // multiple single elements
1973 private:
1974   void simd_ldst(FloatRegister, unsigned type, unsigned size, unsigned xfer_size,
1975           const Address &addr, enum SIMD_Align align, unsigned encode);
1976 public:
1977 #define INSN(NAME, size, encode)                                                     \
1978   inline void NAME(FloatRegister Dd, const Address &addr, enum SIMD_Align align) {   \
1979     simd_ldst(Dd, 0b0111, size, 1, addr, align, encode);                             \
1980   }                                                                                  \
1981   inline void NAME(FloatRegister Dd, FloatRegister Dd1, const Address &addr,         \
1982     enum SIMD_Align align) {                                                         \
1983     assert(Dd->successor(FloatRegisterImpl::DOUBLE) == Dd1, "Must be consecutive");  \
1984     simd_ldst(Dd, 0b1010, size, 2, addr, align, encode);                             \
1985   }                                                                                  \
1986   inline void NAME(FloatRegister Dd, FloatRegister Dd1, FloatRegister Dd2,           \
1987     const Address &addr, enum SIMD_Align align) {                                    \
1988     assert(Dd->successor(FloatRegisterImpl::DOUBLE) == Dd1, "Must be consecutive");  \
1989     assert(Dd1->successor(FloatRegisterImpl::DOUBLE) == Dd2, "Must be consecutive"); \
1990     simd_ldst(Dd, 0b0110, size, 3, addr, align, encode);                             \
1991   }                                                                                  \
1992   inline void NAME(FloatRegister Dd, FloatRegister Dd1, FloatRegister Dd2,           \
1993     FloatRegister Dd3, const Address &addr, enum SIMD_Align align) {                 \
1994     assert(Dd->successor(FloatRegisterImpl::DOUBLE) == Dd1, "Must be consecutive");  \
1995     assert(Dd1->successor(FloatRegisterImpl::DOUBLE) == Dd2, "Must be consecutive"); \
1996     assert(Dd2->successor(FloatRegisterImpl::DOUBLE) == Dd3, "Must be consecutive"); \
1997     simd_ldst(Dd, 0b0010, size, 4, addr, align, encode);                             \
1998   }
1999   INSN(vld1_8,  0b00, 0b10);
2000   INSN(vld1_16, 0b01, 0b10);
2001   INSN(vld1_32, 0b10, 0b10);
2002   INSN(vld1_64, 0b11, 0b10);
2003   INSN(vst1_8,  0b00, 0b00);
2004   INSN(vst1_16, 0b01, 0b00);
2005   INSN(vst1_32, 0b10, 0b00);
2006   INSN(vst1_64, 0b11, 0b00);
2007 #undef INSN
2008 
2009   // single element to one lane
2010 private:
2011   void simd_ldst_single(FloatRegister Rd, unsigned size, unsigned index,
2012         const Address &addr, bool align, unsigned encode);
2013 public:
2014 #define INSN(NAME, size, encode)                                                     \
2015   inline void NAME(FloatRegister Dd, unsigned index, const Address &addr, bool align) { \
2016     simd_ldst_single(Dd, size, index, addr, align, encode);                          \
2017   }
2018   INSN(vld1_8,  0b00, 0b10);
2019   INSN(vld1_16, 0b01, 0b10);
2020   INSN(vld1_32, 0b10, 0b10);
2021   INSN(vst1_8,  0b00, 0b00);
2022   INSN(vst1_16, 0b01, 0b00);
2023   INSN(vst1_32, 0b10, 0b00);
2024 #undef INSN
2025 
2026 private:
2027   void simd_vmov(FloatRegister Dd, unsigned index, Register Rt, bool advsimd,
2028           unsigned index_bits, unsigned bit20, unsigned opc, Condition cond);
2029 public:
2030 #define INSN(NAME, advsimd, opc, index_bits)                                         \
2031   inline void NAME(FloatRegister Rd, unsigned index, Register Rt,                    \
2032                                   Condition cond = Assembler::AL) {                  \
2033     simd_vmov(Rd, index, Rt, advsimd, index_bits, 0, opc, cond);                     \
2034   }
2035   INSN(vmov_8,  true, 0b1000, 2);
2036   INSN(vmov_16, true, 0b0001, 1);
2037   INSN(vmov_32, false, 0b0000, 0);
2038 #undef INSN
2039 #define INSN(NAME, advsimd, opc, index_bits)                                         \
2040   inline void NAME(Register Rt, FloatRegister Rd, unsigned index,                    \
2041                                   Condition cond = Assembler::AL) {                  \
2042     simd_vmov(Rd, index, Rt, advsimd, index_bits, 1, opc, cond);                     \
2043   }
2044   INSN(vmov_8s,  true, 0b01000, 3);
2045   INSN(vmov_16s, true, 0b00001, 2);
2046   INSN(vmov_8u,  true, 0b11000, 3);
2047   INSN(vmov_16u, true, 0b10001, 2);
2048   INSN(vmov_32,  false, 0b00000, 1);
2049 #undef INSN
2050 
2051 private:
2052   void simd_vmov(FloatRegister Dd, unsigned imm, unsigned q, unsigned op_cmode);
2053 public:
2054 #define INSN(NAME, q, op_cmode)                                                      \
2055   inline void NAME(FloatRegister Dd, unsigned imm) {                                 \
2056     simd_vmov(Dd, imm, q, op_cmode);                                                 \
2057   }
2058   INSN(vmov_64_8,  0, 0b01110);
2059   INSN(vmov_64_16, 0, 0b01000);
2060   INSN(vmov_64_32, 0, 0b00000);
2061   INSN(vmov_128_8,  1, 0b01110);
2062   INSN(vmov_128_16, 1, 0b01000);
2063   INSN(vmov_128_32, 1, 0b00000);
2064 #undef INSN
2065 
2066 private:
2067   void simd_logicalop(FloatRegister Dd, FloatRegister Dn, FloatRegister Dm, unsigned q,
2068         unsigned a, unsigned b, unsigned u, unsigned c);
2069 public:
2070 #define INSN(NAME, q, a, b, u, c)                                                    \
2071   inline void NAME(FloatRegister Dd, FloatRegister Dn, FloatRegister Dm) {           \
2072     simd_logicalop(Dd, Dn, Dm, q, a, b, u, c);                                       \
2073   }
2074   INSN(veor_64,  0, 0b0001, 1, 1, 0b00);
2075   INSN(veor_128, 1, 0b0001, 1, 1, 0b00);
2076   INSN(vand_64,  0, 0b0001, 1, 0, 0b00);
2077   INSN(vand_128, 1, 0b0001, 1, 0, 0b00);
2078   INSN(vorr_64,  0, 0b0001, 1, 0, 0b10);
2079   INSN(vorr_128, 1, 0b0001, 1, 0, 0b10);
2080 #undef INSN
2081 
2082   // vmov is actually a vorr
2083 #define vmov_64(Dd, Dm) vorr_64(Dd, Dm, Dm)
2084 #define vmov_128(Qd, Qm) vorr_128(Qd, Qm, Qm)
2085 
2086 private:
2087   void simd_vmul(FloatRegister Dd, FloatRegister Dn, FloatRegister Dm,
2088           unsigned bit24, unsigned bits109, unsigned size, unsigned mul, unsigned bit6);
2089 public:
2090 #define INSN(NAME, bit24, bit9, size, mul, bit6, bit10)                              \
2091   inline void NAME(FloatRegister Dd, FloatRegister Dn, FloatRegister Dm) {           \
2092     simd_vmul(Dd, Dn, Dm, bit24, (bit10<<1)|bit9, size, mul, bit6);                  \
2093   }
2094   INSN(vmul_64_8,   0, 0, 0b00, 1, 0, 0);
2095   INSN(vmul_64_16,  0, 0, 0b01, 1, 0, 0);
2096   INSN(vmul_64_32,  0, 0, 0b10, 1, 0, 0);
2097   INSN(vmulp_64_8,  1, 0, 0b00, 1, 0, 0);
2098   INSN(vmul_128_8,  0, 0, 0b00, 1, 1, 0);
2099   INSN(vmul_128_16, 0, 0, 0b01, 1, 1, 0);
2100   INSN(vmul_128_32, 0, 0, 0b10, 1, 1, 0);
2101   INSN(vmulp_128_8, 1, 0, 0b00, 1, 1, 0);
2102   INSN(vmull_8s,    0, 0, 0b00, 0, 0, 1);
2103   INSN(vmull_16s,   0, 0, 0b01, 0, 0, 1);
2104   INSN(vmull_32s,   0, 0, 0b10, 0, 0, 1);
2105   INSN(vmull_8u,    1, 0, 0b00, 0, 0, 1);
2106   INSN(vmull_16u,   1, 0, 0b01, 0, 0, 1);
2107   INSN(vmull_32u,   1, 0, 0b10, 0, 0, 1);
2108   INSN(vmullp_8,    0, 1, 0b00, 0, 0, 1);
2109   INSN(vmul_64_f32, 1, 0, 0b00, 1, 0, 1);
2110   INSN(vmul_128_f32,1, 0, 0b00, 1, 1, 1);
2111 #undef INSN
2112 
2113 private:
2114   void simd_vuzp(FloatRegister Dd, FloatRegister Dm, unsigned size, unsigned q);
2115 public:
2116 #define INSN(NAME, size, q)                                                          \
2117   inline void NAME(FloatRegister Dd, FloatRegister Dm) {                             \
2118     simd_vuzp(Dd, Dm, size, q);                                                      \
2119   }
2120   INSN(vuzp_64_8,   0b00, 0);
2121   INSN(vuzp_64_16,  0b01, 0);
2122   INSN(vuzp_64_32,  0b10, 0);
2123   INSN(vuzp_128_8,  0b00, 1);
2124   INSN(vuzp_128_16, 0b01, 1);
2125   INSN(vuzp_128_32, 0b10, 1);
2126 #undef INSN
2127 
2128 private:
2129   void simd_vshl(FloatRegister Dd, FloatRegister Dm, unsigned imm,
2130           unsigned q, unsigned u, unsigned encode);
2131 public:
2132 #define INSN(NAME, size, q, u, encode, checkDd)                                      \
2133   inline void NAME(FloatRegister Dd, FloatRegister Dm, unsigned imm) {               \
2134     assert(!checkDd || (Dd->encoding() & 2) == 0, "Odd register");                   \
2135     unsigned encode_eff = encode;                                                    \
2136     unsigned u_eff = u;                                                              \
2137     imm &= size == 6 ? 0x3f : 0x1f; /* per jvms */                                   \
2138     if (imm >= (1u << size)) { /* vshl cannot encode shift by size or more... */     \
2139       encode_eff = 0b0000; /* .. change to equivalent vshr (actually set to 0) */    \
2140       u_eff = 1;                                                                     \
2141       imm = (1u << size);                                                            \
2142     }                                                                                \
2143     simd_vshl(Dd, Dm, imm|(1u<<size), q, u_eff, encode_eff);                         \
2144   }
2145   INSN(vshl_64_8,   3, 0, 0, 0b0101, false);
2146   INSN(vshl_64_16,  4, 0, 0, 0b0101, false);
2147   INSN(vshl_64_32,  5, 0, 0, 0b0101, false);
2148   INSN(vshl_64_64,  6, 0, 0, 0b0101, false);
2149   INSN(vshl_128_8,  3, 1, 0, 0b0101, false);
2150   INSN(vshl_128_16, 4, 1, 0, 0b0101, false);
2151   INSN(vshl_128_32, 5, 1, 0, 0b0101, false);
2152   INSN(vshl_128_64, 6, 1, 0, 0b0101, false);
2153   INSN(vshll_8s,    3, 0, 0, 0b1010, true);
2154   INSN(vshll_8u,    3, 0, 1, 0b1010, true);
2155   INSN(vshll_16s,   4, 0, 0, 0b1010, true);
2156   INSN(vshll_16u,   4, 0, 1, 0b1010, true);
2157   INSN(vshll_32s,   5, 0, 0, 0b1010, true);
2158   INSN(vshll_32u,   5, 0, 1, 0b1010, true);
2159 #undef INSN
2160 #define INSN(NAME, size, q, u)                                                       \
2161   inline void NAME(FloatRegister Dd, FloatRegister Dm, unsigned imm) {               \
2162     unsigned encode_eff = 0b0000;                                                    \
2163     imm &= size == 6 ? 0x3f : 0x1f; /* per jvms */                                   \
2164     if (imm == 0) { /* vshr cannot encode shift by 0... */                           \
2165       encode_eff = 0b0101; /* ... change equivalent vshl */                          \
2166       imm = 1u << size;                                                              \
2167     } else if (imm > (1u << size)) {                                                 \
2168       imm = 1u << size; /* saturate shift */                                         \
2169     } else { /* encode the imm per ARM spec */                                       \
2170       imm = (1u << size+1) - imm;                                                    \
2171     }                                                                                \
2172     simd_vshl(Dd, Dm, imm, q, u, encode_eff);                                        \
2173   }
2174   INSN(vshr_64_u8,   3, 0, 1);
2175   INSN(vshr_64_u16,  4, 0, 1);
2176   INSN(vshr_64_u32,  5, 0, 1);
2177   INSN(vshr_64_u64,  6, 0, 1);
2178   INSN(vshr_128_u8,  3, 1, 1);
2179   INSN(vshr_128_u16, 4, 1, 1);
2180   INSN(vshr_128_u32, 5, 1, 1);
2181   INSN(vshr_128_u64, 6, 1, 1);
2182   INSN(vshr_64_s8,   3, 0, 0);
2183   INSN(vshr_64_s16,  4, 0, 0);
2184   INSN(vshr_64_s32,  5, 0, 0);
2185   INSN(vshr_64_s64,  6, 0, 0);
2186   INSN(vshr_128_s8,  3, 1, 0);
2187   INSN(vshr_128_s16, 4, 1, 0);
2188   INSN(vshr_128_s32, 5, 1, 0);
2189   INSN(vshr_128_s64, 6, 1, 0);
2190 #undef INSN
2191 #define INSN(NAME, encode, size, q)                                            \
2192   inline void NAME(FloatRegister Dd, FloatRegister Dm, unsigned imm) {         \
2193     simd_vshl(Dd, Dm, imm|(1u<<size), q, 1, encode);                           \
2194   }
2195 #define INSN_GR(NAME, U, encode, u)                                            \
2196   INSN(NAME##_64##U##8,   encode, 3, 0);                                       \
2197   INSN(NAME##_64##U##16,  encode, 4, 0);                                       \
2198   INSN(NAME##_64##U##32,  encode, 5, 0);                                       \
2199   INSN(NAME##_64##U##64,  encode, 6, 0);                                       \
2200   INSN(NAME##_128##U##8,  encode, 3, 1);                                       \
2201   INSN(NAME##_128##U##16, encode, 4, 2);                                       \
2202   INSN(NAME##_128##U##32, encode, 5, 3);                                       \
2203   INSN(NAME##_128##U##64, encode, 6, 4);
2204 
2205   INSN_GR(vsli, _, 0b0101, 1);
2206   INSN_GR(vsri, _, 0b0100, 1);
2207   INSN_GR(vsra, _u, 0b0001, 1);
2208   INSN_GR(vsra, _s, 0b0001, 0);
2209 #undef INSN_GR
2210 #undef INSN
2211 
2212 #define vmovl_8s(Qd, Dm)  vshll_8s(Qd, Dm, 0);
2213 #define vmovl_16s(Qd, Dm) vshll_16s(Qd, Dm, 0);
2214 #define vmovl_32s(Qd, Dm) vshll_32s(Qd, Dm, 0);
2215 #define vmovl_8u(Qd, Dm)  vshll_8u(Qd, Dm, 0);
2216 #define vmovl_16u(Qd, Dm) vshll_16u(Qd, Dm, 0);
2217 #define vmovl_32u(Qd, Dm) vshll_32u(Qd, Dm, 0);
2218 
2219 private:
2220   void simd_vshl(FloatRegister Dd, FloatRegister Dm, FloatRegister Dn, unsigned size,
2221           unsigned q, unsigned u);
2222 public:
2223 #define INSN(NAME, size, q, u)                                                       \
2224   inline void NAME(FloatRegister Dd, FloatRegister Dm, FloatRegister Dn) {           \
2225     simd_vshl(Dd, Dm, Dn, size, q, u);                                               \
2226   }
2227   INSN(vshl_64_u8,   0, 0, 1);
2228   INSN(vshl_64_u16,  1, 0, 1);
2229   INSN(vshl_64_u32,  2, 0, 1);
2230   INSN(vshl_64_u64,  3, 0, 1);
2231   INSN(vshl_128_u8,  0, 1, 1);
2232   INSN(vshl_128_u16, 1, 1, 1);
2233   INSN(vshl_128_u32, 2, 1, 1);
2234   INSN(vshl_128_u64, 3, 1, 1);
2235   INSN(vshl_64_s8,   0, 0, 0);
2236   INSN(vshl_64_s16,  1, 0, 0);
2237   INSN(vshl_64_s32,  2, 0, 0);
2238   INSN(vshl_64_s64,  3, 0, 0);
2239   INSN(vshl_128_s8,  0, 1, 0);
2240   INSN(vshl_128_s16, 1, 1, 0);
2241   INSN(vshl_128_s32, 2, 1, 0);
2242   INSN(vshl_128_s64, 3, 1, 0);
2243 #undef INSN
2244 
2245   // Two registers, miscellaneous
2246 private:
2247   void simd_insn(FloatRegister Dd, FloatRegister Dm, unsigned q, unsigned a,
2248           unsigned b, unsigned size);
2249 public:
2250 #define INSN(NAME, q, size, op, a)                                             \
2251   inline void NAME(FloatRegister Dd, FloatRegister Dm) {                       \
2252     simd_insn(Dd, Dm, q, a, q|(op<<1), size);                                  \
2253   }
2254   INSN(vrev16_64_8,    0, 0, 2, 0b00);
2255   INSN(vrev16_128_8,   1, 0, 2, 0b00);
2256   INSN(vrev32_64_8,    0, 0, 1, 0b00);
2257   INSN(vrev32_128_8,   1, 0, 1, 0b00);
2258   INSN(vrev32_64_16,   0, 1, 1, 0b00);
2259   INSN(vrev32_128_16,  1, 1, 1, 0b00);
2260   INSN(vrev64_64_8,    0, 0, 0, 0b00);
2261   INSN(vrev64_128_8,   1, 0, 0, 0b00);
2262   INSN(vrev64_64_16,   0, 1, 0, 0b00);
2263   INSN(vrev64_128_16,  1, 1, 0, 0b00);
2264   INSN(vrev64_64_32,   0, 2, 0, 0b00);
2265   INSN(vrev64_128_32,  1, 2, 0, 0b00);
2266 #undef INSN
2267 #define INSN(NAME, q, a, b, size)                                              \
2268   inline void NAME(FloatRegister Dd, FloatRegister Dm) {                       \
2269     simd_insn(Dd, Dm, q, a, (b<<1)|q, size);                                   \
2270   }
2271 #define INSN_GR(NAME, a, b)                                                    \
2272   INSN(NAME##_64_8, 0, a, b, 0b00);                                            \
2273   INSN(NAME##_64_16, 0, a, b, 0b01);                                           \
2274   INSN(NAME##_64_32, 0, a, b, 0b10);                                           \
2275   INSN(NAME##_128_8, 1, a, b, 0b00);                                           \
2276   INSN(NAME##_128_16, 1, a, b, 0b01);                                          \
2277   INSN(NAME##_128_32, 1, a, b, 0b10);
2278 
2279   INSN_GR(vtrn, 0b10, 0b0001);
2280   INSN(vswp_64, 0, 0b10, 0b0000, 0b00);
2281   INSN(vswp_128, 1, 0b10, 0b0000, 0b00);
2282 #undef INSN_GR
2283 #undef INSN
2284 
2285 private:
2286   void simd_cnt(FloatRegister Dd, FloatRegister Dm, unsigned q);
2287 public:
2288 #define INSN(NAME, q)                                                                \
2289   inline void NAME(FloatRegister Dd, FloatRegister Dm) {                             \
2290     simd_cnt(Dd, Dm, q);                                                             \
2291   }
2292   INSN(vcnt_64, 0);
2293   INSN(vcnt_128, 1);
2294 #undef INSN
2295 
2296 private:
2297   void simd_padl(FloatRegister Dd, FloatRegister Dm, unsigned q, unsigned size,
2298           unsigned op, unsigned encode);
2299 public:
2300 #define INSN(NAME, q, size, op, encode)                                              \
2301   inline void NAME(FloatRegister Dd, FloatRegister Dm) {                             \
2302     simd_padl(Dd, Dm, q, size, op, encode);                                          \
2303   }
2304   INSN(vpadal_64_s8,   0, 0, 0, 0b110);
2305   INSN(vpadal_64_s16,  0, 1, 0, 0b110);
2306   INSN(vpadal_64_s32,  0, 2, 0, 0b110);
2307   INSN(vpadal_64_u8,   0, 0, 1, 0b110);
2308   INSN(vpadal_64_u16,  0, 1, 1, 0b110);
2309   INSN(vpadal_64_u32,  0, 2, 1, 0b110);
2310   INSN(vpadal_128_s8,  1, 0, 0, 0b110);
2311   INSN(vpadal_128_s16, 1, 1, 0, 0b110);
2312   INSN(vpadal_128_s32, 1, 2, 0, 0b110);
2313   INSN(vpadal_128_u8,  1, 0, 1, 0b110);
2314   INSN(vpadal_128_u16, 1, 1, 1, 0b110);
2315   INSN(vpadal_128_u32, 1, 2, 1, 0b110);
2316   INSN(vpaddl_64_s8,   0, 0, 0, 0b010);
2317   INSN(vpaddl_64_s16,  0, 1, 0, 0b010);
2318   INSN(vpaddl_64_s32,  0, 2, 0, 0b010);
2319   INSN(vpaddl_64_u8,   0, 0, 1, 0b010);
2320   INSN(vpaddl_64_u16,  0, 1, 1, 0b010);
2321   INSN(vpaddl_64_u32,  0, 2, 1, 0b010);
2322   INSN(vpaddl_128_s8,  1, 0, 0, 0b010);
2323   INSN(vpaddl_128_s16, 1, 1, 0, 0b010);
2324   INSN(vpaddl_128_s32, 1, 2, 0, 0b010);
2325   INSN(vpaddl_128_u8,  1, 0, 1, 0b010);
2326   INSN(vpaddl_128_u16, 1, 1, 1, 0b010);
2327   INSN(vpaddl_128_u32, 1, 2, 1, 0b010);
2328 #undef INSN
2329 
2330 private:
2331   void simd_dup(FloatRegister Dd, Register Rt, unsigned q, unsigned size);
2332   void simd_dup(FloatRegister Dd, FloatRegister Dm, unsigned index, unsigned q, unsigned size);
2333 public:
2334 #define INSN(NAME, q, size)                                                          \
2335   inline void NAME(FloatRegister Dd, Register Rt) {                                  \
2336     simd_dup(Dd, Rt, q, size);                                                       \
2337   }
2338   INSN(vdup_64_8, 0, 0b10);
2339   INSN(vdup_64_16, 0, 0b01);
2340   INSN(vdup_64_32, 0, 0b00);
2341   INSN(vdup_128_8, 1, 0b10);
2342   INSN(vdup_128_16, 1, 0b01);
2343   INSN(vdup_128_32, 1, 0b00);
2344 #undef INSN
2345 public:
2346 #define INSN(NAME, q, size)                                                          \
2347   inline void NAME(FloatRegister Dd, FloatRegister Dm, unsigned index) {             \
2348     simd_dup(Dd, Dm, index, q, size);                                                \
2349   }
2350   INSN(vdup_64_8, 0, 0b10);
2351   INSN(vdup_64_16, 0, 0b01);
2352   INSN(vdup_64_32, 0, 0b00);
2353   INSN(vdup_128_8, 1, 0b10);
2354   INSN(vdup_128_16, 1, 0b01);
2355   INSN(vdup_128_32, 1, 0b00);
2356 #undef INSN
2357 #define INSN(NAME, q)                                                                \
2358   inline void NAME(FloatRegister Dd, FloatRegister Sm) {                             \
2359     const int m_num = Sm->encoding_nocheck();                                        \
2360     simd_dup(Dd, as_FloatRegister(m_num & ~1), m_num & 1, q, 0b00);                  \
2361   }
2362   INSN(vdups_64, 0);
2363   INSN(vdups_128, 1);
2364 #undef INSN
2365 
2366 private:
2367   void simd_neg(FloatRegister Dd, FloatRegister Dm, unsigned q, unsigned size);
2368 public:
2369 #define INSN(NAME, q, size)                                                          \
2370   inline void NAME(FloatRegister Dd, FloatRegister Dm) {                             \
2371     simd_neg(Dd, Dm, q, size);                                                       \
2372   }
2373   INSN(vneg_64_s8, 0, 0b00);
2374   INSN(vneg_64_s16, 0, 0b01);
2375   INSN(vneg_64_s32, 0, 0b10);
2376   INSN(vneg_128_s8, 1, 0b00);
2377   INSN(vneg_128_s16, 1, 0b01);
2378   INSN(vneg_128_s32, 1, 0b10);
2379 #undef INSN
2380 
2381 private:
2382   void simd_mvn(FloatRegister Dd, FloatRegister Dm, unsigned q);
2383 public:
2384 #define INSN(NAME, q)                                                          \
2385   inline void NAME(FloatRegister Dd, FloatRegister Dm) {                       \
2386     simd_mvn(Dd, Dm, q);                                                       \
2387   }
2388   INSN(vmvn_64, 0);
2389   INSN(vmvn_128, 1);
2390 #undef INSN
2391 
2392   // three registers of the same length
2393 private:
2394   void simd_insn(FloatRegister Dd, FloatRegister Dn, FloatRegister Dm,
2395           unsigned q, unsigned a, unsigned b, unsigned u, unsigned c);
2396 public:
2397 #define INSN(NAME, q, a, b, u, c) \
2398   inline void NAME(FloatRegister Dd, FloatRegister Dn, FloatRegister Dm) {     \
2399     simd_insn(Dd, Dn, Dm, q, a, b, u, c); \
2400   }
2401 #define INSN_GR(NAME, a, b, u) \
2402   INSN(NAME##_64_8, 0, a, b, u, 0b00) \
2403   INSN(NAME##_64_16, 0, a, b, u, 0b01) \
2404   INSN(NAME##_64_32, 0, a, b, u, 0b10) \
2405   INSN(NAME##_64_64, 0, a, b, u, 0b11) \
2406   INSN(NAME##_128_8, 1, a, b, u, 0b00) \
2407   INSN(NAME##_128_16, 1, a, b, u, 0b01) \
2408   INSN(NAME##_128_32, 1, a, b, u, 0b10) \
2409   INSN(NAME##_128_64, 1, a, b, u, 0b11)
2410 
2411   INSN_GR(vadd, 0b1000, 0b0, 0b0);
2412   INSN(vadd_64_f32, 0, 0b1101, 0b0, 0b0, 0b00);
2413   INSN(vadd_128_f32, 1, 0b1101, 0b0, 0b0, 0b00);
2414   INSN_GR(vsub, 0b1000, 0b0, 0b1);
2415   INSN(vsub_64_f32, 0, 0b1101, 0b0, 0b0, 0b10);
2416   INSN(vsub_128_f32, 1, 0b1101, 0b0, 0b0, 0b10);
2417 
2418 #undef INSN_GR
2419 #undef INSN
2420 
2421   // three registers of different length
2422 private:
2423   void simd_insn(FloatRegister Dd, FloatRegister Dn, FloatRegister Dm,
2424           unsigned qn, unsigned a, unsigned b, unsigned u);
2425 public:
2426 #define INSN(NAME, qn, a, b, u)                                                \
2427   inline void NAME(FloatRegister Dd, FloatRegister Dn, FloatRegister Dm) {     \
2428     simd_insn(Dd, Dn, Dm, qn, a, b, u);                                        \
2429   }
2430 #define INSN_GR(NAME, qn, a)                                                   \
2431   INSN(NAME##_8u, qn, a, 0b00, 1)                                              \
2432   INSN(NAME##_16u, qn, a, 0b01, 1)                                             \
2433   INSN(NAME##_32u, qn, a, 0b10, 1)                                             \
2434   INSN(NAME##_8s, qn, a, 0b00, 0)                                              \
2435   INSN(NAME##_16s, qn, a, 0b01, 0)                                             \
2436   INSN(NAME##_32s, qn, a, 0b10, 0)
2437 
2438   INSN_GR(vaddw, 1, 0b0001);
2439   INSN_GR(vaddl, 0, 0b0000);
2440 #undef INSN_GR
2441 #undef INSN
2442 
2443   // VEXT, the instruction out of any class
2444 private:
2445   void simd_vext(FloatRegister Dd, FloatRegister Dn, FloatRegister Dm, unsigned q, unsigned imm);
2446 public:
2447 #define INSN(NAME, q)                                                                    \
2448   inline void NAME(FloatRegister Dd, FloatRegister Dn, FloatRegister Dm, unsigned imm) { \
2449     simd_vext(Dd, Dn, Dm, q, imm);                                                       \
2450   }
2451   INSN(vext_64, 0u);
2452   INSN(vext_128, 1u);
2453 #undef INSN
2454 
2455 public:
2456 
2457 #define INSN(NAME, r)                                                                \
2458   inline void NAME(Address a) {                                                      \
2459     starti;                                                                          \
2460     f(0b1111, 31, 28);                                                               \
2461     f(0b0101, 27, 24), f(0b01, 21, 20);                                              \
2462     f(0b1111, 15, 12);                                                               \
2463     f(r, 22);                                                                        \
2464     rf(a.base(), 16);                                                                \
2465     if (a.get_mode() == Address::imm) {                                              \
2466       f(a.offset() >= 0 ? 1 : 0, 23);                                                \
2467       f(a.offset() >= 0 ? a.offset() : -a.offset(), 11, 0);                          \
2468     } else if (a.get_mode() == Address::reg) {                                       \
2469       assert(a.get_wb_mode() == Address::off, "must be");                            \
2470       assert(!a.shift().is_register(), "must be");                                   \
2471       f(a.op() == Address::ADD ? 1 : 0, 23);                                         \
2472       rf(a.index(), 0);                                                              \
2473       f(0, 4);                                                                       \
2474       f(a.shift().shift(), 11, 7);                                                   \
2475       f(a.shift().kind(), 6, 5);                                                     \
2476     } else {                                                                         \
2477     ShouldNotReachHere();                                                            \
2478     }                                                                                \
2479   }
2480   INSN(pld,  1);
2481   INSN(pldw, 0);
2482 #undef INSN
2483 
2484 #define INSN(NAME, size, c)                                                                 \
2485   inline void NAME(Register Rd, Register Rn, Register Rm, Condition cond = C_DFLT) {        \
2486     starti;                                                                                 \
2487     assert(VM_Version::features() & FT_CRC32, "Instruction is not supported by CPU");       \
2488     f(cond, 31, 28), f(0b00010, 27, 23), f(size, 22, 21), f(0, 20), rf(Rn, 16), rf(Rd, 12); \
2489     f(0b00, 11, 10), c ? f(0b1, 9) : f(0b0, 9), f(0b00100, 8, 4), rf(Rm, 0);                \
2490   }
2491   INSN(crc32b,  0, 0);
2492   INSN(crc32h,  1, 0);
2493   INSN(crc32w,  2, 0);
2494   INSN(crc32cb, 0, 1);
2495   INSN(crc32ch, 1, 1);
2496   INSN(crc32cw, 2, 1);
2497 #undef INSN
2498 
2499 #define INSN(NAME, opc)                                                        \
2500   inline void NAME(FloatRegister Vd, FloatRegister Vm) {                       \
2501     starti;                                                                    \
2502     f(0b111100111, 31, 23), f(0b110000, 21, 16), f(0, 4);                      \
2503     f(opc, 11, 6), fp_rencode(Vd, false, 12, 22), fp_rencode(Vm, false, 0, 5); \
2504   }
2505 
2506   INSN(aese, 0b001100);
2507   INSN(aesd, 0b001101);
2508   INSN(aesmc, 0b001110);
2509   INSN(aesimc, 0b001111);
2510 
2511 #undef INSN
2512 
2513   Assembler(CodeBuffer* code) : AbstractAssembler(code) {}
2514 
2515   virtual RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr,
2516                                                 Register tmp,
2517                                                 int offset) {
2518     ShouldNotCallThis();
2519     return RegisterOrConstant();
2520   }
2521 
2522   // Stack overflow checking
2523   virtual void bang_stack_with_offset(int offset);
2524 
2525   // Immediate values checks and transformations
2526 
2527   static uint32_t encode_imm12(int imm);
2528   static int decode_imm12(uint32_t imm12);
2529   static bool is_valid_for_imm12(int imm);
2530 
2531   static bool is_valid_for_offset_imm(int imm, int nbits) {
2532     return uabs(imm) < (1u << nbits);
2533   }
2534 
2535   static bool operand_valid_for_logical_immediate(bool is32, uint64_t imm);
2536   static bool operand_valid_for_add_sub_immediate(int imm);
2537   static bool operand_valid_for_add_sub_immediate(unsigned imm);
2538   static bool operand_valid_for_add_sub_immediate(unsigned long imm);
2539   static bool operand_valid_for_add_sub_immediate(jlong imm);
2540   static bool operand_valid_for_float_immediate(float imm);
2541   static bool operand_valid_for_double_immediate(double imm);
2542 
2543   void emit_data64(jlong data, relocInfo::relocType rtype, int format = 0);
2544   void emit_data64(jlong data, RelocationHolder const& rspec, int format = 0);
2545 
2546   // useful to revert back the effect of post/pre addressing modifications
2547   // applied to the base register
2548   void compensate_addr_offset(const Address &adr, Condition cond) {
2549     compensate_addr_offset(adr.base(), adr.index(), adr.shift(), adr.op() == Address::ADD, cond);
2550   }
2551   void compensate_addr_offset(Register Rd, Register Roff, shift_op shift, bool isAdd, Condition cond) {
2552     shift_op shift_back;
2553 
2554     if (shift.is_register()) {
2555       switch (shift.kind()) {
2556         case shift_op::LSL:
2557         case shift_op::LSR:
2558           shift_back = asr(shift.reg());
2559           break;
2560         case shift_op::ASR:
2561           shift_back = lsl(shift.reg());
2562           break;
2563         case shift_op::ROR:
2564           Unimplemented(); // need a temp register here
2565           break;
2566         default:
2567           ShouldNotReachHere();
2568       }
2569     } else {
2570       switch (shift.kind()) {
2571         case shift_op::LSL:
2572         case shift_op::LSR:
2573           shift_back = asr(shift.shift());
2574           break;
2575         case shift_op::ASR:
2576           shift_back = lsl(shift.shift());
2577           break;
2578         case shift_op::ROR:
2579           shift_back = ror(32-shift.shift());
2580           break;
2581         default:
2582           ShouldNotReachHere();
2583       }
2584     }
2585     if (isAdd)
2586       sub(Rd, Rd, Roff, shift_back, cond);
2587     else
2588       add(Rd, Rd, Roff, shift_back, cond);
2589   }
2590 };
2591 
2592 inline Assembler::Membar_mask_bits operator|(Assembler::Membar_mask_bits a,
2593                                              Assembler::Membar_mask_bits b) {
2594   return Assembler::Membar_mask_bits(unsigned(a)|unsigned(b));
2595 }
2596 
2597 Instruction_aarch32::~Instruction_aarch32() {
2598   assem->emit();
2599 }
2600 
2601 #undef starti
2602 
2603 // Invert a condition
2604 inline const Assembler::Condition operator~(const Assembler::Condition cond) {
2605   return Assembler::Condition(int(cond) ^ 1);
2606 }
2607 
2608 class BiasedLockingCounters;
2609 
2610 extern "C" void das(uint64_t start, int len);
2611 
2612 #endif // CPU_AARCH32_VM_ASSEMBLER_AARCH32_HPP