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