Bug 591908: Remove Math.floor from microbenchmark iterations/sec calculation (r=fklockii)
[tamarin-stm.git] / nanojit / NativeSparc.h
blobf2268716d3a41a21f4bc8f5fa7f6309e9f471a49
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
14 * License.
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.
23 * Contributor(s):
24 * Adobe AS3 Team
25 * leon.sha@oracle.com
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"
48 #define count_instr()
49 #define count_ret()
50 #define count_push()
51 #define count_pop()
52 #define count_st()
53 #define count_stq()
54 #define count_ld()
55 #define count_ldq()
56 #define count_call()
57 #define count_calli()
58 #define count_prolog()
59 #define count_alu()
60 #define count_mov()
61 #define count_fpu()
62 #define count_jmp()
63 #define count_jcc()
64 #define count_fpuld()
65 #define count_aluld()
66 #define count_alust()
67 #define count_pushld()
68 #define count_imt()
70 namespace nanojit
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
93 static const Register
94 G0 = { 0 },
95 G1 = { 1 },
96 G2 = { 2 },
97 G3 = { 3 },
98 G4 = { 4 },
99 G5 = { 5 }, // Reserved for system
100 G6 = { 6 }, // Reserved for system
101 G7 = { 7 }, // Reserved for system
103 O0 = { 8 },
104 O1 = { 9 },
105 O2 = { 10 },
106 O3 = { 11 },
107 O4 = { 12 },
108 O5 = { 13 },
109 O6 = { 14 }, // SP
110 O7 = { 15 }, // Not used.
112 L0 = { 16 },
113 L1 = { 17 },
114 L2 = { 18 },
115 L3 = { 19 },
116 L4 = { 20 },
117 L5 = { 21 },
118 L6 = { 22 },
119 L7 = { 23 },
121 I0 = { 24 },
122 I1 = { 25 },
123 I2 = { 26 },
124 I3 = { 27 },
125 I4 = { 28 },
126 I5 = { 29 },
127 I6 = { 30 }, // FP
128 I7 = { 31 }, // Not used
130 SP = O6,
131 FP = I6,
133 F0 = { 32 },
134 F1 = { 33 },
135 F2 = { 34 },
136 F3 = { 35 },
137 F4 = { 36 },
138 F5 = { 37 },
139 F6 = { 38 },
140 F7 = { 39 },
141 F8 = { 40 },
142 F9 = { 41 },
143 F10 = { 42 },
144 F11 = { 43 },
145 F12 = { 44 },
146 F13 = { 45 },
147 F14 = { 46 },
148 F15 = { 47 },
149 F16 = { 48 },
150 F17 = { 49 },
151 F18 = { 50 },
152 F19 = { 51 },
153 F20 = { 52 },
154 F21 = { 53 },
155 F22 = { 54 },
156 F23 = { 55 },
157 F24 = { 56 },
158 F25 = { 57 },
159 F26 = { 58 },
160 F27 = { 59 },
161 F28 = { 60 },
162 F29 = { 61 },
163 F30 = { 62 },
164 F31 = { 63 },
166 // helpers
167 FRAME_PTR = G4,
169 deprecated_UnknownReg = { 64 }; // XXX: remove eventually, see bug 538924
171 static const uint32_t FirstRegNum = 0;
172 static const uint32_t LastRegNum = 63;
175 namespace nanojit
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]; \
207 bool has_cmov; \
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) { \
216 --_nIns; \
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; \
222 IMM32(i); \
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; \
238 IMM32(i); \
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); \
412 void NOP(); \
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); \
440 void JMP(void *t); \
441 void MR(Register rd, Register rs);
443 #endif // __nanojit_NativeSparc__