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 #include "utils.h" 28 29 namespace art { 30 namespace arm { 31 32 class Arm32Assembler FINAL : public ArmAssembler { 33 public: Arm32Assembler()34 Arm32Assembler() { 35 } ~Arm32Assembler()36 virtual ~Arm32Assembler() {} 37 IsThumb()38 bool IsThumb() const OVERRIDE { 39 return false; 40 } 41 42 // Data-processing instructions. 43 void and_(Register rd, Register rn, const ShifterOperand& so, Condition cond = AL) OVERRIDE; 44 45 void eor(Register rd, Register rn, const ShifterOperand& so, Condition cond = AL) OVERRIDE; 46 47 void sub(Register rd, Register rn, const ShifterOperand& so, Condition cond = AL) OVERRIDE; 48 void subs(Register rd, Register rn, const ShifterOperand& so, Condition cond = AL) OVERRIDE; 49 50 void rsb(Register rd, Register rn, const ShifterOperand& so, Condition cond = AL) OVERRIDE; 51 void rsbs(Register rd, Register rn, const ShifterOperand& so, Condition cond = AL) OVERRIDE; 52 53 void add(Register rd, Register rn, const ShifterOperand& so, Condition cond = AL) OVERRIDE; 54 55 void adds(Register rd, Register rn, const ShifterOperand& so, Condition cond = AL) OVERRIDE; 56 57 void adc(Register rd, Register rn, const ShifterOperand& so, Condition cond = AL) OVERRIDE; 58 59 void sbc(Register rd, Register rn, const ShifterOperand& so, Condition cond = AL) OVERRIDE; 60 61 void rsc(Register rd, Register rn, const ShifterOperand& so, Condition cond = AL) OVERRIDE; 62 63 void tst(Register rn, const ShifterOperand& so, Condition cond = AL) OVERRIDE; 64 65 void teq(Register rn, const ShifterOperand& so, Condition cond = AL) OVERRIDE; 66 67 void cmp(Register rn, const ShifterOperand& so, Condition cond = AL) OVERRIDE; 68 69 void cmn(Register rn, const ShifterOperand& so, Condition cond = AL) OVERRIDE; 70 71 void orr(Register rd, Register rn, const ShifterOperand& so, Condition cond = AL) OVERRIDE; 72 void orrs(Register rd, Register rn, const ShifterOperand& so, Condition cond = AL) OVERRIDE; 73 74 void mov(Register rd, const ShifterOperand& so, Condition cond = AL) OVERRIDE; 75 void movs(Register rd, const ShifterOperand& so, Condition cond = AL) OVERRIDE; 76 77 void bic(Register rd, Register rn, const ShifterOperand& so, Condition cond = AL) OVERRIDE; 78 79 void mvn(Register rd, const ShifterOperand& so, Condition cond = AL) OVERRIDE; 80 void mvns(Register rd, const ShifterOperand& so, Condition cond = AL) OVERRIDE; 81 82 // Miscellaneous data-processing instructions. 83 void clz(Register rd, Register rm, Condition cond = AL) OVERRIDE; 84 void movw(Register rd, uint16_t imm16, Condition cond = AL) OVERRIDE; 85 void movt(Register rd, uint16_t imm16, Condition cond = AL) OVERRIDE; 86 87 // Multiply instructions. 88 void mul(Register rd, Register rn, Register rm, Condition cond = AL) OVERRIDE; 89 void mla(Register rd, Register rn, Register rm, Register ra, 90 Condition cond = AL) OVERRIDE; 91 void mls(Register rd, Register rn, Register rm, Register ra, 92 Condition cond = AL) OVERRIDE; 93 void umull(Register rd_lo, Register rd_hi, Register rn, Register rm, 94 Condition cond = AL) OVERRIDE; 95 96 void sdiv(Register rd, Register rn, Register rm, Condition cond = AL) OVERRIDE; 97 void udiv(Register rd, Register rn, Register rm, Condition cond = AL) OVERRIDE; 98 99 // Load/store instructions. 100 void ldr(Register rd, const Address& ad, Condition cond = AL) OVERRIDE; 101 void str(Register rd, const Address& ad, Condition cond = AL) OVERRIDE; 102 103 void ldrb(Register rd, const Address& ad, Condition cond = AL) OVERRIDE; 104 void strb(Register rd, const Address& ad, Condition cond = AL) OVERRIDE; 105 106 void ldrh(Register rd, const Address& ad, Condition cond = AL) OVERRIDE; 107 void strh(Register rd, const Address& ad, Condition cond = AL) OVERRIDE; 108 109 void ldrsb(Register rd, const Address& ad, Condition cond = AL) OVERRIDE; 110 void ldrsh(Register rd, const Address& ad, Condition cond = AL) OVERRIDE; 111 112 void ldrd(Register rd, const Address& ad, Condition cond = AL) OVERRIDE; 113 void strd(Register rd, const Address& ad, Condition cond = AL) OVERRIDE; 114 115 void ldm(BlockAddressMode am, Register base, 116 RegList regs, Condition cond = AL) OVERRIDE; 117 void stm(BlockAddressMode am, Register base, 118 RegList regs, Condition cond = AL) OVERRIDE; 119 120 void ldrex(Register rd, Register rn, Condition cond = AL) OVERRIDE; 121 void strex(Register rd, Register rt, Register rn, Condition cond = AL) OVERRIDE; 122 123 // Miscellaneous instructions. 124 void clrex(Condition cond = AL) OVERRIDE; 125 void nop(Condition cond = AL) OVERRIDE; 126 127 // Note that gdb sets breakpoints using the undefined instruction 0xe7f001f0. 128 void bkpt(uint16_t imm16) OVERRIDE; 129 void svc(uint32_t imm24) OVERRIDE; 130 131 void cbz(Register rn, Label* target) OVERRIDE; 132 void cbnz(Register rn, Label* target) OVERRIDE; 133 134 // Floating point instructions (VFPv3-D16 and VFPv3-D32 profiles). 135 void vmovsr(SRegister sn, Register rt, Condition cond = AL) OVERRIDE; 136 void vmovrs(Register rt, SRegister sn, Condition cond = AL) OVERRIDE; 137 void vmovsrr(SRegister sm, Register rt, Register rt2, Condition cond = AL) OVERRIDE; 138 void vmovrrs(Register rt, Register rt2, SRegister sm, Condition cond = AL) OVERRIDE; 139 void vmovdrr(DRegister dm, Register rt, Register rt2, Condition cond = AL) OVERRIDE; 140 void vmovrrd(Register rt, Register rt2, DRegister dm, Condition cond = AL) OVERRIDE; 141 void vmovs(SRegister sd, SRegister sm, Condition cond = AL) OVERRIDE; 142 void vmovd(DRegister dd, DRegister dm, Condition cond = AL) OVERRIDE; 143 144 // Returns false if the immediate cannot be encoded. 145 bool vmovs(SRegister sd, float s_imm, Condition cond = AL) OVERRIDE; 146 bool vmovd(DRegister dd, double d_imm, Condition cond = AL) OVERRIDE; 147 148 void vldrs(SRegister sd, const Address& ad, Condition cond = AL) OVERRIDE; 149 void vstrs(SRegister sd, const Address& ad, Condition cond = AL) OVERRIDE; 150 void vldrd(DRegister dd, const Address& ad, Condition cond = AL) OVERRIDE; 151 void vstrd(DRegister dd, const Address& ad, Condition cond = AL) OVERRIDE; 152 153 void vadds(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL) OVERRIDE; 154 void vaddd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL) OVERRIDE; 155 void vsubs(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL) OVERRIDE; 156 void vsubd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL) OVERRIDE; 157 void vmuls(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL) OVERRIDE; 158 void vmuld(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL) OVERRIDE; 159 void vmlas(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL) OVERRIDE; 160 void vmlad(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL) OVERRIDE; 161 void vmlss(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL) OVERRIDE; 162 void vmlsd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL) OVERRIDE; 163 void vdivs(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL) OVERRIDE; 164 void vdivd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL) OVERRIDE; 165 166 void vabss(SRegister sd, SRegister sm, Condition cond = AL) OVERRIDE; 167 void vabsd(DRegister dd, DRegister dm, Condition cond = AL) OVERRIDE; 168 void vnegs(SRegister sd, SRegister sm, Condition cond = AL) OVERRIDE; 169 void vnegd(DRegister dd, DRegister dm, Condition cond = AL) OVERRIDE; 170 void vsqrts(SRegister sd, SRegister sm, Condition cond = AL) OVERRIDE; 171 void vsqrtd(DRegister dd, DRegister dm, Condition cond = AL) OVERRIDE; 172 173 void vcvtsd(SRegister sd, DRegister dm, Condition cond = AL) OVERRIDE; 174 void vcvtds(DRegister dd, SRegister sm, Condition cond = AL) OVERRIDE; 175 void vcvtis(SRegister sd, SRegister sm, Condition cond = AL) OVERRIDE; 176 void vcvtid(SRegister sd, DRegister dm, Condition cond = AL) OVERRIDE; 177 void vcvtsi(SRegister sd, SRegister sm, Condition cond = AL) OVERRIDE; 178 void vcvtdi(DRegister dd, SRegister sm, Condition cond = AL) OVERRIDE; 179 void vcvtus(SRegister sd, SRegister sm, Condition cond = AL) OVERRIDE; 180 void vcvtud(SRegister sd, DRegister dm, Condition cond = AL) OVERRIDE; 181 void vcvtsu(SRegister sd, SRegister sm, Condition cond = AL) OVERRIDE; 182 void vcvtdu(DRegister dd, SRegister sm, Condition cond = AL) OVERRIDE; 183 184 void vcmps(SRegister sd, SRegister sm, Condition cond = AL) OVERRIDE; 185 void vcmpd(DRegister dd, DRegister dm, Condition cond = AL) OVERRIDE; 186 void vcmpsz(SRegister sd, Condition cond = AL) OVERRIDE; 187 void vcmpdz(DRegister dd, Condition cond = AL) OVERRIDE; 188 void vmstat(Condition cond = AL) OVERRIDE; // VMRS APSR_nzcv, FPSCR 189 190 void vpushs(SRegister reg, int nregs, Condition cond = AL) OVERRIDE; 191 void vpushd(DRegister reg, int nregs, Condition cond = AL) OVERRIDE; 192 void vpops(SRegister reg, int nregs, Condition cond = AL) OVERRIDE; 193 void vpopd(DRegister reg, int nregs, Condition cond = AL) OVERRIDE; 194 195 // Branch instructions. 196 void b(Label* label, Condition cond = AL); 197 void bl(Label* label, Condition cond = AL); 198 void blx(Register rm, Condition cond = AL) OVERRIDE; 199 void bx(Register rm, Condition cond = AL) OVERRIDE; 200 void Lsl(Register rd, Register rm, uint32_t shift_imm, bool setcc = false, 201 Condition cond = AL) OVERRIDE; 202 void Lsr(Register rd, Register rm, uint32_t shift_imm, bool setcc = false, 203 Condition cond = AL) OVERRIDE; 204 void Asr(Register rd, Register rm, uint32_t shift_imm, bool setcc = false, 205 Condition cond = AL) OVERRIDE; 206 void Ror(Register rd, Register rm, uint32_t shift_imm, bool setcc = false, 207 Condition cond = AL) OVERRIDE; 208 void Rrx(Register rd, Register rm, bool setcc = false, 209 Condition cond = AL) OVERRIDE; 210 211 void Lsl(Register rd, Register rm, Register rn, bool setcc = false, 212 Condition cond = AL) OVERRIDE; 213 void Lsr(Register rd, Register rm, Register rn, bool setcc = false, 214 Condition cond = AL) OVERRIDE; 215 void Asr(Register rd, Register rm, Register rn, bool setcc = false, 216 Condition cond = AL) OVERRIDE; 217 void Ror(Register rd, Register rm, Register rn, bool setcc = false, 218 Condition cond = AL) OVERRIDE; 219 220 void Push(Register rd, Condition cond = AL) OVERRIDE; 221 void Pop(Register rd, Condition cond = AL) OVERRIDE; 222 223 void PushList(RegList regs, Condition cond = AL) OVERRIDE; 224 void PopList(RegList regs, Condition cond = AL) OVERRIDE; 225 226 void Mov(Register rd, Register rm, Condition cond = AL) OVERRIDE; 227 228 void CompareAndBranchIfZero(Register r, Label* label) OVERRIDE; 229 void CompareAndBranchIfNonZero(Register r, Label* label) OVERRIDE; 230 231 232 // Macros. 233 // Add signed constant value to rd. May clobber IP. 234 void AddConstant(Register rd, int32_t value, Condition cond = AL) OVERRIDE; 235 void AddConstant(Register rd, Register rn, int32_t value, 236 Condition cond = AL) OVERRIDE; 237 void AddConstantSetFlags(Register rd, Register rn, int32_t value, 238 Condition cond = AL) OVERRIDE; 239 void AddConstantWithCarry(Register rd, Register rn, int32_t value, 240 Condition cond = AL) {} 241 242 // Load and Store. May clobber IP. 243 void LoadImmediate(Register rd, int32_t value, Condition cond = AL) OVERRIDE; 244 void LoadSImmediate(SRegister sd, float value, Condition cond = AL) {} 245 void LoadDImmediate(DRegister dd, double value, 246 Register scratch, Condition cond = AL) {} 247 void MarkExceptionHandler(Label* label) OVERRIDE; 248 void LoadFromOffset(LoadOperandType type, 249 Register reg, 250 Register base, 251 int32_t offset, 252 Condition cond = AL) OVERRIDE; 253 void StoreToOffset(StoreOperandType type, 254 Register reg, 255 Register base, 256 int32_t offset, 257 Condition cond = AL) OVERRIDE; 258 void LoadSFromOffset(SRegister reg, 259 Register base, 260 int32_t offset, 261 Condition cond = AL) OVERRIDE; 262 void StoreSToOffset(SRegister reg, 263 Register base, 264 int32_t offset, 265 Condition cond = AL) OVERRIDE; 266 void LoadDFromOffset(DRegister reg, 267 Register base, 268 int32_t offset, 269 Condition cond = AL) OVERRIDE; 270 void StoreDToOffset(DRegister reg, 271 Register base, 272 int32_t offset, 273 Condition cond = AL) OVERRIDE; 274 275 276 static bool IsInstructionForExceptionHandling(uword pc); 277 278 // Emit data (e.g. encoded instruction or immediate) to the 279 // instruction stream. 280 void Emit(int32_t value); 281 void Bind(Label* label) OVERRIDE; 282 283 void MemoryBarrier(ManagedRegister scratch) OVERRIDE; 284 285 private: 286 void EmitType01(Condition cond, 287 int type, 288 Opcode opcode, 289 int set_cc, 290 Register rn, 291 Register rd, 292 const ShifterOperand& so); 293 294 void EmitType5(Condition cond, int offset, bool link); 295 296 void EmitMemOp(Condition cond, 297 bool load, 298 bool byte, 299 Register rd, 300 const Address& ad); 301 302 void EmitMemOpAddressMode3(Condition cond, 303 int32_t mode, 304 Register rd, 305 const Address& ad); 306 307 void EmitMultiMemOp(Condition cond, 308 BlockAddressMode am, 309 bool load, 310 Register base, 311 RegList regs); 312 313 void EmitShiftImmediate(Condition cond, 314 Shift opcode, 315 Register rd, 316 Register rm, 317 const ShifterOperand& so); 318 319 void EmitShiftRegister(Condition cond, 320 Shift opcode, 321 Register rd, 322 Register rm, 323 const ShifterOperand& so); 324 325 void EmitMulOp(Condition cond, 326 int32_t opcode, 327 Register rd, 328 Register rn, 329 Register rm, 330 Register rs); 331 332 void EmitVFPsss(Condition cond, 333 int32_t opcode, 334 SRegister sd, 335 SRegister sn, 336 SRegister sm); 337 338 void EmitVFPddd(Condition cond, 339 int32_t opcode, 340 DRegister dd, 341 DRegister dn, 342 DRegister dm); 343 344 void EmitVFPsd(Condition cond, 345 int32_t opcode, 346 SRegister sd, 347 DRegister dm); 348 349 void EmitVFPds(Condition cond, 350 int32_t opcode, 351 DRegister dd, 352 SRegister sm); 353 354 void EmitVPushPop(uint32_t reg, int nregs, bool push, bool dbl, Condition cond); 355 356 void EmitBranch(Condition cond, Label* label, bool link); 357 static int32_t EncodeBranchOffset(int offset, int32_t inst); 358 static int DecodeBranchOffset(int32_t inst); 359 int32_t EncodeTstOffset(int offset, int32_t inst); 360 int DecodeTstOffset(int32_t inst); 361 }; 362 363 } // namespace arm 364 } // namespace art 365 366 #endif // ART_COMPILER_UTILS_ARM_ASSEMBLER_ARM32_H_ 367