blob: d083eb43060e022946f045188d25e031912c72f3 [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
Chris Larsen14500822015-10-01 11:35:18 -070049// Used to test the values returned by ClassS/ClassD.
50enum FPClassMaskType {
51 kSignalingNaN = 0x001,
52 kQuietNaN = 0x002,
53 kNegativeInfinity = 0x004,
54 kNegativeNormal = 0x008,
55 kNegativeSubnormal = 0x010,
56 kNegativeZero = 0x020,
57 kPositiveInfinity = 0x040,
58 kPositiveNormal = 0x080,
59 kPositiveSubnormal = 0x100,
60 kPositiveZero = 0x200,
61};
62
Andreas Gampe57b34292015-01-14 15:45:59 -080063class Mips64Assembler FINAL : public Assembler {
64 public:
65 Mips64Assembler() {}
66 virtual ~Mips64Assembler() {}
67
68 // Emit Machine Instructions.
69 void Add(GpuRegister rd, GpuRegister rs, GpuRegister rt);
70 void Addi(GpuRegister rt, GpuRegister rs, uint16_t imm16);
71 void Addu(GpuRegister rd, GpuRegister rs, GpuRegister rt);
72 void Addiu(GpuRegister rt, GpuRegister rs, uint16_t imm16);
Alexey Frunze4dda3372015-06-01 18:31:49 -070073 void Daddu(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64
74 void Daddiu(GpuRegister rt, GpuRegister rs, uint16_t imm16); // MIPS64
Andreas Gampe57b34292015-01-14 15:45:59 -080075 void Sub(GpuRegister rd, GpuRegister rs, GpuRegister rt);
76 void Subu(GpuRegister rd, GpuRegister rs, GpuRegister rt);
Alexey Frunze4dda3372015-06-01 18:31:49 -070077 void Dsubu(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64
78
79 void MultR2(GpuRegister rs, GpuRegister rt); // R2
80 void MultuR2(GpuRegister rs, GpuRegister rt); // R2
81 void DivR2(GpuRegister rs, GpuRegister rt); // R2
82 void DivuR2(GpuRegister rs, GpuRegister rt); // R2
83 void MulR2(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R2
84 void DivR2(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R2
85 void ModR2(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R2
86 void DivuR2(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R2
87 void ModuR2(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R2
88 void MulR6(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R6
89 void DivR6(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R6
90 void ModR6(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R6
91 void DivuR6(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R6
92 void ModuR6(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R6
93 void Dmul(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64 R6
94 void Ddiv(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64 R6
95 void Dmod(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64 R6
96 void Ddivu(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64 R6
97 void Dmodu(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64 R6
Andreas Gampe57b34292015-01-14 15:45:59 -080098
99 void And(GpuRegister rd, GpuRegister rs, GpuRegister rt);
100 void Andi(GpuRegister rt, GpuRegister rs, uint16_t imm16);
101 void Or(GpuRegister rd, GpuRegister rs, GpuRegister rt);
102 void Ori(GpuRegister rt, GpuRegister rs, uint16_t imm16);
103 void Xor(GpuRegister rd, GpuRegister rs, GpuRegister rt);
104 void Xori(GpuRegister rt, GpuRegister rs, uint16_t imm16);
105 void Nor(GpuRegister rd, GpuRegister rs, GpuRegister rt);
106
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700107 void Bitswap(GpuRegister rd, GpuRegister rt); // R6
108 void Dbitswap(GpuRegister rd, GpuRegister rt); // R6
Alexey Frunze4dda3372015-06-01 18:31:49 -0700109 void Seb(GpuRegister rd, GpuRegister rt); // R2+
110 void Seh(GpuRegister rd, GpuRegister rt); // R2+
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700111 void Dsbh(GpuRegister rd, GpuRegister rt); // R2+
112 void Dshd(GpuRegister rd, GpuRegister rt); // R2+
Alexey Frunze4dda3372015-06-01 18:31:49 -0700113 void Dext(GpuRegister rs, GpuRegister rt, int pos, int size_less_one); // MIPS64
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700114 void Wsbh(GpuRegister rd, GpuRegister rt);
115 void Sc(GpuRegister rt, GpuRegister base, int16_t imm9 = 0);
116 void Scd(GpuRegister rt, GpuRegister base, int16_t imm9 = 0);
117 void Ll(GpuRegister rt, GpuRegister base, int16_t imm9 = 0);
118 void Lld(GpuRegister rt, GpuRegister base, int16_t imm9 = 0);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700119
120 void Sll(GpuRegister rd, GpuRegister rt, int shamt);
121 void Srl(GpuRegister rd, GpuRegister rt, int shamt);
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700122 void Rotr(GpuRegister rd, GpuRegister rt, int shamt);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700123 void Sra(GpuRegister rd, GpuRegister rt, int shamt);
124 void Sllv(GpuRegister rd, GpuRegister rt, GpuRegister rs);
125 void Srlv(GpuRegister rd, GpuRegister rt, GpuRegister rs);
126 void Srav(GpuRegister rd, GpuRegister rt, GpuRegister rs);
127 void Dsll(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64
128 void Dsrl(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64
129 void Dsra(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64
130 void Dsll32(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64
131 void Dsrl32(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64
132 void Dsra32(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64
133 void Dsllv(GpuRegister rd, GpuRegister rt, GpuRegister rs); // MIPS64
134 void Dsrlv(GpuRegister rd, GpuRegister rt, GpuRegister rs); // MIPS64
135 void Dsrav(GpuRegister rd, GpuRegister rt, GpuRegister rs); // MIPS64
Andreas Gampe57b34292015-01-14 15:45:59 -0800136
137 void Lb(GpuRegister rt, GpuRegister rs, uint16_t imm16);
138 void Lh(GpuRegister rt, GpuRegister rs, uint16_t imm16);
139 void Lw(GpuRegister rt, GpuRegister rs, uint16_t imm16);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700140 void Ld(GpuRegister rt, GpuRegister rs, uint16_t imm16); // MIPS64
Andreas Gampe57b34292015-01-14 15:45:59 -0800141 void Lbu(GpuRegister rt, GpuRegister rs, uint16_t imm16);
142 void Lhu(GpuRegister rt, GpuRegister rs, uint16_t imm16);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700143 void Lwu(GpuRegister rt, GpuRegister rs, uint16_t imm16); // MIPS64
Andreas Gampe57b34292015-01-14 15:45:59 -0800144 void Lui(GpuRegister rt, uint16_t imm16);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700145 void Dahi(GpuRegister rs, uint16_t imm16); // MIPS64 R6
146 void Dati(GpuRegister rs, uint16_t imm16); // MIPS64 R6
147 void Sync(uint32_t stype);
148 void Mfhi(GpuRegister rd); // R2
149 void Mflo(GpuRegister rd); // R2
Andreas Gampe57b34292015-01-14 15:45:59 -0800150
151 void Sb(GpuRegister rt, GpuRegister rs, uint16_t imm16);
152 void Sh(GpuRegister rt, GpuRegister rs, uint16_t imm16);
153 void Sw(GpuRegister rt, GpuRegister rs, uint16_t imm16);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700154 void Sd(GpuRegister rt, GpuRegister rs, uint16_t imm16); // MIPS64
Andreas Gampe57b34292015-01-14 15:45:59 -0800155
156 void Slt(GpuRegister rd, GpuRegister rs, GpuRegister rt);
157 void Sltu(GpuRegister rd, GpuRegister rs, GpuRegister rt);
158 void Slti(GpuRegister rt, GpuRegister rs, uint16_t imm16);
159 void Sltiu(GpuRegister rt, GpuRegister rs, uint16_t imm16);
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700160 void Seleqz(GpuRegister rd, GpuRegister rs, GpuRegister rt);
161 void Selnez(GpuRegister rd, GpuRegister rs, GpuRegister rt);
162 void Clz(GpuRegister rd, GpuRegister rs);
163 void Clo(GpuRegister rd, GpuRegister rs);
164 void Dclz(GpuRegister rd, GpuRegister rs);
165 void Dclo(GpuRegister rd, GpuRegister rs);
Andreas Gampe57b34292015-01-14 15:45:59 -0800166
Alexey Frunze4dda3372015-06-01 18:31:49 -0700167 void Beq(GpuRegister rs, GpuRegister rt, uint16_t imm16);
168 void Bne(GpuRegister rs, GpuRegister rt, uint16_t imm16);
169 void J(uint32_t addr26);
170 void Jal(uint32_t addr26);
171 void Jalr(GpuRegister rd, GpuRegister rs);
Andreas Gampe57b34292015-01-14 15:45:59 -0800172 void Jalr(GpuRegister rs);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700173 void Jr(GpuRegister rs);
174 void Auipc(GpuRegister rs, uint16_t imm16); // R6
175 void Jic(GpuRegister rt, uint16_t imm16); // R6
176 void Jialc(GpuRegister rt, uint16_t imm16); // R6
177 void Bltc(GpuRegister rs, GpuRegister rt, uint16_t imm16); // R6
178 void Bltzc(GpuRegister rt, uint16_t imm16); // R6
179 void Bgtzc(GpuRegister rt, uint16_t imm16); // R6
180 void Bgec(GpuRegister rs, GpuRegister rt, uint16_t imm16); // R6
181 void Bgezc(GpuRegister rt, uint16_t imm16); // R6
182 void Blezc(GpuRegister rt, uint16_t imm16); // R6
183 void Bltuc(GpuRegister rs, GpuRegister rt, uint16_t imm16); // R6
184 void Bgeuc(GpuRegister rs, GpuRegister rt, uint16_t imm16); // R6
185 void Beqc(GpuRegister rs, GpuRegister rt, uint16_t imm16); // R6
186 void Bnec(GpuRegister rs, GpuRegister rt, uint16_t imm16); // R6
187 void Beqzc(GpuRegister rs, uint32_t imm21); // R6
188 void Bnezc(GpuRegister rs, uint32_t imm21); // R6
Andreas Gampe57b34292015-01-14 15:45:59 -0800189
190 void AddS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
191 void SubS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
192 void MulS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
193 void DivS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
194 void AddD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
195 void SubD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
196 void MulD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
197 void DivD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700198 void SqrtS(FpuRegister fd, FpuRegister fs);
199 void SqrtD(FpuRegister fd, FpuRegister fs);
200 void AbsS(FpuRegister fd, FpuRegister fs);
201 void AbsD(FpuRegister fd, FpuRegister fs);
Andreas Gampe57b34292015-01-14 15:45:59 -0800202 void MovS(FpuRegister fd, FpuRegister fs);
203 void MovD(FpuRegister fd, FpuRegister fs);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700204 void NegS(FpuRegister fd, FpuRegister fs);
205 void NegD(FpuRegister fd, FpuRegister fs);
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700206 void RoundLS(FpuRegister fd, FpuRegister fs);
207 void RoundLD(FpuRegister fd, FpuRegister fs);
208 void RoundWS(FpuRegister fd, FpuRegister fs);
209 void RoundWD(FpuRegister fd, FpuRegister fs);
210 void CeilLS(FpuRegister fd, FpuRegister fs);
211 void CeilLD(FpuRegister fd, FpuRegister fs);
212 void CeilWS(FpuRegister fd, FpuRegister fs);
213 void CeilWD(FpuRegister fd, FpuRegister fs);
214 void FloorLS(FpuRegister fd, FpuRegister fs);
215 void FloorLD(FpuRegister fd, FpuRegister fs);
216 void FloorWS(FpuRegister fd, FpuRegister fs);
217 void FloorWD(FpuRegister fd, FpuRegister fs);
218 void SelS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
219 void SelD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
220 void RintS(FpuRegister fd, FpuRegister fs);
221 void RintD(FpuRegister fd, FpuRegister fs);
222 void ClassS(FpuRegister fd, FpuRegister fs);
223 void ClassD(FpuRegister fd, FpuRegister fs);
224 void MinS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
225 void MinD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
226 void MaxS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
227 void MaxD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700228
229 void Cvtsw(FpuRegister fd, FpuRegister fs);
230 void Cvtdw(FpuRegister fd, FpuRegister fs);
231 void Cvtsd(FpuRegister fd, FpuRegister fs);
232 void Cvtds(FpuRegister fd, FpuRegister fs);
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700233 void Cvtdl(FpuRegister fd, FpuRegister fs);
Andreas Gampe57b34292015-01-14 15:45:59 -0800234
235 void Mfc1(GpuRegister rt, FpuRegister fs);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700236 void Mtc1(GpuRegister rt, FpuRegister fs);
237 void Dmfc1(GpuRegister rt, FpuRegister fs); // MIPS64
238 void Dmtc1(GpuRegister rt, FpuRegister fs); // MIPS64
Andreas Gampe57b34292015-01-14 15:45:59 -0800239 void Lwc1(FpuRegister ft, GpuRegister rs, uint16_t imm16);
240 void Ldc1(FpuRegister ft, GpuRegister rs, uint16_t imm16);
241 void Swc1(FpuRegister ft, GpuRegister rs, uint16_t imm16);
242 void Sdc1(FpuRegister ft, GpuRegister rs, uint16_t imm16);
243
244 void Break();
245 void Nop();
Alexey Frunze4dda3372015-06-01 18:31:49 -0700246 void Move(GpuRegister rd, GpuRegister rs);
247 void Clear(GpuRegister rd);
248 void Not(GpuRegister rd, GpuRegister rs);
Andreas Gampe57b34292015-01-14 15:45:59 -0800249
Alexey Frunze4dda3372015-06-01 18:31:49 -0700250 // Higher level composite instructions
251 void LoadConst32(GpuRegister rd, int32_t value);
252 void LoadConst64(GpuRegister rd, int64_t value); // MIPS64
253
254 void Addiu32(GpuRegister rt, GpuRegister rs, int32_t value, GpuRegister rtmp = AT);
255 void Daddiu64(GpuRegister rt, GpuRegister rs, int64_t value, GpuRegister rtmp = AT); // MIPS64
256
Andreas Gampe85b62f22015-09-09 13:15:38 -0700257 void Bind(Label* label) OVERRIDE; // R6
258 void Jump(Label* label) OVERRIDE {
259 B(label);
260 }
Alexey Frunze4dda3372015-06-01 18:31:49 -0700261 void B(Label* label); // R6
262 void Jalr(Label* label, GpuRegister indirect_reg = RA); // R6
263 // TODO: implement common for R6 and non-R6 interface for conditional branches?
264 void Bltc(GpuRegister rs, GpuRegister rt, Label* label); // R6
265 void Bltzc(GpuRegister rt, Label* label); // R6
266 void Bgtzc(GpuRegister rt, Label* label); // R6
267 void Bgec(GpuRegister rs, GpuRegister rt, Label* label); // R6
268 void Bgezc(GpuRegister rt, Label* label); // R6
269 void Blezc(GpuRegister rt, Label* label); // R6
270 void Bltuc(GpuRegister rs, GpuRegister rt, Label* label); // R6
271 void Bgeuc(GpuRegister rs, GpuRegister rt, Label* label); // R6
272 void Beqc(GpuRegister rs, GpuRegister rt, Label* label); // R6
273 void Bnec(GpuRegister rs, GpuRegister rt, Label* label); // R6
274 void Beqzc(GpuRegister rs, Label* label); // R6
275 void Bnezc(GpuRegister rs, Label* label); // R6
Andreas Gampe57b34292015-01-14 15:45:59 -0800276
277 void EmitLoad(ManagedRegister m_dst, GpuRegister src_register, int32_t src_offset, size_t size);
278 void LoadFromOffset(LoadOperandType type, GpuRegister reg, GpuRegister base, int32_t offset);
279 void LoadFpuFromOffset(LoadOperandType type, FpuRegister reg, GpuRegister base, int32_t offset);
280 void StoreToOffset(StoreOperandType type, GpuRegister reg, GpuRegister base, int32_t offset);
281 void StoreFpuToOffset(StoreOperandType type, FpuRegister reg, GpuRegister base, int32_t offset);
282
283 // Emit data (e.g. encoded instruction or immediate) to the instruction stream.
Alexey Frunze4dda3372015-06-01 18:31:49 -0700284 void Emit(uint32_t value);
Andreas Gampe57b34292015-01-14 15:45:59 -0800285
286 //
287 // Overridden common assembler high-level functionality
288 //
289
290 // Emit code that will create an activation on the stack
291 void BuildFrame(size_t frame_size, ManagedRegister method_reg,
292 const std::vector<ManagedRegister>& callee_save_regs,
293 const ManagedRegisterEntrySpills& entry_spills) OVERRIDE;
294
295 // Emit code that will remove an activation from the stack
296 void RemoveFrame(size_t frame_size,
297 const std::vector<ManagedRegister>& callee_save_regs) OVERRIDE;
298
299 void IncreaseFrameSize(size_t adjust) OVERRIDE;
300 void DecreaseFrameSize(size_t adjust) OVERRIDE;
301
302 // Store routines
303 void Store(FrameOffset offs, ManagedRegister msrc, size_t size) OVERRIDE;
304 void StoreRef(FrameOffset dest, ManagedRegister msrc) OVERRIDE;
305 void StoreRawPtr(FrameOffset dest, ManagedRegister msrc) OVERRIDE;
306
307 void StoreImmediateToFrame(FrameOffset dest, uint32_t imm, ManagedRegister mscratch) OVERRIDE;
308
309 void StoreImmediateToThread64(ThreadOffset<8> dest, uint32_t imm,
310 ManagedRegister mscratch) OVERRIDE;
311
312 void StoreStackOffsetToThread64(ThreadOffset<8> thr_offs, FrameOffset fr_offs,
313 ManagedRegister mscratch) OVERRIDE;
314
315 void StoreStackPointerToThread64(ThreadOffset<8> thr_offs) OVERRIDE;
316
317 void StoreSpanning(FrameOffset dest, ManagedRegister msrc, FrameOffset in_off,
318 ManagedRegister mscratch) OVERRIDE;
319
320 // Load routines
321 void Load(ManagedRegister mdest, FrameOffset src, size_t size) OVERRIDE;
322
323 void LoadFromThread64(ManagedRegister mdest, ThreadOffset<8> src, size_t size) OVERRIDE;
324
Mathieu Chartiere401d142015-04-22 13:56:20 -0700325 void LoadRef(ManagedRegister dest, FrameOffset src) OVERRIDE;
Andreas Gampe57b34292015-01-14 15:45:59 -0800326
Mathieu Chartiere401d142015-04-22 13:56:20 -0700327 void LoadRef(ManagedRegister mdest, ManagedRegister base, MemberOffset offs,
Roland Levillain4d027112015-07-01 15:41:14 +0100328 bool unpoison_reference) OVERRIDE;
Andreas Gampe57b34292015-01-14 15:45:59 -0800329
330 void LoadRawPtr(ManagedRegister mdest, ManagedRegister base, Offset offs) OVERRIDE;
331
332 void LoadRawPtrFromThread64(ManagedRegister mdest, ThreadOffset<8> offs) OVERRIDE;
333
334 // Copying routines
335 void Move(ManagedRegister mdest, ManagedRegister msrc, size_t size) OVERRIDE;
336
337 void CopyRawPtrFromThread64(FrameOffset fr_offs, ThreadOffset<8> thr_offs,
338 ManagedRegister mscratch) OVERRIDE;
339
340 void CopyRawPtrToThread64(ThreadOffset<8> thr_offs, FrameOffset fr_offs,
341 ManagedRegister mscratch) OVERRIDE;
342
343 void CopyRef(FrameOffset dest, FrameOffset src, ManagedRegister mscratch) OVERRIDE;
344
345 void Copy(FrameOffset dest, FrameOffset src, ManagedRegister mscratch, size_t size) OVERRIDE;
346
347 void Copy(FrameOffset dest, ManagedRegister src_base, Offset src_offset, ManagedRegister mscratch,
348 size_t size) OVERRIDE;
349
350 void Copy(ManagedRegister dest_base, Offset dest_offset, FrameOffset src,
351 ManagedRegister mscratch, size_t size) OVERRIDE;
352
353 void Copy(FrameOffset dest, FrameOffset src_base, Offset src_offset, ManagedRegister mscratch,
354 size_t size) OVERRIDE;
355
356 void Copy(ManagedRegister dest, Offset dest_offset, ManagedRegister src, Offset src_offset,
357 ManagedRegister mscratch, size_t size) OVERRIDE;
358
359 void Copy(FrameOffset dest, Offset dest_offset, FrameOffset src, Offset src_offset,
360 ManagedRegister mscratch, size_t size) OVERRIDE;
361
362 void MemoryBarrier(ManagedRegister) OVERRIDE;
363
364 // Sign extension
365 void SignExtend(ManagedRegister mreg, size_t size) OVERRIDE;
366
367 // Zero extension
368 void ZeroExtend(ManagedRegister mreg, size_t size) OVERRIDE;
369
370 // Exploit fast access in managed code to Thread::Current()
371 void GetCurrentThread(ManagedRegister tr) OVERRIDE;
372 void GetCurrentThread(FrameOffset dest_offset, ManagedRegister mscratch) OVERRIDE;
373
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700374 // 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 -0800375 // value is null and null_allowed. in_reg holds a possibly stale reference
376 // that can be used to avoid loading the handle scope entry to see if the value is
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700377 // null.
Andreas Gampe57b34292015-01-14 15:45:59 -0800378 void CreateHandleScopeEntry(ManagedRegister out_reg, FrameOffset handlescope_offset,
379 ManagedRegister in_reg, bool null_allowed) OVERRIDE;
380
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700381 // 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 -0800382 // value is null and null_allowed.
383 void CreateHandleScopeEntry(FrameOffset out_off, FrameOffset handlescope_offset, ManagedRegister
384 mscratch, bool null_allowed) OVERRIDE;
385
386 // src holds a handle scope entry (Object**) load this into dst
387 void LoadReferenceFromHandleScope(ManagedRegister dst, ManagedRegister src) OVERRIDE;
388
389 // Heap::VerifyObject on src. In some cases (such as a reference to this) we
390 // know that src may not be null.
391 void VerifyObject(ManagedRegister src, bool could_be_null) OVERRIDE;
392 void VerifyObject(FrameOffset src, bool could_be_null) OVERRIDE;
393
394 // Call to address held at [base+offset]
395 void Call(ManagedRegister base, Offset offset, ManagedRegister mscratch) OVERRIDE;
396 void Call(FrameOffset base, Offset offset, ManagedRegister mscratch) OVERRIDE;
397 void CallFromThread64(ThreadOffset<8> offset, ManagedRegister mscratch) OVERRIDE;
398
399 // Generate code to check if Thread::Current()->exception_ is non-null
400 // and branch to a ExceptionSlowPath if it is.
401 void ExceptionPoll(ManagedRegister mscratch, size_t stack_adjust) OVERRIDE;
402
403 private:
404 void EmitR(int opcode, GpuRegister rs, GpuRegister rt, GpuRegister rd, int shamt, int funct);
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700405 void EmitRsd(int opcode, GpuRegister rs, GpuRegister rd, int shamt, int funct);
406 void EmitRtd(int opcode, GpuRegister rt, GpuRegister rd, int shamt, int funct);
Andreas Gampe57b34292015-01-14 15:45:59 -0800407 void EmitI(int opcode, GpuRegister rs, GpuRegister rt, uint16_t imm);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700408 void EmitI21(int opcode, GpuRegister rs, uint32_t imm21);
409 void EmitJ(int opcode, uint32_t addr26);
Andreas Gampe57b34292015-01-14 15:45:59 -0800410 void EmitFR(int opcode, int fmt, FpuRegister ft, FpuRegister fs, FpuRegister fd, int funct);
411 void EmitFI(int opcode, int fmt, FpuRegister rt, uint16_t imm);
412
Andreas Gampe57b34292015-01-14 15:45:59 -0800413 DISALLOW_COPY_AND_ASSIGN(Mips64Assembler);
414};
415
416// Slowpath entered when Thread::Current()->_exception is non-null
417class Mips64ExceptionSlowPath FINAL : public SlowPath {
418 public:
Roland Levillain3887c462015-08-12 18:15:42 +0100419 Mips64ExceptionSlowPath(Mips64ManagedRegister scratch, size_t stack_adjust)
Andreas Gampe57b34292015-01-14 15:45:59 -0800420 : scratch_(scratch), stack_adjust_(stack_adjust) {}
421 virtual void Emit(Assembler *sp_asm) OVERRIDE;
422 private:
423 const Mips64ManagedRegister scratch_;
424 const size_t stack_adjust_;
425};
426
427} // namespace mips64
428} // namespace art
429
430#endif // ART_COMPILER_UTILS_MIPS64_ASSEMBLER_MIPS64_H_