• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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_MIPS_ASSEMBLER_MIPS_H_
18 #define ART_COMPILER_UTILS_MIPS_ASSEMBLER_MIPS_H_
19 
20 #include <vector>
21 
22 #include "base/macros.h"
23 #include "constants_mips.h"
24 #include "globals.h"
25 #include "managed_register_mips.h"
26 #include "utils/assembler.h"
27 #include "offsets.h"
28 
29 namespace art {
30 namespace mips {
31 
32 enum LoadOperandType {
33   kLoadSignedByte,
34   kLoadUnsignedByte,
35   kLoadSignedHalfword,
36   kLoadUnsignedHalfword,
37   kLoadWord,
38   kLoadWordPair,
39   kLoadSWord,
40   kLoadDWord
41 };
42 
43 enum StoreOperandType {
44   kStoreByte,
45   kStoreHalfword,
46   kStoreWord,
47   kStoreWordPair,
48   kStoreSWord,
49   kStoreDWord
50 };
51 
52 class MipsAssembler FINAL : public Assembler {
53  public:
MipsAssembler()54   MipsAssembler() {}
~MipsAssembler()55   virtual ~MipsAssembler() {}
56 
57   // Emit Machine Instructions.
58   void Add(Register rd, Register rs, Register rt);
59   void Addu(Register rd, Register rs, Register rt);
60   void Addi(Register rt, Register rs, uint16_t imm16);
61   void Addiu(Register rt, Register rs, uint16_t imm16);
62   void Sub(Register rd, Register rs, Register rt);
63   void Subu(Register rd, Register rs, Register rt);
64   void Mult(Register rs, Register rt);
65   void Multu(Register rs, Register rt);
66   void Div(Register rs, Register rt);
67   void Divu(Register rs, Register rt);
68 
69   void And(Register rd, Register rs, Register rt);
70   void Andi(Register rt, Register rs, uint16_t imm16);
71   void Or(Register rd, Register rs, Register rt);
72   void Ori(Register rt, Register rs, uint16_t imm16);
73   void Xor(Register rd, Register rs, Register rt);
74   void Xori(Register rt, Register rs, uint16_t imm16);
75   void Nor(Register rd, Register rs, Register rt);
76 
77   void Sll(Register rd, Register rs, int shamt);
78   void Srl(Register rd, Register rs, int shamt);
79   void Sra(Register rd, Register rs, int shamt);
80   void Sllv(Register rd, Register rs, Register rt);
81   void Srlv(Register rd, Register rs, Register rt);
82   void Srav(Register rd, Register rs, Register rt);
83 
84   void Lb(Register rt, Register rs, uint16_t imm16);
85   void Lh(Register rt, Register rs, uint16_t imm16);
86   void Lw(Register rt, Register rs, uint16_t imm16);
87   void Lbu(Register rt, Register rs, uint16_t imm16);
88   void Lhu(Register rt, Register rs, uint16_t imm16);
89   void Lui(Register rt, uint16_t imm16);
90   void Mfhi(Register rd);
91   void Mflo(Register rd);
92 
93   void Sb(Register rt, Register rs, uint16_t imm16);
94   void Sh(Register rt, Register rs, uint16_t imm16);
95   void Sw(Register rt, Register rs, uint16_t imm16);
96 
97   void Slt(Register rd, Register rs, Register rt);
98   void Sltu(Register rd, Register rs, Register rt);
99   void Slti(Register rt, Register rs, uint16_t imm16);
100   void Sltiu(Register rt, Register rs, uint16_t imm16);
101 
102   void Beq(Register rt, Register rs, uint16_t imm16);
103   void Bne(Register rt, Register rs, uint16_t imm16);
104   void J(uint32_t address);
105   void Jal(uint32_t address);
106   void Jr(Register rs);
107   void Jalr(Register rs);
108 
109   void AddS(FRegister fd, FRegister fs, FRegister ft);
110   void SubS(FRegister fd, FRegister fs, FRegister ft);
111   void MulS(FRegister fd, FRegister fs, FRegister ft);
112   void DivS(FRegister fd, FRegister fs, FRegister ft);
113   void AddD(DRegister fd, DRegister fs, DRegister ft);
114   void SubD(DRegister fd, DRegister fs, DRegister ft);
115   void MulD(DRegister fd, DRegister fs, DRegister ft);
116   void DivD(DRegister fd, DRegister fs, DRegister ft);
117   void MovS(FRegister fd, FRegister fs);
118   void MovD(DRegister fd, DRegister fs);
119 
120   void Mfc1(Register rt, FRegister fs);
121   void Mtc1(FRegister ft, Register rs);
122   void Lwc1(FRegister ft, Register rs, uint16_t imm16);
123   void Ldc1(DRegister ft, Register rs, uint16_t imm16);
124   void Swc1(FRegister ft, Register rs, uint16_t imm16);
125   void Sdc1(DRegister ft, Register rs, uint16_t imm16);
126 
127   void Break();
128   void Nop();
129   void Move(Register rt, Register rs);
130   void Clear(Register rt);
131   void Not(Register rt, Register rs);
132   void Mul(Register rd, Register rs, Register rt);
133   void Div(Register rd, Register rs, Register rt);
134   void Rem(Register rd, Register rs, Register rt);
135 
136   void AddConstant(Register rt, Register rs, int32_t value);
137   void LoadImmediate(Register rt, int32_t value);
138 
139   void EmitLoad(ManagedRegister m_dst, Register src_register, int32_t src_offset, size_t size);
140   void LoadFromOffset(LoadOperandType type, Register reg, Register base, int32_t offset);
141   void LoadSFromOffset(FRegister reg, Register base, int32_t offset);
142   void LoadDFromOffset(DRegister reg, Register base, int32_t offset);
143   void StoreToOffset(StoreOperandType type, Register reg, Register base, int32_t offset);
144   void StoreFToOffset(FRegister reg, Register base, int32_t offset);
145   void StoreDToOffset(DRegister reg, Register base, int32_t offset);
146 
147   // Emit data (e.g. encoded instruction or immediate) to the instruction stream.
148   void Emit(int32_t value);
149   void EmitBranch(Register rt, Register rs, Label* label, bool equal);
150   void EmitJump(Label* label, bool link);
151   void Bind(Label* label, bool is_jump);
152 
153   //
154   // Overridden common assembler high-level functionality
155   //
156 
157   // Emit code that will create an activation on the stack
158   void BuildFrame(size_t frame_size, ManagedRegister method_reg,
159                   const std::vector<ManagedRegister>& callee_save_regs,
160                   const ManagedRegisterEntrySpills& entry_spills) OVERRIDE;
161 
162   // Emit code that will remove an activation from the stack
163   void RemoveFrame(size_t frame_size, const std::vector<ManagedRegister>& callee_save_regs)
164       OVERRIDE;
165 
166   void IncreaseFrameSize(size_t adjust) OVERRIDE;
167   void DecreaseFrameSize(size_t adjust) OVERRIDE;
168 
169   // Store routines
170   void Store(FrameOffset offs, ManagedRegister msrc, size_t size) OVERRIDE;
171   void StoreRef(FrameOffset dest, ManagedRegister msrc) OVERRIDE;
172   void StoreRawPtr(FrameOffset dest, ManagedRegister msrc) OVERRIDE;
173 
174   void StoreImmediateToFrame(FrameOffset dest, uint32_t imm, ManagedRegister mscratch) OVERRIDE;
175 
176   void StoreImmediateToThread32(ThreadOffset<4> dest, uint32_t imm, ManagedRegister mscratch)
177       OVERRIDE;
178 
179   void StoreStackOffsetToThread32(ThreadOffset<4> thr_offs, FrameOffset fr_offs,
180                                   ManagedRegister mscratch) OVERRIDE;
181 
182   void StoreStackPointerToThread32(ThreadOffset<4> thr_offs) OVERRIDE;
183 
184   void StoreSpanning(FrameOffset dest, ManagedRegister msrc, FrameOffset in_off,
185                      ManagedRegister mscratch) OVERRIDE;
186 
187   // Load routines
188   void Load(ManagedRegister mdest, FrameOffset src, size_t size) OVERRIDE;
189 
190   void LoadFromThread32(ManagedRegister mdest, ThreadOffset<4> src, size_t size) OVERRIDE;
191 
192   void LoadRef(ManagedRegister dest, FrameOffset src) OVERRIDE;
193 
194   void LoadRef(ManagedRegister mdest, ManagedRegister base, MemberOffset offs,
195                bool poison_reference) OVERRIDE;
196 
197   void LoadRawPtr(ManagedRegister mdest, ManagedRegister base, Offset offs) OVERRIDE;
198 
199   void LoadRawPtrFromThread32(ManagedRegister mdest, ThreadOffset<4> offs) OVERRIDE;
200 
201   // Copying routines
202   void Move(ManagedRegister mdest, ManagedRegister msrc, size_t size) OVERRIDE;
203 
204   void CopyRawPtrFromThread32(FrameOffset fr_offs, ThreadOffset<4> thr_offs,
205                               ManagedRegister mscratch) OVERRIDE;
206 
207   void CopyRawPtrToThread32(ThreadOffset<4> thr_offs, FrameOffset fr_offs,
208                             ManagedRegister mscratch) OVERRIDE;
209 
210   void CopyRef(FrameOffset dest, FrameOffset src, ManagedRegister mscratch) OVERRIDE;
211 
212   void Copy(FrameOffset dest, FrameOffset src, ManagedRegister mscratch, size_t size) OVERRIDE;
213 
214   void Copy(FrameOffset dest, ManagedRegister src_base, Offset src_offset, ManagedRegister mscratch,
215             size_t size) OVERRIDE;
216 
217   void Copy(ManagedRegister dest_base, Offset dest_offset, FrameOffset src,
218             ManagedRegister mscratch, size_t size) OVERRIDE;
219 
220   void Copy(FrameOffset dest, FrameOffset src_base, Offset src_offset, ManagedRegister mscratch,
221             size_t size) OVERRIDE;
222 
223   void Copy(ManagedRegister dest, Offset dest_offset, ManagedRegister src, Offset src_offset,
224             ManagedRegister mscratch, size_t size) OVERRIDE;
225 
226   void Copy(FrameOffset dest, Offset dest_offset, FrameOffset src, Offset src_offset,
227             ManagedRegister mscratch, size_t size) OVERRIDE;
228 
229   void MemoryBarrier(ManagedRegister) OVERRIDE;
230 
231   // Sign extension
232   void SignExtend(ManagedRegister mreg, size_t size) OVERRIDE;
233 
234   // Zero extension
235   void ZeroExtend(ManagedRegister mreg, size_t size) OVERRIDE;
236 
237   // Exploit fast access in managed code to Thread::Current()
238   void GetCurrentThread(ManagedRegister tr) OVERRIDE;
239   void GetCurrentThread(FrameOffset dest_offset, ManagedRegister mscratch) OVERRIDE;
240 
241   // Set up out_reg to hold a Object** into the handle scope, or to be null if the
242   // value is null and null_allowed. in_reg holds a possibly stale reference
243   // that can be used to avoid loading the handle scope entry to see if the value is
244   // null.
245   void CreateHandleScopeEntry(ManagedRegister out_reg, FrameOffset handlescope_offset,
246                               ManagedRegister in_reg, bool null_allowed) OVERRIDE;
247 
248   // Set up out_off to hold a Object** into the handle scope, or to be null if the
249   // value is null and null_allowed.
250   void CreateHandleScopeEntry(FrameOffset out_off, FrameOffset handlescope_offset,
251                               ManagedRegister mscratch, bool null_allowed) OVERRIDE;
252 
253   // src holds a handle scope entry (Object**) load this into dst
254   void LoadReferenceFromHandleScope(ManagedRegister dst, ManagedRegister src) OVERRIDE;
255 
256   // Heap::VerifyObject on src. In some cases (such as a reference to this) we
257   // know that src may not be null.
258   void VerifyObject(ManagedRegister src, bool could_be_null) OVERRIDE;
259   void VerifyObject(FrameOffset src, bool could_be_null) OVERRIDE;
260 
261   // Call to address held at [base+offset]
262   void Call(ManagedRegister base, Offset offset, ManagedRegister mscratch) OVERRIDE;
263   void Call(FrameOffset base, Offset offset, ManagedRegister mscratch) OVERRIDE;
264   void CallFromThread32(ThreadOffset<4> offset, ManagedRegister mscratch) OVERRIDE;
265 
266   // Generate code to check if Thread::Current()->exception_ is non-null
267   // and branch to a ExceptionSlowPath if it is.
268   void ExceptionPoll(ManagedRegister mscratch, size_t stack_adjust) OVERRIDE;
269 
270  private:
271   void EmitR(int opcode, Register rs, Register rt, Register rd, int shamt, int funct);
272   void EmitI(int opcode, Register rs, Register rt, uint16_t imm);
273   void EmitJ(int opcode, int address);
274   void EmitFR(int opcode, int fmt, FRegister ft, FRegister fs, FRegister fd, int funct);
275   void EmitFI(int opcode, int fmt, FRegister rt, uint16_t imm);
276 
277   int32_t EncodeBranchOffset(int offset, int32_t inst, bool is_jump);
278   int DecodeBranchOffset(int32_t inst, bool is_jump);
279 
280   DISALLOW_COPY_AND_ASSIGN(MipsAssembler);
281 };
282 
283 // Slowpath entered when Thread::Current()->_exception is non-null
284 class MipsExceptionSlowPath FINAL : public SlowPath {
285  public:
MipsExceptionSlowPath(MipsManagedRegister scratch,size_t stack_adjust)286   explicit MipsExceptionSlowPath(MipsManagedRegister scratch, size_t stack_adjust)
287       : scratch_(scratch), stack_adjust_(stack_adjust) {}
288   virtual void Emit(Assembler *sp_asm) OVERRIDE;
289  private:
290   const MipsManagedRegister scratch_;
291   const size_t stack_adjust_;
292 };
293 
294 }  // namespace mips
295 }  // namespace art
296 
297 #endif  // ART_COMPILER_UTILS_MIPS_ASSEMBLER_MIPS_H_
298