blob: c1703137282c2e21cb3288d5b790f066a0ffcabf [file] [log] [blame]
Andreas Gampe57b34292015-01-14 15:45:59 -08001/*
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_MIPS64_ASSEMBLER_MIPS64_H_
18#define ART_COMPILER_UTILS_MIPS64_ASSEMBLER_MIPS64_H_
19
20#include <vector>
21
22#include "base/macros.h"
23#include "constants_mips64.h"
24#include "globals.h"
25#include "managed_register_mips64.h"
26#include "utils/assembler.h"
27#include "offsets.h"
Andreas Gampe57b34292015-01-14 15:45:59 -080028
29namespace art {
30namespace mips64 {
31
32enum LoadOperandType {
33 kLoadSignedByte,
34 kLoadUnsignedByte,
35 kLoadSignedHalfword,
36 kLoadUnsignedHalfword,
37 kLoadWord,
Douglas Leungd90957f2015-04-30 19:22:49 -070038 kLoadUnsignedWord,
Andreas Gampe57b34292015-01-14 15:45:59 -080039 kLoadDoubleword
40};
41
42enum StoreOperandType {
43 kStoreByte,
44 kStoreHalfword,
45 kStoreWord,
46 kStoreDoubleword
47};
48
49class Mips64Assembler FINAL : public Assembler {
50 public:
51 Mips64Assembler() {}
52 virtual ~Mips64Assembler() {}
53
54 // Emit Machine Instructions.
55 void Add(GpuRegister rd, GpuRegister rs, GpuRegister rt);
56 void Addi(GpuRegister rt, GpuRegister rs, uint16_t imm16);
57 void Addu(GpuRegister rd, GpuRegister rs, GpuRegister rt);
58 void Addiu(GpuRegister rt, GpuRegister rs, uint16_t imm16);
Alexey Frunze4dda3372015-06-01 18:31:49 -070059 void Daddu(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64
60 void Daddiu(GpuRegister rt, GpuRegister rs, uint16_t imm16); // MIPS64
Andreas Gampe57b34292015-01-14 15:45:59 -080061 void Sub(GpuRegister rd, GpuRegister rs, GpuRegister rt);
62 void Subu(GpuRegister rd, GpuRegister rs, GpuRegister rt);
Alexey Frunze4dda3372015-06-01 18:31:49 -070063 void Dsubu(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64
64
65 void MultR2(GpuRegister rs, GpuRegister rt); // R2
66 void MultuR2(GpuRegister rs, GpuRegister rt); // R2
67 void DivR2(GpuRegister rs, GpuRegister rt); // R2
68 void DivuR2(GpuRegister rs, GpuRegister rt); // R2
69 void MulR2(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R2
70 void DivR2(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R2
71 void ModR2(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R2
72 void DivuR2(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R2
73 void ModuR2(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R2
74 void MulR6(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R6
75 void DivR6(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R6
76 void ModR6(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R6
77 void DivuR6(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R6
78 void ModuR6(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R6
79 void Dmul(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64 R6
80 void Ddiv(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64 R6
81 void Dmod(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64 R6
82 void Ddivu(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64 R6
83 void Dmodu(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64 R6
Andreas Gampe57b34292015-01-14 15:45:59 -080084
85 void And(GpuRegister rd, GpuRegister rs, GpuRegister rt);
86 void Andi(GpuRegister rt, GpuRegister rs, uint16_t imm16);
87 void Or(GpuRegister rd, GpuRegister rs, GpuRegister rt);
88 void Ori(GpuRegister rt, GpuRegister rs, uint16_t imm16);
89 void Xor(GpuRegister rd, GpuRegister rs, GpuRegister rt);
90 void Xori(GpuRegister rt, GpuRegister rs, uint16_t imm16);
91 void Nor(GpuRegister rd, GpuRegister rs, GpuRegister rt);
92
Chris Larsen2fadd7b2015-08-14 14:56:10 -070093 void Bitswap(GpuRegister rd, GpuRegister rt); // R6
94 void Dbitswap(GpuRegister rd, GpuRegister rt); // R6
Alexey Frunze4dda3372015-06-01 18:31:49 -070095 void Seb(GpuRegister rd, GpuRegister rt); // R2+
96 void Seh(GpuRegister rd, GpuRegister rt); // R2+
Chris Larsen2fadd7b2015-08-14 14:56:10 -070097 void Dsbh(GpuRegister rd, GpuRegister rt); // R2+
98 void Dshd(GpuRegister rd, GpuRegister rt); // R2+
Alexey Frunze4dda3372015-06-01 18:31:49 -070099 void Dext(GpuRegister rs, GpuRegister rt, int pos, int size_less_one); // MIPS64
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700100 void Wsbh(GpuRegister rd, GpuRegister rt);
101 void Sc(GpuRegister rt, GpuRegister base, int16_t imm9 = 0);
102 void Scd(GpuRegister rt, GpuRegister base, int16_t imm9 = 0);
103 void Ll(GpuRegister rt, GpuRegister base, int16_t imm9 = 0);
104 void Lld(GpuRegister rt, GpuRegister base, int16_t imm9 = 0);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700105
106 void Sll(GpuRegister rd, GpuRegister rt, int shamt);
107 void Srl(GpuRegister rd, GpuRegister rt, int shamt);
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700108 void Rotr(GpuRegister rd, GpuRegister rt, int shamt);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700109 void Sra(GpuRegister rd, GpuRegister rt, int shamt);
110 void Sllv(GpuRegister rd, GpuRegister rt, GpuRegister rs);
111 void Srlv(GpuRegister rd, GpuRegister rt, GpuRegister rs);
112 void Srav(GpuRegister rd, GpuRegister rt, GpuRegister rs);
113 void Dsll(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64
114 void Dsrl(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64
115 void Dsra(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64
116 void Dsll32(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64
117 void Dsrl32(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64
118 void Dsra32(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64
119 void Dsllv(GpuRegister rd, GpuRegister rt, GpuRegister rs); // MIPS64
120 void Dsrlv(GpuRegister rd, GpuRegister rt, GpuRegister rs); // MIPS64
121 void Dsrav(GpuRegister rd, GpuRegister rt, GpuRegister rs); // MIPS64
Andreas Gampe57b34292015-01-14 15:45:59 -0800122
123 void Lb(GpuRegister rt, GpuRegister rs, uint16_t imm16);
124 void Lh(GpuRegister rt, GpuRegister rs, uint16_t imm16);
125 void Lw(GpuRegister rt, GpuRegister rs, uint16_t imm16);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700126 void Ld(GpuRegister rt, GpuRegister rs, uint16_t imm16); // MIPS64
Andreas Gampe57b34292015-01-14 15:45:59 -0800127 void Lbu(GpuRegister rt, GpuRegister rs, uint16_t imm16);
128 void Lhu(GpuRegister rt, GpuRegister rs, uint16_t imm16);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700129 void Lwu(GpuRegister rt, GpuRegister rs, uint16_t imm16); // MIPS64
Andreas Gampe57b34292015-01-14 15:45:59 -0800130 void Lui(GpuRegister rt, uint16_t imm16);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700131 void Dahi(GpuRegister rs, uint16_t imm16); // MIPS64 R6
132 void Dati(GpuRegister rs, uint16_t imm16); // MIPS64 R6
133 void Sync(uint32_t stype);
134 void Mfhi(GpuRegister rd); // R2
135 void Mflo(GpuRegister rd); // R2
Andreas Gampe57b34292015-01-14 15:45:59 -0800136
137 void Sb(GpuRegister rt, GpuRegister rs, uint16_t imm16);
138 void Sh(GpuRegister rt, GpuRegister rs, uint16_t imm16);
139 void Sw(GpuRegister rt, GpuRegister rs, uint16_t imm16);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700140 void Sd(GpuRegister rt, GpuRegister rs, uint16_t imm16); // MIPS64
Andreas Gampe57b34292015-01-14 15:45:59 -0800141
142 void Slt(GpuRegister rd, GpuRegister rs, GpuRegister rt);
143 void Sltu(GpuRegister rd, GpuRegister rs, GpuRegister rt);
144 void Slti(GpuRegister rt, GpuRegister rs, uint16_t imm16);
145 void Sltiu(GpuRegister rt, GpuRegister rs, uint16_t imm16);
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700146 void Seleqz(GpuRegister rd, GpuRegister rs, GpuRegister rt);
147 void Selnez(GpuRegister rd, GpuRegister rs, GpuRegister rt);
148 void Clz(GpuRegister rd, GpuRegister rs);
149 void Clo(GpuRegister rd, GpuRegister rs);
150 void Dclz(GpuRegister rd, GpuRegister rs);
151 void Dclo(GpuRegister rd, GpuRegister rs);
Andreas Gampe57b34292015-01-14 15:45:59 -0800152
Alexey Frunze4dda3372015-06-01 18:31:49 -0700153 void Beq(GpuRegister rs, GpuRegister rt, uint16_t imm16);
154 void Bne(GpuRegister rs, GpuRegister rt, uint16_t imm16);
155 void J(uint32_t addr26);
156 void Jal(uint32_t addr26);
157 void Jalr(GpuRegister rd, GpuRegister rs);
Andreas Gampe57b34292015-01-14 15:45:59 -0800158 void Jalr(GpuRegister rs);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700159 void Jr(GpuRegister rs);
160 void Auipc(GpuRegister rs, uint16_t imm16); // R6
161 void Jic(GpuRegister rt, uint16_t imm16); // R6
162 void Jialc(GpuRegister rt, uint16_t imm16); // R6
163 void Bltc(GpuRegister rs, GpuRegister rt, uint16_t imm16); // R6
164 void Bltzc(GpuRegister rt, uint16_t imm16); // R6
165 void Bgtzc(GpuRegister rt, uint16_t imm16); // R6
166 void Bgec(GpuRegister rs, GpuRegister rt, uint16_t imm16); // R6
167 void Bgezc(GpuRegister rt, uint16_t imm16); // R6
168 void Blezc(GpuRegister rt, uint16_t imm16); // R6
169 void Bltuc(GpuRegister rs, GpuRegister rt, uint16_t imm16); // R6
170 void Bgeuc(GpuRegister rs, GpuRegister rt, uint16_t imm16); // R6
171 void Beqc(GpuRegister rs, GpuRegister rt, uint16_t imm16); // R6
172 void Bnec(GpuRegister rs, GpuRegister rt, uint16_t imm16); // R6
173 void Beqzc(GpuRegister rs, uint32_t imm21); // R6
174 void Bnezc(GpuRegister rs, uint32_t imm21); // R6
Andreas Gampe57b34292015-01-14 15:45:59 -0800175
176 void AddS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
177 void SubS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
178 void MulS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
179 void DivS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
180 void AddD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
181 void SubD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
182 void MulD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
183 void DivD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700184 void SqrtS(FpuRegister fd, FpuRegister fs);
185 void SqrtD(FpuRegister fd, FpuRegister fs);
186 void AbsS(FpuRegister fd, FpuRegister fs);
187 void AbsD(FpuRegister fd, FpuRegister fs);
Andreas Gampe57b34292015-01-14 15:45:59 -0800188 void MovS(FpuRegister fd, FpuRegister fs);
189 void MovD(FpuRegister fd, FpuRegister fs);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700190 void NegS(FpuRegister fd, FpuRegister fs);
191 void NegD(FpuRegister fd, FpuRegister fs);
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700192 void RoundLS(FpuRegister fd, FpuRegister fs);
193 void RoundLD(FpuRegister fd, FpuRegister fs);
194 void RoundWS(FpuRegister fd, FpuRegister fs);
195 void RoundWD(FpuRegister fd, FpuRegister fs);
196 void CeilLS(FpuRegister fd, FpuRegister fs);
197 void CeilLD(FpuRegister fd, FpuRegister fs);
198 void CeilWS(FpuRegister fd, FpuRegister fs);
199 void CeilWD(FpuRegister fd, FpuRegister fs);
200 void FloorLS(FpuRegister fd, FpuRegister fs);
201 void FloorLD(FpuRegister fd, FpuRegister fs);
202 void FloorWS(FpuRegister fd, FpuRegister fs);
203 void FloorWD(FpuRegister fd, FpuRegister fs);
204 void SelS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
205 void SelD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
206 void RintS(FpuRegister fd, FpuRegister fs);
207 void RintD(FpuRegister fd, FpuRegister fs);
208 void ClassS(FpuRegister fd, FpuRegister fs);
209 void ClassD(FpuRegister fd, FpuRegister fs);
210 void MinS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
211 void MinD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
212 void MaxS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
213 void MaxD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700214
215 void Cvtsw(FpuRegister fd, FpuRegister fs);
216 void Cvtdw(FpuRegister fd, FpuRegister fs);
217 void Cvtsd(FpuRegister fd, FpuRegister fs);
218 void Cvtds(FpuRegister fd, FpuRegister fs);
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700219 void Cvtdl(FpuRegister fd, FpuRegister fs);
Andreas Gampe57b34292015-01-14 15:45:59 -0800220
221 void Mfc1(GpuRegister rt, FpuRegister fs);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700222 void Mtc1(GpuRegister rt, FpuRegister fs);
223 void Dmfc1(GpuRegister rt, FpuRegister fs); // MIPS64
224 void Dmtc1(GpuRegister rt, FpuRegister fs); // MIPS64
Andreas Gampe57b34292015-01-14 15:45:59 -0800225 void Lwc1(FpuRegister ft, GpuRegister rs, uint16_t imm16);
226 void Ldc1(FpuRegister ft, GpuRegister rs, uint16_t imm16);
227 void Swc1(FpuRegister ft, GpuRegister rs, uint16_t imm16);
228 void Sdc1(FpuRegister ft, GpuRegister rs, uint16_t imm16);
229
230 void Break();
231 void Nop();
Alexey Frunze4dda3372015-06-01 18:31:49 -0700232 void Move(GpuRegister rd, GpuRegister rs);
233 void Clear(GpuRegister rd);
234 void Not(GpuRegister rd, GpuRegister rs);
Andreas Gampe57b34292015-01-14 15:45:59 -0800235
Alexey Frunze4dda3372015-06-01 18:31:49 -0700236 // Higher level composite instructions
237 void LoadConst32(GpuRegister rd, int32_t value);
238 void LoadConst64(GpuRegister rd, int64_t value); // MIPS64
239
240 void Addiu32(GpuRegister rt, GpuRegister rs, int32_t value, GpuRegister rtmp = AT);
241 void Daddiu64(GpuRegister rt, GpuRegister rs, int64_t value, GpuRegister rtmp = AT); // MIPS64
242
Andreas Gampe85b62f22015-09-09 13:15:38 -0700243 void Bind(Label* label) OVERRIDE; // R6
244 void Jump(Label* label) OVERRIDE {
245 B(label);
246 }
Alexey Frunze4dda3372015-06-01 18:31:49 -0700247 void B(Label* label); // R6
248 void Jalr(Label* label, GpuRegister indirect_reg = RA); // R6
249 // TODO: implement common for R6 and non-R6 interface for conditional branches?
250 void Bltc(GpuRegister rs, GpuRegister rt, Label* label); // R6
251 void Bltzc(GpuRegister rt, Label* label); // R6
252 void Bgtzc(GpuRegister rt, Label* label); // R6
253 void Bgec(GpuRegister rs, GpuRegister rt, Label* label); // R6
254 void Bgezc(GpuRegister rt, Label* label); // R6
255 void Blezc(GpuRegister rt, Label* label); // R6
256 void Bltuc(GpuRegister rs, GpuRegister rt, Label* label); // R6
257 void Bgeuc(GpuRegister rs, GpuRegister rt, Label* label); // R6
258 void Beqc(GpuRegister rs, GpuRegister rt, Label* label); // R6
259 void Bnec(GpuRegister rs, GpuRegister rt, Label* label); // R6
260 void Beqzc(GpuRegister rs, Label* label); // R6
261 void Bnezc(GpuRegister rs, Label* label); // R6
Andreas Gampe57b34292015-01-14 15:45:59 -0800262
263 void EmitLoad(ManagedRegister m_dst, GpuRegister src_register, int32_t src_offset, size_t size);
264 void LoadFromOffset(LoadOperandType type, GpuRegister reg, GpuRegister base, int32_t offset);
265 void LoadFpuFromOffset(LoadOperandType type, FpuRegister reg, GpuRegister base, int32_t offset);
266 void StoreToOffset(StoreOperandType type, GpuRegister reg, GpuRegister base, int32_t offset);
267 void StoreFpuToOffset(StoreOperandType type, FpuRegister reg, GpuRegister base, int32_t offset);
268
269 // Emit data (e.g. encoded instruction or immediate) to the instruction stream.
Alexey Frunze4dda3372015-06-01 18:31:49 -0700270 void Emit(uint32_t value);
Andreas Gampe57b34292015-01-14 15:45:59 -0800271
272 //
273 // Overridden common assembler high-level functionality
274 //
275
276 // Emit code that will create an activation on the stack
277 void BuildFrame(size_t frame_size, ManagedRegister method_reg,
278 const std::vector<ManagedRegister>& callee_save_regs,
279 const ManagedRegisterEntrySpills& entry_spills) OVERRIDE;
280
281 // Emit code that will remove an activation from the stack
282 void RemoveFrame(size_t frame_size,
283 const std::vector<ManagedRegister>& callee_save_regs) OVERRIDE;
284
285 void IncreaseFrameSize(size_t adjust) OVERRIDE;
286 void DecreaseFrameSize(size_t adjust) OVERRIDE;
287
288 // Store routines
289 void Store(FrameOffset offs, ManagedRegister msrc, size_t size) OVERRIDE;
290 void StoreRef(FrameOffset dest, ManagedRegister msrc) OVERRIDE;
291 void StoreRawPtr(FrameOffset dest, ManagedRegister msrc) OVERRIDE;
292
293 void StoreImmediateToFrame(FrameOffset dest, uint32_t imm, ManagedRegister mscratch) OVERRIDE;
294
295 void StoreImmediateToThread64(ThreadOffset<8> dest, uint32_t imm,
296 ManagedRegister mscratch) OVERRIDE;
297
298 void StoreStackOffsetToThread64(ThreadOffset<8> thr_offs, FrameOffset fr_offs,
299 ManagedRegister mscratch) OVERRIDE;
300
301 void StoreStackPointerToThread64(ThreadOffset<8> thr_offs) OVERRIDE;
302
303 void StoreSpanning(FrameOffset dest, ManagedRegister msrc, FrameOffset in_off,
304 ManagedRegister mscratch) OVERRIDE;
305
306 // Load routines
307 void Load(ManagedRegister mdest, FrameOffset src, size_t size) OVERRIDE;
308
309 void LoadFromThread64(ManagedRegister mdest, ThreadOffset<8> src, size_t size) OVERRIDE;
310
Mathieu Chartiere401d142015-04-22 13:56:20 -0700311 void LoadRef(ManagedRegister dest, FrameOffset src) OVERRIDE;
Andreas Gampe57b34292015-01-14 15:45:59 -0800312
Mathieu Chartiere401d142015-04-22 13:56:20 -0700313 void LoadRef(ManagedRegister mdest, ManagedRegister base, MemberOffset offs,
Roland Levillain4d027112015-07-01 15:41:14 +0100314 bool unpoison_reference) OVERRIDE;
Andreas Gampe57b34292015-01-14 15:45:59 -0800315
316 void LoadRawPtr(ManagedRegister mdest, ManagedRegister base, Offset offs) OVERRIDE;
317
318 void LoadRawPtrFromThread64(ManagedRegister mdest, ThreadOffset<8> offs) OVERRIDE;
319
320 // Copying routines
321 void Move(ManagedRegister mdest, ManagedRegister msrc, size_t size) OVERRIDE;
322
323 void CopyRawPtrFromThread64(FrameOffset fr_offs, ThreadOffset<8> thr_offs,
324 ManagedRegister mscratch) OVERRIDE;
325
326 void CopyRawPtrToThread64(ThreadOffset<8> thr_offs, FrameOffset fr_offs,
327 ManagedRegister mscratch) OVERRIDE;
328
329 void CopyRef(FrameOffset dest, FrameOffset src, ManagedRegister mscratch) OVERRIDE;
330
331 void Copy(FrameOffset dest, FrameOffset src, ManagedRegister mscratch, size_t size) OVERRIDE;
332
333 void Copy(FrameOffset dest, ManagedRegister src_base, Offset src_offset, ManagedRegister mscratch,
334 size_t size) OVERRIDE;
335
336 void Copy(ManagedRegister dest_base, Offset dest_offset, FrameOffset src,
337 ManagedRegister mscratch, size_t size) OVERRIDE;
338
339 void Copy(FrameOffset dest, FrameOffset src_base, Offset src_offset, ManagedRegister mscratch,
340 size_t size) OVERRIDE;
341
342 void Copy(ManagedRegister dest, Offset dest_offset, ManagedRegister src, Offset src_offset,
343 ManagedRegister mscratch, size_t size) OVERRIDE;
344
345 void Copy(FrameOffset dest, Offset dest_offset, FrameOffset src, Offset src_offset,
346 ManagedRegister mscratch, size_t size) OVERRIDE;
347
348 void MemoryBarrier(ManagedRegister) OVERRIDE;
349
350 // Sign extension
351 void SignExtend(ManagedRegister mreg, size_t size) OVERRIDE;
352
353 // Zero extension
354 void ZeroExtend(ManagedRegister mreg, size_t size) OVERRIDE;
355
356 // Exploit fast access in managed code to Thread::Current()
357 void GetCurrentThread(ManagedRegister tr) OVERRIDE;
358 void GetCurrentThread(FrameOffset dest_offset, ManagedRegister mscratch) OVERRIDE;
359
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700360 // Set up out_reg to hold a Object** into the handle scope, or to be null if the
Andreas Gampe57b34292015-01-14 15:45:59 -0800361 // value is null and null_allowed. in_reg holds a possibly stale reference
362 // that can be used to avoid loading the handle scope entry to see if the value is
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700363 // null.
Andreas Gampe57b34292015-01-14 15:45:59 -0800364 void CreateHandleScopeEntry(ManagedRegister out_reg, FrameOffset handlescope_offset,
365 ManagedRegister in_reg, bool null_allowed) OVERRIDE;
366
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700367 // Set up out_off to hold a Object** into the handle scope, or to be null if the
Andreas Gampe57b34292015-01-14 15:45:59 -0800368 // value is null and null_allowed.
369 void CreateHandleScopeEntry(FrameOffset out_off, FrameOffset handlescope_offset, ManagedRegister
370 mscratch, bool null_allowed) OVERRIDE;
371
372 // src holds a handle scope entry (Object**) load this into dst
373 void LoadReferenceFromHandleScope(ManagedRegister dst, ManagedRegister src) OVERRIDE;
374
375 // Heap::VerifyObject on src. In some cases (such as a reference to this) we
376 // know that src may not be null.
377 void VerifyObject(ManagedRegister src, bool could_be_null) OVERRIDE;
378 void VerifyObject(FrameOffset src, bool could_be_null) OVERRIDE;
379
380 // Call to address held at [base+offset]
381 void Call(ManagedRegister base, Offset offset, ManagedRegister mscratch) OVERRIDE;
382 void Call(FrameOffset base, Offset offset, ManagedRegister mscratch) OVERRIDE;
383 void CallFromThread64(ThreadOffset<8> offset, ManagedRegister mscratch) OVERRIDE;
384
385 // Generate code to check if Thread::Current()->exception_ is non-null
386 // and branch to a ExceptionSlowPath if it is.
387 void ExceptionPoll(ManagedRegister mscratch, size_t stack_adjust) OVERRIDE;
388
389 private:
390 void EmitR(int opcode, GpuRegister rs, GpuRegister rt, GpuRegister rd, int shamt, int funct);
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700391 void EmitRsd(int opcode, GpuRegister rs, GpuRegister rd, int shamt, int funct);
392 void EmitRtd(int opcode, GpuRegister rt, GpuRegister rd, int shamt, int funct);
Andreas Gampe57b34292015-01-14 15:45:59 -0800393 void EmitI(int opcode, GpuRegister rs, GpuRegister rt, uint16_t imm);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700394 void EmitI21(int opcode, GpuRegister rs, uint32_t imm21);
395 void EmitJ(int opcode, uint32_t addr26);
Andreas Gampe57b34292015-01-14 15:45:59 -0800396 void EmitFR(int opcode, int fmt, FpuRegister ft, FpuRegister fs, FpuRegister fd, int funct);
397 void EmitFI(int opcode, int fmt, FpuRegister rt, uint16_t imm);
398
Andreas Gampe57b34292015-01-14 15:45:59 -0800399 DISALLOW_COPY_AND_ASSIGN(Mips64Assembler);
400};
401
402// Slowpath entered when Thread::Current()->_exception is non-null
403class Mips64ExceptionSlowPath FINAL : public SlowPath {
404 public:
Roland Levillain3887c462015-08-12 18:15:42 +0100405 Mips64ExceptionSlowPath(Mips64ManagedRegister scratch, size_t stack_adjust)
Andreas Gampe57b34292015-01-14 15:45:59 -0800406 : scratch_(scratch), stack_adjust_(stack_adjust) {}
407 virtual void Emit(Assembler *sp_asm) OVERRIDE;
408 private:
409 const Mips64ManagedRegister scratch_;
410 const size_t stack_adjust_;
411};
412
413} // namespace mips64
414} // namespace art
415
416#endif // ART_COMPILER_UTILS_MIPS64_ASSEMBLER_MIPS64_H_