• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(ArenaAllocator * arena)33   explicit Arm32Assembler(ArenaAllocator* arena) : ArmAssembler(arena) {}
~Arm32Assembler()34   virtual ~Arm32Assembler() {}
35 
IsThumb()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