Home | History | Annotate | Download | only in arm
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef ART_COMPILER_UTILS_ARM_ASSEMBLER_ARM32_H_
     18 #define ART_COMPILER_UTILS_ARM_ASSEMBLER_ARM32_H_
     19 
     20 #include <vector>
     21 
     22 #include "base/logging.h"
     23 #include "constants_arm.h"
     24 #include "utils/arm/managed_register_arm.h"
     25 #include "utils/arm/assembler_arm.h"
     26 #include "offsets.h"
     27 
     28 namespace art {
     29 namespace arm {
     30 
     31 class Arm32Assembler FINAL : public ArmAssembler {
     32  public:
     33   explicit Arm32Assembler(ArenaAllocator* arena) : ArmAssembler(arena) {}
     34   virtual ~Arm32Assembler() {}
     35 
     36   bool IsThumb() const OVERRIDE {
     37     return false;
     38   }
     39 
     40   // Data-processing instructions.
     41   virtual void and_(Register rd, Register rn, const ShifterOperand& so,
     42                     Condition cond = AL, SetCc set_cc = kCcDontCare) OVERRIDE;
     43 
     44   virtual void eor(Register rd, Register rn, const ShifterOperand& so,
     45                    Condition cond = AL, SetCc set_cc = kCcDontCare) OVERRIDE;
     46 
     47   virtual void sub(Register rd, Register rn, const ShifterOperand& so,
     48                    Condition cond = AL, SetCc set_cc = kCcDontCare) OVERRIDE;
     49 
     50   virtual void rsb(Register rd, Register rn, const ShifterOperand& so,
     51                    Condition cond = AL, SetCc set_cc = kCcDontCare) OVERRIDE;
     52 
     53   virtual void add(Register rd, Register rn, const ShifterOperand& so,
     54                    Condition cond = AL, SetCc set_cc = kCcDontCare) OVERRIDE;
     55 
     56   virtual void adc(Register rd, Register rn, const ShifterOperand& so,
     57                    Condition cond = AL, SetCc set_cc = kCcDontCare) OVERRIDE;
     58 
     59   virtual void sbc(Register rd, Register rn, const ShifterOperand& so,
     60                    Condition cond = AL, SetCc set_cc = kCcDontCare) OVERRIDE;
     61 
     62   virtual void rsc(Register rd, Register rn, const ShifterOperand& so,
     63                    Condition cond = AL, SetCc set_cc = kCcDontCare) OVERRIDE;
     64 
     65   void tst(Register rn, const ShifterOperand& so, Condition cond = AL) OVERRIDE;
     66 
     67   void teq(Register rn, const ShifterOperand& so, Condition cond = AL) OVERRIDE;
     68 
     69   void cmp(Register rn, const ShifterOperand& so, Condition cond = AL) OVERRIDE;
     70 
     71   void cmn(Register rn, const ShifterOperand& so, Condition cond = AL) OVERRIDE;
     72 
     73   virtual void orr(Register rd, Register rn, const ShifterOperand& so,
     74                    Condition cond = AL, SetCc set_cc = kCcDontCare) OVERRIDE;
     75 
     76   virtual void orn(Register rd, Register rn, const ShifterOperand& so,
     77                    Condition cond = AL, SetCc set_cc = kCcDontCare) OVERRIDE;
     78 
     79   virtual void mov(Register rd, const ShifterOperand& so,
     80                    Condition cond = AL, SetCc set_cc = kCcDontCare) OVERRIDE;
     81 
     82   virtual void bic(Register rd, Register rn, const ShifterOperand& so,
     83                    Condition cond = AL, SetCc set_cc = kCcDontCare) OVERRIDE;
     84 
     85   virtual void mvn(Register rd, const ShifterOperand& so,
     86                    Condition cond = AL, SetCc set_cc = kCcDontCare) OVERRIDE;
     87 
     88   // Miscellaneous data-processing instructions.
     89   void clz(Register rd, Register rm, Condition cond = AL) OVERRIDE;
     90   void movw(Register rd, uint16_t imm16, Condition cond = AL) OVERRIDE;
     91   void movt(Register rd, uint16_t imm16, Condition cond = AL) OVERRIDE;
     92   void rbit(Register rd, Register rm, Condition cond = AL) OVERRIDE;
     93   void rev(Register rd, Register rm, Condition cond = AL) OVERRIDE;
     94   void rev16(Register rd, Register rm, Condition cond = AL) OVERRIDE;
     95   void revsh(Register rd, Register rm, Condition cond = AL) OVERRIDE;
     96 
     97   // Multiply instructions.
     98   void mul(Register rd, Register rn, Register rm, Condition cond = AL) OVERRIDE;
     99   void mla(Register rd, Register rn, Register rm, Register ra,
    100            Condition cond = AL) OVERRIDE;
    101   void mls(Register rd, Register rn, Register rm, Register ra,
    102            Condition cond = AL) OVERRIDE;
    103   void smull(Register rd_lo, Register rd_hi, Register rn, Register rm,
    104              Condition cond = AL) OVERRIDE;
    105   void umull(Register rd_lo, Register rd_hi, Register rn, Register rm,
    106              Condition cond = AL) OVERRIDE;
    107 
    108   void sdiv(Register rd, Register rn, Register rm, Condition cond = AL) OVERRIDE;
    109   void udiv(Register rd, Register rn, Register rm, Condition cond = AL) OVERRIDE;
    110 
    111   // Bit field extract instructions.
    112   void sbfx(Register rd, Register rn, uint32_t lsb, uint32_t width, Condition cond = AL) OVERRIDE;
    113   void ubfx(Register rd, Register rn, uint32_t lsb, uint32_t width, Condition cond = AL) OVERRIDE;
    114 
    115   // Load/store instructions.
    116   void ldr(Register rd, const Address& ad, Condition cond = AL) OVERRIDE;
    117   void str(Register rd, const Address& ad, Condition cond = AL) OVERRIDE;
    118 
    119   void ldrb(Register rd, const Address& ad, Condition cond = AL) OVERRIDE;
    120   void strb(Register rd, const Address& ad, Condition cond = AL) OVERRIDE;
    121 
    122   void ldrh(Register rd, const Address& ad, Condition cond = AL) OVERRIDE;
    123   void strh(Register rd, const Address& ad, Condition cond = AL) OVERRIDE;
    124 
    125   void ldrsb(Register rd, const Address& ad, Condition cond = AL) OVERRIDE;
    126   void ldrsh(Register rd, const Address& ad, Condition cond = AL) OVERRIDE;
    127 
    128   void ldrd(Register rd, const Address& ad, Condition cond = AL) OVERRIDE;
    129   void strd(Register rd, const Address& ad, Condition cond = AL) OVERRIDE;
    130 
    131   void ldm(BlockAddressMode am, Register base,
    132            RegList regs, Condition cond = AL) OVERRIDE;
    133   void stm(BlockAddressMode am, Register base,
    134            RegList regs, Condition cond = AL) OVERRIDE;
    135 
    136   void ldrex(Register rd, Register rn, Condition cond = AL) OVERRIDE;
    137   void strex(Register rd, Register rt, Register rn, Condition cond = AL) OVERRIDE;
    138   void ldrexd(Register rt, Register rt2, Register rn, Condition cond = AL) OVERRIDE;
    139   void strexd(Register rd, Register rt, Register rt2, Register rn, Condition cond = AL) OVERRIDE;
    140 
    141   // Miscellaneous instructions.
    142   void clrex(Condition cond = AL) OVERRIDE;
    143   void nop(Condition cond = AL) OVERRIDE;
    144 
    145   // Note that gdb sets breakpoints using the undefined instruction 0xe7f001f0.
    146   void bkpt(uint16_t imm16) OVERRIDE;
    147   void svc(uint32_t imm24) OVERRIDE;
    148 
    149   void cbz(Register rn, Label* target) OVERRIDE;
    150   void cbnz(Register rn, Label* target) OVERRIDE;
    151 
    152   // Floating point instructions (VFPv3-D16 and VFPv3-D32 profiles).
    153   void vmovsr(SRegister sn, Register rt, Condition cond = AL) OVERRIDE;
    154   void vmovrs(Register rt, SRegister sn, Condition cond = AL) OVERRIDE;
    155   void vmovsrr(SRegister sm, Register rt, Register rt2, Condition cond = AL) OVERRIDE;
    156   void vmovrrs(Register rt, Register rt2, SRegister sm, Condition cond = AL) OVERRIDE;
    157   void vmovdrr(DRegister dm, Register rt, Register rt2, Condition cond = AL) OVERRIDE;
    158   void vmovrrd(Register rt, Register rt2, DRegister dm, Condition cond = AL) OVERRIDE;
    159   void vmovs(SRegister sd, SRegister sm, Condition cond = AL) OVERRIDE;
    160   void vmovd(DRegister dd, DRegister dm, Condition cond = AL) OVERRIDE;
    161 
    162   // Returns false if the immediate cannot be encoded.
    163   bool vmovs(SRegister sd, float s_imm, Condition cond = AL) OVERRIDE;
    164   bool vmovd(DRegister dd, double d_imm, Condition cond = AL) OVERRIDE;
    165 
    166   void vldrs(SRegister sd, const Address& ad, Condition cond = AL) OVERRIDE;
    167   void vstrs(SRegister sd, const Address& ad, Condition cond = AL) OVERRIDE;
    168   void vldrd(DRegister dd, const Address& ad, Condition cond = AL) OVERRIDE;
    169   void vstrd(DRegister dd, const Address& ad, Condition cond = AL) OVERRIDE;
    170 
    171   void vadds(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL) OVERRIDE;
    172   void vaddd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL) OVERRIDE;
    173   void vsubs(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL) OVERRIDE;
    174   void vsubd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL) OVERRIDE;
    175   void vmuls(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL) OVERRIDE;
    176   void vmuld(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL) OVERRIDE;
    177   void vmlas(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL) OVERRIDE;
    178   void vmlad(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL) OVERRIDE;
    179   void vmlss(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL) OVERRIDE;
    180   void vmlsd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL) OVERRIDE;
    181   void vdivs(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL) OVERRIDE;
    182   void vdivd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL) OVERRIDE;
    183 
    184   void vabss(SRegister sd, SRegister sm, Condition cond = AL) OVERRIDE;
    185   void vabsd(DRegister dd, DRegister dm, Condition cond = AL) OVERRIDE;
    186   void vnegs(SRegister sd, SRegister sm, Condition cond = AL) OVERRIDE;
    187   void vnegd(DRegister dd, DRegister dm, Condition cond = AL) OVERRIDE;
    188   void vsqrts(SRegister sd, SRegister sm, Condition cond = AL) OVERRIDE;
    189   void vsqrtd(DRegister dd, DRegister dm, Condition cond = AL) OVERRIDE;
    190 
    191   void vcvtsd(SRegister sd, DRegister dm, Condition cond = AL) OVERRIDE;
    192   void vcvtds(DRegister dd, SRegister sm, Condition cond = AL) OVERRIDE;
    193   void vcvtis(SRegister sd, SRegister sm, Condition cond = AL) OVERRIDE;
    194   void vcvtid(SRegister sd, DRegister dm, Condition cond = AL) OVERRIDE;
    195   void vcvtsi(SRegister sd, SRegister sm, Condition cond = AL) OVERRIDE;
    196   void vcvtdi(DRegister dd, SRegister sm, Condition cond = AL) OVERRIDE;
    197   void vcvtus(SRegister sd, SRegister sm, Condition cond = AL) OVERRIDE;
    198   void vcvtud(SRegister sd, DRegister dm, Condition cond = AL) OVERRIDE;
    199   void vcvtsu(SRegister sd, SRegister sm, Condition cond = AL) OVERRIDE;
    200   void vcvtdu(DRegister dd, SRegister sm, Condition cond = AL) OVERRIDE;
    201 
    202   void vcmps(SRegister sd, SRegister sm, Condition cond = AL) OVERRIDE;
    203   void vcmpd(DRegister dd, DRegister dm, Condition cond = AL) OVERRIDE;
    204   void vcmpsz(SRegister sd, Condition cond = AL) OVERRIDE;
    205   void vcmpdz(DRegister dd, Condition cond = AL) OVERRIDE;
    206   void vmstat(Condition cond = AL) OVERRIDE;  // VMRS APSR_nzcv, FPSCR
    207 
    208   void vpushs(SRegister reg, int nregs, Condition cond = AL) OVERRIDE;
    209   void vpushd(DRegister reg, int nregs, Condition cond = AL) OVERRIDE;
    210   void vpops(SRegister reg, int nregs, Condition cond = AL) OVERRIDE;
    211   void vpopd(DRegister reg, int nregs, Condition cond = AL) OVERRIDE;
    212 
    213   // Branch instructions.
    214   void b(Label* label, Condition cond = AL) OVERRIDE;
    215   void bl(Label* label, Condition cond = AL) OVERRIDE;
    216   void blx(Register rm, Condition cond = AL) OVERRIDE;
    217   void bx(Register rm, Condition cond = AL) OVERRIDE;
    218   virtual void Lsl(Register rd, Register rm, uint32_t shift_imm,
    219                    Condition cond = AL, SetCc set_cc = kCcDontCare) OVERRIDE;
    220   virtual void Lsr(Register rd, Register rm, uint32_t shift_imm,
    221                    Condition cond = AL, SetCc set_cc = kCcDontCare) OVERRIDE;
    222   virtual void Asr(Register rd, Register rm, uint32_t shift_imm,
    223                    Condition cond = AL, SetCc set_cc = kCcDontCare) OVERRIDE;
    224   virtual void Ror(Register rd, Register rm, uint32_t shift_imm,
    225                    Condition cond = AL, SetCc set_cc = kCcDontCare) OVERRIDE;
    226   virtual void Rrx(Register rd, Register rm,
    227                    Condition cond = AL, SetCc set_cc = kCcDontCare) OVERRIDE;
    228 
    229   virtual void Lsl(Register rd, Register rm, Register rn,
    230                    Condition cond = AL, SetCc set_cc = kCcDontCare) OVERRIDE;
    231   virtual void Lsr(Register rd, Register rm, Register rn,
    232                    Condition cond = AL, SetCc set_cc = kCcDontCare) OVERRIDE;
    233   virtual void Asr(Register rd, Register rm, Register rn,
    234                    Condition cond = AL, SetCc set_cc = kCcDontCare) OVERRIDE;
    235   virtual void Ror(Register rd, Register rm, Register rn,
    236                    Condition cond = AL, SetCc set_cc = kCcDontCare) OVERRIDE;
    237 
    238   void Push(Register rd, Condition cond = AL) OVERRIDE;
    239   void Pop(Register rd, Condition cond = AL) OVERRIDE;
    240 
    241   void PushList(RegList regs, Condition cond = AL) OVERRIDE;
    242   void PopList(RegList regs, Condition cond = AL) OVERRIDE;
    243 
    244   void Mov(Register rd, Register rm, Condition cond = AL) OVERRIDE;
    245 
    246   void CompareAndBranchIfZero(Register r, Label* label) OVERRIDE;
    247   void CompareAndBranchIfNonZero(Register r, Label* label) OVERRIDE;
    248 
    249   // Memory barriers.
    250   void dmb(DmbOptions flavor) OVERRIDE;
    251 
    252   // Get the final position of a label after local fixup based on the old position
    253   // recorded before FinalizeCode().
    254   uint32_t GetAdjustedPosition(uint32_t old_position) OVERRIDE;
    255 
    256   Literal* NewLiteral(size_t size, const uint8_t* data) OVERRIDE;
    257   void LoadLiteral(Register rt, Literal* literal) OVERRIDE;
    258   void LoadLiteral(Register rt, Register rt2, Literal* literal) OVERRIDE;
    259   void LoadLiteral(SRegister sd, Literal* literal) OVERRIDE;
    260   void LoadLiteral(DRegister dd, Literal* literal) OVERRIDE;
    261 
    262   // Add signed constant value to rd. May clobber IP.
    263   void AddConstant(Register rd, Register rn, int32_t value,
    264                    Condition cond = AL, SetCc set_cc = kCcDontCare) OVERRIDE;
    265 
    266   void CmpConstant(Register rn, int32_t value, Condition cond = AL) OVERRIDE;
    267 
    268   // Load and Store. May clobber IP.
    269   void LoadImmediate(Register rd, int32_t value, Condition cond = AL) OVERRIDE;
    270   void MarkExceptionHandler(Label* label) OVERRIDE;
    271   void LoadFromOffset(LoadOperandType type,
    272                       Register reg,
    273                       Register base,
    274                       int32_t offset,
    275                       Condition cond = AL) OVERRIDE;
    276   void StoreToOffset(StoreOperandType type,
    277                      Register reg,
    278                      Register base,
    279                      int32_t offset,
    280                      Condition cond = AL) OVERRIDE;
    281   void LoadSFromOffset(SRegister reg,
    282                        Register base,
    283                        int32_t offset,
    284                        Condition cond = AL) OVERRIDE;
    285   void StoreSToOffset(SRegister reg,
    286                       Register base,
    287                       int32_t offset,
    288                       Condition cond = AL) OVERRIDE;
    289   void LoadDFromOffset(DRegister reg,
    290                        Register base,
    291                        int32_t offset,
    292                        Condition cond = AL) OVERRIDE;
    293   void StoreDToOffset(DRegister reg,
    294                       Register base,
    295                       int32_t offset,
    296                       Condition cond = AL) OVERRIDE;
    297 
    298   bool ShifterOperandCanHold(Register rd,
    299                              Register rn,
    300                              Opcode opcode,
    301                              uint32_t immediate,
    302                              SetCc set_cc,
    303                              ShifterOperand* shifter_op) OVERRIDE;
    304   using ArmAssembler::ShifterOperandCanHold;  // Don't hide the non-virtual override.
    305 
    306   bool ShifterOperandCanAlwaysHold(uint32_t immediate) OVERRIDE;
    307 
    308   static bool IsInstructionForExceptionHandling(uintptr_t pc);
    309 
    310   // Emit data (e.g. encoded instruction or immediate) to the
    311   // instruction stream.
    312   void Emit(int32_t value);
    313   void Bind(Label* label) OVERRIDE;
    314 
    315   void MemoryBarrier(ManagedRegister scratch) OVERRIDE;
    316 
    317   JumpTable* CreateJumpTable(std::vector<Label*>&& labels, Register base_reg) OVERRIDE;
    318   void EmitJumpTableDispatch(JumpTable* jump_table, Register displacement_reg) OVERRIDE;
    319 
    320   void FinalizeCode() OVERRIDE;
    321 
    322  private:
    323   void EmitType01(Condition cond,
    324                   int type,
    325                   Opcode opcode,
    326                   SetCc set_cc,
    327                   Register rn,
    328                   Register rd,
    329                   const ShifterOperand& so);
    330 
    331   void EmitType5(Condition cond, int offset, bool link);
    332 
    333   void EmitMemOp(Condition cond,
    334                  bool load,
    335                  bool byte,
    336                  Register rd,
    337                  const Address& ad);
    338 
    339   void EmitMemOpAddressMode3(Condition cond,
    340                              int32_t mode,
    341                              Register rd,
    342                              const Address& ad);
    343 
    344   void EmitMultiMemOp(Condition cond,
    345                       BlockAddressMode am,
    346                       bool load,
    347                       Register base,
    348                       RegList regs);
    349 
    350   void EmitShiftImmediate(Condition cond,
    351                           Shift opcode,
    352                           Register rd,
    353                           Register rm,
    354                           const ShifterOperand& so);
    355 
    356   void EmitShiftRegister(Condition cond,
    357                          Shift opcode,
    358                          Register rd,
    359                          Register rm,
    360                          const ShifterOperand& so);
    361 
    362   void EmitMulOp(Condition cond,
    363                  int32_t opcode,
    364                  Register rd,
    365                  Register rn,
    366                  Register rm,
    367                  Register rs);
    368 
    369   void EmitVFPsss(Condition cond,
    370                   int32_t opcode,
    371                   SRegister sd,
    372                   SRegister sn,
    373                   SRegister sm);
    374 
    375   void EmitVFPddd(Condition cond,
    376                   int32_t opcode,
    377                   DRegister dd,
    378                   DRegister dn,
    379                   DRegister dm);
    380 
    381   void EmitVFPsd(Condition cond,
    382                  int32_t opcode,
    383                  SRegister sd,
    384                  DRegister dm);
    385 
    386   void EmitVFPds(Condition cond,
    387                  int32_t opcode,
    388                  DRegister dd,
    389                  SRegister sm);
    390 
    391   void EmitVPushPop(uint32_t reg, int nregs, bool push, bool dbl, Condition cond);
    392 
    393   void EmitMiscellaneous(Condition cond, uint8_t op1, uint8_t op2,
    394                          uint32_t a_part, uint32_t rest);
    395   void EmitReverseBytes(Register rd, Register rm, Condition cond,
    396                         uint8_t op1, uint8_t op2);
    397 
    398   void EmitBranch(Condition cond, Label* label, bool link);
    399   static int32_t EncodeBranchOffset(int offset, int32_t inst);
    400   static int DecodeBranchOffset(int32_t inst);
    401   bool ShifterOperandCanHoldArm32(uint32_t immediate, ShifterOperand* shifter_op);
    402 };
    403 
    404 }  // namespace arm
    405 }  // namespace art
    406 
    407 #endif  // ART_COMPILER_UTILS_ARM_ASSEMBLER_ARM32_H_
    408