Home | History | Annotate | Download | only in src
      1 //===- subzero/src/IceAssemblerARM32.cpp - Assembler for ARM32 --*- C++ -*-===//
      2 //
      3 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
      4 // for details. All rights reserved. Use of this source code is governed by a
      5 // BSD-style license that can be found in the LICENSE file.
      6 //
      7 // Modified by the Subzero authors.
      8 //
      9 //===----------------------------------------------------------------------===//
     10 //
     11 //                        The Subzero Code Generator
     12 //
     13 // This file is distributed under the University of Illinois Open Source
     14 // License. See LICENSE.TXT for details.
     15 //
     16 //===----------------------------------------------------------------------===//
     17 ///
     18 /// \file
     19 /// \brief Implements the Assembler class for ARM32.
     20 ///
     21 //===----------------------------------------------------------------------===//
     22 
     23 #include "IceAssemblerARM32.h"
     24 #include "IceCfgNode.h"
     25 #include "IceUtils.h"
     26 
     27 namespace {
     28 
     29 using namespace Ice;
     30 using namespace Ice::ARM32;
     31 
     32 using WordType = uint32_t;
     33 static constexpr IValueT kWordSize = sizeof(WordType);
     34 
     35 // The following define individual bits.
     36 static constexpr IValueT B0 = 1;
     37 static constexpr IValueT B1 = 1 << 1;
     38 static constexpr IValueT B2 = 1 << 2;
     39 static constexpr IValueT B3 = 1 << 3;
     40 static constexpr IValueT B4 = 1 << 4;
     41 static constexpr IValueT B5 = 1 << 5;
     42 static constexpr IValueT B6 = 1 << 6;
     43 static constexpr IValueT B7 = 1 << 7;
     44 static constexpr IValueT B8 = 1 << 8;
     45 static constexpr IValueT B9 = 1 << 9;
     46 static constexpr IValueT B10 = 1 << 10;
     47 static constexpr IValueT B11 = 1 << 11;
     48 static constexpr IValueT B12 = 1 << 12;
     49 static constexpr IValueT B13 = 1 << 13;
     50 static constexpr IValueT B14 = 1 << 14;
     51 static constexpr IValueT B15 = 1 << 15;
     52 static constexpr IValueT B16 = 1 << 16;
     53 static constexpr IValueT B17 = 1 << 17;
     54 static constexpr IValueT B18 = 1 << 18;
     55 static constexpr IValueT B19 = 1 << 19;
     56 static constexpr IValueT B20 = 1 << 20;
     57 static constexpr IValueT B21 = 1 << 21;
     58 static constexpr IValueT B22 = 1 << 22;
     59 static constexpr IValueT B23 = 1 << 23;
     60 static constexpr IValueT B24 = 1 << 24;
     61 static constexpr IValueT B25 = 1 << 25;
     62 static constexpr IValueT B26 = 1 << 26;
     63 static constexpr IValueT B27 = 1 << 27;
     64 
     65 // Constants used for the decoding or encoding of the individual fields of
     66 // instructions. Based on ARM section A5.1.
     67 static constexpr IValueT L = 1 << 20; // load (or store)
     68 static constexpr IValueT W = 1 << 21; // writeback base register
     69                                       // (or leave unchanged)
     70 static constexpr IValueT B = 1 << 22; // unsigned byte (or word)
     71 static constexpr IValueT U = 1 << 23; // positive (or negative)
     72                                       // offset/index
     73 static constexpr IValueT P = 1 << 24; // offset/pre-indexed
     74                                       // addressing (or
     75                                       // post-indexed addressing)
     76 
     77 static constexpr IValueT kConditionShift = 28;
     78 static constexpr IValueT kLinkShift = 24;
     79 static constexpr IValueT kOpcodeShift = 21;
     80 static constexpr IValueT kRdShift = 12;
     81 static constexpr IValueT kRmShift = 0;
     82 static constexpr IValueT kRnShift = 16;
     83 static constexpr IValueT kRsShift = 8;
     84 static constexpr IValueT kSShift = 20;
     85 static constexpr IValueT kTypeShift = 25;
     86 
     87 // Immediate instruction fields encoding.
     88 static constexpr IValueT kImmed8Bits = 8;
     89 static constexpr IValueT kImmed8Shift = 0;
     90 static constexpr IValueT kRotateBits = 4;
     91 static constexpr IValueT kRotateShift = 8;
     92 
     93 // Shift instruction register fields encodings.
     94 static constexpr IValueT kShiftImmShift = 7;
     95 static constexpr IValueT kShiftImmBits = 5;
     96 static constexpr IValueT kShiftShift = 5;
     97 static constexpr IValueT kImmed12Bits = 12;
     98 static constexpr IValueT kImm12Shift = 0;
     99 
    100 // Rotation instructions (uxtb etc.).
    101 static constexpr IValueT kRotationShift = 10;
    102 
    103 // MemEx instructions.
    104 static constexpr IValueT kMemExOpcodeShift = 20;
    105 
    106 // Div instruction register field encodings.
    107 static constexpr IValueT kDivRdShift = 16;
    108 static constexpr IValueT kDivRmShift = 8;
    109 static constexpr IValueT kDivRnShift = 0;
    110 
    111 // Type of instruction encoding (bits 25-27). See ARM section A5.1
    112 static constexpr IValueT kInstTypeDataRegister = 0;  // i.e. 000
    113 static constexpr IValueT kInstTypeDataRegShift = 0;  // i.e. 000
    114 static constexpr IValueT kInstTypeDataImmediate = 1; // i.e. 001
    115 static constexpr IValueT kInstTypeMemImmediate = 2;  // i.e. 010
    116 static constexpr IValueT kInstTypeRegisterShift = 3; // i.e. 011
    117 
    118 // Limit on number of registers in a vpush/vpop.
    119 static constexpr SizeT VpushVpopMaxConsecRegs = 16;
    120 
    121 // Offset modifier to current PC for next instruction.  The offset is off by 8
    122 // due to the way the ARM CPUs read PC.
    123 static constexpr IOffsetT kPCReadOffset = 8;
    124 
    125 // Mask to pull out PC offset from branch (b) instruction.
    126 static constexpr int kBranchOffsetBits = 24;
    127 static constexpr IOffsetT kBranchOffsetMask = 0x00ffffff;
    128 
    129 IValueT encodeBool(bool B) { return B ? 1 : 0; }
    130 
    131 IValueT encodeRotation(ARM32::AssemblerARM32::RotationValue Value) {
    132   return static_cast<IValueT>(Value);
    133 }
    134 
    135 IValueT encodeGPRRegister(RegARM32::GPRRegister Rn) {
    136   return static_cast<IValueT>(Rn);
    137 }
    138 
    139 RegARM32::GPRRegister decodeGPRRegister(IValueT R) {
    140   return static_cast<RegARM32::GPRRegister>(R);
    141 }
    142 
    143 IValueT encodeCondition(CondARM32::Cond Cond) {
    144   return static_cast<IValueT>(Cond);
    145 }
    146 
    147 IValueT encodeShift(OperandARM32::ShiftKind Shift) {
    148   // Follows encoding in ARM section A8.4.1 "Constant shifts".
    149   switch (Shift) {
    150   case OperandARM32::kNoShift:
    151   case OperandARM32::LSL:
    152     return 0; // 0b00
    153   case OperandARM32::LSR:
    154     return 1; // 0b01
    155   case OperandARM32::ASR:
    156     return 2; // 0b10
    157   case OperandARM32::ROR:
    158   case OperandARM32::RRX:
    159     return 3; // 0b11
    160   }
    161   llvm::report_fatal_error("Unknown Shift value");
    162   return 0;
    163 }
    164 
    165 // Returns the bits in the corresponding masked value.
    166 IValueT mask(IValueT Value, IValueT Shift, IValueT Bits) {
    167   return (Value >> Shift) & ((1 << Bits) - 1);
    168 }
    169 
    170 // Extract out a Bit in Value.
    171 bool isBitSet(IValueT Bit, IValueT Value) { return (Value & Bit) == Bit; }
    172 
    173 // Returns the GPR register at given Shift in Value.
    174 RegARM32::GPRRegister getGPRReg(IValueT Shift, IValueT Value) {
    175   return decodeGPRRegister((Value >> Shift) & 0xF);
    176 }
    177 
    178 IValueT getEncodedGPRegNum(const Variable *Var) {
    179   assert(Var->hasReg());
    180   const auto Reg = Var->getRegNum();
    181   return llvm::isa<Variable64On32>(Var) ? RegARM32::getI64PairFirstGPRNum(Reg)
    182                                         : RegARM32::getEncodedGPR(Reg);
    183 }
    184 
    185 IValueT getEncodedSRegNum(const Variable *Var) {
    186   assert(Var->hasReg());
    187   return RegARM32::getEncodedSReg(Var->getRegNum());
    188 }
    189 
    190 IValueT getEncodedDRegNum(const Variable *Var) {
    191   return RegARM32::getEncodedDReg(Var->getRegNum());
    192 }
    193 
    194 IValueT getEncodedQRegNum(const Variable *Var) {
    195   return RegARM32::getEncodedQReg(Var->getRegNum());
    196 }
    197 
    198 IValueT mapQRegToDReg(IValueT EncodedQReg) {
    199   IValueT DReg = EncodedQReg << 1;
    200   assert(DReg < RegARM32::getNumDRegs());
    201   return DReg;
    202 }
    203 
    204 IValueT mapQRegToSReg(IValueT EncodedQReg) {
    205   IValueT SReg = EncodedQReg << 2;
    206   assert(SReg < RegARM32::getNumSRegs());
    207   return SReg;
    208 }
    209 
    210 IValueT getYInRegXXXXY(IValueT RegXXXXY) { return RegXXXXY & 0x1; }
    211 
    212 IValueT getXXXXInRegXXXXY(IValueT RegXXXXY) { return RegXXXXY >> 1; }
    213 
    214 IValueT getYInRegYXXXX(IValueT RegYXXXX) { return RegYXXXX >> 4; }
    215 
    216 IValueT getXXXXInRegYXXXX(IValueT RegYXXXX) { return RegYXXXX & 0x0f; }
    217 
    218 // Figures out Op/Cmode values for given Value. Returns true if able to encode.
    219 bool encodeAdvSIMDExpandImm(IValueT Value, Type ElmtTy, IValueT &Op,
    220                             IValueT &Cmode, IValueT &Imm8) {
    221   // TODO(kschimpf): Handle other shifted 8-bit values.
    222   constexpr IValueT Imm8Mask = 0xFF;
    223   if ((Value & IValueT(~Imm8Mask)) != 0)
    224     return false;
    225   Imm8 = Value;
    226   switch (ElmtTy) {
    227   case IceType_i8:
    228     Op = 0;
    229     Cmode = 14; // 0b1110
    230     return true;
    231   case IceType_i16:
    232     Op = 0;
    233     Cmode = 8; // 0b1000
    234     return true;
    235   case IceType_i32:
    236     Op = 0;
    237     Cmode = 0; // 0b0000
    238     return true;
    239   default:
    240     return false;
    241   }
    242 }
    243 
    244 // Defines layouts of an operand representing a (register) memory address,
    245 // possibly modified by an immediate value.
    246 enum EncodedImmAddress {
    247   // Address modified by a rotated immediate 8-bit value.
    248   RotatedImm8Address,
    249 
    250   // Alternate encoding for RotatedImm8Address, where the offset is divided by 4
    251   // before encoding.
    252   RotatedImm8Div4Address,
    253 
    254   // Address modified by an immediate 12-bit value.
    255   Imm12Address,
    256 
    257   // Alternate encoding 3, for an address modified by a rotated immediate 8-bit
    258   // value.
    259   RotatedImm8Enc3Address,
    260 
    261   // Encoding where no immediate offset is used.
    262   NoImmOffsetAddress
    263 };
    264 
    265 // The way an operand is encoded into a sequence of bits in functions
    266 // encodeOperand and encodeAddress below.
    267 enum EncodedOperand {
    268   // Unable to encode, value left undefined.
    269   CantEncode = 0,
    270 
    271   // Value is register found.
    272   EncodedAsRegister,
    273 
    274   // Value=rrrriiiiiiii where rrrr is the rotation, and iiiiiiii is the imm8
    275   // value.
    276   EncodedAsRotatedImm8,
    277 
    278   // EncodedAsImmRegOffset is a memory operand that can take three forms, based
    279   // on type EncodedImmAddress:
    280   //
    281   // ***** RotatedImm8Address *****
    282   //
    283   // Value=0000000pu0w0nnnn0000iiiiiiiiiiii where nnnn is the base register Rn,
    284   // p=1 if pre-indexed addressing, u=1 if offset positive, w=1 if writeback to
    285   // Rn should be used, and iiiiiiiiiiii defines the rotated Imm8 value.
    286   //
    287   // ***** RotatedImm8Div4Address *****
    288   //
    289   // Value=00000000pu0w0nnnn0000iiii0000jjjj where nnnn=Rn, iiiijjjj=Imm8, p=1
    290   // if pre-indexed addressing, u=1 if offset positive, and w=1 if writeback to
    291   // Rn.
    292   //
    293   // ***** Imm12Address *****
    294   //
    295   // Value=0000000pu0w0nnnn0000iiiiiiiiiiii where nnnn is the base register Rn,
    296   // p=1 if pre-indexed addressing, u=1 if offset positive, w=1 if writeback to
    297   // Rn should be used, and iiiiiiiiiiii defines the immediate 12-bit value.
    298   //
    299   // ***** NoImmOffsetAddress *****
    300   //
    301   // Value=000000001000nnnn0000000000000000 where nnnn=Rn.
    302   EncodedAsImmRegOffset,
    303 
    304   // Value=0000000pu0w00nnnnttttiiiiiss0mmmm where nnnn is the base register Rn,
    305   // mmmm is the index register Rm, iiiii is the shift amount, ss is the shift
    306   // kind, p=1 if pre-indexed addressing, u=1 if offset positive, and w=1 if
    307   // writeback to Rn.
    308   EncodedAsShiftRotateImm5,
    309 
    310   // Value=000000000000000000000iiiii0000000 where iiii defines the Imm5 value
    311   // to shift.
    312   EncodedAsShiftImm5,
    313 
    314   // Value=iiiiiss0mmmm where mmmm is the register to rotate, ss is the shift
    315   // kind, and iiiii is the shift amount.
    316   EncodedAsShiftedRegister,
    317 
    318   // Value=ssss0tt1mmmm where mmmm=Rm, tt is an encoded ShiftKind, and ssss=Rms.
    319   EncodedAsRegShiftReg,
    320 
    321   // Value is 32bit integer constant.
    322   EncodedAsConstI32
    323 };
    324 
    325 // Sets Encoding to a rotated Imm8 encoding of Value, if possible.
    326 IValueT encodeRotatedImm8(IValueT RotateAmt, IValueT Immed8) {
    327   assert(RotateAmt < (1 << kRotateBits));
    328   assert(Immed8 < (1 << kImmed8Bits));
    329   return (RotateAmt << kRotateShift) | (Immed8 << kImmed8Shift);
    330 }
    331 
    332 // Encodes iiiiitt0mmmm for data-processing (2nd) operands where iiiii=Imm5,
    333 // tt=Shift, and mmmm=Rm.
    334 IValueT encodeShiftRotateImm5(IValueT Rm, OperandARM32::ShiftKind Shift,
    335                               IOffsetT imm5) {
    336   (void)kShiftImmBits;
    337   assert(imm5 < (1 << kShiftImmBits));
    338   return (imm5 << kShiftImmShift) | (encodeShift(Shift) << kShiftShift) | Rm;
    339 }
    340 
    341 // Encodes mmmmtt01ssss for data-processing operands where mmmm=Rm, ssss=Rs, and
    342 // tt=Shift.
    343 IValueT encodeShiftRotateReg(IValueT Rm, OperandARM32::ShiftKind Shift,
    344                              IValueT Rs) {
    345   return (Rs << kRsShift) | (encodeShift(Shift) << kShiftShift) | B4 |
    346          (Rm << kRmShift);
    347 }
    348 
    349 // Defines the set of registers expected in an operand.
    350 enum RegSetWanted { WantGPRegs, WantSRegs, WantDRegs, WantQRegs };
    351 
    352 EncodedOperand encodeOperand(const Operand *Opnd, IValueT &Value,
    353                              RegSetWanted WantedRegSet) {
    354   Value = 0; // Make sure initialized.
    355   if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) {
    356     if (Var->hasReg()) {
    357       switch (WantedRegSet) {
    358       case WantGPRegs:
    359         Value = getEncodedGPRegNum(Var);
    360         break;
    361       case WantSRegs:
    362         Value = getEncodedSRegNum(Var);
    363         break;
    364       case WantDRegs:
    365         Value = getEncodedDRegNum(Var);
    366         break;
    367       case WantQRegs:
    368         Value = getEncodedQRegNum(Var);
    369         break;
    370       }
    371       return EncodedAsRegister;
    372     }
    373     return CantEncode;
    374   }
    375   if (const auto *FlexImm = llvm::dyn_cast<OperandARM32FlexImm>(Opnd)) {
    376     const IValueT Immed8 = FlexImm->getImm();
    377     const IValueT Rotate = FlexImm->getRotateAmt();
    378     if (!((Rotate < (1 << kRotateBits)) && (Immed8 < (1 << kImmed8Bits))))
    379       return CantEncode;
    380     Value = (Rotate << kRotateShift) | (Immed8 << kImmed8Shift);
    381     return EncodedAsRotatedImm8;
    382   }
    383   if (const auto *Const = llvm::dyn_cast<ConstantInteger32>(Opnd)) {
    384     Value = Const->getValue();
    385     return EncodedAsConstI32;
    386   }
    387   if (const auto *FlexReg = llvm::dyn_cast<OperandARM32FlexReg>(Opnd)) {
    388     Operand *Amt = FlexReg->getShiftAmt();
    389     IValueT Rm;
    390     if (encodeOperand(FlexReg->getReg(), Rm, WantGPRegs) != EncodedAsRegister)
    391       return CantEncode;
    392     if (const auto *Var = llvm::dyn_cast<Variable>(Amt)) {
    393       IValueT Rs;
    394       if (encodeOperand(Var, Rs, WantGPRegs) != EncodedAsRegister)
    395         return CantEncode;
    396       Value = encodeShiftRotateReg(Rm, FlexReg->getShiftOp(), Rs);
    397       return EncodedAsRegShiftReg;
    398     }
    399     // If reached, the amount is a shifted amount by some 5-bit immediate.
    400     uint32_t Imm5;
    401     if (const auto *ShAmt = llvm::dyn_cast<OperandARM32ShAmtImm>(Amt)) {
    402       Imm5 = ShAmt->getShAmtImm();
    403     } else if (const auto *IntConst = llvm::dyn_cast<ConstantInteger32>(Amt)) {
    404       int32_t Val = IntConst->getValue();
    405       if (Val < 0)
    406         return CantEncode;
    407       Imm5 = static_cast<uint32_t>(Val);
    408     } else
    409       return CantEncode;
    410     Value = encodeShiftRotateImm5(Rm, FlexReg->getShiftOp(), Imm5);
    411     return EncodedAsShiftedRegister;
    412   }
    413   if (const auto *ShImm = llvm::dyn_cast<OperandARM32ShAmtImm>(Opnd)) {
    414     const IValueT Immed5 = ShImm->getShAmtImm();
    415     assert(Immed5 < (1 << kShiftImmBits));
    416     Value = (Immed5 << kShiftImmShift);
    417     return EncodedAsShiftImm5;
    418   }
    419   return CantEncode;
    420 }
    421 
    422 IValueT encodeImmRegOffset(IValueT Reg, IOffsetT Offset,
    423                            OperandARM32Mem::AddrMode Mode, IOffsetT MaxOffset,
    424                            IValueT OffsetShift) {
    425   IValueT Value = Mode | (Reg << kRnShift);
    426   if (Offset < 0) {
    427     Offset = -Offset;
    428     Value ^= U; // Flip U to adjust sign.
    429   }
    430   assert(Offset <= MaxOffset);
    431   (void)MaxOffset;
    432   return Value | (Offset >> OffsetShift);
    433 }
    434 
    435 // Encodes immediate register offset using encoding 3.
    436 IValueT encodeImmRegOffsetEnc3(IValueT Rn, IOffsetT Imm8,
    437                                OperandARM32Mem::AddrMode Mode) {
    438   IValueT Value = Mode | (Rn << kRnShift);
    439   if (Imm8 < 0) {
    440     Imm8 = -Imm8;
    441     Value = (Value ^ U);
    442   }
    443   assert(Imm8 < (1 << 8));
    444   Value = Value | B22 | ((Imm8 & 0xf0) << 4) | (Imm8 & 0x0f);
    445   return Value;
    446 }
    447 
    448 IValueT encodeImmRegOffset(EncodedImmAddress ImmEncoding, IValueT Reg,
    449                            IOffsetT Offset, OperandARM32Mem::AddrMode Mode) {
    450   switch (ImmEncoding) {
    451   case RotatedImm8Address: {
    452     constexpr IOffsetT MaxOffset = (1 << 8) - 1;
    453     constexpr IValueT NoRightShift = 0;
    454     return encodeImmRegOffset(Reg, Offset, Mode, MaxOffset, NoRightShift);
    455   }
    456   case RotatedImm8Div4Address: {
    457     assert((Offset & 0x3) == 0);
    458     constexpr IOffsetT MaxOffset = (1 << 8) - 1;
    459     constexpr IValueT RightShift2 = 2;
    460     return encodeImmRegOffset(Reg, Offset, Mode, MaxOffset, RightShift2);
    461   }
    462   case Imm12Address: {
    463     constexpr IOffsetT MaxOffset = (1 << 12) - 1;
    464     constexpr IValueT NoRightShift = 0;
    465     return encodeImmRegOffset(Reg, Offset, Mode, MaxOffset, NoRightShift);
    466   }
    467   case RotatedImm8Enc3Address:
    468     return encodeImmRegOffsetEnc3(Reg, Offset, Mode);
    469   case NoImmOffsetAddress: {
    470     assert(Offset == 0);
    471     assert(Mode == OperandARM32Mem::Offset);
    472     return Reg << kRnShift;
    473   }
    474   }
    475   llvm_unreachable("(silence g++ warning)");
    476 }
    477 
    478 // Encodes memory address Opnd, and encodes that information into Value, based
    479 // on how ARM represents the address. Returns how the value was encoded.
    480 EncodedOperand encodeAddress(const Operand *Opnd, IValueT &Value,
    481                              const AssemblerARM32::TargetInfo &TInfo,
    482                              EncodedImmAddress ImmEncoding) {
    483   Value = 0; // Make sure initialized.
    484   if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) {
    485     // Should be a stack variable, with an offset.
    486     if (Var->hasReg())
    487       return CantEncode;
    488     IOffsetT Offset = Var->getStackOffset();
    489     if (!Utils::IsAbsoluteUint(12, Offset))
    490       return CantEncode;
    491     const auto BaseRegNum =
    492         Var->hasReg() ? Var->getBaseRegNum() : TInfo.FrameOrStackReg;
    493     Value = encodeImmRegOffset(ImmEncoding, BaseRegNum, Offset,
    494                                OperandARM32Mem::Offset);
    495     return EncodedAsImmRegOffset;
    496   }
    497   if (const auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Opnd)) {
    498     Variable *Var = Mem->getBase();
    499     if (!Var->hasReg())
    500       return CantEncode;
    501     IValueT Rn = getEncodedGPRegNum(Var);
    502     if (Mem->isRegReg()) {
    503       const Variable *Index = Mem->getIndex();
    504       if (Var == nullptr)
    505         return CantEncode;
    506       Value = (Rn << kRnShift) | Mem->getAddrMode() |
    507               encodeShiftRotateImm5(getEncodedGPRegNum(Index),
    508                                     Mem->getShiftOp(), Mem->getShiftAmt());
    509       return EncodedAsShiftRotateImm5;
    510     }
    511     // Encoded as immediate register offset.
    512     ConstantInteger32 *Offset = Mem->getOffset();
    513     Value = encodeImmRegOffset(ImmEncoding, Rn, Offset->getValue(),
    514                                Mem->getAddrMode());
    515     return EncodedAsImmRegOffset;
    516   }
    517   return CantEncode;
    518 }
    519 
    520 // Checks that Offset can fit in imm24 constant of branch (b) instruction.
    521 void assertCanEncodeBranchOffset(IOffsetT Offset) {
    522   (void)Offset;
    523   (void)kBranchOffsetBits;
    524   assert(Utils::IsAligned(Offset, 4) &&
    525          Utils::IsInt(kBranchOffsetBits, Offset >> 2));
    526 }
    527 
    528 IValueT encodeBranchOffset(IOffsetT Offset, IValueT Inst) {
    529   // Adjust offset to the way ARM CPUs read PC.
    530   Offset -= kPCReadOffset;
    531 
    532   assertCanEncodeBranchOffset(Offset);
    533 
    534   // Properly preserve only the bits supported in the instruction.
    535   Offset >>= 2;
    536   Offset &= kBranchOffsetMask;
    537   return (Inst & ~kBranchOffsetMask) | Offset;
    538 }
    539 
    540 IValueT encodeRegister(const Operand *OpReg, RegSetWanted WantedRegSet,
    541                        const char *RegName, const char *InstName) {
    542   IValueT Reg = 0;
    543   if (encodeOperand(OpReg, Reg, WantedRegSet) != EncodedAsRegister)
    544     llvm::report_fatal_error(std::string(InstName) + ": Can't find register " +
    545                              RegName);
    546   return Reg;
    547 }
    548 
    549 IValueT encodeGPRegister(const Operand *OpReg, const char *RegName,
    550                          const char *InstName) {
    551   return encodeRegister(OpReg, WantGPRegs, RegName, InstName);
    552 }
    553 
    554 IValueT encodeSRegister(const Operand *OpReg, const char *RegName,
    555                         const char *InstName) {
    556   return encodeRegister(OpReg, WantSRegs, RegName, InstName);
    557 }
    558 
    559 IValueT encodeDRegister(const Operand *OpReg, const char *RegName,
    560                         const char *InstName) {
    561   return encodeRegister(OpReg, WantDRegs, RegName, InstName);
    562 }
    563 
    564 IValueT encodeQRegister(const Operand *OpReg, const char *RegName,
    565                         const char *InstName) {
    566   return encodeRegister(OpReg, WantQRegs, RegName, InstName);
    567 }
    568 
    569 void verifyPOrNotW(IValueT Address, const char *InstName) {
    570   if (BuildDefs::minimal())
    571     return;
    572   if (!isBitSet(P, Address) && isBitSet(W, Address))
    573     llvm::report_fatal_error(std::string(InstName) +
    574                              ": P=0 when W=1 not allowed");
    575 }
    576 
    577 void verifyRegsNotEq(IValueT Reg1, const char *Reg1Name, IValueT Reg2,
    578                      const char *Reg2Name, const char *InstName) {
    579   if (BuildDefs::minimal())
    580     return;
    581   if (Reg1 == Reg2)
    582     llvm::report_fatal_error(std::string(InstName) + ": " + Reg1Name + "=" +
    583                              Reg2Name + " not allowed");
    584 }
    585 
    586 void verifyRegNotPc(IValueT Reg, const char *RegName, const char *InstName) {
    587   verifyRegsNotEq(Reg, RegName, RegARM32::Encoded_Reg_pc, "pc", InstName);
    588 }
    589 
    590 void verifyAddrRegNotPc(IValueT RegShift, IValueT Address, const char *RegName,
    591                         const char *InstName) {
    592   if (BuildDefs::minimal())
    593     return;
    594   if (getGPRReg(RegShift, Address) == RegARM32::Encoded_Reg_pc)
    595     llvm::report_fatal_error(std::string(InstName) + ": " + RegName +
    596                              "=pc not allowed");
    597 }
    598 
    599 void verifyRegNotPcWhenSetFlags(IValueT Reg, bool SetFlags,
    600                                 const char *InstName) {
    601   if (BuildDefs::minimal())
    602     return;
    603   if (SetFlags && (Reg == RegARM32::Encoded_Reg_pc))
    604     llvm::report_fatal_error(std::string(InstName) + ": " +
    605                              RegARM32::getRegName(RegARM32::Reg_pc) +
    606                              "=pc not allowed when CC=1");
    607 }
    608 
    609 } // end of anonymous namespace
    610 
    611 namespace Ice {
    612 namespace ARM32 {
    613 
    614 size_t MoveRelocatableFixup::emit(GlobalContext *Ctx,
    615                                   const Assembler &Asm) const {
    616   if (!BuildDefs::dump())
    617     return InstARM32::InstSize;
    618   Ostream &Str = Ctx->getStrEmit();
    619   IValueT Inst = Asm.load<IValueT>(position());
    620   const bool IsMovw = kind() == llvm::ELF::R_ARM_MOVW_ABS_NC ||
    621                       kind() == llvm::ELF::R_ARM_MOVW_PREL_NC;
    622   const auto Symbol = symbol().toString();
    623   const bool NeedsPCRelSuffix =
    624       (Asm.fixupIsPCRel(kind()) || Symbol == GlobalOffsetTable);
    625   Str << "\t"
    626          "mov" << (IsMovw ? "w" : "t") << "\t"
    627       << RegARM32::getRegName(RegNumT::fixme((Inst >> kRdShift) & 0xF))
    628       << ", #:" << (IsMovw ? "lower" : "upper") << "16:" << Symbol
    629       << (NeedsPCRelSuffix ? " - ." : "") << "\t@ .word "
    630       // TODO(jpp): This is broken, it also needs to add a magic constant.
    631       << llvm::format_hex_no_prefix(Inst, 8) << "\n";
    632   return InstARM32::InstSize;
    633 }
    634 
    635 IValueT AssemblerARM32::encodeElmtType(Type ElmtTy) {
    636   switch (ElmtTy) {
    637   case IceType_i8:
    638     return 0;
    639   case IceType_i16:
    640     return 1;
    641   case IceType_i32:
    642   case IceType_f32:
    643     return 2;
    644   case IceType_i64:
    645     return 3;
    646   default:
    647     llvm::report_fatal_error("SIMD op: Don't understand element type " +
    648                              typeStdString(ElmtTy));
    649   }
    650 }
    651 
    652 // This fixup points to an ARM32 instruction with the following format:
    653 void MoveRelocatableFixup::emitOffset(Assembler *Asm) const {
    654   // cccc00110T00iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd,
    655   // iiiiiiiiiiiiiiii = Imm16, and T=1 for movt.
    656 
    657   const IValueT Inst = Asm->load<IValueT>(position());
    658   constexpr IValueT Imm16Mask = 0x000F0FFF;
    659   const IValueT Imm16 = offset() & 0xffff;
    660   Asm->store(position(),
    661              (Inst & ~Imm16Mask) | ((Imm16 >> 12) << 16) | (Imm16 & 0xfff));
    662 }
    663 
    664 MoveRelocatableFixup *AssemblerARM32::createMoveFixup(bool IsMovW,
    665                                                       const Constant *Value) {
    666   MoveRelocatableFixup *F =
    667       new (allocate<MoveRelocatableFixup>()) MoveRelocatableFixup();
    668   F->set_kind(IsMovW ? (IsNonsfi ? llvm::ELF::R_ARM_MOVW_PREL_NC
    669                                  : llvm::ELF::R_ARM_MOVW_ABS_NC)
    670                      : (IsNonsfi ? llvm::ELF::R_ARM_MOVT_PREL
    671                                  : llvm::ELF::R_ARM_MOVT_ABS));
    672   F->set_value(Value);
    673   Buffer.installFixup(F);
    674   return F;
    675 }
    676 
    677 size_t BlRelocatableFixup::emit(GlobalContext *Ctx,
    678                                 const Assembler &Asm) const {
    679   if (!BuildDefs::dump())
    680     return InstARM32::InstSize;
    681   Ostream &Str = Ctx->getStrEmit();
    682   IValueT Inst = Asm.load<IValueT>(position());
    683   Str << "\t"
    684          "bl\t" << symbol() << "\t@ .word "
    685       << llvm::format_hex_no_prefix(Inst, 8) << "\n";
    686   return InstARM32::InstSize;
    687 }
    688 
    689 void BlRelocatableFixup::emitOffset(Assembler *Asm) const {
    690   // cccc101liiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond, l=Link, and
    691   // iiiiiiiiiiiiiiiiiiiiiiii=
    692   // EncodedBranchOffset(cccc101l000000000000000000000000, Offset);
    693   const IValueT Inst = Asm->load<IValueT>(position());
    694   constexpr IValueT OffsetMask = 0x00FFFFFF;
    695   Asm->store(position(), encodeBranchOffset(offset(), Inst & ~OffsetMask));
    696 }
    697 
    698 void AssemblerARM32::padWithNop(intptr_t Padding) {
    699   constexpr intptr_t InstWidth = sizeof(IValueT);
    700   assert(Padding % InstWidth == 0 &&
    701          "Padding not multiple of instruction size");
    702   for (intptr_t i = 0; i < Padding; i += InstWidth)
    703     nop();
    704 }
    705 
    706 BlRelocatableFixup *
    707 AssemblerARM32::createBlFixup(const ConstantRelocatable *BlTarget) {
    708   BlRelocatableFixup *F =
    709       new (allocate<BlRelocatableFixup>()) BlRelocatableFixup();
    710   F->set_kind(llvm::ELF::R_ARM_CALL);
    711   F->set_value(BlTarget);
    712   Buffer.installFixup(F);
    713   return F;
    714 }
    715 
    716 void AssemblerARM32::bindCfgNodeLabel(const CfgNode *Node) {
    717   if (BuildDefs::dump() && !getFlags().getDisableHybridAssembly()) {
    718     // Generate label name so that branches can find it.
    719     constexpr SizeT InstSize = 0;
    720     emitTextInst(Node->getAsmName() + ":", InstSize);
    721   }
    722   SizeT NodeNumber = Node->getIndex();
    723   assert(!getPreliminary());
    724   Label *L = getOrCreateCfgNodeLabel(NodeNumber);
    725   this->bind(L);
    726 }
    727 
    728 Label *AssemblerARM32::getOrCreateLabel(SizeT Number, LabelVector &Labels) {
    729   Label *L = nullptr;
    730   if (Number == Labels.size()) {
    731     L = new (this->allocate<Label>()) Label();
    732     Labels.push_back(L);
    733     return L;
    734   }
    735   if (Number > Labels.size()) {
    736     Labels.resize(Number + 1);
    737   }
    738   L = Labels[Number];
    739   if (!L) {
    740     L = new (this->allocate<Label>()) Label();
    741     Labels[Number] = L;
    742   }
    743   return L;
    744 }
    745 
    746 // Pull out offset from branch Inst.
    747 IOffsetT AssemblerARM32::decodeBranchOffset(IValueT Inst) {
    748   // Sign-extend, left-shift by 2, and adjust to the way ARM CPUs read PC.
    749   const IOffsetT Offset = (Inst & kBranchOffsetMask) << 8;
    750   return (Offset >> 6) + kPCReadOffset;
    751 }
    752 
    753 void AssemblerARM32::bind(Label *L) {
    754   IOffsetT BoundPc = Buffer.size();
    755   assert(!L->isBound()); // Labels can only be bound once.
    756   while (L->isLinked()) {
    757     IOffsetT Position = L->getLinkPosition();
    758     IOffsetT Dest = BoundPc - Position;
    759     IValueT Inst = Buffer.load<IValueT>(Position);
    760     Buffer.store<IValueT>(Position, encodeBranchOffset(Dest, Inst));
    761     L->setPosition(decodeBranchOffset(Inst));
    762   }
    763   L->bindTo(BoundPc);
    764 }
    765 
    766 void AssemblerARM32::emitTextInst(const std::string &Text, SizeT InstSize) {
    767   AssemblerFixup *F = createTextFixup(Text, InstSize);
    768   emitFixup(F);
    769   for (SizeT I = 0; I < InstSize; ++I) {
    770     AssemblerBuffer::EnsureCapacity ensured(&Buffer);
    771     Buffer.emit<char>(0);
    772   }
    773 }
    774 
    775 void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT InstType,
    776                                 IValueT Opcode, bool SetFlags, IValueT Rn,
    777                                 IValueT Rd, IValueT Imm12,
    778                                 EmitChecks RuleChecks, const char *InstName) {
    779   switch (RuleChecks) {
    780   case NoChecks:
    781     break;
    782   case RdIsPcAndSetFlags:
    783     verifyRegNotPcWhenSetFlags(Rd, SetFlags, InstName);
    784     break;
    785   }
    786   assert(Rd < RegARM32::getNumGPRegs());
    787   assert(CondARM32::isDefined(Cond));
    788   const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) |
    789                            (InstType << kTypeShift) | (Opcode << kOpcodeShift) |
    790                            (encodeBool(SetFlags) << kSShift) |
    791                            (Rn << kRnShift) | (Rd << kRdShift) | Imm12;
    792   emitInst(Encoding);
    793 }
    794 
    795 void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT Opcode,
    796                                 const Operand *OpRd, const Operand *OpRn,
    797                                 const Operand *OpSrc1, bool SetFlags,
    798                                 EmitChecks RuleChecks, const char *InstName) {
    799   IValueT Rd = encodeGPRegister(OpRd, "Rd", InstName);
    800   IValueT Rn = encodeGPRegister(OpRn, "Rn", InstName);
    801   emitType01(Cond, Opcode, Rd, Rn, OpSrc1, SetFlags, RuleChecks, InstName);
    802 }
    803 
    804 void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT Opcode,
    805                                 IValueT Rd, IValueT Rn, const Operand *OpSrc1,
    806                                 bool SetFlags, EmitChecks RuleChecks,
    807                                 const char *InstName) {
    808   IValueT Src1Value;
    809   // TODO(kschimpf) Other possible decodings of data operations.
    810   switch (encodeOperand(OpSrc1, Src1Value, WantGPRegs)) {
    811   default:
    812     llvm::report_fatal_error(std::string(InstName) +
    813                              ": Can't encode instruction");
    814     return;
    815   case EncodedAsRegister: {
    816     // XXX (register)
    817     //   xxx{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>}
    818     //
    819     // cccc000xxxxsnnnnddddiiiiitt0mmmm where cccc=Cond, xxxx=Opcode, dddd=Rd,
    820     // nnnn=Rn, mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
    821     constexpr IValueT Imm5 = 0;
    822     Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Imm5);
    823     emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value,
    824                RuleChecks, InstName);
    825     return;
    826   }
    827   case EncodedAsShiftedRegister: {
    828     // Form is defined in case EncodedAsRegister. (i.e. XXX (register)).
    829     emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value,
    830                RuleChecks, InstName);
    831     return;
    832   }
    833   case EncodedAsConstI32: {
    834     // See if we can convert this to an XXX (immediate).
    835     IValueT RotateAmt;
    836     IValueT Imm8;
    837     if (!OperandARM32FlexImm::canHoldImm(Src1Value, &RotateAmt, &Imm8))
    838       llvm::report_fatal_error(std::string(InstName) +
    839                                ": Immediate rotated constant not valid");
    840     Src1Value = encodeRotatedImm8(RotateAmt, Imm8);
    841     // Intentionally fall to next case!
    842   }
    843   case EncodedAsRotatedImm8: {
    844     // XXX (Immediate)
    845     //   xxx{s}<c> <Rd>, <Rn>, #<RotatedImm8>
    846     //
    847     // cccc001xxxxsnnnnddddiiiiiiiiiiii where cccc=Cond, xxxx=Opcode, dddd=Rd,
    848     // nnnn=Rn, s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
    849     emitType01(Cond, kInstTypeDataImmediate, Opcode, SetFlags, Rn, Rd,
    850                Src1Value, RuleChecks, InstName);
    851     return;
    852   }
    853   case EncodedAsRegShiftReg: {
    854     // XXX (register-shifted reg)
    855     //   xxx{s}<c> <Rd>, <Rn>, <Rm>, <type> <Rs>
    856     //
    857     // cccc000xxxxfnnnnddddssss0tt1mmmm where cccc=Cond, xxxx=Opcode, dddd=Rd,
    858     // nnnn=Rn, ssss=Rs, f=SetFlags, tt is encoding of type, and
    859     // Src1Value=ssss01tt1mmmm.
    860     emitType01(Cond, kInstTypeDataRegShift, Opcode, SetFlags, Rn, Rd, Src1Value,
    861                RuleChecks, InstName);
    862     return;
    863   }
    864   }
    865 }
    866 
    867 void AssemblerARM32::emitType05(CondARM32::Cond Cond, IOffsetT Offset,
    868                                 bool Link) {
    869   // cccc101liiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond, l=Link, and
    870   // iiiiiiiiiiiiiiiiiiiiiiii=
    871   // EncodedBranchOffset(cccc101l000000000000000000000000, Offset);
    872   assert(CondARM32::isDefined(Cond));
    873   IValueT Encoding = static_cast<int32_t>(Cond) << kConditionShift |
    874                      5 << kTypeShift | (Link ? 1 : 0) << kLinkShift;
    875   Encoding = encodeBranchOffset(Offset, Encoding);
    876   emitInst(Encoding);
    877 }
    878 
    879 void AssemblerARM32::emitBranch(Label *L, CondARM32::Cond Cond, bool Link) {
    880   // TODO(kschimpf): Handle far jumps.
    881   if (L->isBound()) {
    882     const int32_t Dest = L->getPosition() - Buffer.size();
    883     emitType05(Cond, Dest, Link);
    884     return;
    885   }
    886   const IOffsetT Position = Buffer.size();
    887   // Use the offset field of the branch instruction for linking the sites.
    888   emitType05(Cond, L->getEncodedPosition(), Link);
    889   L->linkTo(*this, Position);
    890 }
    891 
    892 void AssemblerARM32::emitCompareOp(CondARM32::Cond Cond, IValueT Opcode,
    893                                    const Operand *OpRn, const Operand *OpSrc1,
    894                                    const char *InstName) {
    895   // XXX (register)
    896   //   XXX<c> <Rn>, <Rm>{, <shift>}
    897   //
    898   // ccccyyyxxxx1nnnn0000iiiiitt0mmmm where cccc=Cond, nnnn=Rn, mmmm=Rm, iiiii
    899   // defines shift constant, tt=ShiftKind, yyy=kInstTypeDataRegister, and
    900   // xxxx=Opcode.
    901   //
    902   // XXX (immediate)
    903   //  XXX<c> <Rn>, #<RotatedImm8>
    904   //
    905   // ccccyyyxxxx1nnnn0000iiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
    906   // yyy=kInstTypeDataImmdiate, xxxx=Opcode, and iiiiiiiiiiii=Src1Value
    907   // defining RotatedImm8.
    908   constexpr bool SetFlags = true;
    909   constexpr IValueT Rd = RegARM32::Encoded_Reg_r0;
    910   IValueT Rn = encodeGPRegister(OpRn, "Rn", InstName);
    911   emitType01(Cond, Opcode, Rd, Rn, OpSrc1, SetFlags, NoChecks, InstName);
    912 }
    913 
    914 void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, IValueT InstType,
    915                                bool IsLoad, bool IsByte, IValueT Rt,
    916                                IValueT Address) {
    917   assert(Rt < RegARM32::getNumGPRegs());
    918   assert(CondARM32::isDefined(Cond));
    919   const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) |
    920                            (InstType << kTypeShift) | (IsLoad ? L : 0) |
    921                            (IsByte ? B : 0) | (Rt << kRdShift) | Address;
    922   emitInst(Encoding);
    923 }
    924 
    925 void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, bool IsLoad, bool IsByte,
    926                                IValueT Rt, const Operand *OpAddress,
    927                                const TargetInfo &TInfo, const char *InstName) {
    928   IValueT Address;
    929   switch (encodeAddress(OpAddress, Address, TInfo, Imm12Address)) {
    930   default:
    931     llvm::report_fatal_error(std::string(InstName) +
    932                              ": Memory address not understood");
    933   case EncodedAsImmRegOffset: {
    934     // XXX{B} (immediate):
    935     //   xxx{b}<c> <Rt>, [<Rn>{, #+/-<imm12>}]      ; p=1, w=0
    936     //   xxx{b}<c> <Rt>, [<Rn>], #+/-<imm12>        ; p=1, w=1
    937     //   xxx{b}<c> <Rt>, [<Rn>, #+/-<imm12>]!       ; p=0, w=1
    938     //
    939     // cccc010pubwlnnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
    940     // iiiiiiiiiiii=imm12, b=IsByte, pu0w<<21 is a BlockAddr, l=IsLoad, and
    941     // pu0w0nnnn0000iiiiiiiiiiii=Address.
    942     RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address);
    943 
    944     // Check if conditions of rules violated.
    945     verifyRegNotPc(Rn, "Rn", InstName);
    946     verifyPOrNotW(Address, InstName);
    947     if (!IsByte && (Rn == RegARM32::Encoded_Reg_sp) && !isBitSet(P, Address) &&
    948         isBitSet(U, Address) && !isBitSet(W, Address) &&
    949         (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */))
    950       llvm::report_fatal_error(std::string(InstName) +
    951                                ": Use push/pop instead");
    952 
    953     emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address);
    954     return;
    955   }
    956   case EncodedAsShiftRotateImm5: {
    957     // XXX{B} (register)
    958     //   xxx{b}<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!}
    959     //   xxx{b}<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>}
    960     //
    961     // cccc011pubwlnnnnttttiiiiiss0mmmm where cccc=Cond, tttt=Rt,
    962     // b=IsByte, U=1 if +, pu0b is a BlockAddr, l=IsLoad, and
    963     // pu0w0nnnn0000iiiiiss0mmmm=Address.
    964     RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address);
    965     RegARM32::GPRRegister Rm = getGPRReg(kRmShift, Address);
    966 
    967     // Check if conditions of rules violated.
    968     verifyPOrNotW(Address, InstName);
    969     verifyRegNotPc(Rm, "Rm", InstName);
    970     if (IsByte)
    971       verifyRegNotPc(Rt, "Rt", InstName);
    972     if (isBitSet(W, Address)) {
    973       verifyRegNotPc(Rn, "Rn", InstName);
    974       verifyRegsNotEq(Rn, "Rn", Rt, "Rt", InstName);
    975     }
    976     emitMemOp(Cond, kInstTypeRegisterShift, IsLoad, IsByte, Rt, Address);
    977     return;
    978   }
    979   }
    980 }
    981 
    982 void AssemblerARM32::emitMemOpEnc3(CondARM32::Cond Cond, IValueT Opcode,
    983                                    IValueT Rt, const Operand *OpAddress,
    984                                    const TargetInfo &TInfo,
    985                                    const char *InstName) {
    986   IValueT Address;
    987   switch (encodeAddress(OpAddress, Address, TInfo, RotatedImm8Enc3Address)) {
    988   default:
    989     llvm::report_fatal_error(std::string(InstName) +
    990                              ": Memory address not understood");
    991   case EncodedAsImmRegOffset: {
    992     // XXXH (immediate)
    993     //   xxxh<c> <Rt>, [<Rn>{, #+-<Imm8>}]
    994     //   xxxh<c> <Rt>, [<Rn>, #+/-<Imm8>]
    995     //   xxxh<c> <Rt>, [<Rn>, #+/-<Imm8>]!
    996     //
    997     // cccc000pu0wxnnnnttttiiiiyyyyjjjj where cccc=Cond, nnnn=Rn, tttt=Rt,
    998     // iiiijjjj=Imm8, pu0w<<21 is a BlockAddr, x000000000000yyyy0000=Opcode,
    999     // and pu0w0nnnn0000iiii0000jjjj=Address.
   1000     assert(Rt < RegARM32::getNumGPRegs());
   1001     assert(CondARM32::isDefined(Cond));
   1002     verifyPOrNotW(Address, InstName);
   1003     verifyRegNotPc(Rt, "Rt", InstName);
   1004     if (isBitSet(W, Address))
   1005       verifyRegsNotEq(getGPRReg(kRnShift, Address), "Rn", Rt, "Rt", InstName);
   1006     const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) |
   1007                              Opcode | (Rt << kRdShift) | Address;
   1008     emitInst(Encoding);
   1009     return;
   1010   }
   1011   case EncodedAsShiftRotateImm5: {
   1012     // XXXH (register)
   1013     //   xxxh<c> <Rt>, [<Rn>, +/-<Rm>]{!}
   1014     //   xxxh<c> <Rt>, [<Rn>], +/-<Rm>
   1015     //
   1016     // cccc000pu0wxnnnntttt00001011mmmm where cccc=Cond, tttt=Rt, nnnn=Rn,
   1017     // mmmm=Rm, pu0w<<21 is a BlockAddr, x000000000000yyyy0000=Opcode, and
   1018     // pu0w0nnnn000000000000mmmm=Address.
   1019     assert(Rt < RegARM32::getNumGPRegs());
   1020     assert(CondARM32::isDefined(Cond));
   1021     verifyPOrNotW(Address, InstName);
   1022     verifyRegNotPc(Rt, "Rt", InstName);
   1023     verifyAddrRegNotPc(kRmShift, Address, "Rm", InstName);
   1024     const RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address);
   1025     if (isBitSet(W, Address)) {
   1026       verifyRegNotPc(Rn, "Rn", InstName);
   1027       verifyRegsNotEq(Rn, "Rn", Rt, "Rt", InstName);
   1028     }
   1029     if (mask(Address, kShiftImmShift, 5) != 0)
   1030       // For encoding 3, no shift is allowed.
   1031       llvm::report_fatal_error(std::string(InstName) +
   1032                                ": Shift constant not allowed");
   1033     const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) |
   1034                              Opcode | (Rt << kRdShift) | Address;
   1035     emitInst(Encoding);
   1036     return;
   1037   }
   1038   }
   1039 }
   1040 
   1041 void AssemblerARM32::emitDivOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd,
   1042                                IValueT Rn, IValueT Rm) {
   1043   assert(Rd < RegARM32::getNumGPRegs());
   1044   assert(Rn < RegARM32::getNumGPRegs());
   1045   assert(Rm < RegARM32::getNumGPRegs());
   1046   assert(CondARM32::isDefined(Cond));
   1047   const IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) |
   1048                            (Rn << kDivRnShift) | (Rd << kDivRdShift) | B26 |
   1049                            B25 | B24 | B20 | B15 | B14 | B13 | B12 | B4 |
   1050                            (Rm << kDivRmShift);
   1051   emitInst(Encoding);
   1052 }
   1053 
   1054 void AssemblerARM32::emitInsertExtractInt(CondARM32::Cond Cond,
   1055                                           const Operand *OpQn, uint32_t Index,
   1056                                           const Operand *OpRt, bool IsExtract,
   1057                                           const char *InstName) {
   1058   const IValueT Rt = encodeGPRegister(OpRt, "Rt", InstName);
   1059   IValueT Dn = mapQRegToDReg(encodeQRegister(OpQn, "Qn", InstName));
   1060   assert(Rt != RegARM32::Encoded_Reg_pc);
   1061   assert(Rt != RegARM32::Encoded_Reg_sp);
   1062   assert(CondARM32::isDefined(Cond));
   1063   const uint32_t BitSize = typeWidthInBytes(OpRt->getType()) * CHAR_BIT;
   1064   IValueT Opcode1 = 0;
   1065   IValueT Opcode2 = 0;
   1066   switch (BitSize) {
   1067   default:
   1068     llvm::report_fatal_error(std::string(InstName) +
   1069                              ": Unable to process type " +
   1070                              typeStdString(OpRt->getType()));
   1071   case 8:
   1072     assert(Index < 16);
   1073     Dn = Dn | mask(Index, 3, 1);
   1074     Opcode1 = B1 | mask(Index, 2, 1);
   1075     Opcode2 = mask(Index, 0, 2);
   1076     break;
   1077   case 16:
   1078     assert(Index < 8);
   1079     Dn = Dn | mask(Index, 2, 1);
   1080     Opcode1 = mask(Index, 1, 1);
   1081     Opcode2 = (mask(Index, 0, 1) << 1) | B0;
   1082     break;
   1083   case 32:
   1084     assert(Index < 4);
   1085     Dn = Dn | mask(Index, 1, 1);
   1086     Opcode1 = mask(Index, 0, 1);
   1087     break;
   1088   }
   1089   const IValueT Encoding = B27 | B26 | B25 | B11 | B9 | B8 | B4 |
   1090                            (encodeCondition(Cond) << kConditionShift) |
   1091                            (Opcode1 << 21) |
   1092                            (getXXXXInRegYXXXX(Dn) << kRnShift) | (Rt << 12) |
   1093                            (encodeBool(IsExtract) << 20) |
   1094                            (getYInRegYXXXX(Dn) << 7) | (Opcode2 << 5);
   1095   emitInst(Encoding);
   1096 }
   1097 
   1098 void AssemblerARM32::emitMoveSS(CondARM32::Cond Cond, IValueT Sd, IValueT Sm) {
   1099   // VMOV (register) - ARM section A8.8.340, encoding A2:
   1100   //   vmov<c>.f32 <Sd>, <Sm>
   1101   //
   1102   // cccc11101D110000dddd101001M0mmmm where cccc=Cond, ddddD=Sd, and mmmmM=Sm.
   1103   constexpr IValueT VmovssOpcode = B23 | B21 | B20 | B6;
   1104   constexpr IValueT S0 = 0;
   1105   emitVFPsss(Cond, VmovssOpcode, Sd, S0, Sm);
   1106 }
   1107 
   1108 void AssemblerARM32::emitMulOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd,
   1109                                IValueT Rn, IValueT Rm, IValueT Rs,
   1110                                bool SetFlags) {
   1111   assert(Rd < RegARM32::getNumGPRegs());
   1112   assert(Rn < RegARM32::getNumGPRegs());
   1113   assert(Rm < RegARM32::getNumGPRegs());
   1114   assert(Rs < RegARM32::getNumGPRegs());
   1115   assert(CondARM32::isDefined(Cond));
   1116   IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) |
   1117                      (encodeBool(SetFlags) << kSShift) | (Rn << kRnShift) |
   1118                      (Rd << kRdShift) | (Rs << kRsShift) | B7 | B4 |
   1119                      (Rm << kRmShift);
   1120   emitInst(Encoding);
   1121 }
   1122 
   1123 void AssemblerARM32::emitMultiMemOp(CondARM32::Cond Cond,
   1124                                     BlockAddressMode AddressMode, bool IsLoad,
   1125                                     IValueT BaseReg, IValueT Registers) {
   1126   assert(CondARM32::isDefined(Cond));
   1127   assert(BaseReg < RegARM32::getNumGPRegs());
   1128   assert(Registers < (1 << RegARM32::getNumGPRegs()));
   1129   IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B27 |
   1130                      AddressMode | (IsLoad ? L : 0) | (BaseReg << kRnShift) |
   1131                      Registers;
   1132   emitInst(Encoding);
   1133 }
   1134 
   1135 void AssemblerARM32::emitSignExtend(CondARM32::Cond Cond, IValueT Opcode,
   1136                                     const Operand *OpRd, const Operand *OpSrc0,
   1137                                     const char *InstName) {
   1138   IValueT Rd = encodeGPRegister(OpRd, "Rd", InstName);
   1139   IValueT Rm = encodeGPRegister(OpSrc0, "Rm", InstName);
   1140   // Note: For the moment, we assume no rotation is specified.
   1141   RotationValue Rotation = kRotateNone;
   1142   constexpr IValueT Rn = RegARM32::Encoded_Reg_pc;
   1143   const Type Ty = OpSrc0->getType();
   1144   switch (Ty) {
   1145   default:
   1146     llvm::report_fatal_error(std::string(InstName) + ": Type " +
   1147                              typeString(Ty) + " not allowed");
   1148     break;
   1149   case IceType_i1:
   1150   case IceType_i8: {
   1151     // SXTB/UXTB - Arm sections A8.8.233 and A8.8.274, encoding A1:
   1152     //   sxtb<c> <Rd>, <Rm>{, <rotate>}
   1153     //   uxtb<c> <Rd>, <Rm>{, <rotate>}
   1154     //
   1155     // ccccxxxxxxxx1111ddddrr000111mmmm where cccc=Cond, xxxxxxxx<<20=Opcode,
   1156     // dddd=Rd, mmmm=Rm, and rr defined (RotationValue) rotate.
   1157     break;
   1158   }
   1159   case IceType_i16: {
   1160     // SXTH/UXTH - ARM sections A8.8.235 and A8.8.276, encoding A1:
   1161     //   uxth<c> <Rd>< <Rm>{, <rotate>}
   1162     //
   1163     // cccc01101111nnnnddddrr000111mmmm where cccc=Cond, dddd=Rd, mmmm=Rm, and
   1164     // rr defined (RotationValue) rotate.
   1165     Opcode |= B20;
   1166     break;
   1167   }
   1168   }
   1169 
   1170   assert(CondARM32::isDefined(Cond));
   1171   IValueT Rot = encodeRotation(Rotation);
   1172   if (!Utils::IsUint(2, Rot))
   1173     llvm::report_fatal_error(std::string(InstName) +
   1174                              ": Illegal rotation value");
   1175   IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | Opcode |
   1176                      (Rn << kRnShift) | (Rd << kRdShift) |
   1177                      (Rot << kRotationShift) | B6 | B5 | B4 | (Rm << kRmShift);
   1178   emitInst(Encoding);
   1179 }
   1180 
   1181 void AssemblerARM32::emitSIMDBase(IValueT Opcode, IValueT Dd, IValueT Dn,
   1182                                   IValueT Dm, bool UseQRegs, bool IsFloatTy) {
   1183   const IValueT Encoding =
   1184       Opcode | B25 | (encodeCondition(CondARM32::kNone) << kConditionShift) |
   1185       (getYInRegYXXXX(Dd) << 22) | (getXXXXInRegYXXXX(Dn) << 16) |
   1186       (getXXXXInRegYXXXX(Dd) << 12) | (IsFloatTy ? B10 : 0) |
   1187       (getYInRegYXXXX(Dn) << 7) | (encodeBool(UseQRegs) << 6) |
   1188       (getYInRegYXXXX(Dm) << 5) | getXXXXInRegYXXXX(Dm);
   1189   emitInst(Encoding);
   1190 }
   1191 
   1192 void AssemblerARM32::emitSIMD(IValueT Opcode, Type ElmtTy, IValueT Dd,
   1193                               IValueT Dn, IValueT Dm, bool UseQRegs) {
   1194   constexpr IValueT ElmtShift = 20;
   1195   const IValueT ElmtSize = encodeElmtType(ElmtTy);
   1196   assert(Utils::IsUint(2, ElmtSize));
   1197   emitSIMDBase(Opcode | (ElmtSize << ElmtShift), Dd, Dn, Dm, UseQRegs,
   1198                isFloatingType(ElmtTy));
   1199 }
   1200 
   1201 void AssemblerARM32::emitSIMDqqqBase(IValueT Opcode, const Operand *OpQd,
   1202                                      const Operand *OpQn, const Operand *OpQm,
   1203                                      bool IsFloatTy, const char *OpcodeName) {
   1204   const IValueT Qd = encodeQRegister(OpQd, "Qd", OpcodeName);
   1205   const IValueT Qn = encodeQRegister(OpQn, "Qn", OpcodeName);
   1206   const IValueT Qm = encodeQRegister(OpQm, "Qm", OpcodeName);
   1207   constexpr bool UseQRegs = true;
   1208   emitSIMDBase(Opcode, mapQRegToDReg(Qd), mapQRegToDReg(Qn), mapQRegToDReg(Qm),
   1209                UseQRegs, IsFloatTy);
   1210 }
   1211 
   1212 void AssemblerARM32::emitSIMDqqq(IValueT Opcode, Type ElmtTy,
   1213                                  const Operand *OpQd, const Operand *OpQn,
   1214                                  const Operand *OpQm, const char *OpcodeName) {
   1215   constexpr IValueT ElmtShift = 20;
   1216   const IValueT ElmtSize = encodeElmtType(ElmtTy);
   1217   assert(Utils::IsUint(2, ElmtSize));
   1218   emitSIMDqqqBase(Opcode | (ElmtSize << ElmtShift), OpQd, OpQn, OpQm,
   1219                   isFloatingType(ElmtTy), OpcodeName);
   1220 }
   1221 
   1222 void AssemblerARM32::emitSIMDShiftqqc(IValueT Opcode, const Operand *OpQd,
   1223                                       const Operand *OpQm, const IValueT Imm6,
   1224                                       const char *OpcodeName) {
   1225   const IValueT Qd = encodeQRegister(OpQd, "Qd", OpcodeName);
   1226   const IValueT Qn = 0;
   1227   const IValueT Qm = encodeQRegister(OpQm, "Qm", OpcodeName);
   1228   constexpr bool UseQRegs = true;
   1229   constexpr bool IsFloatTy = false;
   1230   constexpr IValueT ElmtShift = 16;
   1231   emitSIMDBase(Opcode | (Imm6 << ElmtShift), mapQRegToDReg(Qd),
   1232                mapQRegToDReg(Qn), mapQRegToDReg(Qm), UseQRegs, IsFloatTy);
   1233 }
   1234 
   1235 void AssemblerARM32::emitSIMDCvtqq(IValueT Opcode, const Operand *OpQd,
   1236                                    const Operand *OpQm,
   1237                                    const char *OpcodeName) {
   1238   const IValueT SIMDOpcode =
   1239       B24 | B23 | B21 | B20 | B19 | B17 | B16 | B10 | B9 | Opcode;
   1240   constexpr bool UseQRegs = true;
   1241   constexpr bool IsFloatTy = false;
   1242   const IValueT Qd = encodeQRegister(OpQd, "Qd", OpcodeName);
   1243   constexpr IValueT Qn = 0;
   1244   const IValueT Qm = encodeQRegister(OpQm, "Qm", OpcodeName);
   1245   emitSIMDBase(SIMDOpcode, mapQRegToDReg(Qd), mapQRegToDReg(Qn),
   1246                mapQRegToDReg(Qm), UseQRegs, IsFloatTy);
   1247 }
   1248 
   1249 void AssemblerARM32::emitVFPddd(CondARM32::Cond Cond, IValueT Opcode,
   1250                                 IValueT Dd, IValueT Dn, IValueT Dm) {
   1251   assert(Dd < RegARM32::getNumDRegs());
   1252   assert(Dn < RegARM32::getNumDRegs());
   1253   assert(Dm < RegARM32::getNumDRegs());
   1254   assert(CondARM32::isDefined(Cond));
   1255   constexpr IValueT VFPOpcode = B27 | B26 | B25 | B11 | B9 | B8;
   1256   const IValueT Encoding =
   1257       Opcode | VFPOpcode | (encodeCondition(Cond) << kConditionShift) |
   1258       (getYInRegYXXXX(Dd) << 22) | (getXXXXInRegYXXXX(Dn) << 16) |
   1259       (getXXXXInRegYXXXX(Dd) << 12) | (getYInRegYXXXX(Dn) << 7) |
   1260       (getYInRegYXXXX(Dm) << 5) | getXXXXInRegYXXXX(Dm);
   1261   emitInst(Encoding);
   1262 }
   1263 
   1264 void AssemblerARM32::emitVFPddd(CondARM32::Cond Cond, IValueT Opcode,
   1265                                 const Operand *OpDd, const Operand *OpDn,
   1266                                 const Operand *OpDm, const char *InstName) {
   1267   IValueT Dd = encodeDRegister(OpDd, "Dd", InstName);
   1268   IValueT Dn = encodeDRegister(OpDn, "Dn", InstName);
   1269   IValueT Dm = encodeDRegister(OpDm, "Dm", InstName);
   1270   emitVFPddd(Cond, Opcode, Dd, Dn, Dm);
   1271 }
   1272 
   1273 void AssemblerARM32::emitVFPsss(CondARM32::Cond Cond, IValueT Opcode,
   1274                                 IValueT Sd, IValueT Sn, IValueT Sm) {
   1275   assert(Sd < RegARM32::getNumSRegs());
   1276   assert(Sn < RegARM32::getNumSRegs());
   1277   assert(Sm < RegARM32::getNumSRegs());
   1278   assert(CondARM32::isDefined(Cond));
   1279   constexpr IValueT VFPOpcode = B27 | B26 | B25 | B11 | B9;
   1280   const IValueT Encoding =
   1281       Opcode | VFPOpcode | (encodeCondition(Cond) << kConditionShift) |
   1282       (getYInRegXXXXY(Sd) << 22) | (getXXXXInRegXXXXY(Sn) << 16) |
   1283       (getXXXXInRegXXXXY(Sd) << 12) | (getYInRegXXXXY(Sn) << 7) |
   1284       (getYInRegXXXXY(Sm) << 5) | getXXXXInRegXXXXY(Sm);
   1285   emitInst(Encoding);
   1286 }
   1287 
   1288 void AssemblerARM32::emitVFPsss(CondARM32::Cond Cond, IValueT Opcode,
   1289                                 const Operand *OpSd, const Operand *OpSn,
   1290                                 const Operand *OpSm, const char *InstName) {
   1291   const IValueT Sd = encodeSRegister(OpSd, "Sd", InstName);
   1292   const IValueT Sn = encodeSRegister(OpSn, "Sn", InstName);
   1293   const IValueT Sm = encodeSRegister(OpSm, "Sm", InstName);
   1294   emitVFPsss(Cond, Opcode, Sd, Sn, Sm);
   1295 }
   1296 
   1297 void AssemblerARM32::adc(const Operand *OpRd, const Operand *OpRn,
   1298                          const Operand *OpSrc1, bool SetFlags,
   1299                          CondARM32::Cond Cond) {
   1300   // ADC (register) - ARM section 18.8.2, encoding A1:
   1301   //   adc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>}
   1302   //
   1303   // cccc0000101snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
   1304   // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
   1305   //
   1306   // ADC (Immediate) - ARM section A8.8.1, encoding A1:
   1307   //   adc{s}<c> <Rd>, <Rn>, #<RotatedImm8>
   1308   //
   1309   // cccc0010101snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
   1310   // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
   1311   constexpr const char *AdcName = "adc";
   1312   constexpr IValueT AdcOpcode = B2 | B0; // 0101
   1313   emitType01(Cond, AdcOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
   1314              AdcName);
   1315 }
   1316 
   1317 void AssemblerARM32::add(const Operand *OpRd, const Operand *OpRn,
   1318                          const Operand *OpSrc1, bool SetFlags,
   1319                          CondARM32::Cond Cond) {
   1320   // ADD (register) - ARM section A8.8.7, encoding A1:
   1321   //   add{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>}
   1322   // ADD (Sp plus register) - ARM section A8.8.11, encoding A1:
   1323   //   add{s}<c> sp, <Rn>, <Rm>{, <shiff>}
   1324   //
   1325   // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
   1326   // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
   1327   //
   1328   // ADD (Immediate) - ARM section A8.8.5, encoding A1:
   1329   //   add{s}<c> <Rd>, <Rn>, #<RotatedImm8>
   1330   // ADD (SP plus immediate) - ARM section A8.8.9, encoding A1.
   1331   //   add{s}<c> <Rd>, sp, #<RotatedImm8>
   1332   //
   1333   // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
   1334   // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
   1335   constexpr const char *AddName = "add";
   1336   constexpr IValueT Add = B2; // 0100
   1337   emitType01(Cond, Add, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
   1338              AddName);
   1339 }
   1340 
   1341 void AssemblerARM32::and_(const Operand *OpRd, const Operand *OpRn,
   1342                           const Operand *OpSrc1, bool SetFlags,
   1343                           CondARM32::Cond Cond) {
   1344   // AND (register) - ARM section A8.8.14, encoding A1:
   1345   //   and{s}<c> <Rd>, <Rn>{, <shift>}
   1346   //
   1347   // cccc0000000snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
   1348   // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
   1349   //
   1350   // AND (Immediate) - ARM section A8.8.13, encoding A1:
   1351   //   and{s}<c> <Rd>, <Rn>, #<RotatedImm8>
   1352   //
   1353   // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
   1354   // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
   1355   constexpr const char *AndName = "and";
   1356   constexpr IValueT And = 0; // 0000
   1357   emitType01(Cond, And, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
   1358              AndName);
   1359 }
   1360 
   1361 void AssemblerARM32::b(Label *L, CondARM32::Cond Cond) {
   1362   emitBranch(L, Cond, false);
   1363 }
   1364 
   1365 void AssemblerARM32::bkpt(uint16_t Imm16) {
   1366   // BKPT - ARM section A*.8.24 - encoding A1:
   1367   //   bkpt #<Imm16>
   1368   //
   1369   // cccc00010010iiiiiiiiiiii0111iiii where cccc=AL and iiiiiiiiiiiiiiii=Imm16
   1370   const IValueT Encoding = (CondARM32::AL << kConditionShift) | B24 | B21 |
   1371                            ((Imm16 >> 4) << 8) | B6 | B5 | B4 | (Imm16 & 0xf);
   1372   emitInst(Encoding);
   1373 }
   1374 
   1375 void AssemblerARM32::bic(const Operand *OpRd, const Operand *OpRn,
   1376                          const Operand *OpSrc1, bool SetFlags,
   1377                          CondARM32::Cond Cond) {
   1378   // BIC (register) - ARM section A8.8.22, encoding A1:
   1379   //   bic{s}<c> <Rd>, <Rn>, <Rm>{, <shift>}
   1380   //
   1381   // cccc0001110snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
   1382   // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
   1383   //
   1384   // BIC (immediate) - ARM section A8.8.21, encoding A1:
   1385   //   bic{s}<c> <Rd>, <Rn>, #<RotatedImm8>
   1386   //
   1387   // cccc0011110snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rn, nnnn=Rn,
   1388   // s=SetFlags, and iiiiiiiiiiii=Src1Value defining RotatedImm8.
   1389   constexpr const char *BicName = "bic";
   1390   constexpr IValueT BicOpcode = B3 | B2 | B1; // i.e. 1110
   1391   emitType01(Cond, BicOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
   1392              BicName);
   1393 }
   1394 
   1395 void AssemblerARM32::bl(const ConstantRelocatable *Target) {
   1396   // BL (immediate) - ARM section A8.8.25, encoding A1:
   1397   //   bl<c> <label>
   1398   //
   1399   // cccc1011iiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond (not currently allowed)
   1400   // and iiiiiiiiiiiiiiiiiiiiiiii is the (encoded) Target to branch to.
   1401   emitFixup(createBlFixup(Target));
   1402   constexpr CondARM32::Cond Cond = CondARM32::AL;
   1403   constexpr IValueT Immed = 0;
   1404   constexpr bool Link = true;
   1405   emitType05(Cond, Immed, Link);
   1406 }
   1407 
   1408 void AssemblerARM32::blx(const Operand *Target) {
   1409   // BLX (register) - ARM section A8.8.26, encoding A1:
   1410   //   blx<c> <Rm>
   1411   //
   1412   // cccc000100101111111111110011mmmm where cccc=Cond (not currently allowed)
   1413   // and mmmm=Rm.
   1414   constexpr const char *BlxName = "Blx";
   1415   IValueT Rm = encodeGPRegister(Target, "Rm", BlxName);
   1416   verifyRegNotPc(Rm, "Rm", BlxName);
   1417   constexpr CondARM32::Cond Cond = CondARM32::AL;
   1418   int32_t Encoding = (encodeCondition(Cond) << kConditionShift) | B24 | B21 |
   1419                      (0xfff << 8) | B5 | B4 | (Rm << kRmShift);
   1420   emitInst(Encoding);
   1421 }
   1422 
   1423 void AssemblerARM32::bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond) {
   1424   // BX - ARM section A8.8.27, encoding A1:
   1425   //   bx<c> <Rm>
   1426   //
   1427   // cccc000100101111111111110001mmmm where mmmm=rm and cccc=Cond.
   1428   assert(CondARM32::isDefined(Cond));
   1429   const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B24 |
   1430                            B21 | (0xfff << 8) | B4 |
   1431                            (encodeGPRRegister(Rm) << kRmShift);
   1432   emitInst(Encoding);
   1433 }
   1434 
   1435 void AssemblerARM32::clz(const Operand *OpRd, const Operand *OpSrc,
   1436                          CondARM32::Cond Cond) {
   1437   // CLZ - ARM section A8.8.33, encoding A1:
   1438   //   clz<c> <Rd> <Rm>
   1439   //
   1440   // cccc000101101111dddd11110001mmmm where cccc=Cond, dddd=Rd, and mmmm=Rm.
   1441   constexpr const char *ClzName = "clz";
   1442   constexpr const char *RdName = "Rd";
   1443   constexpr const char *RmName = "Rm";
   1444   IValueT Rd = encodeGPRegister(OpRd, RdName, ClzName);
   1445   assert(Rd < RegARM32::getNumGPRegs());
   1446   verifyRegNotPc(Rd, RdName, ClzName);
   1447   IValueT Rm = encodeGPRegister(OpSrc, RmName, ClzName);
   1448   assert(Rm < RegARM32::getNumGPRegs());
   1449   verifyRegNotPc(Rm, RmName, ClzName);
   1450   assert(CondARM32::isDefined(Cond));
   1451   constexpr IValueT PredefinedBits =
   1452       B24 | B22 | B21 | (0xF << 16) | (0xf << 8) | B4;
   1453   const IValueT Encoding = PredefinedBits | (Cond << kConditionShift) |
   1454                            (Rd << kRdShift) | (Rm << kRmShift);
   1455   emitInst(Encoding);
   1456 }
   1457 
   1458 void AssemblerARM32::cmn(const Operand *OpRn, const Operand *OpSrc1,
   1459                          CondARM32::Cond Cond) {
   1460   // CMN (immediate) - ARM section A8.8.34, encoding A1:
   1461   //   cmn<c> <Rn>, #<RotatedImm8>
   1462   //
   1463   // cccc00110111nnnn0000iiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
   1464   // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
   1465   //
   1466   // CMN (register) - ARM section A8.8.35, encodeing A1:
   1467   //   cmn<c> <Rn>, <Rm>{, <shift>}
   1468   //
   1469   // cccc00010111nnnn0000iiiiitt0mmmm where cccc=Cond, nnnn=Rn, mmmm=Rm,
   1470   // iiiii=Shift, and tt=ShiftKind.
   1471   constexpr const char *CmnName = "cmn";
   1472   constexpr IValueT CmnOpcode = B3 | B1 | B0; // ie. 1011
   1473   emitCompareOp(Cond, CmnOpcode, OpRn, OpSrc1, CmnName);
   1474 }
   1475 
   1476 void AssemblerARM32::cmp(const Operand *OpRn, const Operand *OpSrc1,
   1477                          CondARM32::Cond Cond) {
   1478   // CMP (register) - ARM section A8.8.38, encoding A1:
   1479   //   cmp<c> <Rn>, <Rm>{, <shift>}
   1480   //
   1481   // cccc00010101nnnn0000iiiiitt0mmmm where cccc=Cond, nnnn=Rn, mmmm=Rm,
   1482   // iiiii=Shift, and tt=ShiftKind.
   1483   //
   1484   // CMP (immediate) - ARM section A8.8.37
   1485   //  cmp<c: <Rn>, #<RotatedImm8>
   1486   //
   1487   // cccc00110101nnnn0000iiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
   1488   // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
   1489   constexpr const char *CmpName = "cmp";
   1490   constexpr IValueT CmpOpcode = B3 | B1; // ie. 1010
   1491   emitCompareOp(Cond, CmpOpcode, OpRn, OpSrc1, CmpName);
   1492 }
   1493 
   1494 void AssemblerARM32::dmb(IValueT Option) {
   1495   // DMB - ARM section A8.8.43, encoding A1:
   1496   //   dmb <option>
   1497   //
   1498   // 1111010101111111111100000101xxxx where xxxx=Option.
   1499   assert(Utils::IsUint(4, Option) && "Bad dmb option");
   1500   const IValueT Encoding =
   1501       (encodeCondition(CondARM32::kNone) << kConditionShift) | B26 | B24 | B22 |
   1502       B21 | B20 | B19 | B18 | B17 | B16 | B15 | B14 | B13 | B12 | B6 | B4 |
   1503       Option;
   1504   emitInst(Encoding);
   1505 }
   1506 
   1507 void AssemblerARM32::eor(const Operand *OpRd, const Operand *OpRn,
   1508                          const Operand *OpSrc1, bool SetFlags,
   1509                          CondARM32::Cond Cond) {
   1510   // EOR (register) - ARM section A*.8.47, encoding A1:
   1511   //   eor{s}<c> <Rd>, <Rn>, <Rm>{, <shift>}
   1512   //
   1513   // cccc0000001snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
   1514   // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
   1515   //
   1516   // EOR (Immediate) - ARM section A8.*.46, encoding A1:
   1517   //   eor{s}<c> <Rd>, <Rn>, #RotatedImm8
   1518   //
   1519   // cccc0010001snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
   1520   // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
   1521   constexpr const char *EorName = "eor";
   1522   constexpr IValueT EorOpcode = B0; // 0001
   1523   emitType01(Cond, EorOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
   1524              EorName);
   1525 }
   1526 
   1527 void AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress,
   1528                          CondARM32::Cond Cond, const TargetInfo &TInfo) {
   1529   constexpr const char *LdrName = "ldr";
   1530   constexpr bool IsLoad = true;
   1531   IValueT Rt = encodeGPRegister(OpRt, "Rt", LdrName);
   1532   const Type Ty = OpRt->getType();
   1533   switch (Ty) {
   1534   case IceType_i64:
   1535     // LDRD is not implemented because target lowering handles i64 and double by
   1536     // using two (32-bit) load instructions. Note: Intentionally drop to default
   1537     // case.
   1538     llvm::report_fatal_error(std::string("ldr : Type ") + typeString(Ty) +
   1539                              " not implemented");
   1540   default:
   1541     llvm::report_fatal_error(std::string("ldr : Type ") + typeString(Ty) +
   1542                              " not allowed");
   1543   case IceType_i1:
   1544   case IceType_i8: {
   1545     // LDRB (immediate) - ARM section A8.8.68, encoding A1:
   1546     //   ldrb<c> <Rt>, [<Rn>{, #+/-<imm12>}]     ; p=1, w=0
   1547     //   ldrb<c> <Rt>, [<Rn>], #+/-<imm12>       ; p=1, w=1
   1548     //   ldrb<c> <Rt>, [<Rn>, #+/-<imm12>]!      ; p=0, w=1
   1549     //
   1550     // cccc010pu1w1nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
   1551     // iiiiiiiiiiii=imm12, u=1 if +, pu0w is a BlockAddr, and
   1552     // pu0w0nnnn0000iiiiiiiiiiii=Address.
   1553     //
   1554     // LDRB (register) - ARM section A8.8.66, encoding A1:
   1555     //   ldrb<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!}
   1556     //   ldrb<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>}
   1557     //
   1558     // cccc011pu1w1nnnnttttiiiiiss0mmmm where cccc=Cond, tttt=Rt, U=1 if +, pu0b
   1559     // is a BlockAddr, and pu0w0nnnn0000iiiiiss0mmmm=Address.
   1560     constexpr bool IsByte = true;
   1561     emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo, LdrName);
   1562     return;
   1563   }
   1564   case IceType_i16: {
   1565     // LDRH (immediate) - ARM section A8.8.80, encoding A1:
   1566     //   ldrh<c> <Rt>, [<Rn>{, #+/-<Imm8>}]
   1567     //   ldrh<c> <Rt>, [<Rn>], #+/-<Imm8>
   1568     //   ldrh<c> <Rt>, [<Rn>, #+/-<Imm8>]!
   1569     //
   1570     // cccc000pu1w1nnnnttttiiii1011iiii where cccc=Cond, tttt=Rt, nnnn=Rn,
   1571     // iiiiiiii=Imm8, u=1 if +, pu0w is a BlockAddr, and
   1572     // pu0w0nnnn0000iiiiiiiiiiii=Address.
   1573     constexpr const char *Ldrh = "ldrh";
   1574     emitMemOpEnc3(Cond, L | B7 | B5 | B4, Rt, OpAddress, TInfo, Ldrh);
   1575     return;
   1576   }
   1577   case IceType_i32: {
   1578     // LDR (immediate) - ARM section A8.8.63, encoding A1:
   1579     //   ldr<c> <Rt>, [<Rn>{, #+/-<imm12>}]      ; p=1, w=0
   1580     //   ldr<c> <Rt>, [<Rn>], #+/-<imm12>        ; p=1, w=1
   1581     //   ldr<c> <Rt>, [<Rn>, #+/-<imm12>]!       ; p=0, w=1
   1582     //
   1583     // cccc010pu0w1nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
   1584     // iiiiiiiiiiii=imm12, u=1 if +, pu0w is a BlockAddr, and
   1585     //
   1586     // LDR (register) - ARM section A8.8.70, encoding A1:
   1587     //   ldrb<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!}
   1588     //   ldrb<c> <Rt>, [<Rn>], +-<Rm>{, <shift>}
   1589     //
   1590     // cccc011pu0w1nnnnttttiiiiiss0mmmm where cccc=Cond, tttt=Rt, U=1 if +, pu0b
   1591     // is a BlockAddr, and pu0w0nnnn0000iiiiiss0mmmm=Address.
   1592     constexpr bool IsByte = false;
   1593     emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo, LdrName);
   1594     return;
   1595   }
   1596   }
   1597 }
   1598 
   1599 void AssemblerARM32::emitMemExOp(CondARM32::Cond Cond, Type Ty, bool IsLoad,
   1600                                  const Operand *OpRd, IValueT Rt,
   1601                                  const Operand *OpAddress,
   1602                                  const TargetInfo &TInfo,
   1603                                  const char *InstName) {
   1604   IValueT Rd = encodeGPRegister(OpRd, "Rd", InstName);
   1605   IValueT MemExOpcode = IsLoad ? B0 : 0;
   1606   switch (Ty) {
   1607   default:
   1608     llvm::report_fatal_error(std::string(InstName) + ": Type " +
   1609                              typeString(Ty) + " not allowed");
   1610   case IceType_i1:
   1611   case IceType_i8:
   1612     MemExOpcode |= B2;
   1613     break;
   1614   case IceType_i16:
   1615     MemExOpcode |= B2 | B1;
   1616     break;
   1617   case IceType_i32:
   1618     break;
   1619   case IceType_i64:
   1620     MemExOpcode |= B1;
   1621   }
   1622   IValueT AddressRn;
   1623   if (encodeAddress(OpAddress, AddressRn, TInfo, NoImmOffsetAddress) !=
   1624       EncodedAsImmRegOffset)
   1625     llvm::report_fatal_error(std::string(InstName) +
   1626                              ": Can't extract Rn from address");
   1627   assert(Utils::IsAbsoluteUint(3, MemExOpcode));
   1628   assert(Rd < RegARM32::getNumGPRegs());
   1629   assert(Rt < RegARM32::getNumGPRegs());
   1630   assert(CondARM32::isDefined(Cond));
   1631   IValueT Encoding = (Cond << kConditionShift) | B24 | B23 | B11 | B10 | B9 |
   1632                      B8 | B7 | B4 | (MemExOpcode << kMemExOpcodeShift) |
   1633                      AddressRn | (Rd << kRdShift) | (Rt << kRmShift);
   1634   emitInst(Encoding);
   1635   return;
   1636 }
   1637 
   1638 void AssemblerARM32::ldrex(const Operand *OpRt, const Operand *OpAddress,
   1639                            CondARM32::Cond Cond, const TargetInfo &TInfo) {
   1640   // LDREXB - ARM section A8.8.76, encoding A1:
   1641   //   ldrexb<c> <Rt>, [<Rn>]
   1642   //
   1643   // cccc00011101nnnntttt111110011111 where cccc=Cond, tttt=Rt, and nnnn=Rn.
   1644   //
   1645   // LDREXH - ARM section A8.8.78, encoding A1:
   1646   //   ldrexh<c> <Rt>, [<Rn>]
   1647   //
   1648   // cccc00011111nnnntttt111110011111 where cccc=Cond, tttt=Rt, and nnnn=Rn.
   1649   //
   1650   // LDREX - ARM section A8.8.75, encoding A1:
   1651   //   ldrex<c> <Rt>, [<Rn>]
   1652   //
   1653   // cccc00011001nnnntttt111110011111 where cccc=Cond, tttt=Rt, and nnnn=Rn.
   1654   //
   1655   // LDREXD - ARM section A8.
   1656   //   ldrexd<c> <Rt>, [<Rn>]
   1657   //
   1658   // cccc00011001nnnntttt111110011111 where cccc=Cond, tttt=Rt, and nnnn=Rn.
   1659   constexpr const char *LdrexName = "ldrex";
   1660   const Type Ty = OpRt->getType();
   1661   constexpr bool IsLoad = true;
   1662   constexpr IValueT Rm = RegARM32::Encoded_Reg_pc;
   1663   emitMemExOp(Cond, Ty, IsLoad, OpRt, Rm, OpAddress, TInfo, LdrexName);
   1664 }
   1665 
   1666 void AssemblerARM32::emitShift(const CondARM32::Cond Cond,
   1667                                const OperandARM32::ShiftKind Shift,
   1668                                const Operand *OpRd, const Operand *OpRm,
   1669                                const Operand *OpSrc1, const bool SetFlags,
   1670                                const char *InstName) {
   1671   constexpr IValueT ShiftOpcode = B3 | B2 | B0; // 1101
   1672   IValueT Rd = encodeGPRegister(OpRd, "Rd", InstName);
   1673   IValueT Rm = encodeGPRegister(OpRm, "Rm", InstName);
   1674   IValueT Value;
   1675   switch (encodeOperand(OpSrc1, Value, WantGPRegs)) {
   1676   default:
   1677     llvm::report_fatal_error(std::string(InstName) +
   1678                              ": Last operand not understood");
   1679   case EncodedAsShiftImm5: {
   1680     // XXX (immediate)
   1681     //   xxx{s}<c> <Rd>, <Rm>, #imm5
   1682     //
   1683     // cccc0001101s0000ddddiiiii000mmmm where cccc=Cond, s=SetFlags, dddd=Rd,
   1684     // iiiii=imm5, and mmmm=Rm.
   1685     constexpr IValueT Rn = 0; // Rn field is not used.
   1686     Value = Value | (Rm << kRmShift) | (Shift << kShiftShift);
   1687     emitType01(Cond, kInstTypeDataRegShift, ShiftOpcode, SetFlags, Rn, Rd,
   1688                Value, RdIsPcAndSetFlags, InstName);
   1689     return;
   1690   }
   1691   case EncodedAsRegister: {
   1692     // XXX (register)
   1693     //   xxx{S}<c> <Rd>, <Rm>, <Rs>
   1694     //
   1695     // cccc0001101s0000ddddssss0001mmmm where cccc=Cond, s=SetFlags, dddd=Rd,
   1696     // mmmm=Rm, and ssss=Rs.
   1697     constexpr IValueT Rn = 0; // Rn field is not used.
   1698     IValueT Rs = encodeGPRegister(OpSrc1, "Rs", InstName);
   1699     verifyRegNotPc(Rd, "Rd", InstName);
   1700     verifyRegNotPc(Rm, "Rm", InstName);
   1701     verifyRegNotPc(Rs, "Rs", InstName);
   1702     emitType01(Cond, kInstTypeDataRegShift, ShiftOpcode, SetFlags, Rn, Rd,
   1703                encodeShiftRotateReg(Rm, Shift, Rs), NoChecks, InstName);
   1704     return;
   1705   }
   1706   }
   1707 }
   1708 
   1709 void AssemblerARM32::asr(const Operand *OpRd, const Operand *OpRm,
   1710                          const Operand *OpSrc1, bool SetFlags,
   1711                          CondARM32::Cond Cond) {
   1712   constexpr const char *AsrName = "asr";
   1713   emitShift(Cond, OperandARM32::ASR, OpRd, OpRm, OpSrc1, SetFlags, AsrName);
   1714 }
   1715 
   1716 void AssemblerARM32::lsl(const Operand *OpRd, const Operand *OpRm,
   1717                          const Operand *OpSrc1, bool SetFlags,
   1718                          CondARM32::Cond Cond) {
   1719   constexpr const char *LslName = "lsl";
   1720   emitShift(Cond, OperandARM32::LSL, OpRd, OpRm, OpSrc1, SetFlags, LslName);
   1721 }
   1722 
   1723 void AssemblerARM32::lsr(const Operand *OpRd, const Operand *OpRm,
   1724                          const Operand *OpSrc1, bool SetFlags,
   1725                          CondARM32::Cond Cond) {
   1726   constexpr const char *LsrName = "lsr";
   1727   emitShift(Cond, OperandARM32::LSR, OpRd, OpRm, OpSrc1, SetFlags, LsrName);
   1728 }
   1729 
   1730 void AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc,
   1731                          CondARM32::Cond Cond) {
   1732   // MOV (register) - ARM section A8.8.104, encoding A1:
   1733   //   mov{S}<c> <Rd>, <Rn>
   1734   //
   1735   // cccc0001101s0000dddd00000000mmmm where cccc=Cond, s=SetFlags, dddd=Rd,
   1736   // and nnnn=Rn.
   1737   //
   1738   // MOV (immediate) - ARM section A8.8.102, encoding A1:
   1739   //   mov{S}<c> <Rd>, #<RotatedImm8>
   1740   //
   1741   // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags, dddd=Rd,
   1742   // and iiiiiiiiiiii=RotatedImm8=Src.  Note: We don't use movs in this
   1743   // assembler.
   1744   constexpr const char *MovName = "mov";
   1745   IValueT Rd = encodeGPRegister(OpRd, "Rd", MovName);
   1746   constexpr bool SetFlags = false;
   1747   constexpr IValueT Rn = 0;
   1748   constexpr IValueT MovOpcode = B3 | B2 | B0; // 1101.
   1749   emitType01(Cond, MovOpcode, Rd, Rn, OpSrc, SetFlags, RdIsPcAndSetFlags,
   1750              MovName);
   1751 }
   1752 
   1753 void AssemblerARM32::emitMovwt(CondARM32::Cond Cond, bool IsMovW,
   1754                                const Operand *OpRd, const Operand *OpSrc,
   1755                                const char *MovName) {
   1756   IValueT Opcode = B25 | B24 | (IsMovW ? 0 : B22);
   1757   IValueT Rd = encodeGPRegister(OpRd, "Rd", MovName);
   1758   IValueT Imm16;
   1759   if (const auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc)) {
   1760     emitFixup(createMoveFixup(IsMovW, Src));
   1761     // Use 0 for the lower 16 bits of the relocatable, and add a fixup to
   1762     // install the correct bits.
   1763     Imm16 = 0;
   1764   } else if (encodeOperand(OpSrc, Imm16, WantGPRegs) != EncodedAsConstI32) {
   1765     llvm::report_fatal_error(std::string(MovName) + ": Not i32 constant");
   1766   }
   1767   assert(CondARM32::isDefined(Cond));
   1768   if (!Utils::IsAbsoluteUint(16, Imm16))
   1769     llvm::report_fatal_error(std::string(MovName) + ": Constant not i16");
   1770   const IValueT Encoding = encodeCondition(Cond) << kConditionShift | Opcode |
   1771                            ((Imm16 >> 12) << 16) | Rd << kRdShift |
   1772                            (Imm16 & 0xfff);
   1773   emitInst(Encoding);
   1774 }
   1775 
   1776 void AssemblerARM32::movw(const Operand *OpRd, const Operand *OpSrc,
   1777                           CondARM32::Cond Cond) {
   1778   // MOV (immediate) - ARM section A8.8.102, encoding A2:
   1779   //  movw<c> <Rd>, #<imm16>
   1780   //
   1781   // cccc00110000iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, and
   1782   // iiiiiiiiiiiiiiii=imm16.
   1783   constexpr const char *MovwName = "movw";
   1784   constexpr bool IsMovW = true;
   1785   emitMovwt(Cond, IsMovW, OpRd, OpSrc, MovwName);
   1786 }
   1787 
   1788 void AssemblerARM32::movt(const Operand *OpRd, const Operand *OpSrc,
   1789                           CondARM32::Cond Cond) {
   1790   // MOVT - ARM section A8.8.106, encoding A1:
   1791   //  movt<c> <Rd>, #<imm16>
   1792   //
   1793   // cccc00110100iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, and
   1794   // iiiiiiiiiiiiiiii=imm16.
   1795   constexpr const char *MovtName = "movt";
   1796   constexpr bool IsMovW = false;
   1797   emitMovwt(Cond, IsMovW, OpRd, OpSrc, MovtName);
   1798 }
   1799 
   1800 void AssemblerARM32::mvn(const Operand *OpRd, const Operand *OpSrc,
   1801                          CondARM32::Cond Cond) {
   1802   // MVN (immediate) - ARM section A8.8.115, encoding A1:
   1803   //   mvn{s}<c> <Rd>, #<const>
   1804   //
   1805   // cccc0011111s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags=0, dddd=Rd,
   1806   // and iiiiiiiiiiii=const
   1807   //
   1808   // MVN (register) - ARM section A8.8.116, encoding A1:
   1809   //   mvn{s}<c> <Rd>, <Rm>{, <shift>
   1810   //
   1811   // cccc0001111s0000ddddiiiiitt0mmmm where cccc=Cond, s=SetFlags=0, dddd=Rd,
   1812   // mmmm=Rm, iiii defines shift constant, and tt=ShiftKind.
   1813   constexpr const char *MvnName = "mvn";
   1814   IValueT Rd = encodeGPRegister(OpRd, "Rd", MvnName);
   1815   constexpr IValueT MvnOpcode = B3 | B2 | B1 | B0; // i.e. 1111
   1816   constexpr IValueT Rn = 0;
   1817   constexpr bool SetFlags = false;
   1818   emitType01(Cond, MvnOpcode, Rd, Rn, OpSrc, SetFlags, RdIsPcAndSetFlags,
   1819              MvnName);
   1820 }
   1821 
   1822 void AssemblerARM32::nop() {
   1823   // NOP - Section A8.8.119, encoding A1:
   1824   //  nop<c>
   1825   //
   1826   // cccc0011001000001111000000000000 where cccc=Cond.
   1827   constexpr CondARM32::Cond Cond = CondARM32::AL;
   1828   const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B25 |
   1829                            B24 | B21 | B15 | B14 | B13 | B12;
   1830   emitInst(Encoding);
   1831 }
   1832 
   1833 void AssemblerARM32::sbc(const Operand *OpRd, const Operand *OpRn,
   1834                          const Operand *OpSrc1, bool SetFlags,
   1835                          CondARM32::Cond Cond) {
   1836   // SBC (register) - ARM section 18.8.162, encoding A1:
   1837   //   sbc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>}
   1838   //
   1839   // cccc0000110snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
   1840   // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
   1841   //
   1842   // SBC (Immediate) - ARM section A8.8.161, encoding A1:
   1843   //   sbc{s}<c> <Rd>, <Rn>, #<RotatedImm8>
   1844   //
   1845   // cccc0010110snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
   1846   // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
   1847   constexpr const char *SbcName = "sbc";
   1848   constexpr IValueT SbcOpcode = B2 | B1; // 0110
   1849   emitType01(Cond, SbcOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
   1850              SbcName);
   1851 }
   1852 
   1853 void AssemblerARM32::sdiv(const Operand *OpRd, const Operand *OpRn,
   1854                           const Operand *OpSrc1, CondARM32::Cond Cond) {
   1855   // SDIV - ARM section A8.8.165, encoding A1.
   1856   //   sdiv<c> <Rd>, <Rn>, <Rm>
   1857   //
   1858   // cccc01110001dddd1111mmmm0001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, and
   1859   // mmmm=Rm.
   1860   constexpr const char *SdivName = "sdiv";
   1861   IValueT Rd = encodeGPRegister(OpRd, "Rd", SdivName);
   1862   IValueT Rn = encodeGPRegister(OpRn, "Rn", SdivName);
   1863   IValueT Rm = encodeGPRegister(OpSrc1, "Rm", SdivName);
   1864   verifyRegNotPc(Rd, "Rd", SdivName);
   1865   verifyRegNotPc(Rn, "Rn", SdivName);
   1866   verifyRegNotPc(Rm, "Rm", SdivName);
   1867   // Assembler registers rd, rn, rm are encoded as rn, rm, rs.
   1868   constexpr IValueT SdivOpcode = 0;
   1869   emitDivOp(Cond, SdivOpcode, Rd, Rn, Rm);
   1870 }
   1871 
   1872 void AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress,
   1873                          CondARM32::Cond Cond, const TargetInfo &TInfo) {
   1874   constexpr const char *StrName = "str";
   1875   constexpr bool IsLoad = false;
   1876   IValueT Rt = encodeGPRegister(OpRt, "Rt", StrName);
   1877   const Type Ty = OpRt->getType();
   1878   switch (Ty) {
   1879   case IceType_i64:
   1880     // STRD is not implemented because target lowering handles i64 and double by
   1881     // using two (32-bit) store instructions.  Note: Intentionally drop to
   1882     // default case.
   1883     llvm::report_fatal_error(std::string(StrName) + ": Type " + typeString(Ty) +
   1884                              " not implemented");
   1885   default:
   1886     llvm::report_fatal_error(std::string(StrName) + ": Type " + typeString(Ty) +
   1887                              " not allowed");
   1888   case IceType_i1:
   1889   case IceType_i8: {
   1890     // STRB (immediate) - ARM section A8.8.207, encoding A1:
   1891     //   strb<c> <Rt>, [<Rn>{, #+/-<imm12>}]     ; p=1, w=0
   1892     //   strb<c> <Rt>, [<Rn>], #+/-<imm12>       ; p=1, w=1
   1893     //   strb<c> <Rt>, [<Rn>, #+/-<imm12>]!      ; p=0, w=1
   1894     //
   1895     // cccc010pu1w0nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
   1896     // iiiiiiiiiiii=imm12, u=1 if +.
   1897     constexpr bool IsByte = true;
   1898     emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo, StrName);
   1899     return;
   1900   }
   1901   case IceType_i16: {
   1902     // STRH (immediate) - ARM section A8.*.217, encoding A1:
   1903     //   strh<c> <Rt>, [<Rn>{, #+/-<Imm8>}]
   1904     //   strh<c> <Rt>, [<Rn>], #+/-<Imm8>
   1905     //   strh<c> <Rt>, [<Rn>, #+/-<Imm8>]!
   1906     //
   1907     // cccc000pu1w0nnnnttttiiii1011iiii where cccc=Cond, tttt=Rt, nnnn=Rn,
   1908     // iiiiiiii=Imm8, u=1 if +, pu0w is a BlockAddr, and
   1909     // pu0w0nnnn0000iiiiiiiiiiii=Address.
   1910     constexpr const char *Strh = "strh";
   1911     emitMemOpEnc3(Cond, B7 | B5 | B4, Rt, OpAddress, TInfo, Strh);
   1912     return;
   1913   }
   1914   case IceType_i32: {
   1915     // Note: Handles i32 and float stores. Target lowering handles i64 and
   1916     // double by using two (32 bit) store instructions.
   1917     //
   1918     // STR (immediate) - ARM section A8.8.207, encoding A1:
   1919     //   str<c> <Rt>, [<Rn>{, #+/-<imm12>}]     ; p=1, w=0
   1920     //   str<c> <Rt>, [<Rn>], #+/-<imm12>       ; p=1, w=1
   1921     //   str<c> <Rt>, [<Rn>, #+/-<imm12>]!      ; p=0, w=1
   1922     //
   1923     // cccc010pu1w0nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
   1924     // iiiiiiiiiiii=imm12, u=1 if +.
   1925     constexpr bool IsByte = false;
   1926     emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo, StrName);
   1927     return;
   1928   }
   1929   }
   1930 }
   1931 
   1932 void AssemblerARM32::strex(const Operand *OpRd, const Operand *OpRt,
   1933                            const Operand *OpAddress, CondARM32::Cond Cond,
   1934                            const TargetInfo &TInfo) {
   1935   // STREXB - ARM section A8.8.213, encoding A1:
   1936   //   strexb<c> <Rd>, <Rt>, [<Rn>]
   1937   //
   1938   // cccc00011100nnnndddd11111001tttt where cccc=Cond, dddd=Rd, tttt=Rt, and
   1939   // nnnn=Rn.
   1940   //
   1941   // STREXH - ARM section A8.8.215, encoding A1:
   1942   //   strexh<c> <Rd>, <Rt>, [<Rn>]
   1943   //
   1944   // cccc00011110nnnndddd11111001tttt where cccc=Cond, dddd=Rd, tttt=Rt, and
   1945   // nnnn=Rn.
   1946   //
   1947   // STREX - ARM section A8.8.212, encoding A1:
   1948   //   strex<c> <Rd>, <Rt>, [<Rn>]
   1949   //
   1950   // cccc00011000nnnndddd11111001tttt where cccc=Cond, dddd=Rd, tttt=Rt, and
   1951   // nnnn=Rn.
   1952   //
   1953   // STREXD - ARM section A8.8.214, encoding A1:
   1954   //   strexd<c> <Rd>, <Rt>, [<Rn>]
   1955   //
   1956   // cccc00011010nnnndddd11111001tttt where cccc=Cond, dddd=Rd, tttt=Rt, and
   1957   // nnnn=Rn.
   1958   constexpr const char *StrexName = "strex";
   1959   // Note: Rt uses Rm shift in encoding.
   1960   IValueT Rt = encodeGPRegister(OpRt, "Rt", StrexName);
   1961   const Type Ty = OpRt->getType();
   1962   constexpr bool IsLoad = true;
   1963   emitMemExOp(Cond, Ty, !IsLoad, OpRd, Rt, OpAddress, TInfo, StrexName);
   1964 }
   1965 
   1966 void AssemblerARM32::orr(const Operand *OpRd, const Operand *OpRn,
   1967                          const Operand *OpSrc1, bool SetFlags,
   1968                          CondARM32::Cond Cond) {
   1969   // ORR (register) - ARM Section A8.8.123, encoding A1:
   1970   //   orr{s}<c> <Rd>, <Rn>, <Rm>
   1971   //
   1972   // cccc0001100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
   1973   // mmmm=Rm, iiiii=shift, tt=ShiftKind,, and s=SetFlags.
   1974   //
   1975   // ORR (register) - ARM Section A8.8.123, encoding A1:
   1976   //   orr{s}<c> <Rd>, <Rn>,  #<RotatedImm8>
   1977   //
   1978   // cccc0001100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
   1979   // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
   1980   constexpr const char *OrrName = "orr";
   1981   constexpr IValueT OrrOpcode = B3 | B2; // i.e. 1100
   1982   emitType01(Cond, OrrOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
   1983              OrrName);
   1984 }
   1985 
   1986 void AssemblerARM32::pop(const Variable *OpRt, CondARM32::Cond Cond) {
   1987   // POP - ARM section A8.8.132, encoding A2:
   1988   //   pop<c> {Rt}
   1989   //
   1990   // cccc010010011101dddd000000000100 where dddd=Rt and cccc=Cond.
   1991   constexpr const char *Pop = "pop";
   1992   IValueT Rt = encodeGPRegister(OpRt, "Rt", Pop);
   1993   verifyRegsNotEq(Rt, "Rt", RegARM32::Encoded_Reg_sp, "sp", Pop);
   1994   // Same as load instruction.
   1995   constexpr bool IsLoad = true;
   1996   constexpr bool IsByte = false;
   1997   constexpr IOffsetT MaxOffset = (1 << 8) - 1;
   1998   constexpr IValueT NoShiftRight = 0;
   1999   IValueT Address =
   2000       encodeImmRegOffset(RegARM32::Encoded_Reg_sp, kWordSize,
   2001                          OperandARM32Mem::PostIndex, MaxOffset, NoShiftRight);
   2002   emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address);
   2003 }
   2004 
   2005 void AssemblerARM32::popList(const IValueT Registers, CondARM32::Cond Cond) {
   2006   // POP - ARM section A8.*.131, encoding A1:
   2007   //   pop<c> <registers>
   2008   //
   2009   // cccc100010111101rrrrrrrrrrrrrrrr where cccc=Cond and
   2010   // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register).
   2011   constexpr bool IsLoad = true;
   2012   emitMultiMemOp(Cond, IA_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers);
   2013 }
   2014 
   2015 void AssemblerARM32::push(const Operand *OpRt, CondARM32::Cond Cond) {
   2016   // PUSH - ARM section A8.8.133, encoding A2:
   2017   //   push<c> {Rt}
   2018   //
   2019   // cccc010100101101dddd000000000100 where dddd=Rt and cccc=Cond.
   2020   constexpr const char *Push = "push";
   2021   IValueT Rt = encodeGPRegister(OpRt, "Rt", Push);
   2022   verifyRegsNotEq(Rt, "Rt", RegARM32::Encoded_Reg_sp, "sp", Push);
   2023   // Same as store instruction.
   2024   constexpr bool isLoad = false;
   2025   constexpr bool isByte = false;
   2026   constexpr IOffsetT MaxOffset = (1 << 8) - 1;
   2027   constexpr IValueT NoShiftRight = 0;
   2028   IValueT Address =
   2029       encodeImmRegOffset(RegARM32::Encoded_Reg_sp, -kWordSize,
   2030                          OperandARM32Mem::PreIndex, MaxOffset, NoShiftRight);
   2031   emitMemOp(Cond, kInstTypeMemImmediate, isLoad, isByte, Rt, Address);
   2032 }
   2033 
   2034 void AssemblerARM32::pushList(const IValueT Registers, CondARM32::Cond Cond) {
   2035   // PUSH - ARM section A8.8.133, encoding A1:
   2036   //   push<c> <Registers>
   2037   //
   2038   // cccc100100101101rrrrrrrrrrrrrrrr where cccc=Cond and
   2039   // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register).
   2040   constexpr bool IsLoad = false;
   2041   emitMultiMemOp(Cond, DB_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers);
   2042 }
   2043 
   2044 void AssemblerARM32::mla(const Operand *OpRd, const Operand *OpRn,
   2045                          const Operand *OpRm, const Operand *OpRa,
   2046                          CondARM32::Cond Cond) {
   2047   // MLA - ARM section A8.8.114, encoding A1.
   2048   //   mla{s}<c> <Rd>, <Rn>, <Rm>, <Ra>
   2049   //
   2050   // cccc0000001sddddaaaammmm1001nnnn where cccc=Cond, s=SetFlags, dddd=Rd,
   2051   // aaaa=Ra, mmmm=Rm, and nnnn=Rn.
   2052   constexpr const char *MlaName = "mla";
   2053   IValueT Rd = encodeGPRegister(OpRd, "Rd", MlaName);
   2054   IValueT Rn = encodeGPRegister(OpRn, "Rn", MlaName);
   2055   IValueT Rm = encodeGPRegister(OpRm, "Rm", MlaName);
   2056   IValueT Ra = encodeGPRegister(OpRa, "Ra", MlaName);
   2057   verifyRegNotPc(Rd, "Rd", MlaName);
   2058   verifyRegNotPc(Rn, "Rn", MlaName);
   2059   verifyRegNotPc(Rm, "Rm", MlaName);
   2060   verifyRegNotPc(Ra, "Ra", MlaName);
   2061   constexpr IValueT MlaOpcode = B21;
   2062   constexpr bool SetFlags = true;
   2063   // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
   2064   emitMulOp(Cond, MlaOpcode, Ra, Rd, Rn, Rm, !SetFlags);
   2065 }
   2066 
   2067 void AssemblerARM32::mls(const Operand *OpRd, const Operand *OpRn,
   2068                          const Operand *OpRm, const Operand *OpRa,
   2069                          CondARM32::Cond Cond) {
   2070   constexpr const char *MlsName = "mls";
   2071   IValueT Rd = encodeGPRegister(OpRd, "Rd", MlsName);
   2072   IValueT Rn = encodeGPRegister(OpRn, "Rn", MlsName);
   2073   IValueT Rm = encodeGPRegister(OpRm, "Rm", MlsName);
   2074   IValueT Ra = encodeGPRegister(OpRa, "Ra", MlsName);
   2075   verifyRegNotPc(Rd, "Rd", MlsName);
   2076   verifyRegNotPc(Rn, "Rn", MlsName);
   2077   verifyRegNotPc(Rm, "Rm", MlsName);
   2078   verifyRegNotPc(Ra, "Ra", MlsName);
   2079   constexpr IValueT MlsOpcode = B22 | B21;
   2080   constexpr bool SetFlags = true;
   2081   // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
   2082   emitMulOp(Cond, MlsOpcode, Ra, Rd, Rn, Rm, !SetFlags);
   2083 }
   2084 
   2085 void AssemblerARM32::mul(const Operand *OpRd, const Operand *OpRn,
   2086                          const Operand *OpSrc1, bool SetFlags,
   2087                          CondARM32::Cond Cond) {
   2088   // MUL - ARM section A8.8.114, encoding A1.
   2089   //   mul{s}<c> <Rd>, <Rn>, <Rm>
   2090   //
   2091   // cccc0000000sdddd0000mmmm1001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn,
   2092   // mmmm=Rm, and s=SetFlags.
   2093   constexpr const char *MulName = "mul";
   2094   IValueT Rd = encodeGPRegister(OpRd, "Rd", MulName);
   2095   IValueT Rn = encodeGPRegister(OpRn, "Rn", MulName);
   2096   IValueT Rm = encodeGPRegister(OpSrc1, "Rm", MulName);
   2097   verifyRegNotPc(Rd, "Rd", MulName);
   2098   verifyRegNotPc(Rn, "Rn", MulName);
   2099   verifyRegNotPc(Rm, "Rm", MulName);
   2100   // Assembler registers rd, rn, rm are encoded as rn, rm, rs.
   2101   constexpr IValueT MulOpcode = 0;
   2102   emitMulOp(Cond, MulOpcode, RegARM32::Encoded_Reg_r0, Rd, Rn, Rm, SetFlags);
   2103 }
   2104 
   2105 void AssemblerARM32::emitRdRm(CondARM32::Cond Cond, IValueT Opcode,
   2106                               const Operand *OpRd, const Operand *OpRm,
   2107                               const char *InstName) {
   2108   IValueT Rd = encodeGPRegister(OpRd, "Rd", InstName);
   2109   IValueT Rm = encodeGPRegister(OpRm, "Rm", InstName);
   2110   IValueT Encoding =
   2111       (Cond << kConditionShift) | Opcode | (Rd << kRdShift) | (Rm << kRmShift);
   2112   emitInst(Encoding);
   2113 }
   2114 
   2115 void AssemblerARM32::rbit(const Operand *OpRd, const Operand *OpRm,
   2116                           CondARM32::Cond Cond) {
   2117   // RBIT - ARM section A8.8.144, encoding A1:
   2118   //   rbit<c> <Rd>, <Rm>
   2119   //
   2120   // cccc011011111111dddd11110011mmmm where cccc=Cond, dddd=Rn, and mmmm=Rm.
   2121   constexpr const char *RbitName = "rev";
   2122   constexpr IValueT RbitOpcode = B26 | B25 | B23 | B22 | B21 | B20 | B19 | B18 |
   2123                                  B17 | B16 | B11 | B10 | B9 | B8 | B5 | B4;
   2124   emitRdRm(Cond, RbitOpcode, OpRd, OpRm, RbitName);
   2125 }
   2126 
   2127 void AssemblerARM32::rev(const Operand *OpRd, const Operand *OpRm,
   2128                          CondARM32::Cond Cond) {
   2129   // REV - ARM section A8.8.145, encoding A1:
   2130   //   rev<c> <Rd>, <Rm>
   2131   //
   2132   // cccc011010111111dddd11110011mmmm where cccc=Cond, dddd=Rn, and mmmm=Rm.
   2133   constexpr const char *RevName = "rev";
   2134   constexpr IValueT RevOpcode = B26 | B25 | B23 | B21 | B20 | B19 | B18 | B17 |
   2135                                 B16 | B11 | B10 | B9 | B8 | B5 | B4;
   2136   emitRdRm(Cond, RevOpcode, OpRd, OpRm, RevName);
   2137 }
   2138 
   2139 void AssemblerARM32::rsb(const Operand *OpRd, const Operand *OpRn,
   2140                          const Operand *OpSrc1, bool SetFlags,
   2141                          CondARM32::Cond Cond) {
   2142   // RSB (immediate) - ARM section A8.8.152, encoding A1.
   2143   //   rsb{s}<c> <Rd>, <Rn>, #<RotatedImm8>
   2144   //
   2145   // cccc0010011snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
   2146   // s=setFlags and iiiiiiiiiiii defines the RotatedImm8 value.
   2147   //
   2148   // RSB (register) - ARM section A8.8.163, encoding A1.
   2149   //   rsb{s}<c> <Rd>, <Rn>, <Rm>{, <Shift>}
   2150   //
   2151   // cccc0000011snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
   2152   // mmmm=Rm, iiiii=shift, tt==ShiftKind, and s=SetFlags.
   2153   constexpr const char *RsbName = "rsb";
   2154   constexpr IValueT RsbOpcode = B1 | B0; // 0011
   2155   emitType01(Cond, RsbOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
   2156              RsbName);
   2157 }
   2158 
   2159 void AssemblerARM32::rsc(const Operand *OpRd, const Operand *OpRn,
   2160                          const Operand *OpSrc1, bool SetFlags,
   2161                          CondARM32::Cond Cond) {
   2162   // RSC (immediate) - ARM section A8.8.155, encoding A1:
   2163   //   rsc{s}<c> <Rd>, <Rn>, #<RotatedImm8>
   2164   //
   2165   // cccc0010111snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
   2166   // mmmm=Rm, iiiii=shift, tt=ShiftKind, and s=SetFlags.
   2167   //
   2168   // RSC (register) - ARM section A8.8.156, encoding A1:
   2169   //   rsc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>}
   2170   //
   2171   // cccc0000111snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
   2172   // mmmm=Rm, iiiii=shift, tt=ShiftKind, and s=SetFlags.
   2173   //
   2174   // RSC (register-shifted register) - ARM section A8.8.157, encoding A1:
   2175   //   rsc{s}<c> <Rd>, <Rn>, <Rm>, <type> <Rs>
   2176   //
   2177   // cccc0000111fnnnnddddssss0tt1mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
   2178   // mmmm=Rm, ssss=Rs, tt defined <type>, and f=SetFlags.
   2179   constexpr const char *RscName = "rsc";
   2180   constexpr IValueT RscOpcode = B2 | B1 | B0; // i.e. 0111.
   2181   emitType01(Cond, RscOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
   2182              RscName);
   2183 }
   2184 
   2185 void AssemblerARM32::sxt(const Operand *OpRd, const Operand *OpSrc0,
   2186                          CondARM32::Cond Cond) {
   2187   constexpr const char *SxtName = "sxt";
   2188   constexpr IValueT SxtOpcode = B26 | B25 | B23 | B21;
   2189   emitSignExtend(Cond, SxtOpcode, OpRd, OpSrc0, SxtName);
   2190 }
   2191 
   2192 void AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn,
   2193                          const Operand *OpSrc1, bool SetFlags,
   2194                          CondARM32::Cond Cond) {
   2195   // SUB (register) - ARM section A8.8.223, encoding A1:
   2196   //   sub{s}<c> <Rd>, <Rn>, <Rm>{, <shift>}
   2197   // SUB (SP minus register): See ARM section 8.8.226, encoding A1:
   2198   //   sub{s}<c> <Rd>, sp, <Rm>{, <Shift>}
   2199   //
   2200   // cccc0000010snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
   2201   // mmmm=Rm, iiiii=shift, tt=ShiftKind, and s=SetFlags.
   2202   //
   2203   // Sub (Immediate) - ARM section A8.8.222, encoding A1:
   2204   //    sub{s}<c> <Rd>, <Rn>, #<RotatedImm8>
   2205   // Sub (Sp minus immediate) - ARM section A8.8.225, encoding A1:
   2206   //    sub{s}<c> sp, <Rn>, #<RotatedImm8>
   2207   //
   2208   // cccc0010010snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
   2209   // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8
   2210   constexpr const char *SubName = "sub";
   2211   constexpr IValueT SubOpcode = B1; // 0010
   2212   emitType01(Cond, SubOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
   2213              SubName);
   2214 }
   2215 
   2216 namespace {
   2217 
   2218 // Use a particular UDF encoding -- TRAPNaCl in LLVM: 0xE7FEDEF0
   2219 // http://llvm.org/viewvc/llvm-project?view=revision&revision=173943
   2220 const uint8_t TrapBytesRaw[] = {0xE7, 0xFE, 0xDE, 0xF0};
   2221 
   2222 const auto TrapBytes =
   2223     llvm::ArrayRef<uint8_t>(TrapBytesRaw, llvm::array_lengthof(TrapBytesRaw));
   2224 
   2225 } // end of anonymous namespace
   2226 
   2227 llvm::ArrayRef<uint8_t> AssemblerARM32::getNonExecBundlePadding() const {
   2228   return TrapBytes;
   2229 }
   2230 
   2231 void AssemblerARM32::trap() {
   2232   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
   2233   for (const uint8_t &Byte : reverse_range(TrapBytes))
   2234     Buffer.emit<uint8_t>(Byte);
   2235 }
   2236 
   2237 void AssemblerARM32::tst(const Operand *OpRn, const Operand *OpSrc1,
   2238                          CondARM32::Cond Cond) {
   2239   // TST (register) - ARM section A8.8.241, encoding A1:
   2240   //   tst<c> <Rn>, <Rm>(, <shift>}
   2241   //
   2242   // cccc00010001nnnn0000iiiiitt0mmmm where cccc=Cond, nnnn=Rn, mmmm=Rm,
   2243   // iiiii=Shift, and tt=ShiftKind.
   2244   //
   2245   // TST (immediate) - ARM section A8.8.240, encoding A1:
   2246   //   tst<c> <Rn>, #<RotatedImm8>
   2247   //
   2248   // cccc00110001nnnn0000iiiiiiiiiiii where cccc=Cond, nnnn=Rn, and
   2249   // iiiiiiiiiiii defines RotatedImm8.
   2250   constexpr const char *TstName = "tst";
   2251   constexpr IValueT TstOpcode = B3; // ie. 1000
   2252   emitCompareOp(Cond, TstOpcode, OpRn, OpSrc1, TstName);
   2253 }
   2254 
   2255 void AssemblerARM32::udiv(const Operand *OpRd, const Operand *OpRn,
   2256                           const Operand *OpSrc1, CondARM32::Cond Cond) {
   2257   // UDIV - ARM section A8.8.248, encoding A1.
   2258   //   udiv<c> <Rd>, <Rn>, <Rm>
   2259   //
   2260   // cccc01110011dddd1111mmmm0001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, and
   2261   // mmmm=Rm.
   2262   constexpr const char *UdivName = "udiv";
   2263   IValueT Rd = encodeGPRegister(OpRd, "Rd", UdivName);
   2264   IValueT Rn = encodeGPRegister(OpRn, "Rn", UdivName);
   2265   IValueT Rm = encodeGPRegister(OpSrc1, "Rm", UdivName);
   2266   verifyRegNotPc(Rd, "Rd", UdivName);
   2267   verifyRegNotPc(Rn, "Rn", UdivName);
   2268   verifyRegNotPc(Rm, "Rm", UdivName);
   2269   // Assembler registers rd, rn, rm are encoded as rn, rm, rs.
   2270   constexpr IValueT UdivOpcode = B21;
   2271   emitDivOp(Cond, UdivOpcode, Rd, Rn, Rm);
   2272 }
   2273 
   2274 void AssemblerARM32::umull(const Operand *OpRdLo, const Operand *OpRdHi,
   2275                            const Operand *OpRn, const Operand *OpRm,
   2276                            CondARM32::Cond Cond) {
   2277   // UMULL - ARM section A8.8.257, encoding A1:
   2278   //   umull<c> <RdLo>, <RdHi>, <Rn>, <Rm>
   2279   //
   2280   // cccc0000100shhhhllllmmmm1001nnnn where hhhh=RdHi, llll=RdLo, nnnn=Rn,
   2281   // mmmm=Rm, and s=SetFlags
   2282   constexpr const char *UmullName = "umull";
   2283   IValueT RdLo = encodeGPRegister(OpRdLo, "RdLo", UmullName);
   2284   IValueT RdHi = encodeGPRegister(OpRdHi, "RdHi", UmullName);
   2285   IValueT Rn = encodeGPRegister(OpRn, "Rn", UmullName);
   2286   IValueT Rm = encodeGPRegister(OpRm, "Rm", UmullName);
   2287   verifyRegNotPc(RdLo, "RdLo", UmullName);
   2288   verifyRegNotPc(RdHi, "RdHi", UmullName);
   2289   verifyRegNotPc(Rn, "Rn", UmullName);
   2290   verifyRegNotPc(Rm, "Rm", UmullName);
   2291   verifyRegsNotEq(RdHi, "RdHi", RdLo, "RdLo", UmullName);
   2292   constexpr IValueT UmullOpcode = B23;
   2293   constexpr bool SetFlags = false;
   2294   emitMulOp(Cond, UmullOpcode, RdLo, RdHi, Rn, Rm, SetFlags);
   2295 }
   2296 
   2297 void AssemblerARM32::uxt(const Operand *OpRd, const Operand *OpSrc0,
   2298                          CondARM32::Cond Cond) {
   2299   constexpr const char *UxtName = "uxt";
   2300   constexpr IValueT UxtOpcode = B26 | B25 | B23 | B22 | B21;
   2301   emitSignExtend(Cond, UxtOpcode, OpRd, OpSrc0, UxtName);
   2302 }
   2303 
   2304 void AssemblerARM32::vabss(const Operand *OpSd, const Operand *OpSm,
   2305                            CondARM32::Cond Cond) {
   2306   // VABS - ARM section A8.8.280, encoding A2:
   2307   //   vabs<c>.f32 <Sd>, <Sm>
   2308   //
   2309   // cccc11101D110000dddd101011M0mmmm where cccc=Cond, ddddD=Sd, and mmmmM=Sm.
   2310   constexpr const char *Vabss = "vabss";
   2311   IValueT Sd = encodeSRegister(OpSd, "Sd", Vabss);
   2312   IValueT Sm = encodeSRegister(OpSm, "Sm", Vabss);
   2313   constexpr IValueT S0 = 0;
   2314   constexpr IValueT VabssOpcode = B23 | B21 | B20 | B7 | B6;
   2315   emitVFPsss(Cond, VabssOpcode, Sd, S0, Sm);
   2316 }
   2317 
   2318 void AssemblerARM32::vabsd(const Operand *OpDd, const Operand *OpDm,
   2319                            CondARM32::Cond Cond) {
   2320   // VABS - ARM section A8.8.280, encoding A2:
   2321   //   vabs<c>.f64 <Dd>, <Dm>
   2322   //
   2323   // cccc11101D110000dddd101111M0mmmm where cccc=Cond, Ddddd=Dd, and Mmmmm=Dm.
   2324   constexpr const char *Vabsd = "vabsd";
   2325   const IValueT Dd = encodeDRegister(OpDd, "Dd", Vabsd);
   2326   const IValueT Dm = encodeDRegister(OpDm, "Dm", Vabsd);
   2327   constexpr IValueT D0 = 0;
   2328   constexpr IValueT VabsdOpcode = B23 | B21 | B20 | B7 | B6;
   2329   emitVFPddd(Cond, VabsdOpcode, Dd, D0, Dm);
   2330 }
   2331 
   2332 void AssemblerARM32::vabsq(const Operand *OpQd, const Operand *OpQm) {
   2333   // VABS - ARM section A8.8.280, encoding A1:
   2334   //   vabs.<dt> <Qd>, <Qm>
   2335   //
   2336   // 111100111D11ss01ddd0f1101M0mmm0 where Dddd=OpQd, Mddd=OpQm, and
   2337   // <dt> in {s8, s16, s32, f32} and ss is the encoding of <dt>.
   2338   const Type ElmtTy = typeElementType(OpQd->getType());
   2339   assert(ElmtTy != IceType_i64 && "vabsq doesn't allow i64!");
   2340   constexpr const char *Vabsq = "vabsq";
   2341   const IValueT Dd = mapQRegToDReg(encodeQRegister(OpQd, "Qd", Vabsq));
   2342   const IValueT Dm = mapQRegToDReg(encodeQRegister(OpQm, "Qm", Vabsq));
   2343   constexpr IValueT Dn = 0;
   2344   const IValueT VabsqOpcode =
   2345       B24 | B23 | B21 | B20 | B16 | B9 | B8 | (encodeElmtType(ElmtTy) << 18);
   2346   constexpr bool UseQRegs = true;
   2347   emitSIMDBase(VabsqOpcode, Dd, Dn, Dm, UseQRegs, isFloatingType(ElmtTy));
   2348 }
   2349 
   2350 void AssemblerARM32::vadds(const Operand *OpSd, const Operand *OpSn,
   2351                            const Operand *OpSm, CondARM32::Cond Cond) {
   2352   // VADD (floating-point) - ARM section A8.8.283, encoding A2:
   2353   //   vadd<c>.f32 <Sd>, <Sn>, <Sm>
   2354   //
   2355   // cccc11100D11nnnndddd101sN0M0mmmm where cccc=Cond, s=0, ddddD=Rd, nnnnN=Rn,
   2356   // and mmmmM=Rm.
   2357   constexpr const char *Vadds = "vadds";
   2358   constexpr IValueT VaddsOpcode = B21 | B20;
   2359   emitVFPsss(Cond, VaddsOpcode, OpSd, OpSn, OpSm, Vadds);
   2360 }
   2361 
   2362 void AssemblerARM32::vaddqi(Type ElmtTy, const Operand *OpQd,
   2363                             const Operand *OpQm, const Operand *OpQn) {
   2364   // VADD (integer) - ARM section A8.8.282, encoding A1:
   2365   //   vadd.<dt> <Qd>, <Qn>, <Qm>
   2366   //
   2367   // 111100100Dssnnn0ddd01000N1M0mmm0 where Dddd=OpQd, Nnnn=OpQm, Mmmm=OpQm,
   2368   // and dt in [i8, i16, i32, i64] where ss is the index.
   2369   assert(isScalarIntegerType(ElmtTy) &&
   2370          "vaddqi expects vector with integer element type");
   2371   constexpr const char *Vaddqi = "vaddqi";
   2372   constexpr IValueT VaddqiOpcode = B11;
   2373   emitSIMDqqq(VaddqiOpcode, ElmtTy, OpQd, OpQm, OpQn, Vaddqi);
   2374 }
   2375 
   2376 void AssemblerARM32::vaddqf(const Operand *OpQd, const Operand *OpQn,
   2377                             const Operand *OpQm) {
   2378   // VADD (floating-point) - ARM section A8.8.283, Encoding A1:
   2379   //   vadd.f32 <Qd>, <Qn>, <Qm>
   2380   //
   2381   // 111100100D00nnn0ddd01101N1M0mmm0 where Dddd=Qd, Nnnn=Qn, and Mmmm=Qm.
   2382   assert(OpQd->getType() == IceType_v4f32 && "vaddqf expects type <4 x float>");
   2383   constexpr const char *Vaddqf = "vaddqf";
   2384   constexpr IValueT VaddqfOpcode = B11 | B8;
   2385   constexpr bool IsFloatTy = true;
   2386   emitSIMDqqqBase(VaddqfOpcode, OpQd, OpQn, OpQm, IsFloatTy, Vaddqf);
   2387 }
   2388 
   2389 void AssemblerARM32::vaddd(const Operand *OpDd, const Operand *OpDn,
   2390                            const Operand *OpDm, CondARM32::Cond Cond) {
   2391   // VADD (floating-point) - ARM section A8.8.283, encoding A2:
   2392   //   vadd<c>.f64 <Dd>, <Dn>, <Dm>
   2393   //
   2394   // cccc11100D11nnnndddd101sN0M0mmmm where cccc=Cond, s=1, Ddddd=Rd, Nnnnn=Rn,
   2395   // and Mmmmm=Rm.
   2396   constexpr const char *Vaddd = "vaddd";
   2397   constexpr IValueT VadddOpcode = B21 | B20;
   2398   emitVFPddd(Cond, VadddOpcode, OpDd, OpDn, OpDm, Vaddd);
   2399 }
   2400 
   2401 void AssemblerARM32::vandq(const Operand *OpQd, const Operand *OpQm,
   2402                            const Operand *OpQn) {
   2403   // VAND (register) - ARM section A8.8.287, encoding A1:
   2404   //   vand <Qd>, <Qn>, <Qm>
   2405   //
   2406   // 111100100D00nnn0ddd00001N1M1mmm0 where Dddd=OpQd, Nnnn=OpQm, and Mmmm=OpQm.
   2407   constexpr const char *Vandq = "vandq";
   2408   constexpr IValueT VandqOpcode = B8 | B4;
   2409   constexpr Type ElmtTy = IceType_i8;
   2410   emitSIMDqqq(VandqOpcode, ElmtTy, OpQd, OpQm, OpQn, Vandq);
   2411 }
   2412 
   2413 void AssemblerARM32::vbslq(const Operand *OpQd, const Operand *OpQm,
   2414                            const Operand *OpQn) {
   2415   // VBSL (register) - ARM section A8.8.290, encoding A1:
   2416   //   vbsl <Qd>, <Qn>, <Qm>
   2417   //
   2418   // 111100110D01nnn0ddd00001N1M1mmm0 where Dddd=OpQd, Nnnn=OpQm, and Mmmm=OpQm.
   2419   constexpr const char *Vbslq = "vbslq";
   2420   constexpr IValueT VbslqOpcode = B24 | B20 | B8 | B4;
   2421   constexpr Type ElmtTy = IceType_i8; // emits sz=0
   2422   emitSIMDqqq(VbslqOpcode, ElmtTy, OpQd, OpQm, OpQn, Vbslq);
   2423 }
   2424 
   2425 void AssemblerARM32::vceqqi(const Type ElmtTy, const Operand *OpQd,
   2426                             const Operand *OpQm, const Operand *OpQn) {
   2427   // vceq (register) - ARM section A8.8.291, encoding A1:
   2428   //   vceq.<st> <Qd>, <Qn>, <Qm>
   2429   //
   2430   // 111100110Dssnnnndddd1000NQM1mmmm where Dddd=OpQd, Nnnn=OpQm, Mmmm=OpQm, and
   2431   // st in [i8, i16, i32] where ss is the index.
   2432   constexpr const char *Vceq = "vceq";
   2433   constexpr IValueT VceqOpcode = B24 | B11 | B4;
   2434   emitSIMDqqq(VceqOpcode, ElmtTy, OpQd, OpQm, OpQn, Vceq);
   2435 }
   2436 
   2437 void AssemblerARM32::vceqqs(const Operand *OpQd, const Operand *OpQm,
   2438                             const Operand *OpQn) {
   2439   // vceq (register) - ARM section A8.8.291, encoding A2:
   2440   //   vceq.f32 <Qd>, <Qn>, <Qm>
   2441   //
   2442   // 111100100D00nnnndddd1110NQM0mmmm where Dddd=OpQd, Nnnn=OpQm, and Mmmm=OpQm.
   2443   constexpr const char *Vceq = "vceq";
   2444   constexpr IValueT VceqOpcode = B11 | B10 | B9;
   2445   constexpr Type ElmtTy = IceType_i8; // encoded as 0b00
   2446   emitSIMDqqq(VceqOpcode, ElmtTy, OpQd, OpQm, OpQn, Vceq);
   2447 }
   2448 
   2449 void AssemblerARM32::vcgeqi(const Type ElmtTy, const Operand *OpQd,
   2450                             const Operand *OpQm, const Operand *OpQn) {
   2451   // vcge (register) - ARM section A8.8.293, encoding A1:
   2452   //   vcge.<st> <Qd>, <Qn>, <Qm>
   2453   //
   2454   // 1111001U0Dssnnnndddd0011NQM1mmmm where Dddd=OpQd, Nnnn=OpQm, Mmmm=OpQm,
   2455   // 0=U, and st in [s8, s16, s32] where ss is the index.
   2456   constexpr const char *Vcge = "vcge";
   2457   constexpr IValueT VcgeOpcode = B9 | B8 | B4;
   2458   emitSIMDqqq(VcgeOpcode, ElmtTy, OpQd, OpQm, OpQn, Vcge);
   2459 }
   2460 
   2461 void AssemblerARM32::vcugeqi(const Type ElmtTy, const Operand *OpQd,
   2462                              const Operand *OpQm, const Operand *OpQn) {
   2463   // vcge (register) - ARM section A8.8.293, encoding A1:
   2464   //   vcge.<st> <Qd>, <Qn>, <Qm>
   2465   //
   2466   // 1111001U0Dssnnnndddd0011NQM1mmmm where Dddd=OpQd, Nnnn=OpQm, Mmmm=OpQm,
   2467   // 1=U, and st in [u8, u16, u32] where ss is the index.
   2468   constexpr const char *Vcge = "vcge";
   2469   constexpr IValueT VcgeOpcode = B24 | B9 | B8 | B4;
   2470   emitSIMDqqq(VcgeOpcode, ElmtTy, OpQd, OpQm, OpQn, Vcge);
   2471 }
   2472 
   2473 void AssemblerARM32::vcgeqs(const Operand *OpQd, const Operand *OpQm,
   2474                             const Operand *OpQn) {
   2475   // vcge (register) - ARM section A8.8.293, encoding A2:
   2476   //   vcge.f32 <Qd>, <Qn>, <Qm>
   2477   //
   2478   // 111100110D00nnnndddd1110NQM0mmmm where Dddd=OpQd, Nnnn=OpQm, and Mmmm=OpQm.
   2479   constexpr const char *Vcge = "vcge";
   2480   constexpr IValueT VcgeOpcode = B24 | B11 | B10 | B9;
   2481   constexpr Type ElmtTy = IceType_i8; // encoded as 0b00.
   2482   emitSIMDqqq(VcgeOpcode, ElmtTy, OpQd, OpQm, OpQn, Vcge);
   2483 }
   2484 
   2485 void AssemblerARM32::vcgtqi(const Type ElmtTy, const Operand *OpQd,
   2486                             const Operand *OpQm, const Operand *OpQn) {
   2487   // vcgt (register) - ARM section A8.8.295, encoding A1:
   2488   //   vcgt.<st> <Qd>, <Qn>, <Qm>
   2489   //
   2490   // 1111001U0Dssnnnndddd0011NQM0mmmm where Dddd=OpQd, Nnnn=OpQm, Mmmm=OpQm,
   2491   // 0=U, and st in [s8, s16, s32] where ss is the index.
   2492   constexpr const char *Vcge = "vcgt";
   2493   constexpr IValueT VcgeOpcode = B9 | B8;
   2494   emitSIMDqqq(VcgeOpcode, ElmtTy, OpQd, OpQm, OpQn, Vcge);
   2495 }
   2496 
   2497 void AssemblerARM32::vcugtqi(const Type ElmtTy, const Operand *OpQd,
   2498                              const Operand *OpQm, const Operand *OpQn) {
   2499   // vcgt (register) - ARM section A8.8.295, encoding A1:
   2500   //   vcgt.<st> <Qd>, <Qn>, <Qm>
   2501   //
   2502   // 111100110Dssnnnndddd0011NQM0mmmm where Dddd=OpQd, Nnnn=OpQm, Mmmm=OpQm,
   2503   // 1=U, and st in [u8, u16, u32] where ss is the index.
   2504   constexpr const char *Vcge = "vcgt";
   2505   constexpr IValueT VcgeOpcode = B24 | B9 | B8;
   2506   emitSIMDqqq(VcgeOpcode, ElmtTy, OpQd, OpQm, OpQn, Vcge);
   2507 }
   2508 
   2509 void AssemblerARM32::vcgtqs(const Operand *OpQd, const Operand *OpQm,
   2510                             const Operand *OpQn) {
   2511   // vcgt (register) - ARM section A8.8.295, encoding A2:
   2512   //   vcgt.f32 <Qd>, <Qn>, <Qm>
   2513   //
   2514   // 111100110D10nnnndddd1110NQM0mmmm where Dddd=OpQd, Nnnn=OpQm, and Mmmm=OpQm.
   2515   constexpr const char *Vcge = "vcgt";
   2516   constexpr IValueT VcgeOpcode = B24 | B21 | B11 | B10 | B9;
   2517   constexpr Type ElmtTy = IceType_i8; // encoded as 0b00.
   2518   emitSIMDqqq(VcgeOpcode, ElmtTy, OpQd, OpQm, OpQn, Vcge);
   2519 }
   2520 
   2521 void AssemblerARM32::vcmpd(const Operand *OpDd, const Operand *OpDm,
   2522                            CondARM32::Cond Cond) {
   2523   constexpr const char *Vcmpd = "vcmpd";
   2524   IValueT Dd = encodeDRegister(OpDd, "Dd", Vcmpd);
   2525   IValueT Dm = encodeDRegister(OpDm, "Dm", Vcmpd);
   2526   constexpr IValueT VcmpdOpcode = B23 | B21 | B20 | B18 | B6;
   2527   constexpr IValueT Dn = 0;
   2528   emitVFPddd(Cond, VcmpdOpcode, Dd, Dn, Dm);
   2529 }
   2530 
   2531 void AssemblerARM32::vcmpdz(const Operand *OpDd, CondARM32::Cond Cond) {
   2532   constexpr const char *Vcmpdz = "vcmpdz";
   2533   IValueT Dd = encodeDRegister(OpDd, "Dd", Vcmpdz);
   2534   constexpr IValueT VcmpdzOpcode = B23 | B21 | B20 | B18 | B16 | B6;
   2535   constexpr IValueT Dn = 0;
   2536   constexpr IValueT Dm = 0;
   2537   emitVFPddd(Cond, VcmpdzOpcode, Dd, Dn, Dm);
   2538 }
   2539 
   2540 void AssemblerARM32::vcmps(const Operand *OpSd, const Operand *OpSm,
   2541                            CondARM32::Cond Cond) {
   2542   constexpr const char *Vcmps = "vcmps";
   2543   IValueT Sd = encodeSRegister(OpSd, "Sd", Vcmps);
   2544   IValueT Sm = encodeSRegister(OpSm, "Sm", Vcmps);
   2545   constexpr IValueT VcmpsOpcode = B23 | B21 | B20 | B18 | B6;
   2546   constexpr IValueT Sn = 0;
   2547   emitVFPsss(Cond, VcmpsOpcode, Sd, Sn, Sm);
   2548 }
   2549 
   2550 void AssemblerARM32::vcmpsz(const Operand *OpSd, CondARM32::Cond Cond) {
   2551   constexpr const char *Vcmpsz = "vcmps";
   2552   IValueT Sd = encodeSRegister(OpSd, "Sd", Vcmpsz);
   2553   constexpr IValueT VcmpszOpcode = B23 | B21 | B20 | B18 | B16 | B6;
   2554   constexpr IValueT Sn = 0;
   2555   constexpr IValueT Sm = 0;
   2556   emitVFPsss(Cond, VcmpszOpcode, Sd, Sn, Sm);
   2557 }
   2558 
   2559 void AssemblerARM32::emitVFPsd(CondARM32::Cond Cond, IValueT Opcode, IValueT Sd,
   2560                                IValueT Dm) {
   2561   assert(Sd < RegARM32::getNumSRegs());
   2562   assert(Dm < RegARM32::getNumDRegs());
   2563   assert(CondARM32::isDefined(Cond));
   2564   constexpr IValueT VFPOpcode = B27 | B26 | B25 | B11 | B9;
   2565   const IValueT Encoding =
   2566       Opcode | VFPOpcode | (encodeCondition(Cond) << kConditionShift) |
   2567       (getYInRegXXXXY(Sd) << 22) | (getXXXXInRegXXXXY(Sd) << 12) |
   2568       (getYInRegYXXXX(Dm) << 5) | getXXXXInRegYXXXX(Dm);
   2569   emitInst(Encoding);
   2570 }
   2571 
   2572 void AssemblerARM32::vcvtdi(const Operand *OpDd, const Operand *OpSm,
   2573                             CondARM32::Cond Cond) {
   2574   // VCVT (between floating-point and integer, Floating-point)
   2575   //      - ARM Section A8.8.306, encoding A1:
   2576   //   vcvt<c>.f64.s32 <Dd>, <Sm>
   2577   //
   2578   // cccc11101D111000dddd10111M0mmmm where cccc=Cond, Ddddd=Dd, and mmmmM=Sm.
   2579   constexpr const char *Vcvtdi = "vcvtdi";
   2580   IValueT Dd = encodeDRegister(OpDd, "Dd", Vcvtdi);
   2581   IValueT Sm = encodeSRegister(OpSm, "Sm", Vcvtdi);
   2582   constexpr IValueT VcvtdiOpcode = B23 | B21 | B20 | B19 | B8 | B7 | B6;
   2583   emitVFPds(Cond, VcvtdiOpcode, Dd, Sm);
   2584 }
   2585 
   2586 void AssemblerARM32::vcvtdu(const Operand *OpDd, const Operand *OpSm,
   2587                             CondARM32::Cond Cond) {
   2588   // VCVT (between floating-point and integer, Floating-point)
   2589   //      - ARM Section A8.8.306, encoding A1:
   2590   //   vcvt<c>.f64.u32 <Dd>, <Sm>
   2591   //
   2592   // cccc11101D111000dddd10101M0mmmm where cccc=Cond, Ddddd=Dd, and mmmmM=Sm.
   2593   constexpr const char *Vcvtdu = "vcvtdu";
   2594   IValueT Dd = encodeDRegister(OpDd, "Dd", Vcvtdu);
   2595   IValueT Sm = encodeSRegister(OpSm, "Sm", Vcvtdu);
   2596   constexpr IValueT VcvtduOpcode = B23 | B21 | B20 | B19 | B8 | B6;
   2597   emitVFPds(Cond, VcvtduOpcode, Dd, Sm);
   2598 }
   2599 
   2600 void AssemblerARM32::vcvtsd(const Operand *OpSd, const Operand *OpDm,
   2601                             CondARM32::Cond Cond) {
   2602   constexpr const char *Vcvtsd = "vcvtsd";
   2603   IValueT Sd = encodeSRegister(OpSd, "Sd", Vcvtsd);
   2604   IValueT Dm = encodeDRegister(OpDm, "Dm", Vcvtsd);
   2605   constexpr IValueT VcvtsdOpcode =
   2606       B23 | B21 | B20 | B18 | B17 | B16 | B8 | B7 | B6;
   2607   emitVFPsd(Cond, VcvtsdOpcode, Sd, Dm);
   2608 }
   2609 
   2610 void AssemblerARM32::vcvtis(const Operand *OpSd, const Operand *OpSm,
   2611                             CondARM32::Cond Cond) {
   2612   // VCVT (between floating-point and integer, Floating-point)
   2613   //      - ARM Section A8.8.306, encoding A1:
   2614   //   vcvt<c>.s32.f32 <Sd>, <Sm>
   2615   //
   2616   // cccc11101D111101dddd10011M0mmmm where cccc=Cond, ddddD=Sd, and mmmmM=Sm.
   2617   constexpr const char *Vcvtis = "vcvtis";
   2618   IValueT Sd = encodeSRegister(OpSd, "Sd", Vcvtis);
   2619   IValueT Sm = encodeSRegister(OpSm, "Sm", Vcvtis);
   2620   constexpr IValueT VcvtisOpcode = B23 | B21 | B20 | B19 | B18 | B16 | B7 | B6;
   2621   constexpr IValueT S0 = 0;
   2622   emitVFPsss(Cond, VcvtisOpcode, Sd, S0, Sm);
   2623 }
   2624 
   2625 void AssemblerARM32::vcvtid(const Operand *OpSd, const Operand *OpDm,
   2626                             CondARM32::Cond Cond) {
   2627   // VCVT (between floating-point and integer, Floating-point)
   2628   //      - ARM Section A8.8.306, encoding A1:
   2629   //   vcvt<c>.s32.f64 <Sd>, <Dm>
   2630   //
   2631   // cccc11101D111101dddd10111M0mmmm where cccc=Cond, ddddD=Sd, and Mmmmm=Dm.
   2632   constexpr const char *Vcvtid = "vcvtid";
   2633   IValueT Sd = encodeSRegister(OpSd, "Sd", Vcvtid);
   2634   IValueT Dm = encodeDRegister(OpDm, "Dm", Vcvtid);
   2635   constexpr IValueT VcvtidOpcode =
   2636       B23 | B21 | B20 | B19 | B18 | B16 | B8 | B7 | B6;
   2637   emitVFPsd(Cond, VcvtidOpcode, Sd, Dm);
   2638 }
   2639 
   2640 void AssemblerARM32::vcvtsi(const Operand *OpSd, const Operand *OpSm,
   2641                             CondARM32::Cond Cond) {
   2642   // VCVT (between floating-point and integer, Floating-point)
   2643   //      - ARM Section A8.8.306, encoding A1:
   2644   //   vcvt<c>.f32.s32 <Sd>, <Sm>
   2645   //
   2646   // cccc11101D111000dddd10011M0mmmm where cccc=Cond, ddddD=Sd, and mmmmM=Sm.
   2647   constexpr const char *Vcvtsi = "vcvtsi";
   2648   IValueT Sd = encodeSRegister(OpSd, "Sd", Vcvtsi);
   2649   IValueT Sm = encodeSRegister(OpSm, "Sm", Vcvtsi);
   2650   constexpr IValueT VcvtsiOpcode = B23 | B21 | B20 | B19 | B7 | B6;
   2651   constexpr IValueT S0 = 0;
   2652   emitVFPsss(Cond, VcvtsiOpcode, Sd, S0, Sm);
   2653 }
   2654 
   2655 void AssemblerARM32::vcvtsu(const Operand *OpSd, const Operand *OpSm,
   2656                             CondARM32::Cond Cond) {
   2657   // VCVT (between floating-point and integer, Floating-point)
   2658   //      - ARM Section A8.8.306, encoding A1:
   2659   //   vcvt<c>.f32.u32 <Sd>, <Sm>
   2660   //
   2661   // cccc11101D111000dddd10001M0mmmm where cccc=Cond, ddddD=Sd, and mmmmM=Sm.
   2662   constexpr const char *Vcvtsu = "vcvtsu";
   2663   IValueT Sd = encodeSRegister(OpSd, "Sd", Vcvtsu);
   2664   IValueT Sm = encodeSRegister(OpSm, "Sm", Vcvtsu);
   2665   constexpr IValueT VcvtsuOpcode = B23 | B21 | B20 | B19 | B6;
   2666   constexpr IValueT S0 = 0;
   2667   emitVFPsss(Cond, VcvtsuOpcode, Sd, S0, Sm);
   2668 }
   2669 
   2670 void AssemblerARM32::vcvtud(const Operand *OpSd, const Operand *OpDm,
   2671                             CondARM32::Cond Cond) {
   2672   // VCVT (between floating-point and integer, Floating-point)
   2673   //      - ARM Section A8.8.306, encoding A1:
   2674   //   vcvt<c>.u32.f64 <Sd>, <Dm>
   2675   //
   2676   // cccc11101D111100dddd10111M0mmmm where cccc=Cond, ddddD=Sd, and Mmmmm=Dm.
   2677   constexpr const char *Vcvtud = "vcvtud";
   2678   IValueT Sd = encodeSRegister(OpSd, "Sd", Vcvtud);
   2679   IValueT Dm = encodeDRegister(OpDm, "Dm", Vcvtud);
   2680   constexpr IValueT VcvtudOpcode = B23 | B21 | B20 | B19 | B18 | B8 | B7 | B6;
   2681   emitVFPsd(Cond, VcvtudOpcode, Sd, Dm);
   2682 }
   2683 
   2684 void AssemblerARM32::vcvtus(const Operand *OpSd, const Operand *OpSm,
   2685                             CondARM32::Cond Cond) {
   2686   // VCVT (between floating-point and integer, Floating-point)
   2687   //      - ARM Section A8.8.306, encoding A1:
   2688   //   vcvt<c>.u32.f32 <Sd>, <Sm>
   2689   //
   2690   // cccc11101D111100dddd10011M0mmmm where cccc=Cond, ddddD=Sd, and mmmmM=Sm.
   2691   constexpr const char *Vcvtus = "vcvtus";
   2692   IValueT Sd = encodeSRegister(OpSd, "Sd", Vcvtus);
   2693   IValueT Sm = encodeSRegister(OpSm, "Sm", Vcvtus);
   2694   constexpr IValueT VcvtsiOpcode = B23 | B21 | B20 | B19 | B18 | B7 | B6;
   2695   constexpr IValueT S0 = 0;
   2696   emitVFPsss(Cond, VcvtsiOpcode, Sd, S0, Sm);
   2697 }
   2698 
   2699 void AssemblerARM32::vcvtqsi(const Operand *OpQd, const Operand *OpQm) {
   2700   // VCVT (between floating-point and integer, Advanced SIMD)
   2701   //      - ARM Section A8.8.305, encoding A1:
   2702   //   vcvt<c>.f32.s32 <Qd>, <Qm>
   2703   //
   2704   // 111100111D11ss11dddd011ooQM0mmmm where Ddddd=Qd, Mmmmm=Qm, and 10=op.
   2705   constexpr const char *Vcvtqsi = "vcvt.s32.f32";
   2706   constexpr IValueT VcvtqsiOpcode = B8;
   2707   emitSIMDCvtqq(VcvtqsiOpcode, OpQd, OpQm, Vcvtqsi);
   2708 }
   2709 
   2710 void AssemblerARM32::vcvtqsu(const Operand *OpQd, const Operand *OpQm) {
   2711   // VCVT (between floating-point and integer, Advanced SIMD)
   2712   //      - ARM Section A8.8.305, encoding A1:
   2713   //   vcvt<c>.f32.u32 <Qd>, <Qm>
   2714   //
   2715   // 111100111D11ss11dddd011ooQM0mmmm where Ddddd=Qd, Mmmmm=Qm, and 11=op.
   2716   constexpr const char *Vcvtqsu = "vcvt.u32.f32";
   2717   constexpr IValueT VcvtqsuOpcode = B8 | B7;
   2718   emitSIMDCvtqq(VcvtqsuOpcode, OpQd, OpQm, Vcvtqsu);
   2719 }
   2720 
   2721 void AssemblerARM32::vcvtqis(const Operand *OpQd, const Operand *OpQm) {
   2722   // VCVT (between floating-point and integer, Advanced SIMD)
   2723   //      - ARM Section A8.8.305, encoding A1:
   2724   //   vcvt<c>.f32.s32 <Qd>, <Qm>
   2725   //
   2726   // 111100111D11ss11dddd011ooQM0mmmm where Ddddd=Qd, Mmmmm=Qm, and 01=op.
   2727   constexpr const char *Vcvtqis = "vcvt.f32.s32";
   2728   constexpr IValueT VcvtqisOpcode = 0;
   2729   emitSIMDCvtqq(VcvtqisOpcode, OpQd, OpQm, Vcvtqis);
   2730 }
   2731 
   2732 void AssemblerARM32::vcvtqus(const Operand *OpQd, const Operand *OpQm) {
   2733   // VCVT (between floating-point and integer, Advanced SIMD)
   2734   //      - ARM Section A8.8.305, encoding A1:
   2735   //   vcvt<c>.f32.u32 <Qd>, <Qm>
   2736   //
   2737   // 111100111D11ss11dddd011ooQM0mmmm where Ddddd=Qd, Mmmmm=Qm, and 01=op.
   2738   constexpr const char *Vcvtqus = "vcvt.f32.u32";
   2739   constexpr IValueT VcvtqusOpcode = B7;
   2740   emitSIMDCvtqq(VcvtqusOpcode, OpQd, OpQm, Vcvtqus);
   2741 }
   2742 
   2743 void AssemblerARM32::emitVFPds(CondARM32::Cond Cond, IValueT Opcode, IValueT Dd,
   2744                                IValueT Sm) {
   2745   assert(Dd < RegARM32::getNumDRegs());
   2746   assert(Sm < RegARM32::getNumSRegs());
   2747   assert(CondARM32::isDefined(Cond));
   2748   constexpr IValueT VFPOpcode = B27 | B26 | B25 | B11 | B9;
   2749   const IValueT Encoding =
   2750       Opcode | VFPOpcode | (encodeCondition(Cond) << kConditionShift) |
   2751       (getYInRegYXXXX(Dd) << 22) | (getXXXXInRegYXXXX(Dd) << 12) |
   2752       (getYInRegXXXXY(Sm) << 5) | getXXXXInRegXXXXY(Sm);
   2753   emitInst(Encoding);
   2754 }
   2755 
   2756 void AssemblerARM32::vcvtds(const Operand *OpDd, const Operand *OpSm,
   2757                             CondARM32::Cond Cond) {
   2758   constexpr const char *Vcvtds = "Vctds";
   2759   IValueT Dd = encodeDRegister(OpDd, "Dd", Vcvtds);
   2760   IValueT Sm = encodeSRegister(OpSm, "Sm", Vcvtds);
   2761   constexpr IValueT VcvtdsOpcode = B23 | B21 | B20 | B18 | B17 | B16 | B7 | B6;
   2762   emitVFPds(Cond, VcvtdsOpcode, Dd, Sm);
   2763 }
   2764 
   2765 void AssemblerARM32::vdivs(const Operand *OpSd, const Operand *OpSn,
   2766                            const Operand *OpSm, CondARM32::Cond Cond) {
   2767   // VDIV (floating-point) - ARM section A8.8.283, encoding A2:
   2768   //   vdiv<c>.f32 <Sd>, <Sn>, <Sm>
   2769   //
   2770   // cccc11101D00nnnndddd101sN0M0mmmm where cccc=Cond, s=0, ddddD=Rd, nnnnN=Rn,
   2771   // and mmmmM=Rm.
   2772   constexpr const char *Vdivs = "vdivs";
   2773   constexpr IValueT VdivsOpcode = B23;
   2774   emitVFPsss(Cond, VdivsOpcode, OpSd, OpSn, OpSm, Vdivs);
   2775 }
   2776 
   2777 void AssemblerARM32::vdivd(const Operand *OpDd, const Operand *OpDn,
   2778                            const Operand *OpDm, CondARM32::Cond Cond) {
   2779   // VDIV (floating-point) - ARM section A8.8.283, encoding A2:
   2780   //   vdiv<c>.f64 <Dd>, <Dn>, <Dm>
   2781   //
   2782   // cccc11101D00nnnndddd101sN0M0mmmm where cccc=Cond, s=1, Ddddd=Rd, Nnnnn=Rn,
   2783   // and Mmmmm=Rm.
   2784   constexpr const char *Vdivd = "vdivd";
   2785   constexpr IValueT VdivdOpcode = B23;
   2786   emitVFPddd(Cond, VdivdOpcode, OpDd, OpDn, OpDm, Vdivd);
   2787 }
   2788 
   2789 void AssemblerARM32::veord(const Operand *OpDd, const Operand *OpDn,
   2790                            const Operand *OpDm) {
   2791   // VEOR - ARM secdtion A8.8.315, encoding A1:
   2792   //   veor<c> <Dd>, <Dn>, <Dm>
   2793   //
   2794   // 111100110D00nnnndddd0001N0M1mmmm where Ddddd=Dd, Nnnnn=Dn, and Mmmmm=Dm.
   2795   constexpr const char *Veord = "veord";
   2796   IValueT Dd = encodeDRegister(OpDd, "Dd", Veord);
   2797   IValueT Dn = encodeDRegister(OpDn, "Dn", Veord);
   2798   IValueT Dm = encodeDRegister(OpDm, "Dm", Veord);
   2799   const IValueT Encoding =
   2800       B25 | B24 | B8 | B4 |
   2801       (encodeCondition(CondARM32::Cond::kNone) << kConditionShift) |
   2802       (getYInRegYXXXX(Dd) << 22) | (getXXXXInRegYXXXX(Dn) << 16) |
   2803       (getXXXXInRegYXXXX(Dd) << 12) | (getYInRegYXXXX(Dn) << 7) |
   2804       (getYInRegYXXXX(Dm) << 5) | getXXXXInRegYXXXX(Dm);
   2805   emitInst(Encoding);
   2806 }
   2807 
   2808 void AssemblerARM32::veorq(const Operand *OpQd, const Operand *OpQn,
   2809                            const Operand *OpQm) {
   2810   // VEOR - ARM section A8.8.316, encoding A1:
   2811   //   veor <Qd>, <Qn>, <Qm>
   2812   //
   2813   // 111100110D00nnn0ddd00001N1M1mmm0 where Dddd=Qd, Nnnn=Qn, and Mmmm=Qm.
   2814   constexpr const char *Veorq = "veorq";
   2815   constexpr IValueT VeorqOpcode = B24 | B8 | B4;
   2816   emitSIMDqqq(VeorqOpcode, IceType_i8, OpQd, OpQn, OpQm, Veorq);
   2817 }
   2818 
   2819 void AssemblerARM32::vldrd(const Operand *OpDd, const Operand *OpAddress,
   2820                            CondARM32::Cond Cond, const TargetInfo &TInfo) {
   2821   // VLDR - ARM section A8.8.333, encoding A1.
   2822   //   vldr<c> <Dd>, [<Rn>{, #+/-<imm>}]
   2823   //
   2824   // cccc1101UD01nnnndddd1011iiiiiiii where cccc=Cond, nnnn=Rn, Ddddd=Rd,
   2825   // iiiiiiii=abs(Imm >> 2), and U=1 if Opcode>=0.
   2826   constexpr const char *Vldrd = "vldrd";
   2827   IValueT Dd = encodeDRegister(OpDd, "Dd", Vldrd);
   2828   assert(CondARM32::isDefined(Cond));
   2829   IValueT Address;
   2830   EncodedOperand AddressEncoding =
   2831       encodeAddress(OpAddress, Address, TInfo, RotatedImm8Div4Address);
   2832   (void)AddressEncoding;
   2833   assert(AddressEncoding == EncodedAsImmRegOffset);
   2834   IValueT Encoding = B27 | B26 | B24 | B20 | B11 | B9 | B8 |
   2835                      (encodeCondition(Cond) << kConditionShift) |
   2836                      (getYInRegYXXXX(Dd) << 22) |
   2837                      (getXXXXInRegYXXXX(Dd) << 12) | Address;
   2838   emitInst(Encoding);
   2839 }
   2840 
   2841 void AssemblerARM32::vldrs(const Operand *OpSd, const Operand *OpAddress,
   2842                            CondARM32::Cond Cond, const TargetInfo &TInfo) {
   2843   // VDLR - ARM section A8.8.333, encoding A2.
   2844   //   vldr<c> <Sd>, [<Rn>{, #+/-<imm>]]
   2845   //
   2846   // cccc1101UD01nnnndddd1010iiiiiiii where cccc=Cond, nnnn=Rn, ddddD=Sd,
   2847   // iiiiiiii=abs(Opcode), and U=1 if Opcode >= 0;
   2848   constexpr const char *Vldrs = "vldrs";
   2849   IValueT Sd = encodeSRegister(OpSd, "Sd", Vldrs);
   2850   assert(CondARM32::isDefined(Cond));
   2851   IValueT Address;
   2852   EncodedOperand AddressEncoding =
   2853       encodeAddress(OpAddress, Address, TInfo, RotatedImm8Div4Address);
   2854   (void)AddressEncoding;
   2855   assert(AddressEncoding == EncodedAsImmRegOffset);
   2856   IValueT Encoding = B27 | B26 | B24 | B20 | B11 | B9 |
   2857                      (encodeCondition(Cond) << kConditionShift) |
   2858                      (getYInRegXXXXY(Sd) << 22) |
   2859                      (getXXXXInRegXXXXY(Sd) << 12) | Address;
   2860   emitInst(Encoding);
   2861 }
   2862 
   2863 void AssemblerARM32::emitVMem1Op(IValueT Opcode, IValueT Dd, IValueT Rn,
   2864                                  IValueT Rm, DRegListSize NumDRegs,
   2865                                  size_t ElmtSize, IValueT Align,
   2866                                  const char *InstName) {
   2867   assert(Utils::IsAbsoluteUint(2, Align));
   2868   IValueT EncodedElmtSize;
   2869   switch (ElmtSize) {
   2870   default: {
   2871     std::string Buffer;
   2872     llvm::raw_string_ostream StrBuf(Buffer);
   2873     StrBuf << InstName << ": found invalid vector element size " << ElmtSize;
   2874     llvm::report_fatal_error(StrBuf.str());
   2875   }
   2876   case 8:
   2877     EncodedElmtSize = 0;
   2878     break;
   2879   case 16:
   2880     EncodedElmtSize = 1;
   2881     break;
   2882   case 32:
   2883     EncodedElmtSize = 2;
   2884     break;
   2885   case 64:
   2886     EncodedElmtSize = 3;
   2887   }
   2888   const IValueT Encoding =
   2889       Opcode | (encodeCondition(CondARM32::kNone) << kConditionShift) |
   2890       (getYInRegYXXXX(Dd) << 22) | (Rn << kRnShift) |
   2891       (getXXXXInRegYXXXX(Dd) << kRdShift) | (NumDRegs << 8) |
   2892       (EncodedElmtSize << 6) | (Align << 4) | Rm;
   2893   emitInst(Encoding);
   2894 }
   2895 
   2896 void AssemblerARM32::vld1qr(size_t ElmtSize, const Operand *OpQd,
   2897                             const Operand *OpAddress, const TargetInfo &TInfo) {
   2898   // VLD1 (multiple single elements) - ARM section A8.8.320, encoding A1:
   2899   //   vld1.<size> <Qd>, [<Rn>]
   2900   //
   2901   // 111101000D10nnnnddd0ttttssaammmm where tttt=DRegListSize2, Dddd=Qd,
   2902   // nnnn=Rn, aa=0 (use default alignment), size=ElmtSize, and ss is the
   2903   // encoding of ElmtSize.
   2904   constexpr const char *Vld1qr = "vld1qr";
   2905   const IValueT Qd = encodeQRegister(OpQd, "Qd", Vld1qr);
   2906   const IValueT Dd = mapQRegToDReg(Qd);
   2907   IValueT Address;
   2908   if (encodeAddress(OpAddress, Address, TInfo, NoImmOffsetAddress) !=
   2909       EncodedAsImmRegOffset)
   2910     llvm::report_fatal_error(std::string(Vld1qr) + ": malform memory address");
   2911   const IValueT Rn = mask(Address, kRnShift, 4);
   2912   constexpr IValueT Rm = RegARM32::Reg_pc;
   2913   constexpr IValueT Opcode = B26 | B21;
   2914   constexpr IValueT Align = 0; // use default alignment.
   2915   emitVMem1Op(Opcode, Dd, Rn, Rm, DRegListSize2, ElmtSize, Align, Vld1qr);
   2916 }
   2917 
   2918 bool AssemblerARM32::vmovqc(const Operand *OpQd, const ConstantInteger32 *Imm) {
   2919   // VMOV (immediate) - ARM section A8.8.320, encoding A1:
   2920   //   VMOV.<dt> <Qd>, #<Imm>
   2921   // 1111001x1D000yyyddddcccc01p1zzzz where Qd=Ddddd, Imm=xyyyzzzz, cmode=cccc,
   2922   // and Op=p.
   2923   constexpr const char *Vmovc = "vmovc";
   2924   const IValueT Dd = mapQRegToDReg(encodeQRegister(OpQd, "Qd", Vmovc));
   2925   IValueT Value = Imm->getValue();
   2926   const Type VecTy = OpQd->getType();
   2927   if (!isVectorType(VecTy))
   2928     return false;
   2929 
   2930   IValueT Op;
   2931   IValueT Cmode;
   2932   IValueT Imm8;
   2933   if (!encodeAdvSIMDExpandImm(Value, typeElementType(VecTy), Op, Cmode, Imm8))
   2934     return false;
   2935   if (Op == 0 && mask(Cmode, 0, 1) == 1)
   2936     return false;
   2937   if (Op == 1 && Cmode != 13)
   2938     return false;
   2939   const IValueT Encoding =
   2940       (0xF << kConditionShift) | B25 | B23 | B6 | B4 |
   2941       (mask(Imm8, 7, 1) << 24) | (getYInRegYXXXX(Dd) << 22) |
   2942       (mask(Imm8, 4, 3) << 16) | (getXXXXInRegYXXXX(Dd) << 12) | (Cmode << 8) |
   2943       (Op << 5) | mask(Imm8, 0, 4);
   2944   emitInst(Encoding);
   2945   return true;
   2946 }
   2947 
   2948 void AssemblerARM32::vmovd(const Operand *OpDd,
   2949                            const OperandARM32FlexFpImm *OpFpImm,
   2950                            CondARM32::Cond Cond) {
   2951   // VMOV (immediate) - ARM section A8.8.339, encoding A2:
   2952   //   vmov<c>.f64 <Dd>, #<imm>
   2953   //
   2954   // cccc11101D11xxxxdddd10110000yyyy where cccc=Cond, ddddD=Sn, xxxxyyyy=imm.
   2955   constexpr const char *Vmovd = "vmovd";
   2956   IValueT Dd = encodeSRegister(OpDd, "Dd", Vmovd);
   2957   IValueT Imm8 = OpFpImm->getModifiedImm();
   2958   assert(Imm8 < (1 << 8));
   2959   constexpr IValueT VmovsOpcode = B23 | B21 | B20 | B8;
   2960   IValueT OpcodePlusImm8 = VmovsOpcode | ((Imm8 >> 4) << 16) | (Imm8 & 0xf);
   2961   constexpr IValueT D0 = 0;
   2962   emitVFPddd(Cond, OpcodePlusImm8, Dd, D0, D0);
   2963 }
   2964 
   2965 void AssemblerARM32::vmovdd(const Operand *OpDd, const Variable *OpDm,
   2966                             CondARM32::Cond Cond) {
   2967   // VMOV (register) - ARM section A8.8.340, encoding A2:
   2968   //   vmov<c>.f64 <Dd>, <Sm>
   2969   //
   2970   // cccc11101D110000dddd101101M0mmmm where cccc=Cond, Ddddd=Sd, and Mmmmm=Sm.
   2971   constexpr const char *Vmovdd = "Vmovdd";
   2972   IValueT Dd = encodeSRegister(OpDd, "Dd", Vmovdd);
   2973   IValueT Dm = encodeSRegister(OpDm, "Dm", Vmovdd);
   2974   constexpr IValueT VmovddOpcode = B23 | B21 | B20 | B6;
   2975   constexpr IValueT D0 = 0;
   2976   emitVFPddd(Cond, VmovddOpcode, Dd, D0, Dm);
   2977 }
   2978 
   2979 void AssemblerARM32::vmovdrr(const Operand *OpDm, const Operand *OpRt,
   2980                              const Operand *OpRt2, CondARM32::Cond Cond) {
   2981   // VMOV (between two ARM core registers and a doubleword extension register).
   2982   // ARM section A8.8.345, encoding A1:
   2983   //   vmov<c> <Dm>, <Rt>, <Rt2>
   2984   //
   2985   // cccc11000100xxxxyyyy101100M1mmmm where cccc=Cond, xxxx=Rt, yyyy=Rt2, and
   2986   // Mmmmm=Dm.
   2987   constexpr const char *Vmovdrr = "vmovdrr";
   2988   IValueT Dm = encodeDRegister(OpDm, "Dm", Vmovdrr);
   2989   IValueT Rt = encodeGPRegister(OpRt, "Rt", Vmovdrr);
   2990   IValueT Rt2 = encodeGPRegister(OpRt2, "Rt", Vmovdrr);
   2991   assert(Rt != RegARM32::Encoded_Reg_sp);
   2992   assert(Rt != RegARM32::Encoded_Reg_pc);
   2993   assert(Rt2 != RegARM32::Encoded_Reg_sp);
   2994   assert(Rt2 != RegARM32::Encoded_Reg_pc);
   2995   assert(Rt != Rt2);
   2996   assert(CondARM32::isDefined(Cond));
   2997   IValueT Encoding = B27 | B26 | B22 | B11 | B9 | B8 | B4 |
   2998                      (encodeCondition(Cond) << kConditionShift) | (Rt2 << 16) |
   2999                      (Rt << 12) | (getYInRegYXXXX(Dm) << 5) |
   3000                      getXXXXInRegYXXXX(Dm);
   3001   emitInst(Encoding);
   3002 }
   3003 
   3004 void AssemblerARM32::vmovqir(const Operand *OpQn, uint32_t Index,
   3005                              const Operand *OpRt, CondARM32::Cond Cond) {
   3006   // VMOV (ARM core register to scalar) - ARM section A8.8.341, encoding A1:
   3007   //   vmov<c>.<size> <Dn[x]>, <Rt>
   3008   constexpr const char *Vmovdr = "vmovdr";
   3009   constexpr bool IsExtract = true;
   3010   emitInsertExtractInt(Cond, OpQn, Index, OpRt, !IsExtract, Vmovdr);
   3011 }
   3012 
   3013 void AssemblerARM32::vmovqis(const Operand *OpQd, uint32_t Index,
   3014                              const Operand *OpSm, CondARM32::Cond Cond) {
   3015   constexpr const char *Vmovqis = "vmovqis";
   3016   assert(Index < 4);
   3017   IValueT Sd = mapQRegToSReg(encodeQRegister(OpQd, "Qd", Vmovqis)) + Index;
   3018   IValueT Sm = encodeSRegister(OpSm, "Sm", Vmovqis);
   3019   emitMoveSS(Cond, Sd, Sm);
   3020 }
   3021 
   3022 void AssemblerARM32::vmovrqi(const Operand *OpRt, const Operand *OpQn,
   3023                              uint32_t Index, CondARM32::Cond Cond) {
   3024   // VMOV (scalar to ARM core register) - ARM section A8.8.342, encoding A1:
   3025   //   vmov<c>.<dt> <Rt>, <Dn[x]>
   3026   constexpr const char *Vmovrd = "vmovrd";
   3027   constexpr bool IsExtract = true;
   3028   emitInsertExtractInt(Cond, OpQn, Index, OpRt, IsExtract, Vmovrd);
   3029 }
   3030 
   3031 void AssemblerARM32::vmovrrd(const Operand *OpRt, const Operand *OpRt2,
   3032                              const Operand *OpDm, CondARM32::Cond Cond) {
   3033   // VMOV (between two ARM core registers and a doubleword extension register).
   3034   // ARM section A8.8.345, encoding A1:
   3035   //   vmov<c> <Rt>, <Rt2>, <Dm>
   3036   //
   3037   // cccc11000101xxxxyyyy101100M1mmmm where cccc=Cond, xxxx=Rt, yyyy=Rt2, and
   3038   // Mmmmm=Dm.
   3039   constexpr const char *Vmovrrd = "vmovrrd";
   3040   IValueT Rt = encodeGPRegister(OpRt, "Rt", Vmovrrd);
   3041   IValueT Rt2 = encodeGPRegister(OpRt2, "Rt", Vmovrrd);
   3042   IValueT Dm = encodeDRegister(OpDm, "Dm", Vmovrrd);
   3043   assert(Rt != RegARM32::Encoded_Reg_sp);
   3044   assert(Rt != RegARM32::Encoded_Reg_pc);
   3045   assert(Rt2 != RegARM32::Encoded_Reg_sp);
   3046   assert(Rt2 != RegARM32::Encoded_Reg_pc);
   3047   assert(Rt != Rt2);
   3048   assert(CondARM32::isDefined(Cond));
   3049   IValueT Encoding = B27 | B26 | B22 | B20 | B11 | B9 | B8 | B4 |
   3050                      (encodeCondition(Cond) << kConditionShift) | (Rt2 << 16) |
   3051                      (Rt << 12) | (getYInRegYXXXX(Dm) << 5) |
   3052                      getXXXXInRegYXXXX(Dm);
   3053   emitInst(Encoding);
   3054 }
   3055 
   3056 void AssemblerARM32::vmovrs(const Operand *OpRt, const Operand *OpSn,
   3057                             CondARM32::Cond Cond) {
   3058   // VMOV (between ARM core register and single-precision register)
   3059   //   ARM section A8.8.343, encoding A1.
   3060   //
   3061   //   vmov<c> <Rt>, <Sn>
   3062   //
   3063   // cccc11100001nnnntttt1010N0010000 where cccc=Cond, nnnnN = Sn, and tttt=Rt.
   3064   constexpr const char *Vmovrs = "vmovrs";
   3065   IValueT Rt = encodeGPRegister(OpRt, "Rt", Vmovrs);
   3066   IValueT Sn = encodeSRegister(OpSn, "Sn", Vmovrs);
   3067   assert(CondARM32::isDefined(Cond));
   3068   IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B27 | B26 |
   3069                      B25 | B20 | B11 | B9 | B4 | (getXXXXInRegXXXXY(Sn) << 16) |
   3070                      (Rt << kRdShift) | (getYInRegXXXXY(Sn) << 7);
   3071   emitInst(Encoding);
   3072 }
   3073 
   3074 void AssemblerARM32::vmovs(const Operand *OpSd,
   3075                            const OperandARM32FlexFpImm *OpFpImm,
   3076                            CondARM32::Cond Cond) {
   3077   // VMOV (immediate) - ARM section A8.8.339, encoding A2:
   3078   //   vmov<c>.f32 <Sd>, #<imm>
   3079   //
   3080   // cccc11101D11xxxxdddd10100000yyyy where cccc=Cond, ddddD=Sn, xxxxyyyy=imm.
   3081   constexpr const char *Vmovs = "vmovs";
   3082   IValueT Sd = encodeSRegister(OpSd, "Sd", Vmovs);
   3083   IValueT Imm8 = OpFpImm->getModifiedImm();
   3084   assert(Imm8 < (1 << 8));
   3085   constexpr IValueT VmovsOpcode = B23 | B21 | B20;
   3086   IValueT OpcodePlusImm8 = VmovsOpcode | ((Imm8 >> 4) << 16) | (Imm8 & 0xf);
   3087   constexpr IValueT S0 = 0;
   3088   emitVFPsss(Cond, OpcodePlusImm8, Sd, S0, S0);
   3089 }
   3090 
   3091 void AssemblerARM32::vmovss(const Operand *OpSd, const Variable *OpSm,
   3092                             CondARM32::Cond Cond) {
   3093   constexpr const char *Vmovss = "Vmovss";
   3094   IValueT Sd = encodeSRegister(OpSd, "Sd", Vmovss);
   3095   IValueT Sm = encodeSRegister(OpSm, "Sm", Vmovss);
   3096   emitMoveSS(Cond, Sd, Sm);
   3097 }
   3098 
   3099 void AssemblerARM32::vmovsqi(const Operand *OpSd, const Operand *OpQm,
   3100                              uint32_t Index, CondARM32::Cond Cond) {
   3101   constexpr const char *Vmovsqi = "vmovsqi";
   3102   const IValueT Sd = encodeSRegister(OpSd, "Sd", Vmovsqi);
   3103   assert(Index < 4);
   3104   const IValueT Sm =
   3105       mapQRegToSReg(encodeQRegister(OpQm, "Qm", Vmovsqi)) + Index;
   3106   emitMoveSS(Cond, Sd, Sm);
   3107 }
   3108 
   3109 void AssemblerARM32::vmovsr(const Operand *OpSn, const Operand *OpRt,
   3110                             CondARM32::Cond Cond) {
   3111   // VMOV (between ARM core register and single-precision register)
   3112   //   ARM section A8.8.343, encoding A1.
   3113   //
   3114   //   vmov<c> <Sn>, <Rt>
   3115   //
   3116   // cccc11100000nnnntttt1010N0010000 where cccc=Cond, nnnnN = Sn, and tttt=Rt.
   3117   constexpr const char *Vmovsr = "vmovsr";
   3118   IValueT Sn = encodeSRegister(OpSn, "Sn", Vmovsr);
   3119   IValueT Rt = encodeGPRegister(OpRt, "Rt", Vmovsr);
   3120   assert(Sn < RegARM32::getNumSRegs());
   3121   assert(Rt < RegARM32::getNumGPRegs());
   3122   assert(CondARM32::isDefined(Cond));
   3123   IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B27 | B26 |
   3124                      B25 | B11 | B9 | B4 | (getXXXXInRegXXXXY(Sn) << 16) |
   3125                      (Rt << kRdShift) | (getYInRegXXXXY(Sn) << 7);
   3126   emitInst(Encoding);
   3127 }
   3128 
   3129 void AssemblerARM32::vmlad(const Operand *OpDd, const Operand *OpDn,
   3130                            const Operand *OpDm, CondARM32::Cond Cond) {
   3131   // VMLA, VMLS (floating-point), ARM section A8.8.337, encoding A2:
   3132   //   vmla<c>.f64 <Dd>, <Dn>, <Dm>
   3133   //
   3134   // cccc11100d00nnnndddd1011n0M0mmmm where cccc=Cond, Ddddd=Dd, Nnnnn=Dn, and
   3135   // Mmmmm=Dm
   3136   constexpr const char *Vmlad = "vmlad";
   3137   constexpr IValueT VmladOpcode = 0;
   3138   emitVFPddd(Cond, VmladOpcode, OpDd, OpDn, OpDm, Vmlad);
   3139 }
   3140 
   3141 void AssemblerARM32::vmlas(const Operand *OpSd, const Operand *OpSn,
   3142                            const Operand *OpSm, CondARM32::Cond Cond) {
   3143   // VMLA, VMLS (floating-point), ARM section A8.8.337, encoding A2:
   3144   //   vmla<c>.f32 <Sd>, <Sn>, <Sm>
   3145   //
   3146   // cccc11100d00nnnndddd1010n0M0mmmm where cccc=Cond, ddddD=Sd, nnnnN=Sn, and
   3147   // mmmmM=Sm
   3148   constexpr const char *Vmlas = "vmlas";
   3149   constexpr IValueT VmlasOpcode = 0;
   3150   emitVFPsss(Cond, VmlasOpcode, OpSd, OpSn, OpSm, Vmlas);
   3151 }
   3152 
   3153 void AssemblerARM32::vmlsd(const Operand *OpDd, const Operand *OpDn,
   3154                            const Operand *OpDm, CondARM32::Cond Cond) {
   3155   // VMLA, VMLS (floating-point), ARM section A8.8.337, encoding A2:
   3156   //   vmls<c>.f64 <Dd>, <Dn>, <Dm>
   3157   //
   3158   // cccc11100d00nnnndddd1011n1M0mmmm where cccc=Cond, Ddddd=Dd, Nnnnn=Dn, and
   3159   // Mmmmm=Dm
   3160   constexpr const char *Vmlad = "vmlad";
   3161   constexpr IValueT VmladOpcode = B6;
   3162   emitVFPddd(Cond, VmladOpcode, OpDd, OpDn, OpDm, Vmlad);
   3163 }
   3164 
   3165 void AssemblerARM32::vmlss(const Operand *OpSd, const Operand *OpSn,
   3166                            const Operand *OpSm, CondARM32::Cond Cond) {
   3167   // VMLA, VMLS (floating-point), ARM section A8.8.337, encoding A2:
   3168   //   vmls<c>.f32 <Sd>, <Sn>, <Sm>
   3169   //
   3170   // cccc11100d00nnnndddd1010n1M0mmmm where cccc=Cond, ddddD=Sd, nnnnN=Sn, and
   3171   // mmmmM=Sm
   3172   constexpr const char *Vmlas = "vmlas";
   3173   constexpr IValueT VmlasOpcode = B6;
   3174   emitVFPsss(Cond, VmlasOpcode, OpSd, OpSn, OpSm, Vmlas);
   3175 }
   3176 
   3177 void AssemblerARM32::vmrsAPSR_nzcv(CondARM32::Cond Cond) {
   3178   // MVRS - ARM section A*.8.348, encoding A1:
   3179   //   vmrs<c> APSR_nzcv, FPSCR
   3180   //
   3181   // cccc111011110001tttt101000010000 where tttt=0x15 (i.e. when Rt=pc, use
   3182   // APSR_nzcv instead).
   3183   assert(CondARM32::isDefined(Cond));
   3184   IValueT Encoding = B27 | B26 | B25 | B23 | B22 | B21 | B20 | B16 | B15 | B14 |
   3185                      B13 | B12 | B11 | B9 | B4 |
   3186                      (encodeCondition(Cond) << kConditionShift);
   3187   emitInst(Encoding);
   3188 }
   3189 
   3190 void AssemblerARM32::vmuls(const Operand *OpSd, const Operand *OpSn,
   3191                            const Operand *OpSm, CondARM32::Cond Cond) {
   3192   // VMUL (floating-point) - ARM section A8.8.351, encoding A2:
   3193   //   vmul<c>.f32 <Sd>, <Sn>, <Sm>
   3194   //
   3195   // cccc11100D10nnnndddd101sN0M0mmmm where cccc=Cond, s=0, ddddD=Rd, nnnnN=Rn,
   3196   // and mmmmM=Rm.
   3197   constexpr const char *Vmuls = "vmuls";
   3198   constexpr IValueT VmulsOpcode = B21;
   3199   emitVFPsss(Cond, VmulsOpcode, OpSd, OpSn, OpSm, Vmuls);
   3200 }
   3201 
   3202 void AssemblerARM32::vmuld(const Operand *OpDd, const Operand *OpDn,
   3203                            const Operand *OpDm, CondARM32::Cond Cond) {
   3204   // VMUL (floating-point) - ARM section A8.8.351, encoding A2:
   3205   //   vmul<c>.f64 <Dd>, <Dn>, <Dm>
   3206   //
   3207   // cccc11100D10nnnndddd101sN0M0mmmm where cccc=Cond, s=1, Ddddd=Rd, Nnnnn=Rn,
   3208   // and Mmmmm=Rm.
   3209   constexpr const char *Vmuld = "vmuld";
   3210   constexpr IValueT VmuldOpcode = B21;
   3211   emitVFPddd(Cond, VmuldOpcode, OpDd, OpDn, OpDm, Vmuld);
   3212 }
   3213 
   3214 void AssemblerARM32::vmulqi(Type ElmtTy, const Operand *OpQd,
   3215                             const Operand *OpQn, const Operand *OpQm) {
   3216   // VMUL, VMULL (integer and polynomial) - ARM section A8.8.350, encoding A1:
   3217   //   vmul<c>.<dt> <Qd>, <Qn>, <Qm>
   3218   //
   3219   // 111100100Dssnnn0ddd01001NqM1mmm0 where Dddd=Qd, Nnnn=Qn, Mmmm=Qm, and
   3220   // dt in [i8, i16, i32] where ss is the index.
   3221   assert(isScalarIntegerType(ElmtTy) &&
   3222          "vmulqi expects vector with integer element type");
   3223   assert(ElmtTy != IceType_i64 && "vmulqi on i64 vector not allowed");
   3224   constexpr const char *Vmulqi = "vmulqi";
   3225   constexpr IValueT VmulqiOpcode = B11 | B8 | B4;
   3226   emitSIMDqqq(VmulqiOpcode, ElmtTy, OpQd, OpQn, OpQm, Vmulqi);
   3227 }
   3228 
   3229 void AssemblerARM32::vmulqf(const Operand *OpQd, const Operand *OpQn,
   3230                             const Operand *OpQm) {
   3231   // VMUL (floating-point) - ARM section A8.8.351, encoding A1:
   3232   //   vmul.f32 <Qd>, <Qn>, <Qm>
   3233   //
   3234   // 111100110D00nnn0ddd01101MqM1mmm0 where Dddd=Qd, Nnnn=Qn, and Mmmm=Qm.
   3235   assert(OpQd->getType() == IceType_v4f32 && "vmulqf expects type <4 x float>");
   3236   constexpr const char *Vmulqf = "vmulqf";
   3237   constexpr IValueT VmulqfOpcode = B24 | B11 | B8 | B4;
   3238   constexpr bool IsFloatTy = true;
   3239   emitSIMDqqqBase(VmulqfOpcode, OpQd, OpQn, OpQm, IsFloatTy, Vmulqf);
   3240 }
   3241 
   3242 void AssemblerARM32::vmvnq(const Operand *OpQd, const Operand *OpQm) {
   3243   // VMVN (integer) - ARM section A8.8.354, encoding A1:
   3244   //   vmvn <Qd>, <Qm>
   3245   //
   3246   // 111100111D110000dddd01011QM0mmmm where Dddd=Qd, Mmmm=Qm, and 1=Q.
   3247   // TODO(jpp) xxx: unify
   3248   constexpr const char *Vmvn = "vmvn";
   3249   constexpr IValueT VmvnOpcode = B24 | B23 | B21 | B20 | B10 | B8 | B7;
   3250   const IValueT Qd = encodeQRegister(OpQd, "Qd", Vmvn);
   3251   constexpr IValueT Qn = 0;
   3252   const IValueT Qm = encodeQRegister(OpQm, "Qm", Vmvn);
   3253   constexpr bool UseQRegs = true;
   3254   constexpr bool IsFloat = false;
   3255   emitSIMDBase(VmvnOpcode, mapQRegToDReg(Qd), mapQRegToDReg(Qn),
   3256                mapQRegToDReg(Qm), UseQRegs, IsFloat);
   3257 }
   3258 
   3259 void AssemblerARM32::vnegqs(Type ElmtTy, const Operand *OpQd,
   3260                             const Operand *OpQm) {
   3261   // VNEG - ARM section A8.8.355, encoding A1:
   3262   //   vneg.<dt> <Qd>, <Qm>
   3263   //
   3264   // 111111111D11ss01dddd0F111QM0mmmm where Dddd=Qd, and Mmmm=Qm, and:
   3265   //     * dt=s8  -> 00=ss, 0=F
   3266   //     * dt=s16 -> 01=ss, 0=F
   3267   //     * dt=s32 -> 10=ss, 0=F
   3268   //     * dt=s32 -> 10=ss, 1=F
   3269   constexpr const char *Vneg = "vneg";
   3270   constexpr IValueT VnegOpcode = B24 | B23 | B21 | B20 | B16 | B9 | B8 | B7;
   3271   const IValueT Qd = encodeQRegister(OpQd, "Qd", Vneg);
   3272   constexpr IValueT Qn = 0;
   3273   const IValueT Qm = encodeQRegister(OpQm, "Qm", Vneg);
   3274   constexpr bool UseQRegs = true;
   3275   constexpr IValueT ElmtShift = 18;
   3276   const IValueT ElmtSize = encodeElmtType(ElmtTy);
   3277   assert(Utils::IsUint(2, ElmtSize));
   3278   emitSIMDBase(VnegOpcode | (ElmtSize << ElmtShift), mapQRegToDReg(Qd),
   3279                mapQRegToDReg(Qn), mapQRegToDReg(Qm), UseQRegs,
   3280                isFloatingType(ElmtTy));
   3281 }
   3282 
   3283 void AssemblerARM32::vorrq(const Operand *OpQd, const Operand *OpQm,
   3284                            const Operand *OpQn) {
   3285   // VORR (register) - ARM section A8.8.360, encoding A1:
   3286   //   vorr <Qd>, <Qn>, <Qm>
   3287   //
   3288   // 111100100D10nnn0ddd00001N1M1mmm0 where Dddd=OpQd, Nnnn=OpQm, and Mmmm=OpQm.
   3289   constexpr const char *Vorrq = "vorrq";
   3290   constexpr IValueT VorrqOpcode = B21 | B8 | B4;
   3291   constexpr Type ElmtTy = IceType_i8;
   3292   emitSIMDqqq(VorrqOpcode, ElmtTy, OpQd, OpQm, OpQn, Vorrq);
   3293 }
   3294 
   3295 void AssemblerARM32::vstrd(const Operand *OpDd, const Operand *OpAddress,
   3296                            CondARM32::Cond Cond, const TargetInfo &TInfo) {
   3297   // VSTR - ARM section A8.8.413, encoding A1:
   3298   //   vstr<c> <Dd>, [<Rn>{, #+/-<Imm>}]
   3299   //
   3300   // cccc1101UD00nnnndddd1011iiiiiiii where cccc=Cond, nnnn=Rn, Ddddd=Rd,
   3301   // iiiiiiii=abs(Imm >> 2), and U=1 if Imm>=0.
   3302   constexpr const char *Vstrd = "vstrd";
   3303   IValueT Dd = encodeDRegister(OpDd, "Dd", Vstrd);
   3304   assert(CondARM32::isDefined(Cond));
   3305   IValueT Address;
   3306   IValueT AddressEncoding =
   3307       encodeAddress(OpAddress, Address, TInfo, RotatedImm8Div4Address);
   3308   (void)AddressEncoding;
   3309   assert(AddressEncoding == EncodedAsImmRegOffset);
   3310   IValueT Encoding = B27 | B26 | B24 | B11 | B9 | B8 |
   3311                      (encodeCondition(Cond) << kConditionShift) |
   3312                      (getYInRegYXXXX(Dd) << 22) |
   3313                      (getXXXXInRegYXXXX(Dd) << 12) | Address;
   3314   emitInst(Encoding);
   3315 }
   3316 
   3317 void AssemblerARM32::vstrs(const Operand *OpSd, const Operand *OpAddress,
   3318                            CondARM32::Cond Cond, const TargetInfo &TInfo) {
   3319   // VSTR - ARM section A8.8.413, encoding A2:
   3320   //   vstr<c> <Sd>, [<Rn>{, #+/-<imm>]]
   3321   //
   3322   // cccc1101UD01nnnndddd1010iiiiiiii where cccc=Cond, nnnn=Rn, ddddD=Sd,
   3323   // iiiiiiii=abs(Opcode), and U=1 if Opcode >= 0;
   3324   constexpr const char *Vstrs = "vstrs";
   3325   IValueT Sd = encodeSRegister(OpSd, "Sd", Vstrs);
   3326   assert(CondARM32::isDefined(Cond));
   3327   IValueT Address;
   3328   IValueT AddressEncoding =
   3329       encodeAddress(OpAddress, Address, TInfo, RotatedImm8Div4Address);
   3330   (void)AddressEncoding;
   3331   assert(AddressEncoding == EncodedAsImmRegOffset);
   3332   IValueT Encoding =
   3333       B27 | B26 | B24 | B11 | B9 | (encodeCondition(Cond) << kConditionShift) |
   3334       (getYInRegXXXXY(Sd) << 22) | (getXXXXInRegXXXXY(Sd) << 12) | Address;
   3335   emitInst(Encoding);
   3336 }
   3337 
   3338 void AssemblerARM32::vst1qr(size_t ElmtSize, const Operand *OpQd,
   3339                             const Operand *OpAddress, const TargetInfo &TInfo) {
   3340   // VST1 (multiple single elements) - ARM section A8.8.404, encoding A1:
   3341   //   vst1.<size> <Qd>, [<Rn>]
   3342   //
   3343   // 111101000D00nnnnddd0ttttssaammmm where tttt=DRegListSize2, Dddd=Qd,
   3344   // nnnn=Rn, aa=0 (use default alignment), size=ElmtSize, and ss is the
   3345   // encoding of ElmtSize.
   3346   constexpr const char *Vst1qr = "vst1qr";
   3347   const IValueT Qd = encodeQRegister(OpQd, "Qd", Vst1qr);
   3348   const IValueT Dd = mapQRegToDReg(Qd);
   3349   IValueT Address;
   3350   if (encodeAddress(OpAddress, Address, TInfo, NoImmOffsetAddress) !=
   3351       EncodedAsImmRegOffset)
   3352     llvm::report_fatal_error(std::string(Vst1qr) + ": malform memory address");
   3353   const IValueT Rn = mask(Address, kRnShift, 4);
   3354   constexpr IValueT Rm = RegARM32::Reg_pc;
   3355   constexpr IValueT Opcode = B26;
   3356   constexpr IValueT Align = 0; // use default alignment.
   3357   emitVMem1Op(Opcode, Dd, Rn, Rm, DRegListSize2, ElmtSize, Align, Vst1qr);
   3358 }
   3359 
   3360 void AssemblerARM32::vsubs(const Operand *OpSd, const Operand *OpSn,
   3361                            const Operand *OpSm, CondARM32::Cond Cond) {
   3362   // VSUB (floating-point) - ARM section A8.8.415, encoding A2:
   3363   //   vsub<c>.f32 <Sd>, <Sn>, <Sm>
   3364   //
   3365   // cccc11100D11nnnndddd101sN1M0mmmm where cccc=Cond, s=0, ddddD=Rd, nnnnN=Rn,
   3366   // and mmmmM=Rm.
   3367   constexpr const char *Vsubs = "vsubs";
   3368   constexpr IValueT VsubsOpcode = B21 | B20 | B6;
   3369   emitVFPsss(Cond, VsubsOpcode, OpSd, OpSn, OpSm, Vsubs);
   3370 }
   3371 
   3372 void AssemblerARM32::vsubd(const Operand *OpDd, const Operand *OpDn,
   3373                            const Operand *OpDm, CondARM32::Cond Cond) {
   3374   // VSUB (floating-point) - ARM section A8.8.415, encoding A2:
   3375   //   vsub<c>.f64 <Dd>, <Dn>, <Dm>
   3376   //
   3377   // cccc11100D11nnnndddd101sN1M0mmmm where cccc=Cond, s=1, Ddddd=Rd, Nnnnn=Rn,
   3378   // and Mmmmm=Rm.
   3379   constexpr const char *Vsubd = "vsubd";
   3380   constexpr IValueT VsubdOpcode = B21 | B20 | B6;
   3381   emitVFPddd(Cond, VsubdOpcode, OpDd, OpDn, OpDm, Vsubd);
   3382 }
   3383 
   3384 void AssemblerARM32::vsubqi(Type ElmtTy, const Operand *OpQd,
   3385                             const Operand *OpQm, const Operand *OpQn) {
   3386   // VSUB (integer) - ARM section A8.8.414, encoding A1:
   3387   //   vsub.<dt> <Qd>, <Qn>, <Qm>
   3388   //
   3389   // 111100110Dssnnn0ddd01000N1M0mmm0 where Dddd=OpQd, Nnnn=OpQm, Mmmm=OpQm,
   3390   // and dt in [i8, i16, i32, i64] where ss is the index.
   3391   assert(isScalarIntegerType(ElmtTy) &&
   3392          "vsubqi expects vector with integer element type");
   3393   constexpr const char *Vsubqi = "vsubqi";
   3394   constexpr IValueT VsubqiOpcode = B24 | B11;
   3395   emitSIMDqqq(VsubqiOpcode, ElmtTy, OpQd, OpQm, OpQn, Vsubqi);
   3396 }
   3397 
   3398 void AssemblerARM32::vsubqf(const Operand *OpQd, const Operand *OpQn,
   3399                             const Operand *OpQm) {
   3400   // VSUB (floating-point) - ARM section A8.8.415, Encoding A1:
   3401   //   vsub.f32 <Qd>, <Qn>, <Qm>
   3402   //
   3403   // 111100100D10nnn0ddd01101N1M0mmm0 where Dddd=Qd, Nnnn=Qn, and Mmmm=Qm.
   3404   assert(OpQd->getType() == IceType_v4f32 && "vsubqf expects type <4 x float>");
   3405   constexpr const char *Vsubqf = "vsubqf";
   3406   constexpr IValueT VsubqfOpcode = B21 | B11 | B8;
   3407   emitSIMDqqq(VsubqfOpcode, IceType_f32, OpQd, OpQn, OpQm, Vsubqf);
   3408 }
   3409 
   3410 void AssemblerARM32::emitVStackOp(CondARM32::Cond Cond, IValueT Opcode,
   3411                                   const Variable *OpBaseReg,
   3412                                   SizeT NumConsecRegs) {
   3413   const IValueT BaseReg = getEncodedSRegNum(OpBaseReg);
   3414   const IValueT DLastBit = mask(BaseReg, 0, 1); // Last bit of base register.
   3415   const IValueT Rd = mask(BaseReg, 1, 4);       // Top 4 bits of base register.
   3416   assert(0 < NumConsecRegs);
   3417   (void)VpushVpopMaxConsecRegs;
   3418   assert(NumConsecRegs <= VpushVpopMaxConsecRegs);
   3419   assert((BaseReg + NumConsecRegs) <= RegARM32::getNumSRegs());
   3420   assert(CondARM32::isDefined(Cond));
   3421   const IValueT Encoding = Opcode | (Cond << kConditionShift) | DLastBit |
   3422                            (Rd << kRdShift) | NumConsecRegs;
   3423   emitInst(Encoding);
   3424 }
   3425 
   3426 void AssemblerARM32::vpop(const Variable *OpBaseReg, SizeT NumConsecRegs,
   3427                           CondARM32::Cond Cond) {
   3428   // Note: Current implementation assumes that OpBaseReg is defined using S
   3429   // registers. It doesn't implement the D register form.
   3430   //
   3431   // VPOP - ARM section A8.8.367, encoding A2:
   3432   //  vpop<c> <RegList>
   3433   //
   3434   // cccc11001D111101dddd1010iiiiiiii where cccc=Cond, ddddD=BaseReg, and
   3435   // iiiiiiii=NumConsecRegs.
   3436   constexpr IValueT VpopOpcode =
   3437       B27 | B26 | B23 | B21 | B20 | B19 | B18 | B16 | B11 | B9;
   3438   emitVStackOp(Cond, VpopOpcode, OpBaseReg, NumConsecRegs);
   3439 }
   3440 
   3441 void AssemblerARM32::vpush(const Variable *OpBaseReg, SizeT NumConsecRegs,
   3442                            CondARM32::Cond Cond) {
   3443   // Note: Current implementation assumes that OpBaseReg is defined using S
   3444   // registers. It doesn't implement the D register form.
   3445   //
   3446   // VPUSH - ARM section A8.8.368, encoding A2:
   3447   //   vpush<c> <RegList>
   3448   //
   3449   // cccc11010D101101dddd1010iiiiiiii where cccc=Cond, ddddD=BaseReg, and
   3450   // iiiiiiii=NumConsecRegs.
   3451   constexpr IValueT VpushOpcode =
   3452       B27 | B26 | B24 | B21 | B19 | B18 | B16 | B11 | B9;
   3453   emitVStackOp(Cond, VpushOpcode, OpBaseReg, NumConsecRegs);
   3454 }
   3455 
   3456 void AssemblerARM32::vshlqi(Type ElmtTy, const Operand *OpQd,
   3457                             const Operand *OpQm, const Operand *OpQn) {
   3458   // VSHL - ARM section A8.8.396, encoding A1:
   3459   //   vshl Qd, Qm, Qn
   3460   //
   3461   // 1111001U0Dssnnnndddd0100NQM0mmmm where Ddddd=Qd, Mmmmm=Qm, Nnnnn=Qn, 0=U,
   3462   // 1=Q
   3463   assert(isScalarIntegerType(ElmtTy) &&
   3464          "vshl expects vector with integer element type");
   3465   constexpr const char *Vshl = "vshl";
   3466   constexpr IValueT VshlOpcode = B10 | B6;
   3467   emitSIMDqqq(VshlOpcode, ElmtTy, OpQd, OpQn, OpQm, Vshl);
   3468 }
   3469 
   3470 namespace {
   3471 enum SIMDShiftType { ST_Vshl, ST_Vshr };
   3472 IValueT encodeSIMDShiftImm6(SIMDShiftType Shift, Type ElmtTy,
   3473                             const ConstantInteger32 *Imm6) {
   3474   const IValueT Imm = Imm6->getValue();
   3475   assert(Imm > 0);
   3476   const SizeT MaxShift = getScalarIntBitWidth(ElmtTy);
   3477   assert(Imm < MaxShift);
   3478   assert(ElmtTy == IceType_i8 || ElmtTy == IceType_i16 ||
   3479          ElmtTy == IceType_i32);
   3480   const IValueT VshlImm = Imm - MaxShift;
   3481   const IValueT VshrImm = 2 * MaxShift - Imm;
   3482   return ((Shift == ST_Vshl) ? VshlImm : VshrImm) & (2 * MaxShift - 1);
   3483 }
   3484 } // end of anonymous namespace
   3485 
   3486 void AssemblerARM32::vshlqc(Type ElmtTy, const Operand *OpQd,
   3487                             const Operand *OpQm,
   3488                             const ConstantInteger32 *Imm6) {
   3489   // VSHL - ARM section A8.8.395, encoding A1:
   3490   //   vshl Qd, Qm, #Imm
   3491   //
   3492   // 1111001U1Diiiiiidddd0101LQM1mmmm where Ddddd=Qd, Mmmmm=Qm, iiiiii=Imm6,
   3493   // 0=U, 1=Q, 0=L.
   3494   assert(isScalarIntegerType(ElmtTy) &&
   3495          "vshl expects vector with integer element type");
   3496   constexpr const char *Vshl = "vshl";
   3497   constexpr IValueT VshlOpcode = B23 | B10 | B8 | B4;
   3498   emitSIMDShiftqqc(VshlOpcode, OpQd, OpQm,
   3499                    encodeSIMDShiftImm6(ST_Vshl, ElmtTy, Imm6), Vshl);
   3500 }
   3501 
   3502 void AssemblerARM32::vshrqic(Type ElmtTy, const Operand *OpQd,
   3503                              const Operand *OpQm,
   3504                              const ConstantInteger32 *Imm6) {
   3505   // VSHR - ARM section A8.8.398, encoding A1:
   3506   //   vshr Qd, Qm, #Imm
   3507   //
   3508   // 1111001U1Diiiiiidddd0101LQM1mmmm where Ddddd=Qd, Mmmmm=Qm, iiiiii=Imm6,
   3509   // 0=U, 1=Q, 0=L.
   3510   assert(isScalarIntegerType(ElmtTy) &&
   3511          "vshr expects vector with integer element type");
   3512   constexpr const char *Vshr = "vshr";
   3513   constexpr IValueT VshrOpcode = B23 | B4;
   3514   emitSIMDShiftqqc(VshrOpcode, OpQd, OpQm,
   3515                    encodeSIMDShiftImm6(ST_Vshr, ElmtTy, Imm6), Vshr);
   3516 }
   3517 
   3518 void AssemblerARM32::vshrquc(Type ElmtTy, const Operand *OpQd,
   3519                              const Operand *OpQm,
   3520                              const ConstantInteger32 *Imm6) {
   3521   // VSHR - ARM section A8.8.398, encoding A1:
   3522   //   vshr Qd, Qm, #Imm
   3523   //
   3524   // 1111001U1Diiiiiidddd0101LQM1mmmm where Ddddd=Qd, Mmmmm=Qm, iiiiii=Imm6,
   3525   // 0=U, 1=Q, 0=L.
   3526   assert(isScalarIntegerType(ElmtTy) &&
   3527          "vshr expects vector with integer element type");
   3528   constexpr const char *Vshr = "vshr";
   3529   constexpr IValueT VshrOpcode = B23 | B4;
   3530   emitSIMDShiftqqc(VshrOpcode, OpQd, OpQm,
   3531                    encodeSIMDShiftImm6(ST_Vshr, ElmtTy, Imm6), Vshr);
   3532 }
   3533 
   3534 void AssemblerARM32::vshlqu(Type ElmtTy, const Operand *OpQd,
   3535                             const Operand *OpQm, const Operand *OpQn) {
   3536   // VSHL - ARM section A8.8.396, encoding A1:
   3537   //   vshl Qd, Qm, Qn
   3538   //
   3539   // 1111001U0Dssnnnndddd0100NQM0mmmm where Ddddd=Qd, Mmmmm=Qm, Nnnnn=Qn, 1=U,
   3540   // 1=Q
   3541   assert(isScalarIntegerType(ElmtTy) &&
   3542          "vshl expects vector with integer element type");
   3543   constexpr const char *Vshl = "vshl";
   3544   constexpr IValueT VshlOpcode = B24 | B10 | B6;
   3545   emitSIMDqqq(VshlOpcode, ElmtTy, OpQd, OpQn, OpQm, Vshl);
   3546 }
   3547 
   3548 void AssemblerARM32::vsqrtd(const Operand *OpDd, const Operand *OpDm,
   3549                             CondARM32::Cond Cond) {
   3550   // VSQRT - ARM section A8.8.401, encoding A1:
   3551   //   vsqrt<c>.f64 <Dd>, <Dm>
   3552   //
   3553   // cccc11101D110001dddd101111M0mmmm where cccc=Cond, Ddddd=Sd, and Mmmmm=Sm.
   3554   constexpr const char *Vsqrtd = "vsqrtd";
   3555   IValueT Dd = encodeDRegister(OpDd, "Dd", Vsqrtd);
   3556   IValueT Dm = encodeDRegister(OpDm, "Dm", Vsqrtd);
   3557   constexpr IValueT VsqrtdOpcode = B23 | B21 | B20 | B16 | B7 | B6;
   3558   constexpr IValueT D0 = 0;
   3559   emitVFPddd(Cond, VsqrtdOpcode, Dd, D0, Dm);
   3560 }
   3561 
   3562 void AssemblerARM32::vsqrts(const Operand *OpSd, const Operand *OpSm,
   3563                             CondARM32::Cond Cond) {
   3564   // VSQRT - ARM section A8.8.401, encoding A1:
   3565   //   vsqrt<c>.f32 <Sd>, <Sm>
   3566   //
   3567   // cccc11101D110001dddd101011M0mmmm where cccc=Cond, ddddD=Sd, and mmmmM=Sm.
   3568   constexpr const char *Vsqrts = "vsqrts";
   3569   IValueT Sd = encodeSRegister(OpSd, "Sd", Vsqrts);
   3570   IValueT Sm = encodeSRegister(OpSm, "Sm", Vsqrts);
   3571   constexpr IValueT VsqrtsOpcode = B23 | B21 | B20 | B16 | B7 | B6;
   3572   constexpr IValueT S0 = 0;
   3573   emitVFPsss(Cond, VsqrtsOpcode, Sd, S0, Sm);
   3574 }
   3575 
   3576 } // end of namespace ARM32
   3577 } // end of namespace Ice
   3578