blob: 33f22d2c2d3a99c542f08c9e29e5b9ec64b62bfc [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);
Chris Larsen9aebff22015-09-22 17:54:15 -0700126 void Rotrv(GpuRegister rd, GpuRegister rt, GpuRegister rs);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700127 void Srav(GpuRegister rd, GpuRegister rt, GpuRegister rs);
128 void Dsll(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64
129 void Dsrl(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64
Chris Larsen9aebff22015-09-22 17:54:15 -0700130 void Drotr(GpuRegister rd, GpuRegister rt, int shamt);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700131 void Dsra(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64
132 void Dsll32(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64
133 void Dsrl32(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64
Chris Larsen9aebff22015-09-22 17:54:15 -0700134 void Drotr32(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64
Alexey Frunze4dda3372015-06-01 18:31:49 -0700135 void Dsra32(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64
136 void Dsllv(GpuRegister rd, GpuRegister rt, GpuRegister rs); // MIPS64
137 void Dsrlv(GpuRegister rd, GpuRegister rt, GpuRegister rs); // MIPS64
Chris Larsen9aebff22015-09-22 17:54:15 -0700138 void Drotrv(GpuRegister rd, GpuRegister rt, GpuRegister rs); // MIPS64
Alexey Frunze4dda3372015-06-01 18:31:49 -0700139 void Dsrav(GpuRegister rd, GpuRegister rt, GpuRegister rs); // MIPS64
Andreas Gampe57b34292015-01-14 15:45:59 -0800140
141 void Lb(GpuRegister rt, GpuRegister rs, uint16_t imm16);
142 void Lh(GpuRegister rt, GpuRegister rs, uint16_t imm16);
143 void Lw(GpuRegister rt, GpuRegister rs, uint16_t imm16);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700144 void Ld(GpuRegister rt, GpuRegister rs, uint16_t imm16); // MIPS64
Andreas Gampe57b34292015-01-14 15:45:59 -0800145 void Lbu(GpuRegister rt, GpuRegister rs, uint16_t imm16);
146 void Lhu(GpuRegister rt, GpuRegister rs, uint16_t imm16);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700147 void Lwu(GpuRegister rt, GpuRegister rs, uint16_t imm16); // MIPS64
Andreas Gampe57b34292015-01-14 15:45:59 -0800148 void Lui(GpuRegister rt, uint16_t imm16);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700149 void Dahi(GpuRegister rs, uint16_t imm16); // MIPS64 R6
150 void Dati(GpuRegister rs, uint16_t imm16); // MIPS64 R6
151 void Sync(uint32_t stype);
152 void Mfhi(GpuRegister rd); // R2
153 void Mflo(GpuRegister rd); // R2
Andreas Gampe57b34292015-01-14 15:45:59 -0800154
155 void Sb(GpuRegister rt, GpuRegister rs, uint16_t imm16);
156 void Sh(GpuRegister rt, GpuRegister rs, uint16_t imm16);
157 void Sw(GpuRegister rt, GpuRegister rs, uint16_t imm16);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700158 void Sd(GpuRegister rt, GpuRegister rs, uint16_t imm16); // MIPS64
Andreas Gampe57b34292015-01-14 15:45:59 -0800159
160 void Slt(GpuRegister rd, GpuRegister rs, GpuRegister rt);
161 void Sltu(GpuRegister rd, GpuRegister rs, GpuRegister rt);
162 void Slti(GpuRegister rt, GpuRegister rs, uint16_t imm16);
163 void Sltiu(GpuRegister rt, GpuRegister rs, uint16_t imm16);
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700164 void Seleqz(GpuRegister rd, GpuRegister rs, GpuRegister rt);
165 void Selnez(GpuRegister rd, GpuRegister rs, GpuRegister rt);
166 void Clz(GpuRegister rd, GpuRegister rs);
167 void Clo(GpuRegister rd, GpuRegister rs);
168 void Dclz(GpuRegister rd, GpuRegister rs);
169 void Dclo(GpuRegister rd, GpuRegister rs);
Andreas Gampe57b34292015-01-14 15:45:59 -0800170
Alexey Frunze4dda3372015-06-01 18:31:49 -0700171 void Beq(GpuRegister rs, GpuRegister rt, uint16_t imm16);
172 void Bne(GpuRegister rs, GpuRegister rt, uint16_t imm16);
173 void J(uint32_t addr26);
174 void Jal(uint32_t addr26);
175 void Jalr(GpuRegister rd, GpuRegister rs);
Andreas Gampe57b34292015-01-14 15:45:59 -0800176 void Jalr(GpuRegister rs);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700177 void Jr(GpuRegister rs);
178 void Auipc(GpuRegister rs, uint16_t imm16); // R6
179 void Jic(GpuRegister rt, uint16_t imm16); // R6
180 void Jialc(GpuRegister rt, uint16_t imm16); // R6
181 void Bltc(GpuRegister rs, GpuRegister rt, uint16_t imm16); // R6
182 void Bltzc(GpuRegister rt, uint16_t imm16); // R6
183 void Bgtzc(GpuRegister rt, uint16_t imm16); // R6
184 void Bgec(GpuRegister rs, GpuRegister rt, uint16_t imm16); // R6
185 void Bgezc(GpuRegister rt, uint16_t imm16); // R6
186 void Blezc(GpuRegister rt, uint16_t imm16); // R6
187 void Bltuc(GpuRegister rs, GpuRegister rt, uint16_t imm16); // R6
188 void Bgeuc(GpuRegister rs, GpuRegister rt, uint16_t imm16); // R6
189 void Beqc(GpuRegister rs, GpuRegister rt, uint16_t imm16); // R6
190 void Bnec(GpuRegister rs, GpuRegister rt, uint16_t imm16); // R6
191 void Beqzc(GpuRegister rs, uint32_t imm21); // R6
192 void Bnezc(GpuRegister rs, uint32_t imm21); // R6
Andreas Gampe57b34292015-01-14 15:45:59 -0800193
194 void AddS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
195 void SubS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
196 void MulS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
197 void DivS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
198 void AddD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
199 void SubD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
200 void MulD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
201 void DivD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700202 void SqrtS(FpuRegister fd, FpuRegister fs);
203 void SqrtD(FpuRegister fd, FpuRegister fs);
204 void AbsS(FpuRegister fd, FpuRegister fs);
205 void AbsD(FpuRegister fd, FpuRegister fs);
Andreas Gampe57b34292015-01-14 15:45:59 -0800206 void MovS(FpuRegister fd, FpuRegister fs);
207 void MovD(FpuRegister fd, FpuRegister fs);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700208 void NegS(FpuRegister fd, FpuRegister fs);
209 void NegD(FpuRegister fd, FpuRegister fs);
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700210 void RoundLS(FpuRegister fd, FpuRegister fs);
211 void RoundLD(FpuRegister fd, FpuRegister fs);
212 void RoundWS(FpuRegister fd, FpuRegister fs);
213 void RoundWD(FpuRegister fd, FpuRegister fs);
214 void CeilLS(FpuRegister fd, FpuRegister fs);
215 void CeilLD(FpuRegister fd, FpuRegister fs);
216 void CeilWS(FpuRegister fd, FpuRegister fs);
217 void CeilWD(FpuRegister fd, FpuRegister fs);
218 void FloorLS(FpuRegister fd, FpuRegister fs);
219 void FloorLD(FpuRegister fd, FpuRegister fs);
220 void FloorWS(FpuRegister fd, FpuRegister fs);
221 void FloorWD(FpuRegister fd, FpuRegister fs);
222 void SelS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
223 void SelD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
224 void RintS(FpuRegister fd, FpuRegister fs);
225 void RintD(FpuRegister fd, FpuRegister fs);
226 void ClassS(FpuRegister fd, FpuRegister fs);
227 void ClassD(FpuRegister fd, FpuRegister fs);
228 void MinS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
229 void MinD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
230 void MaxS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
231 void MaxD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700232
233 void Cvtsw(FpuRegister fd, FpuRegister fs);
234 void Cvtdw(FpuRegister fd, FpuRegister fs);
235 void Cvtsd(FpuRegister fd, FpuRegister fs);
236 void Cvtds(FpuRegister fd, FpuRegister fs);
Chris Larsen51417632015-10-02 13:24:25 -0700237 void Cvtsl(FpuRegister fd, FpuRegister fs);
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700238 void Cvtdl(FpuRegister fd, FpuRegister fs);
Andreas Gampe57b34292015-01-14 15:45:59 -0800239
240 void Mfc1(GpuRegister rt, FpuRegister fs);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700241 void Mtc1(GpuRegister rt, FpuRegister fs);
242 void Dmfc1(GpuRegister rt, FpuRegister fs); // MIPS64
243 void Dmtc1(GpuRegister rt, FpuRegister fs); // MIPS64
Andreas Gampe57b34292015-01-14 15:45:59 -0800244 void Lwc1(FpuRegister ft, GpuRegister rs, uint16_t imm16);
245 void Ldc1(FpuRegister ft, GpuRegister rs, uint16_t imm16);
246 void Swc1(FpuRegister ft, GpuRegister rs, uint16_t imm16);
247 void Sdc1(FpuRegister ft, GpuRegister rs, uint16_t imm16);
248
249 void Break();
250 void Nop();
Alexey Frunze4dda3372015-06-01 18:31:49 -0700251 void Move(GpuRegister rd, GpuRegister rs);
252 void Clear(GpuRegister rd);
253 void Not(GpuRegister rd, GpuRegister rs);
Andreas Gampe57b34292015-01-14 15:45:59 -0800254
Alexey Frunze4dda3372015-06-01 18:31:49 -0700255 // Higher level composite instructions
256 void LoadConst32(GpuRegister rd, int32_t value);
257 void LoadConst64(GpuRegister rd, int64_t value); // MIPS64
258
259 void Addiu32(GpuRegister rt, GpuRegister rs, int32_t value, GpuRegister rtmp = AT);
260 void Daddiu64(GpuRegister rt, GpuRegister rs, int64_t value, GpuRegister rtmp = AT); // MIPS64
261
Andreas Gampe85b62f22015-09-09 13:15:38 -0700262 void Bind(Label* label) OVERRIDE; // R6
263 void Jump(Label* label) OVERRIDE {
264 B(label);
265 }
Alexey Frunze4dda3372015-06-01 18:31:49 -0700266 void B(Label* label); // R6
267 void Jalr(Label* label, GpuRegister indirect_reg = RA); // R6
268 // TODO: implement common for R6 and non-R6 interface for conditional branches?
269 void Bltc(GpuRegister rs, GpuRegister rt, Label* label); // R6
270 void Bltzc(GpuRegister rt, Label* label); // R6
271 void Bgtzc(GpuRegister rt, Label* label); // R6
272 void Bgec(GpuRegister rs, GpuRegister rt, Label* label); // R6
273 void Bgezc(GpuRegister rt, Label* label); // R6
274 void Blezc(GpuRegister rt, Label* label); // R6
275 void Bltuc(GpuRegister rs, GpuRegister rt, Label* label); // R6
276 void Bgeuc(GpuRegister rs, GpuRegister rt, Label* label); // R6
277 void Beqc(GpuRegister rs, GpuRegister rt, Label* label); // R6
278 void Bnec(GpuRegister rs, GpuRegister rt, Label* label); // R6
279 void Beqzc(GpuRegister rs, Label* label); // R6
280 void Bnezc(GpuRegister rs, Label* label); // R6
Andreas Gampe57b34292015-01-14 15:45:59 -0800281
282 void EmitLoad(ManagedRegister m_dst, GpuRegister src_register, int32_t src_offset, size_t size);
283 void LoadFromOffset(LoadOperandType type, GpuRegister reg, GpuRegister base, int32_t offset);
284 void LoadFpuFromOffset(LoadOperandType type, FpuRegister reg, GpuRegister base, int32_t offset);
285 void StoreToOffset(StoreOperandType type, GpuRegister reg, GpuRegister base, int32_t offset);
286 void StoreFpuToOffset(StoreOperandType type, FpuRegister reg, GpuRegister base, int32_t offset);
287
288 // Emit data (e.g. encoded instruction or immediate) to the instruction stream.
Alexey Frunze4dda3372015-06-01 18:31:49 -0700289 void Emit(uint32_t value);
Andreas Gampe57b34292015-01-14 15:45:59 -0800290
291 //
292 // Overridden common assembler high-level functionality
293 //
294
295 // Emit code that will create an activation on the stack
296 void BuildFrame(size_t frame_size, ManagedRegister method_reg,
297 const std::vector<ManagedRegister>& callee_save_regs,
298 const ManagedRegisterEntrySpills& entry_spills) OVERRIDE;
299
300 // Emit code that will remove an activation from the stack
301 void RemoveFrame(size_t frame_size,
302 const std::vector<ManagedRegister>& callee_save_regs) OVERRIDE;
303
304 void IncreaseFrameSize(size_t adjust) OVERRIDE;
305 void DecreaseFrameSize(size_t adjust) OVERRIDE;
306
307 // Store routines
308 void Store(FrameOffset offs, ManagedRegister msrc, size_t size) OVERRIDE;
309 void StoreRef(FrameOffset dest, ManagedRegister msrc) OVERRIDE;
310 void StoreRawPtr(FrameOffset dest, ManagedRegister msrc) OVERRIDE;
311
312 void StoreImmediateToFrame(FrameOffset dest, uint32_t imm, ManagedRegister mscratch) OVERRIDE;
313
314 void StoreImmediateToThread64(ThreadOffset<8> dest, uint32_t imm,
315 ManagedRegister mscratch) OVERRIDE;
316
317 void StoreStackOffsetToThread64(ThreadOffset<8> thr_offs, FrameOffset fr_offs,
318 ManagedRegister mscratch) OVERRIDE;
319
320 void StoreStackPointerToThread64(ThreadOffset<8> thr_offs) OVERRIDE;
321
322 void StoreSpanning(FrameOffset dest, ManagedRegister msrc, FrameOffset in_off,
323 ManagedRegister mscratch) OVERRIDE;
324
325 // Load routines
326 void Load(ManagedRegister mdest, FrameOffset src, size_t size) OVERRIDE;
327
328 void LoadFromThread64(ManagedRegister mdest, ThreadOffset<8> src, size_t size) OVERRIDE;
329
Mathieu Chartiere401d142015-04-22 13:56:20 -0700330 void LoadRef(ManagedRegister dest, FrameOffset src) OVERRIDE;
Andreas Gampe57b34292015-01-14 15:45:59 -0800331
Mathieu Chartiere401d142015-04-22 13:56:20 -0700332 void LoadRef(ManagedRegister mdest, ManagedRegister base, MemberOffset offs,
Roland Levillain4d027112015-07-01 15:41:14 +0100333 bool unpoison_reference) OVERRIDE;
Andreas Gampe57b34292015-01-14 15:45:59 -0800334
335 void LoadRawPtr(ManagedRegister mdest, ManagedRegister base, Offset offs) OVERRIDE;
336
337 void LoadRawPtrFromThread64(ManagedRegister mdest, ThreadOffset<8> offs) OVERRIDE;
338
339 // Copying routines
340 void Move(ManagedRegister mdest, ManagedRegister msrc, size_t size) OVERRIDE;
341
342 void CopyRawPtrFromThread64(FrameOffset fr_offs, ThreadOffset<8> thr_offs,
343 ManagedRegister mscratch) OVERRIDE;
344
345 void CopyRawPtrToThread64(ThreadOffset<8> thr_offs, FrameOffset fr_offs,
346 ManagedRegister mscratch) OVERRIDE;
347
348 void CopyRef(FrameOffset dest, FrameOffset src, ManagedRegister mscratch) OVERRIDE;
349
350 void Copy(FrameOffset dest, FrameOffset src, ManagedRegister mscratch, size_t size) OVERRIDE;
351
352 void Copy(FrameOffset dest, ManagedRegister src_base, Offset src_offset, ManagedRegister mscratch,
353 size_t size) OVERRIDE;
354
355 void Copy(ManagedRegister dest_base, Offset dest_offset, FrameOffset src,
356 ManagedRegister mscratch, size_t size) OVERRIDE;
357
358 void Copy(FrameOffset dest, FrameOffset src_base, Offset src_offset, ManagedRegister mscratch,
359 size_t size) OVERRIDE;
360
361 void Copy(ManagedRegister dest, Offset dest_offset, ManagedRegister src, Offset src_offset,
362 ManagedRegister mscratch, size_t size) OVERRIDE;
363
364 void Copy(FrameOffset dest, Offset dest_offset, FrameOffset src, Offset src_offset,
365 ManagedRegister mscratch, size_t size) OVERRIDE;
366
367 void MemoryBarrier(ManagedRegister) OVERRIDE;
368
369 // Sign extension
370 void SignExtend(ManagedRegister mreg, size_t size) OVERRIDE;
371
372 // Zero extension
373 void ZeroExtend(ManagedRegister mreg, size_t size) OVERRIDE;
374
375 // Exploit fast access in managed code to Thread::Current()
376 void GetCurrentThread(ManagedRegister tr) OVERRIDE;
377 void GetCurrentThread(FrameOffset dest_offset, ManagedRegister mscratch) OVERRIDE;
378
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700379 // 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 -0800380 // value is null and null_allowed. in_reg holds a possibly stale reference
381 // that can be used to avoid loading the handle scope entry to see if the value is
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700382 // null.
Andreas Gampe57b34292015-01-14 15:45:59 -0800383 void CreateHandleScopeEntry(ManagedRegister out_reg, FrameOffset handlescope_offset,
384 ManagedRegister in_reg, bool null_allowed) OVERRIDE;
385
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700386 // 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 -0800387 // value is null and null_allowed.
388 void CreateHandleScopeEntry(FrameOffset out_off, FrameOffset handlescope_offset, ManagedRegister
389 mscratch, bool null_allowed) OVERRIDE;
390
391 // src holds a handle scope entry (Object**) load this into dst
392 void LoadReferenceFromHandleScope(ManagedRegister dst, ManagedRegister src) OVERRIDE;
393
394 // Heap::VerifyObject on src. In some cases (such as a reference to this) we
395 // know that src may not be null.
396 void VerifyObject(ManagedRegister src, bool could_be_null) OVERRIDE;
397 void VerifyObject(FrameOffset src, bool could_be_null) OVERRIDE;
398
399 // Call to address held at [base+offset]
400 void Call(ManagedRegister base, Offset offset, ManagedRegister mscratch) OVERRIDE;
401 void Call(FrameOffset base, Offset offset, ManagedRegister mscratch) OVERRIDE;
402 void CallFromThread64(ThreadOffset<8> offset, ManagedRegister mscratch) OVERRIDE;
403
404 // Generate code to check if Thread::Current()->exception_ is non-null
405 // and branch to a ExceptionSlowPath if it is.
406 void ExceptionPoll(ManagedRegister mscratch, size_t stack_adjust) OVERRIDE;
407
408 private:
409 void EmitR(int opcode, GpuRegister rs, GpuRegister rt, GpuRegister rd, int shamt, int funct);
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700410 void EmitRsd(int opcode, GpuRegister rs, GpuRegister rd, int shamt, int funct);
411 void EmitRtd(int opcode, GpuRegister rt, GpuRegister rd, int shamt, int funct);
Andreas Gampe57b34292015-01-14 15:45:59 -0800412 void EmitI(int opcode, GpuRegister rs, GpuRegister rt, uint16_t imm);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700413 void EmitI21(int opcode, GpuRegister rs, uint32_t imm21);
414 void EmitJ(int opcode, uint32_t addr26);
Andreas Gampe57b34292015-01-14 15:45:59 -0800415 void EmitFR(int opcode, int fmt, FpuRegister ft, FpuRegister fs, FpuRegister fd, int funct);
416 void EmitFI(int opcode, int fmt, FpuRegister rt, uint16_t imm);
417
Andreas Gampe57b34292015-01-14 15:45:59 -0800418 DISALLOW_COPY_AND_ASSIGN(Mips64Assembler);
419};
420
421// Slowpath entered when Thread::Current()->_exception is non-null
422class Mips64ExceptionSlowPath FINAL : public SlowPath {
423 public:
Roland Levillain3887c462015-08-12 18:15:42 +0100424 Mips64ExceptionSlowPath(Mips64ManagedRegister scratch, size_t stack_adjust)
Andreas Gampe57b34292015-01-14 15:45:59 -0800425 : scratch_(scratch), stack_adjust_(stack_adjust) {}
426 virtual void Emit(Assembler *sp_asm) OVERRIDE;
427 private:
428 const Mips64ManagedRegister scratch_;
429 const size_t stack_adjust_;
430};
431
432} // namespace mips64
433} // namespace art
434
435#endif // ART_COMPILER_UTILS_MIPS64_ASSEMBLER_MIPS64_H_