blob: 42962bca20dc7c9360eb330f8f4387d2263f136d [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.
Andreas Gampe57b34292015-01-14 15:45:59 -080069 void Addu(GpuRegister rd, GpuRegister rs, GpuRegister rt);
70 void Addiu(GpuRegister rt, GpuRegister rs, uint16_t imm16);
Alexey Frunze4dda3372015-06-01 18:31:49 -070071 void Daddu(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64
72 void Daddiu(GpuRegister rt, GpuRegister rs, uint16_t imm16); // MIPS64
Andreas Gampe57b34292015-01-14 15:45:59 -080073 void Subu(GpuRegister rd, GpuRegister rs, GpuRegister rt);
Alexey Frunze4dda3372015-06-01 18:31:49 -070074 void Dsubu(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64
75
Alexey Frunzec857c742015-09-23 15:12:39 -070076 void MulR6(GpuRegister rd, GpuRegister rs, GpuRegister rt);
77 void MuhR6(GpuRegister rd, GpuRegister rs, GpuRegister rt);
78 void DivR6(GpuRegister rd, GpuRegister rs, GpuRegister rt);
79 void ModR6(GpuRegister rd, GpuRegister rs, GpuRegister rt);
80 void DivuR6(GpuRegister rd, GpuRegister rs, GpuRegister rt);
81 void ModuR6(GpuRegister rd, GpuRegister rs, GpuRegister rt);
82 void Dmul(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64
83 void Dmuh(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64
84 void Ddiv(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64
85 void Dmod(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64
86 void Ddivu(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64
87 void Dmodu(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64
Andreas Gampe57b34292015-01-14 15:45:59 -080088
89 void And(GpuRegister rd, GpuRegister rs, GpuRegister rt);
90 void Andi(GpuRegister rt, GpuRegister rs, uint16_t imm16);
91 void Or(GpuRegister rd, GpuRegister rs, GpuRegister rt);
92 void Ori(GpuRegister rt, GpuRegister rs, uint16_t imm16);
93 void Xor(GpuRegister rd, GpuRegister rs, GpuRegister rt);
94 void Xori(GpuRegister rt, GpuRegister rs, uint16_t imm16);
95 void Nor(GpuRegister rd, GpuRegister rs, GpuRegister rt);
96
Alexey Frunzec857c742015-09-23 15:12:39 -070097 void Bitswap(GpuRegister rd, GpuRegister rt);
98 void Dbitswap(GpuRegister rd, GpuRegister rt);
99 void Seb(GpuRegister rd, GpuRegister rt);
100 void Seh(GpuRegister rd, GpuRegister rt);
101 void Dsbh(GpuRegister rd, GpuRegister rt);
102 void Dshd(GpuRegister rd, GpuRegister rt);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700103 void Dext(GpuRegister rs, GpuRegister rt, int pos, int size_less_one); // MIPS64
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700104 void Wsbh(GpuRegister rd, GpuRegister rt);
105 void Sc(GpuRegister rt, GpuRegister base, int16_t imm9 = 0);
106 void Scd(GpuRegister rt, GpuRegister base, int16_t imm9 = 0);
107 void Ll(GpuRegister rt, GpuRegister base, int16_t imm9 = 0);
108 void Lld(GpuRegister rt, GpuRegister base, int16_t imm9 = 0);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700109
110 void Sll(GpuRegister rd, GpuRegister rt, int shamt);
111 void Srl(GpuRegister rd, GpuRegister rt, int shamt);
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700112 void Rotr(GpuRegister rd, GpuRegister rt, int shamt);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700113 void Sra(GpuRegister rd, GpuRegister rt, int shamt);
114 void Sllv(GpuRegister rd, GpuRegister rt, GpuRegister rs);
115 void Srlv(GpuRegister rd, GpuRegister rt, GpuRegister rs);
Chris Larsen9aebff22015-09-22 17:54:15 -0700116 void Rotrv(GpuRegister rd, GpuRegister rt, GpuRegister rs);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700117 void Srav(GpuRegister rd, GpuRegister rt, GpuRegister rs);
118 void Dsll(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64
119 void Dsrl(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64
Chris Larsen9aebff22015-09-22 17:54:15 -0700120 void Drotr(GpuRegister rd, GpuRegister rt, int shamt);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700121 void Dsra(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64
122 void Dsll32(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64
123 void Dsrl32(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64
Chris Larsen9aebff22015-09-22 17:54:15 -0700124 void Drotr32(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64
Alexey Frunze4dda3372015-06-01 18:31:49 -0700125 void Dsra32(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64
126 void Dsllv(GpuRegister rd, GpuRegister rt, GpuRegister rs); // MIPS64
127 void Dsrlv(GpuRegister rd, GpuRegister rt, GpuRegister rs); // MIPS64
Chris Larsen9aebff22015-09-22 17:54:15 -0700128 void Drotrv(GpuRegister rd, GpuRegister rt, GpuRegister rs); // MIPS64
Alexey Frunze4dda3372015-06-01 18:31:49 -0700129 void Dsrav(GpuRegister rd, GpuRegister rt, GpuRegister rs); // MIPS64
Andreas Gampe57b34292015-01-14 15:45:59 -0800130
131 void Lb(GpuRegister rt, GpuRegister rs, uint16_t imm16);
132 void Lh(GpuRegister rt, GpuRegister rs, uint16_t imm16);
133 void Lw(GpuRegister rt, GpuRegister rs, uint16_t imm16);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700134 void Ld(GpuRegister rt, GpuRegister rs, uint16_t imm16); // MIPS64
Andreas Gampe57b34292015-01-14 15:45:59 -0800135 void Lbu(GpuRegister rt, GpuRegister rs, uint16_t imm16);
136 void Lhu(GpuRegister rt, GpuRegister rs, uint16_t imm16);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700137 void Lwu(GpuRegister rt, GpuRegister rs, uint16_t imm16); // MIPS64
Andreas Gampe57b34292015-01-14 15:45:59 -0800138 void Lui(GpuRegister rt, uint16_t imm16);
Alexey Frunzec857c742015-09-23 15:12:39 -0700139 void Dahi(GpuRegister rs, uint16_t imm16); // MIPS64
140 void Dati(GpuRegister rs, uint16_t imm16); // MIPS64
Alexey Frunze4dda3372015-06-01 18:31:49 -0700141 void Sync(uint32_t stype);
Andreas Gampe57b34292015-01-14 15:45:59 -0800142
143 void Sb(GpuRegister rt, GpuRegister rs, uint16_t imm16);
144 void Sh(GpuRegister rt, GpuRegister rs, uint16_t imm16);
145 void Sw(GpuRegister rt, GpuRegister rs, uint16_t imm16);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700146 void Sd(GpuRegister rt, GpuRegister rs, uint16_t imm16); // MIPS64
Andreas Gampe57b34292015-01-14 15:45:59 -0800147
148 void Slt(GpuRegister rd, GpuRegister rs, GpuRegister rt);
149 void Sltu(GpuRegister rd, GpuRegister rs, GpuRegister rt);
150 void Slti(GpuRegister rt, GpuRegister rs, uint16_t imm16);
151 void Sltiu(GpuRegister rt, GpuRegister rs, uint16_t imm16);
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700152 void Seleqz(GpuRegister rd, GpuRegister rs, GpuRegister rt);
153 void Selnez(GpuRegister rd, GpuRegister rs, GpuRegister rt);
154 void Clz(GpuRegister rd, GpuRegister rs);
155 void Clo(GpuRegister rd, GpuRegister rs);
156 void Dclz(GpuRegister rd, GpuRegister rs);
157 void Dclo(GpuRegister rd, GpuRegister rs);
Andreas Gampe57b34292015-01-14 15:45:59 -0800158
Alexey Frunze4dda3372015-06-01 18:31:49 -0700159 void Beq(GpuRegister rs, GpuRegister rt, uint16_t imm16);
160 void Bne(GpuRegister rs, GpuRegister rt, uint16_t imm16);
161 void J(uint32_t addr26);
162 void Jal(uint32_t addr26);
163 void Jalr(GpuRegister rd, GpuRegister rs);
Andreas Gampe57b34292015-01-14 15:45:59 -0800164 void Jalr(GpuRegister rs);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700165 void Jr(GpuRegister rs);
Alexey Frunzec857c742015-09-23 15:12:39 -0700166 void Auipc(GpuRegister rs, uint16_t imm16);
167 void Jic(GpuRegister rt, uint16_t imm16);
168 void Jialc(GpuRegister rt, uint16_t imm16);
169 void Bltc(GpuRegister rs, GpuRegister rt, uint16_t imm16);
170 void Bltzc(GpuRegister rt, uint16_t imm16);
171 void Bgtzc(GpuRegister rt, uint16_t imm16);
172 void Bgec(GpuRegister rs, GpuRegister rt, uint16_t imm16);
173 void Bgezc(GpuRegister rt, uint16_t imm16);
174 void Blezc(GpuRegister rt, uint16_t imm16);
175 void Bltuc(GpuRegister rs, GpuRegister rt, uint16_t imm16);
176 void Bgeuc(GpuRegister rs, GpuRegister rt, uint16_t imm16);
177 void Beqc(GpuRegister rs, GpuRegister rt, uint16_t imm16);
178 void Bnec(GpuRegister rs, GpuRegister rt, uint16_t imm16);
179 void Beqzc(GpuRegister rs, uint32_t imm21);
180 void Bnezc(GpuRegister rs, uint32_t imm21);
Andreas Gampe57b34292015-01-14 15:45:59 -0800181
182 void AddS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
183 void SubS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
184 void MulS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
185 void DivS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
186 void AddD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
187 void SubD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
188 void MulD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
189 void DivD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700190 void SqrtS(FpuRegister fd, FpuRegister fs);
191 void SqrtD(FpuRegister fd, FpuRegister fs);
192 void AbsS(FpuRegister fd, FpuRegister fs);
193 void AbsD(FpuRegister fd, FpuRegister fs);
Andreas Gampe57b34292015-01-14 15:45:59 -0800194 void MovS(FpuRegister fd, FpuRegister fs);
195 void MovD(FpuRegister fd, FpuRegister fs);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700196 void NegS(FpuRegister fd, FpuRegister fs);
197 void NegD(FpuRegister fd, FpuRegister fs);
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700198 void RoundLS(FpuRegister fd, FpuRegister fs);
199 void RoundLD(FpuRegister fd, FpuRegister fs);
200 void RoundWS(FpuRegister fd, FpuRegister fs);
201 void RoundWD(FpuRegister fd, FpuRegister fs);
202 void CeilLS(FpuRegister fd, FpuRegister fs);
203 void CeilLD(FpuRegister fd, FpuRegister fs);
204 void CeilWS(FpuRegister fd, FpuRegister fs);
205 void CeilWD(FpuRegister fd, FpuRegister fs);
206 void FloorLS(FpuRegister fd, FpuRegister fs);
207 void FloorLD(FpuRegister fd, FpuRegister fs);
208 void FloorWS(FpuRegister fd, FpuRegister fs);
209 void FloorWD(FpuRegister fd, FpuRegister fs);
210 void SelS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
211 void SelD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
212 void RintS(FpuRegister fd, FpuRegister fs);
213 void RintD(FpuRegister fd, FpuRegister fs);
214 void ClassS(FpuRegister fd, FpuRegister fs);
215 void ClassD(FpuRegister fd, FpuRegister fs);
216 void MinS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
217 void MinD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
218 void MaxS(FpuRegister fd, FpuRegister fs, FpuRegister ft);
219 void MaxD(FpuRegister fd, FpuRegister fs, FpuRegister ft);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700220
221 void Cvtsw(FpuRegister fd, FpuRegister fs);
222 void Cvtdw(FpuRegister fd, FpuRegister fs);
223 void Cvtsd(FpuRegister fd, FpuRegister fs);
224 void Cvtds(FpuRegister fd, FpuRegister fs);
Chris Larsen51417632015-10-02 13:24:25 -0700225 void Cvtsl(FpuRegister fd, FpuRegister fs);
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700226 void Cvtdl(FpuRegister fd, FpuRegister fs);
Andreas Gampe57b34292015-01-14 15:45:59 -0800227
228 void Mfc1(GpuRegister rt, FpuRegister fs);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700229 void Mtc1(GpuRegister rt, FpuRegister fs);
230 void Dmfc1(GpuRegister rt, FpuRegister fs); // MIPS64
231 void Dmtc1(GpuRegister rt, FpuRegister fs); // MIPS64
Andreas Gampe57b34292015-01-14 15:45:59 -0800232 void Lwc1(FpuRegister ft, GpuRegister rs, uint16_t imm16);
233 void Ldc1(FpuRegister ft, GpuRegister rs, uint16_t imm16);
234 void Swc1(FpuRegister ft, GpuRegister rs, uint16_t imm16);
235 void Sdc1(FpuRegister ft, GpuRegister rs, uint16_t imm16);
236
237 void Break();
238 void Nop();
Alexey Frunze4dda3372015-06-01 18:31:49 -0700239 void Move(GpuRegister rd, GpuRegister rs);
240 void Clear(GpuRegister rd);
241 void Not(GpuRegister rd, GpuRegister rs);
Andreas Gampe57b34292015-01-14 15:45:59 -0800242
Alexey Frunze4dda3372015-06-01 18:31:49 -0700243 // Higher level composite instructions
244 void LoadConst32(GpuRegister rd, int32_t value);
245 void LoadConst64(GpuRegister rd, int64_t value); // MIPS64
246
247 void Addiu32(GpuRegister rt, GpuRegister rs, int32_t value, GpuRegister rtmp = AT);
248 void Daddiu64(GpuRegister rt, GpuRegister rs, int64_t value, GpuRegister rtmp = AT); // MIPS64
249
Alexey Frunzec857c742015-09-23 15:12:39 -0700250 void Bind(Label* label) OVERRIDE;
Andreas Gampe85b62f22015-09-09 13:15:38 -0700251 void Jump(Label* label) OVERRIDE {
252 B(label);
253 }
Alexey Frunzec857c742015-09-23 15:12:39 -0700254 void B(Label* label);
255 void Jalr(Label* label, GpuRegister indirect_reg = RA);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700256 // TODO: implement common for R6 and non-R6 interface for conditional branches?
Alexey Frunzec857c742015-09-23 15:12:39 -0700257 void Bltc(GpuRegister rs, GpuRegister rt, Label* label);
258 void Bltzc(GpuRegister rt, Label* label);
259 void Bgtzc(GpuRegister rt, Label* label);
260 void Bgec(GpuRegister rs, GpuRegister rt, Label* label);
261 void Bgezc(GpuRegister rt, Label* label);
262 void Blezc(GpuRegister rt, Label* label);
263 void Bltuc(GpuRegister rs, GpuRegister rt, Label* label);
264 void Bgeuc(GpuRegister rs, GpuRegister rt, Label* label);
265 void Beqc(GpuRegister rs, GpuRegister rt, Label* label);
266 void Bnec(GpuRegister rs, GpuRegister rt, Label* label);
267 void Beqzc(GpuRegister rs, Label* label);
268 void Bnezc(GpuRegister rs, Label* label);
Andreas Gampe57b34292015-01-14 15:45:59 -0800269
270 void EmitLoad(ManagedRegister m_dst, GpuRegister src_register, int32_t src_offset, size_t size);
271 void LoadFromOffset(LoadOperandType type, GpuRegister reg, GpuRegister base, int32_t offset);
272 void LoadFpuFromOffset(LoadOperandType type, FpuRegister reg, GpuRegister base, int32_t offset);
273 void StoreToOffset(StoreOperandType type, GpuRegister reg, GpuRegister base, int32_t offset);
274 void StoreFpuToOffset(StoreOperandType type, FpuRegister reg, GpuRegister base, int32_t offset);
275
276 // Emit data (e.g. encoded instruction or immediate) to the instruction stream.
Alexey Frunze4dda3372015-06-01 18:31:49 -0700277 void Emit(uint32_t value);
Andreas Gampe57b34292015-01-14 15:45:59 -0800278
279 //
280 // Overridden common assembler high-level functionality
281 //
282
283 // Emit code that will create an activation on the stack
284 void BuildFrame(size_t frame_size, ManagedRegister method_reg,
285 const std::vector<ManagedRegister>& callee_save_regs,
286 const ManagedRegisterEntrySpills& entry_spills) OVERRIDE;
287
288 // Emit code that will remove an activation from the stack
289 void RemoveFrame(size_t frame_size,
290 const std::vector<ManagedRegister>& callee_save_regs) OVERRIDE;
291
292 void IncreaseFrameSize(size_t adjust) OVERRIDE;
293 void DecreaseFrameSize(size_t adjust) OVERRIDE;
294
295 // Store routines
296 void Store(FrameOffset offs, ManagedRegister msrc, size_t size) OVERRIDE;
297 void StoreRef(FrameOffset dest, ManagedRegister msrc) OVERRIDE;
298 void StoreRawPtr(FrameOffset dest, ManagedRegister msrc) OVERRIDE;
299
300 void StoreImmediateToFrame(FrameOffset dest, uint32_t imm, ManagedRegister mscratch) OVERRIDE;
301
302 void StoreImmediateToThread64(ThreadOffset<8> dest, uint32_t imm,
303 ManagedRegister mscratch) OVERRIDE;
304
305 void StoreStackOffsetToThread64(ThreadOffset<8> thr_offs, FrameOffset fr_offs,
306 ManagedRegister mscratch) OVERRIDE;
307
308 void StoreStackPointerToThread64(ThreadOffset<8> thr_offs) OVERRIDE;
309
310 void StoreSpanning(FrameOffset dest, ManagedRegister msrc, FrameOffset in_off,
311 ManagedRegister mscratch) OVERRIDE;
312
313 // Load routines
314 void Load(ManagedRegister mdest, FrameOffset src, size_t size) OVERRIDE;
315
316 void LoadFromThread64(ManagedRegister mdest, ThreadOffset<8> src, size_t size) OVERRIDE;
317
Mathieu Chartiere401d142015-04-22 13:56:20 -0700318 void LoadRef(ManagedRegister dest, FrameOffset src) OVERRIDE;
Andreas Gampe57b34292015-01-14 15:45:59 -0800319
Mathieu Chartiere401d142015-04-22 13:56:20 -0700320 void LoadRef(ManagedRegister mdest, ManagedRegister base, MemberOffset offs,
Roland Levillain4d027112015-07-01 15:41:14 +0100321 bool unpoison_reference) OVERRIDE;
Andreas Gampe57b34292015-01-14 15:45:59 -0800322
323 void LoadRawPtr(ManagedRegister mdest, ManagedRegister base, Offset offs) OVERRIDE;
324
325 void LoadRawPtrFromThread64(ManagedRegister mdest, ThreadOffset<8> offs) OVERRIDE;
326
327 // Copying routines
328 void Move(ManagedRegister mdest, ManagedRegister msrc, size_t size) OVERRIDE;
329
330 void CopyRawPtrFromThread64(FrameOffset fr_offs, ThreadOffset<8> thr_offs,
331 ManagedRegister mscratch) OVERRIDE;
332
333 void CopyRawPtrToThread64(ThreadOffset<8> thr_offs, FrameOffset fr_offs,
334 ManagedRegister mscratch) OVERRIDE;
335
336 void CopyRef(FrameOffset dest, FrameOffset src, ManagedRegister mscratch) OVERRIDE;
337
338 void Copy(FrameOffset dest, FrameOffset src, ManagedRegister mscratch, size_t size) OVERRIDE;
339
340 void Copy(FrameOffset dest, ManagedRegister src_base, Offset src_offset, ManagedRegister mscratch,
341 size_t size) OVERRIDE;
342
343 void Copy(ManagedRegister dest_base, Offset dest_offset, FrameOffset src,
344 ManagedRegister mscratch, size_t size) OVERRIDE;
345
346 void Copy(FrameOffset dest, FrameOffset src_base, Offset src_offset, ManagedRegister mscratch,
347 size_t size) OVERRIDE;
348
349 void Copy(ManagedRegister dest, Offset dest_offset, ManagedRegister src, Offset src_offset,
350 ManagedRegister mscratch, size_t size) OVERRIDE;
351
352 void Copy(FrameOffset dest, Offset dest_offset, FrameOffset src, Offset src_offset,
353 ManagedRegister mscratch, size_t size) OVERRIDE;
354
355 void MemoryBarrier(ManagedRegister) OVERRIDE;
356
357 // Sign extension
358 void SignExtend(ManagedRegister mreg, size_t size) OVERRIDE;
359
360 // Zero extension
361 void ZeroExtend(ManagedRegister mreg, size_t size) OVERRIDE;
362
363 // Exploit fast access in managed code to Thread::Current()
364 void GetCurrentThread(ManagedRegister tr) OVERRIDE;
365 void GetCurrentThread(FrameOffset dest_offset, ManagedRegister mscratch) OVERRIDE;
366
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700367 // 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 -0800368 // value is null and null_allowed. in_reg holds a possibly stale reference
369 // that can be used to avoid loading the handle scope entry to see if the value is
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700370 // null.
Andreas Gampe57b34292015-01-14 15:45:59 -0800371 void CreateHandleScopeEntry(ManagedRegister out_reg, FrameOffset handlescope_offset,
372 ManagedRegister in_reg, bool null_allowed) OVERRIDE;
373
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700374 // 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 -0800375 // value is null and null_allowed.
376 void CreateHandleScopeEntry(FrameOffset out_off, FrameOffset handlescope_offset, ManagedRegister
377 mscratch, bool null_allowed) OVERRIDE;
378
379 // src holds a handle scope entry (Object**) load this into dst
380 void LoadReferenceFromHandleScope(ManagedRegister dst, ManagedRegister src) OVERRIDE;
381
382 // Heap::VerifyObject on src. In some cases (such as a reference to this) we
383 // know that src may not be null.
384 void VerifyObject(ManagedRegister src, bool could_be_null) OVERRIDE;
385 void VerifyObject(FrameOffset src, bool could_be_null) OVERRIDE;
386
387 // Call to address held at [base+offset]
388 void Call(ManagedRegister base, Offset offset, ManagedRegister mscratch) OVERRIDE;
389 void Call(FrameOffset base, Offset offset, ManagedRegister mscratch) OVERRIDE;
390 void CallFromThread64(ThreadOffset<8> offset, ManagedRegister mscratch) OVERRIDE;
391
392 // Generate code to check if Thread::Current()->exception_ is non-null
393 // and branch to a ExceptionSlowPath if it is.
394 void ExceptionPoll(ManagedRegister mscratch, size_t stack_adjust) OVERRIDE;
395
396 private:
397 void EmitR(int opcode, GpuRegister rs, GpuRegister rt, GpuRegister rd, int shamt, int funct);
Chris Larsen2fadd7b2015-08-14 14:56:10 -0700398 void EmitRsd(int opcode, GpuRegister rs, GpuRegister rd, int shamt, int funct);
399 void EmitRtd(int opcode, GpuRegister rt, GpuRegister rd, int shamt, int funct);
Andreas Gampe57b34292015-01-14 15:45:59 -0800400 void EmitI(int opcode, GpuRegister rs, GpuRegister rt, uint16_t imm);
Alexey Frunze4dda3372015-06-01 18:31:49 -0700401 void EmitI21(int opcode, GpuRegister rs, uint32_t imm21);
402 void EmitJ(int opcode, uint32_t addr26);
Andreas Gampe57b34292015-01-14 15:45:59 -0800403 void EmitFR(int opcode, int fmt, FpuRegister ft, FpuRegister fs, FpuRegister fd, int funct);
404 void EmitFI(int opcode, int fmt, FpuRegister rt, uint16_t imm);
405
Andreas Gampe57b34292015-01-14 15:45:59 -0800406 DISALLOW_COPY_AND_ASSIGN(Mips64Assembler);
407};
408
409// Slowpath entered when Thread::Current()->_exception is non-null
410class Mips64ExceptionSlowPath FINAL : public SlowPath {
411 public:
Roland Levillain3887c462015-08-12 18:15:42 +0100412 Mips64ExceptionSlowPath(Mips64ManagedRegister scratch, size_t stack_adjust)
Andreas Gampe57b34292015-01-14 15:45:59 -0800413 : scratch_(scratch), stack_adjust_(stack_adjust) {}
414 virtual void Emit(Assembler *sp_asm) OVERRIDE;
415 private:
416 const Mips64ManagedRegister scratch_;
417 const size_t stack_adjust_;
418};
419
420} // namespace mips64
421} // namespace art
422
423#endif // ART_COMPILER_UTILS_MIPS64_ASSEMBLER_MIPS64_H_