1 /* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
2 /* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
3 /* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
16 * The Original Code is [Open Source Virtual Machine].
18 * The Initial Developer of the Original Code is
19 * Adobe System Incorporated.
20 * Portions created by the Initial Developer are Copyright (C) 2004-2007
21 * the Initial Developer. All Rights Reserved.
26 * ginn.chen@oracle.com
28 * Alternatively, the contents of this file may be used under the terms of
29 * either the GNU General Public License Version 2 or later (the "GPL"), or
30 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
31 * in which case the provisions of the GPL or the LGPL are applicable instead
32 * of those above. If you wish to allow use of your version of this file only
33 * under the terms of either the GPL or the LGPL, and not to allow others to
34 * use your version of this file under the terms of the MPL, indicate your
35 * decision by deleting the provisions above and replace them with the notice
36 * and other provisions required by the GPL or the LGPL. If you do not delete
37 * the provisions above, a recipient may use your version of this file under
38 * the terms of any one of the MPL, the GPL or the LGPL.
40 * ***** END LICENSE BLOCK ***** */
43 #ifndef __nanojit_NativeSparc__
44 #define __nanojit_NativeSparc__
46 #include "NativeCommon.h"
58 #define count_prolog()
67 #define count_pushld()
72 const int NJ_MAX_REGISTERS
= 30; // L0 - L7, I0 - I5, F2 - F14
74 const int LARGEST_UNDERRUN_PROT
= 32; // largest value passed to underrunProtect
76 #define NJ_MAX_STACK_ENTRY 8192
77 #define NJ_MAX_PARAMETERS 1
79 #define NJ_JTBL_SUPPORTED 0
80 #define NJ_EXPANDED_LOADSTORE_SUPPORTED 0
81 #define NJ_F2I_SUPPORTED 1
82 #define NJ_SOFTFLOAT_SUPPORTED 0
83 #define NJ_DIVI_SUPPORTED 0
85 const int NJ_ALIGN_STACK
= 16;
87 typedef uint32_t NIns
;
89 // Bytes of icache to flush after Assembler::patch
90 const size_t LARGEST_BRANCH_PATCH
= 2 * sizeof(NIns
);
92 // These are used as register numbers in various parts of the code
99 G5
= { 5 }, // Reserved for system
100 G6
= { 6 }, // Reserved for system
101 G7
= { 7 }, // Reserved for system
110 O7
= { 15 }, // Not used.
128 I7
= { 31 }, // Not used
169 deprecated_UnknownReg
= { 64 }; // XXX: remove eventually, see bug 538924
171 static const uint32_t FirstRegNum
= 0;
172 static const uint32_t LastRegNum
= 63;
177 // We only use 32 registers to be managed.
178 // So we choose some of them.
179 // And other unmanaged registers we can use them directly.
180 // The registers that can be used directly are G0-G4, L0, L2, L4, L6
181 // SP, FP, F8-F12, F24-F28
182 typedef uint64_t RegisterMask
;
183 #define _rmask_(r) ((RegisterMask)1<<(REGNUM(r)))
184 #define _reg_(r) (REGNUM(r) & 0x1F)
185 // Assembler::savedRegs[] is not needed for sparc because the
186 // registers are already saved automatically by "save" instruction.
187 static const int NumSavedRegs
= 0;
189 static const RegisterMask SavedRegs
= _rmask_(L1
) | _rmask_(L3
) | _rmask_(L5
) | _rmask_(L7
) |
190 _rmask_(I0
) | _rmask_(I1
) | _rmask_(I2
) | _rmask_(I3
) |
191 _rmask_(I4
) | _rmask_(I5
);
192 static const RegisterMask GpRegs
= SavedRegs
| _rmask_(O0
) | _rmask_(O1
) | _rmask_(O2
) |
193 _rmask_(O3
) | _rmask_(O4
) | _rmask_(O5
);
194 static const RegisterMask FpRegs
= _rmask_(F0
) | _rmask_(F2
) | _rmask_(F4
) |
195 _rmask_(F6
) | _rmask_(F14
) | _rmask_(F16
) |
196 _rmask_(F18
) | _rmask_(F20
) | _rmask_(F22
);
197 static const RegisterMask AllowableFlagRegs
= GpRegs
;
199 verbose_only( extern const char* regNames
[]; )
201 #define DECLARE_PLATFORM_STATS()
203 #define DECLARE_PLATFORM_REGALLOC()
205 #define DECLARE_PLATFORM_ASSEMBLER() \
206 const static Register argRegs[6], retRegs[1]; \
208 void nativePageReset(); \
209 void nativePageSetup(); \
210 void underrunProtect(int bytes); \
211 void asm_align_code(); \
212 void asm_cmp(LIns *cond); \
213 void asm_cmpd(LIns *cond); \
214 NIns* asm_branchd(bool, LIns*, NIns*); \
215 void IMM32(int32_t i) { \
217 *((int32_t*)_nIns) = i; \
219 void CALL(const CallInfo* ci); \
220 void Format_2(int32_t x, int32_t op2, int32_t imm22) { \
221 int32_t i = x << 25 | op2 << 22 | imm22 & 0x3FFFFF; \
224 void Format_2A(Register rd, int32_t op2, int32_t imm22) { \
225 Format_2(_reg_(rd), op2, imm22); \
227 void Format_2_2(int32_t a, int32_t cond, int32_t op2, int32_t disp22) { \
228 Format_2((a & 0x1) << 4 | cond & 0xF, op2, disp22); \
230 void Format_2_3(int32_t a, int32_t cond, int32_t op2, int32_t cc1, int32_t cc0, int32_t p, int32_t disp19) { \
231 Format_2_2(a, cond, op2, (cc1 & 0x1) << 21 | (cc0 & 0x1) << 20 | (p & 0x1) << 19 | disp19 & 0x7FFFF); \
233 void Format_2_4(int32_t a, int32_t rcond, int32_t op2, int32_t d16hi, int32_t p, int32_t rs1, int32_t d16lo) { \
234 Format_2_2(a, rcond & 0x7, op2, (d16hi & 0x3) << 20 | (p & 0x1) << 19 | rs1 << 14 | d16lo & 0x3FFF); \
236 void Format_3(int32_t op1, int32_t x, int32_t op3, int32_t bits19) { \
237 int32_t i = op1 << 30 | x << 25 | op3 << 19 | bits19 & 0x7FFFF; \
240 void Format_3A(int32_t op1, Register rd, int32_t op3, int32_t bits19) { \
241 Format_3(op1, _reg_(rd), op3, bits19); \
243 void Format_3_1(int32_t op1, Register rd, int32_t op3, Register rs1, int32_t bit8, Register rs2) { \
244 Format_3A(op1, rd, op3, _reg_(rs1) << 14 | (bit8 & 0xFF) << 5 | _reg_(rs2)); \
246 void Format_3_1I(int32_t op1, Register rd, int32_t op3, Register rs1, int32_t simm13) { \
247 Format_3A(op1, rd, op3, _reg_(rs1) << 14 | 1 << 13 | simm13 & 0x1FFF); \
249 void Format_3_2(int32_t op1, Register rd, int32_t op3, Register rs1, int32_t rcond, Register rs2) { \
250 Format_3A(op1, rd, op3, _reg_(rs1) << 14 | (rcond & 0x3) << 10 | _reg_(rs2)); \
252 void Format_3_2I(int32_t op1, Register rd, int32_t op3, Register rs1, int32_t rcond, int32_t simm10) { \
253 Format_3A(op1, rd, op3, _reg_(rs1) << 14 | 1 << 13 | (rcond & 0x3) << 10 | simm10 & 0x1FFF); \
255 void Format_3_3(int32_t op1, Register rd, int32_t op3, Register rs1, int32_t cmask, int32_t mmask) { \
256 Format_3A(op1, rd, op3, _reg_(rs1) << 14 | 1 << 13 | (cmask & 0x7) << 5 | mmask & 0xF); \
258 void Format_3_4(int32_t op1, Register rd, int32_t op3, int32_t bits19) { \
259 Format_3A(op1, rd, op3, bits19); \
261 void Format_3_5(int32_t op1, Register rd, int32_t op3, Register rs1, int32_t x, Register rs2) { \
262 Format_3A(op1, rd, op3, _reg_(rs1) << 14 | (x & 0x1) << 12 | _reg_(rs2)); \
264 void Format_3_6(int32_t op1, Register rd, int32_t op3, Register rs1, int32_t shcnt32) { \
265 Format_3A(op1, rd, op3, _reg_(rs1) << 14 | 1 << 13 | (shcnt32 & 0x3F)); \
267 void Format_3_7(int32_t op1, Register rd, int32_t op3, Register rs1, int32_t shcnt64) { \
268 Format_3A(op1, rd, op3, _reg_(rs1) << 14 | 1 << 13 | 1 << 12 | (shcnt64 & 0x7F)); \
270 void Format_3_8(int32_t op1, Register rd, int32_t op3, Register rs1, int32_t bits9, Register rs2) { \
271 Format_3A(op1, rd, op3, _reg_(rs1) << 14 | (bits9 & 0x1FF) << 5 | _reg_(rs2)); \
273 void Format_3_9(int32_t op1, int32_t cc1, int32_t cc0, int32_t op3, Register rs1, int32_t bits9, Register rs2) { \
274 Format_3(op1, (cc1 & 0x1) << 1 | (cc0 & 0x1), op3, _reg_(rs1) << 14 | (bits9 & 0x1FF) << 5 | _reg_(rs2)); \
276 void Format_4_1(Register rd, int32_t op3, Register rs1, int32_t cc1, int32_t cc0, Register rs2) { \
277 Format_3A(2, rd, op3, _reg_(rs1) << 14 | (cc1 & 0x1) << 12 | (cc0 & 0x1) << 11 | _reg_(rs2)); \
279 void Format_4_1I(Register rd, int32_t op3, Register rs1, int32_t cc1, int32_t cc0, int32_t simm11) { \
280 Format_3A(2, rd, op3, _reg_(rs1) << 14 | (cc1 & 0x1) << 12 | 1 << 13 |(cc0 & 0x1) << 11 | simm11 & 0x7FF); \
282 void Format_4_2(Register rd, int32_t op3, int32_t cc2, int32_t cond, int32_t cc1, int32_t cc0, Register rs2) { \
283 Format_3A(2, rd, op3, (cc2 & 0x1) << 18 | (cond & 0xF) << 14 | (cc1 & 0x1) << 12 | (cc0 & 0x1) << 11 | _reg_(rs2)); \
285 void Format_4_2I(Register rd, int32_t op3, int32_t cc2, int32_t cond, int32_t cc1, int32_t cc0, int32_t simm11) { \
286 Format_3A(2, rd, op3, (cc2 & 0x1) << 18 | (cond & 0xF) << 14 | 1 << 13 | (cc1 & 0x1) << 12 | (cc0 & 0x1) << 11 | (simm11 & 0x7FF)); \
288 void Format_4_3(Register rd, int32_t op3, Register rs1, int32_t cc1, int32_t cc0, int32_t swap_trap) { \
289 Format_3A(2, rd, op3, _reg_(rs1) << 14 | 1 << 13 | (cc1 & 0x1) << 12 | (cc0 & 0x1) << 11 | swap_trap & 0x7F); \
291 void Format_4_4(Register rd, int32_t op3, Register rs1, int32_t rcond, int32_t opf_low, Register rs2) { \
292 Format_3A(2, rd, op3, _reg_(rs1) << 14 | (rcond & 0x7) << 10 | (opf_low & 0x1F) << 5 | _reg_(rs2)); \
294 void Format_4_5(Register rd, int32_t op3, int32_t cond, int32_t opf_cc, int32_t opf_low, Register rs2) { \
295 Format_3A(2, rd, op3, (cond & 0xF) << 14 | (opf_cc & 0x7) << 11 | (opf_low & 0x3F) << 5 | _reg_(rs2)); \
297 void IntegerOperation(Register rs1, Register rs2, Register rd, int32_t op3, const char *opcode); \
298 void Assembler::IntegerOperationI(Register rs1, int32_t simm13, Register rd, int32_t op3, const char *opcode); \
299 void FloatOperation(Register rs1, Register rs2, Register rd, int32_t op3, const char *opcode); \
300 void Bicc(int32_t a, int32_t dsp22, int32_t cond, const char *opcode); \
301 void FBfcc(int32_t a, int32_t dsp22, int32_t cond, const char *opcode); \
302 void LoadOperation(Register rs1, Register rs2, Register rd, int32_t op3, const char* opcode); \
303 void LoadOperationI(Register rs1, int32_t simm13, Register rd, int32_t op3, const char* opcode); \
304 void MOVcc(Register rs, int32_t cc2, int32_t cc1, int32_t cc0, Register rd, int32_t cond, const char *opcode); \
305 void MOVccI(int32_t simm11, int32_t cc2, int32_t cc1, int32_t cc0, Register rd, int32_t cond, const char *opcode); \
306 void FMOVDcc(Register rs, int32_t opt_cc, Register rd, int32_t cond, const char *opcode); \
307 void ShiftOperation(Register rs1, Register rs2, Register rd, int32_t op3, const char* opcode); \
308 void ShiftOperationI(Register rs1, int32_t shcnt32, Register rd, int32_t op3, const char* opcode); \
309 void Store(Register rd, Register rs1, Register rs2, int32_t op3, const char* opcode); \
310 void Assembler::StoreI(Register rd, int32_t simm13, Register rs1, int32_t op3, const char* opcode); \
311 void ADD(Register rs1, Register rs2, Register rd); \
312 void ADDCC(Register rs1, Register rs2, Register rd); \
313 void AND(Register rs1, Register rs2, Register rd); \
314 void ANDCC(Register rs1, Register rs2, Register rd); \
315 void OR(Register rs1, Register rs2, Register rd); \
316 void ORI(Register rs1, int32_t simm13, Register rd); \
317 void ORN(Register rs1, Register rs2, Register rd); \
318 void SMULCC(Register rs1, Register rs2, Register rd); \
319 void SUB(Register rs1, Register rs2, Register rd); \
320 void SUBCC(Register rs1, Register rs2, Register rd); \
321 void SUBI(Register rs1, int32_t simm13, Register rd); \
322 void XOR(Register rs1, Register rs2, Register rd); \
323 void BA(int32_t a, int32_t dsp22); \
324 void BE(int32_t a, int32_t dsp22); \
325 void BNE(int32_t a, int32_t dsp22); \
326 void BG(int32_t a, int32_t dsp22); \
327 void BGU(int32_t a, int32_t dsp22); \
328 void BGE(int32_t a, int32_t dsp22); \
329 void BL(int32_t a, int32_t dsp22); \
330 void BLE(int32_t a, int32_t dsp22); \
331 void BLEU(int32_t a, int32_t dsp22); \
332 void BCC(int32_t a, int32_t dsp22); \
333 void BCS(int32_t a, int32_t dsp22); \
334 void BVC(int32_t a, int32_t dsp22); \
335 void BVS(int32_t a, int32_t dsp22); \
336 void FABSS(Register rs2, Register rd); \
337 void FADDD(Register rs1, Register rs2, Register rd); \
338 void FBE(int32_t a, int32_t dsp22); \
339 void FBNE(int32_t a, int32_t dsp22); \
340 void FBUE(int32_t a, int32_t dsp22); \
341 void FBG(int32_t a, int32_t dsp22); \
342 void FBUG(int32_t a, int32_t dsp22); \
343 void FBGE(int32_t a, int32_t dsp22); \
344 void FBUGE(int32_t a, int32_t dsp22); \
345 void FBL(int32_t a, int32_t dsp22); \
346 void FBUL(int32_t a, int32_t dsp22); \
347 void FBLE(int32_t a, int32_t dsp22); \
348 void FBULE(int32_t a, int32_t dsp22); \
349 void FCMPD(Register rs1, Register rs2); \
350 void FSUBD(Register rs1, Register rs2, Register rd); \
351 void FMULD(Register rs1, Register rs2, Register rd); \
352 void FDTOI(Register rs2, Register rd); \
353 void FDIVD(Register rs1, Register rs2, Register rd); \
354 void FMOVD(Register rs2, Register rd); \
355 void FNEGD(Register rs2, Register rd); \
356 void FITOD(Register rs2, Register rd); \
357 void JMPL(Register rs1, Register rs2, Register rd); \
358 void JMPLI(Register rs1, int32_t simm13, Register rd); \
359 void LDF(Register rs1, Register rs2, Register rd); \
360 void LDFI(Register rs1, int32_t simm13, Register rd); \
361 void LDDF32(Register rs1, int32_t immI, Register rd); \
362 void LDUB(Register rs1, Register rs2, Register rd); \
363 void LDUBI(Register rs1, int32_t simm13, Register rd); \
364 void LDUB32(Register rs1, int32_t immI, Register rd); \
365 void LDUH(Register rs1, Register rs2, Register rd); \
366 void LDUHI(Register rs1, int32_t simm13, Register rd); \
367 void LDUH32(Register rs1, int32_t immI, Register rd); \
368 void LDSW(Register rs1, Register rs2, Register rd); \
369 void LDSWI(Register rs1, int32_t simm13, Register rd); \
370 void LDSW32(Register rs1, int32_t immI, Register rd); \
371 void MOVE(Register rs, Register rd); \
372 void MOVNE(Register rs, Register rd); \
373 void MOVL(Register rs, Register rd); \
374 void MOVLE(Register rs, Register rd); \
375 void MOVG(Register rs, Register rd); \
376 void MOVGE(Register rs, Register rd); \
377 void MOVLEU(Register rs, Register rd); \
378 void MOVGU(Register rs, Register rd); \
379 void MOVCC(Register rs, Register rd); \
380 void MOVCS(Register rs, Register rd); \
381 void MOVVC(Register rs, Register rd); \
382 void MOVEI(int32_t simm11, Register rd); \
383 void MOVNEI(int32_t simm11, Register rd); \
384 void MOVLI(int32_t simm11, Register rd); \
385 void MOVLEI(int32_t simm11, Register rd); \
386 void MOVGI(int32_t simm11, Register rd); \
387 void MOVGEI(int32_t simm11, Register rd); \
388 void MOVLEUI(int32_t simm11, Register rd); \
389 void MOVGUI(int32_t simm11, Register rd); \
390 void MOVCCI(int32_t simm11, Register rd); \
391 void MOVCSI(int32_t simm11, Register rd); \
392 void MOVVSI(int32_t simm11, Register rd); \
393 void MOVFEI(int32_t simm11, Register rd); \
394 void MOVFLI(int32_t simm11, Register rd); \
395 void MOVFLEI(int32_t simm11, Register rd); \
396 void MOVFGI(int32_t simm11, Register rd); \
397 void MOVFGEI(int32_t simm11, Register rd); \
398 void FMOVDNE(Register rs, Register rd); \
399 void FMOVDL(Register rs, Register rd); \
400 void FMOVDLE(Register rs, Register rd); \
401 void FMOVDLEU(Register rs, Register rd); \
402 void FMOVDG(Register rs, Register rd); \
403 void FMOVDGU(Register rs, Register rd); \
404 void FMOVDGE(Register rs, Register rd); \
405 void FMOVDCC(Register rs, Register rd); \
406 void FMOVDCS(Register rs, Register rd); \
407 void FMOVDFNE(Register rs, Register rd); \
408 void FMOVDFUG(Register rs, Register rd); \
409 void FMOVDFUGE(Register rs, Register rd); \
410 void FMOVDFUL(Register rs, Register rd); \
411 void FMOVDFULE(Register rs, Register rd); \
413 void RDY(Register rd); \
414 void RESTORE(Register rs1, Register rs2, Register rd); \
415 void SAVE(Register rs1, Register rs2, Register rd); \
416 void SAVEI(Register rs1, int32_t simm13, Register rd); \
417 void SETHI(int32_t immI, Register rd); \
418 void SET32(int32_t immI, Register rd); \
419 void SLL(Register rs1, Register rs2, Register rd); \
420 void SRA(Register rs1, Register rs2, Register rd); \
421 void SRAI(Register rs1, int32_t shcnt32, Register rd); \
422 void SRL(Register rs1, Register rs2, Register rd); \
423 void STF(Register rd, Register rs1, Register rs2); \
424 void STFI(Register rd, int32_t simm13, Register rs1); \
425 void STF32(Register rd, int32_t immI, Register rs1); \
426 void STDF32(Register rd, int32_t immI, Register rs1); \
427 void STW(Register rd, Register rs1, Register rs2); \
428 void STWI(Register rd, int32_t simm13, Register rs1); \
429 void STW32(Register rd, int32_t immI, Register rs1); \
430 void STB(Register rd, Register rs1, Register rs2); \
431 void STBI(Register rd, int32_t simm13, Register rs1); \
432 void STB32(Register rd, int32_t immI, Register rs1); \
433 bool isIMM13(int32_t imm) { return (imm) <= 0xfff && (imm) >= -0x1000; } \
434 bool isIMM19(int32_t imm) { return (imm) <= 0x3ffff && (imm) >= -0x40000; } \
435 bool isIMM22(int32_t imm) { return (imm) <= 0x1fffff && (imm) >= -0x200000; } \
436 void JMP_long_nocheck(int32_t t); \
437 void JMP_long(int32_t t); \
438 void JMP_long_placeholder(); \
439 int32_t JCC(void *t); \
441 void MR(Register rd, Register rs);
443 #endif // __nanojit_NativeSparc__