* src/vm/jit/alpha/codegen.h: Removed M_COPY.
[cacao.git] / src / vm / jit / mips / codegen.h
1 /* src/vm/jit/mips/codegen.h - code generation macros and definitions for MIPS
2
3    Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Authors: Andreas Krall
28
29    $Id: codegen.h 5632 2006-10-02 13:43:15Z edwin $
30
31 */
32
33
34 #ifndef _CODEGEN_H
35 #define _CODEGEN_H
36
37 #include "config.h"
38 #include "vm/types.h"
39
40 #include "vm/jit/jit.h"
41
42
43 /* some defines ***************************************************************/
44
45 #define PATCHER_CALL_SIZE    2 * 4      /* size in bytes of a patcher call    */
46
47
48 /* additional functions and macros to generate code ***************************/
49
50 #define gen_nullptr_check(objreg) \
51     if (checknull) { \
52         M_BEQZ(objreg, 0); \
53         codegen_add_nullpointerexception_ref(cd); \
54         M_NOP; \
55     }
56
57 #define gen_bound_check \
58     if (checkbounds) { \
59         M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size)); \
60         M_CMPULT(s2, REG_ITMP3, REG_ITMP3); \
61         M_BEQZ(REG_ITMP3, 0); \
62         codegen_add_arrayindexoutofboundsexception_ref(cd, s2); \
63         M_NOP; \
64     }
65
66 #define gen_div_check(r) \
67     do { \
68         M_BEQZ((r), 0); \
69         codegen_add_arithmeticexception_ref(cd); \
70         M_NOP; \
71     } while (0)
72
73
74 /* MCODECHECK(icnt) */
75
76 #define MCODECHECK(icnt) \
77     do { \
78         if ((cd->mcodeptr + (icnt) * 4) > cd->mcodeend) \
79             codegen_increase(cd); \
80     } while (0)
81
82
83 #define ALIGNCODENOP \
84     if ((s4) ((ptrint) cd->mcodeptr & 7)) { \
85         M_NOP; \
86     }
87
88
89 #define M_INTMOVE(a,b) if (a != b) { M_MOV(a, b); }
90
91 #define M_FLTMOVE(a,b) \
92     do { \
93         if ((a) != (b)) \
94             M_FMOV(a, b); \
95     } while (0)
96
97 #define M_DBLMOVE(a,b) \
98     do { \
99         if ((a) != (b)) \
100             M_DMOV(a, b); \
101     } while (0)
102
103 #define ICONST(r,c)                     emit_iconst(cd, (r), (c))
104 #define LCONST(r,c)                     emit_lconst(cd, (r), (c))
105
106
107 /* macros to create code ******************************************************/
108
109 /* code generation macros operands:
110       op ..... opcode
111       fu ..... function-number
112       rs ..... register number source 1
113       rt ..... register number or constant integer source 2
114       rd ..... register number destination
115       imm .... immediate/offset
116       sa ..... shift amount
117 */
118
119
120 #define M_ITYPE(op,rs,rt,imm) \
121     do { \
122         *((u4 *) cd->mcodeptr) = (((op) << 26) | ((rs) << 21) | ((rt) << 16) | ((imm) & 0xffff)); \
123         cd->mcodeptr += 4; \
124     } while (0)
125
126 #define M_JTYPE(op,imm) \
127     do { \
128         *((u4 *) cd->mcodeptr) = (((op) << 26) | ((off) & 0x3ffffff)); \
129         cd->mcodeptr += 4; \
130     } while (0)
131
132 #define M_RTYPE(op,rs,rt,rd,sa,fu) \
133     do { \
134         *((u4 *) cd->mcodeptr) = (((op) << 26) | ((rs) << 21) | ((rt) << 16) | ((rd) << 11) | ((sa) << 6) | (fu)); \
135         cd->mcodeptr += 4; \
136     } while (0)
137
138 #define M_FP2(fu, fmt, fs, fd)       M_RTYPE(0x11, fmt,  0, fs, fd, fu)
139 #define M_FP3(fu, fmt, fs, ft, fd)   M_RTYPE(0x11, fmt, ft, fs, fd, fu)
140
141 #define FMT_F  16
142 #define FMT_D  17
143 #define FMT_I  20
144 #define FMT_L  21
145
146
147 /* macros for all used commands (see a MIPS-manual for description) ***********/
148
149 /* load/store macros use the form OPERATION(source/dest, base, offset)        */
150
151 #define M_LDA(a,b,disp) \
152     do { \
153         s4 lo = (short) (disp); \
154         s4 hi = (short) (((disp) - lo) >> 16); \
155         if (hi == 0) { \
156             M_AADD_IMM(b,lo,a); \
157         } else { \
158             M_LUI(REG_ITMP3,hi); \
159             M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3); \
160             M_AADD(REG_ITMP3,b,a); \
161         } \
162     } while (0)
163
164 #define M_BLDS(a,b,disp)        M_ITYPE(0x20,b,a,disp)          /*  8 load    */
165 #define M_BLDU(a,b,disp)        M_ITYPE(0x24,b,a,disp)          /*  8 load    */
166 #define M_SLDS(a,b,disp)        M_ITYPE(0x21,b,a,disp)          /* 16 load    */
167 #define M_SLDU(a,b,disp)        M_ITYPE(0x25,b,a,disp)          /* 16 load    */
168
169 #define M_ILD_INTERN(a,b,disp)  M_ITYPE(0x23,b,a,disp)          /* 32 load    */
170 #define M_LLD_INTERN(a,b,disp)  M_ITYPE(0x37,b,a,disp)          /* 64 load    */
171
172 #define M_ILD(a,b,disp) \
173     do { \
174         s4 lo = (short) (disp); \
175         s4 hi = (short) (((disp) - lo) >> 16); \
176         if (hi == 0) { \
177             M_ILD_INTERN(a,b,lo); \
178         } else { \
179             M_LUI(a,hi); \
180             M_AADD(b,a,a); \
181             M_ILD_INTERN(a,a,lo); \
182         } \
183     } while (0)
184
185 #define M_LLD(a,b,disp) \
186     do { \
187         s4 lo = (short) (disp); \
188         s4 hi = (short) (((disp) - lo) >> 16); \
189         if (hi == 0) { \
190             M_LLD_INTERN(a,b,lo); \
191         } else { \
192             M_LUI(a,hi); \
193             M_AADD(b,a,a); \
194             M_LLD_INTERN(a,a,lo); \
195         } \
196     } while (0)
197
198 #define M_BST(a,b,disp)         M_ITYPE(0x28,b,a,disp)          /*  8 store   */
199 #define M_SST(a,b,disp)         M_ITYPE(0x29,b,a,disp)          /* 16 store   */
200
201 #define M_IST_INTERN(a,b,disp)  M_ITYPE(0x2b,b,a,disp)          /* 32 store   */
202 #define M_LST_INTERN(a,b,disp)  M_ITYPE(0x3f,b,a,disp)          /* 64 store   */
203
204 #define M_IST(a,b,disp) \
205     do { \
206         s4 lo = (short) (disp); \
207         s4 hi = (short) (((disp) - lo) >> 16); \
208         if (hi == 0) { \
209             M_IST_INTERN(a,b,lo); \
210         } else { \
211             M_LUI(REG_ITMP3, hi); \
212             M_AADD(b, REG_ITMP3, REG_ITMP3); \
213             M_IST_INTERN(a,REG_ITMP3,lo); \
214         } \
215     } while (0)
216
217 #define M_LST(a,b,disp) \
218     do { \
219         s4 lo = (short) (disp); \
220         s4 hi = (short) (((disp) - lo) >> 16); \
221         if (hi == 0) { \
222             M_LST_INTERN(a,b,lo); \
223         } else { \
224             M_LUI(REG_ITMP3, hi); \
225             M_AADD(b, REG_ITMP3, REG_ITMP3); \
226             M_LST_INTERN(a,REG_ITMP3,lo); \
227         } \
228     } while (0)
229
230 #define M_FLD_INTERN(a,b,disp)  M_ITYPE(0x31,b,a,disp)          /* load flt   */
231 #define M_DLD_INTERN(a,b,disp)  M_ITYPE(0x35,b,a,disp)          /* load dbl   */
232
233 #define M_FLD(a,b,disp) \
234     do { \
235         s4 lo = (short) (disp); \
236         s4 hi = (short) (((disp) - lo) >> 16); \
237         if (hi == 0) { \
238             M_FLD_INTERN(a,b,lo); \
239         } else { \
240             M_LUI(REG_ITMP3,hi); \
241             M_AADD(b,REG_ITMP3,REG_ITMP3); \
242             M_FLD_INTERN(a,REG_ITMP3,lo); \
243         } \
244     } while (0)
245
246 #define M_DLD(a,b,disp) \
247     do { \
248         s4 lo = (short) (disp); \
249         s4 hi = (short) (((disp) - lo) >> 16); \
250         if (hi == 0) { \
251             M_DLD_INTERN(a,b,lo); \
252         } else { \
253             M_LUI(REG_ITMP3,hi); \
254             M_AADD(b,REG_ITMP3,REG_ITMP3); \
255             M_DLD_INTERN(a,REG_ITMP3,lo); \
256         } \
257     } while (0)
258
259 #define M_FST_INTERN(a,b,disp)  M_ITYPE(0x39,b,a,disp)          /* store flt  */
260 #define M_DST_INTERN(a,b,disp)  M_ITYPE(0x3d,b,a,disp)          /* store dbl  */
261
262 #define M_FST(a,b,disp) \
263     do { \
264         s4 lo = (short) (disp); \
265         s4 hi = (short) (((disp) - lo) >> 16); \
266         if (hi == 0) { \
267             M_FST_INTERN(a,b,lo); \
268         } else { \
269             M_LUI(REG_ITMP3, hi); \
270             M_AADD(b, REG_ITMP3, REG_ITMP3); \
271             M_FST_INTERN(a,REG_ITMP3,lo); \
272         } \
273     } while (0)
274
275 #define M_DST(a,b,disp) \
276     do { \
277         s4 lo = (short) (disp); \
278         s4 hi = (short) (((disp) - lo) >> 16); \
279         if (hi == 0) { \
280             M_DST_INTERN(a,b,lo); \
281         } else { \
282             M_LUI(REG_ITMP3, hi); \
283             M_AADD(b, REG_ITMP3, REG_ITMP3); \
284             M_DST_INTERN(a,REG_ITMP3,lo); \
285         } \
286     } while (0)
287
288 #define M_BEQ(a,b,disp)         M_ITYPE(0x04,a,b,disp)          /* br a == b  */
289 #define M_BNE(a,b,disp)         M_ITYPE(0x05,a,b,disp)          /* br a != b  */
290 #define M_BEQZ(a,disp)          M_ITYPE(0x04,a,0,disp)          /* br a == 0  */
291 #define M_BLTZ(a,disp)          M_ITYPE(0x01,a,0,disp)          /* br a <  0  */
292 #define M_BLEZ(a,disp)          M_ITYPE(0x06,a,0,disp)          /* br a <= 0  */
293 #define M_BNEZ(a,disp)          M_ITYPE(0x05,a,0,disp)          /* br a != 0  */
294 #define M_BGEZ(a,disp)          M_ITYPE(0x01,a,1,disp)          /* br a >= 0  */
295 #define M_BGTZ(a,disp)          M_ITYPE(0x07,a,0,disp)          /* br a >  0  */
296
297 #define M_BEQL(a,b,disp)        M_ITYPE(0x14,a,b,disp)          /* br a == b  */
298 #define M_BNEL(a,b,disp)        M_ITYPE(0x15,a,b,disp)          /* br a != b  */
299 #define M_BEQZL(a,disp)         M_ITYPE(0x14,a,0,disp)          /* br a == 0  */
300 #define M_BLTZL(a,disp)         M_ITYPE(0x01,a,2,disp)          /* br a <  0  */
301 #define M_BLEZL(a,disp)         M_ITYPE(0x16,a,0,disp)          /* br a <= 0  */
302 #define M_BNEZL(a,disp)         M_ITYPE(0x15,a,0,disp)          /* br a != 0  */
303 #define M_BGEZL(a,disp)         M_ITYPE(0x01,a,3,disp)          /* br a >= 0  */
304 #define M_BGTZL(a,disp)         M_ITYPE(0x17,a,0,disp)          /* br a >  0  */
305
306 #define M_BR(disp)              M_ITYPE(0x04,0,0,disp)          /* branch     */
307 #define M_BRS(disp)             M_ITYPE(0x01,0,17,disp)         /* branch sbr */
308
309 #define M_JMP(a)                M_RTYPE(0,a,0,0,0,0x08)         /* jump       */
310 #define M_JSR(r,a)              M_RTYPE(0,a,0,r,0,0x09)         /* call       */
311 #define M_RET(a)                M_RTYPE(0,a,0,0,0,0x08)         /* return     */
312
313 #define M_TGE(a,b,code)         M_RTYPE(0,a,b,0,code&3ff,0x30)  /* trp a >= b */
314 #define M_TGEU(a,b,code)        M_RTYPE(0,a,b,0,code&3ff,0x31)  /* trp a >= b */
315 #define M_TLT(a,b,code)         M_RTYPE(0,a,b,0,code&3ff,0x32)  /* trp a <  b */
316 #define M_TLTU(a,b,code)        M_RTYPE(0,a,b,0,code&3ff,0x33)  /* trp a <  b */
317 #define M_TEQ(a,b,code)         M_RTYPE(0,a,b,0,code&3ff,0x34)  /* trp a == b */
318 #define M_TNE(a,b,code)         M_RTYPE(0,a,b,0,code&3ff,0x36)  /* trp a != b */
319 #define M_TLE(a,b,code)         M_RTYPE(0,b,a,0,code&3ff,0x30)  /* trp a <= b */
320 #define M_TLEU(a,b,code)        M_RTYPE(0,b,a,0,code&3ff,0x31)  /* trp a <= b */
321 #define M_TGT(a,b,code)         M_RTYPE(0,b,a,0,code&3ff,0x32)  /* trp a >  b */
322 #define M_TGTU(a,b,code)        M_RTYPE(0,b,a,0,code&3ff,0x33)  /* trp a >  b */
323
324 #define M_TGE_IMM(a,b)          M_ITYPE(1,a,0x08,b)             /* trp a >= b */
325 #define M_TGEU_IMM(a,b)         M_ITYPE(1,a,0x09,b)             /* trp a >= b */
326 #define M_TLT_IMM(a,b)          M_ITYPE(1,a,0x0a,b)             /* trp a <  b */
327 #define M_TLTU_IMM(a,b)         M_ITYPE(1,a,0x0b,b)             /* trp a <  b */
328 #define M_TEQ_IMM(a,b)          M_ITYPE(1,a,0x0c,b)             /* trp a == b */
329 #define M_TNE_IMM(a,b)          M_ITYPE(1,a,0x0e,b)             /* trp a != b */
330 #if 0
331 #define M_TGT_IMM(a,b)          M_ITYPE(1,a,0x08,b+1)           /* trp a >  b */
332 #define M_TGTU_IMM(a,b)         M_ITYPE(1,a,0x09,b+1)           /* trp a >  b */
333 #define M_TLE_IMM(a,b)          M_ITYPE(1,a,0x0a,b+1)           /* trp a <= b */
334 #define M_TLEU_IMM(a,b)         M_ITYPE(1,a,0x0b,b+1)           /* trp a <= b */
335 #endif
336
337 /* arithmetic macros use the form OPERATION(source, source/immediate, dest)   */
338
339 #define M_IADD(a,b,c)           M_RTYPE(0,a,b,c,0,0x21)         /* 32 add     */
340 #define M_LADD(a,b,c)           M_RTYPE(0,a,b,c,0,0x2d)         /* 64 add     */
341 #define M_ISUB(a,b,c)           M_RTYPE(0,a,b,c,0,0x23)         /* 32 sub     */
342 #define M_LSUB(a,b,c)           M_RTYPE(0,a,b,c,0,0x2f)         /* 64 sub     */
343 #define M_IMUL(a,b)             M_ITYPE(0,a,b,0x18)             /* 32 mul     */
344 #define M_LMUL(a,b)             M_ITYPE(0,a,b,0x1c)             /* 64 mul     */
345 #define M_IDIV(a,b)             M_ITYPE(0,a,b,0x1a)             /* 32 div     */
346 #define M_LDIV(a,b)             M_ITYPE(0,a,b,0x1e)             /* 64 div     */
347
348 #define M_MFLO(a)               M_RTYPE(0,0,0,a,0,0x12)         /* quotient   */
349 #define M_MFHI(a)               M_RTYPE(0,0,0,a,0,0x10)         /* remainder  */
350
351 #define M_IADD_IMM(a,b,c)       M_ITYPE(0x09,a,c,b)             /* 32 add     */
352 #define M_LADD_IMM(a,b,c)       M_ITYPE(0x19,a,c,b)             /* 64 add     */
353 #define M_ISUB_IMM(a,b,c)       M_ITYPE(0x09,a,c,-(b))          /* 32 sub     */
354 #define M_LSUB_IMM(a,b,c)       M_ITYPE(0x19,a,c,-(b))          /* 64 sub     */
355
356 #define M_LUI(a,imm)            M_ITYPE(0x0f,0,a,imm)           /* a = imm<<16*/
357
358 #define M_CMPLT(a,b,c)          M_RTYPE(0,a,b,c,0,0x2a)         /* c = a <  b */
359 #define M_CMPGT(a,b,c)          M_RTYPE(0,b,a,c,0,0x2a)         /* c = a >  b */
360
361 #define M_CMPULT(a,b,c)         M_RTYPE(0,a,b,c,0,0x2b)         /* c = a <  b */
362 #define M_CMPUGT(a,b,c)         M_RTYPE(0,b,a,c,0,0x2b)         /* c = a >  b */
363
364 #define M_CMPLT_IMM(a,b,c)      M_ITYPE(0x0a,a,c,b)             /* c = a <  b */
365 #define M_CMPULT_IMM(a,b,c)     M_ITYPE(0x0b,a,c,b)             /* c = a <  b */
366
367 #define M_AND(a,b,c)            M_RTYPE(0,a,b,c,0,0x24)         /* c = a &  b */
368 #define M_OR( a,b,c)            M_RTYPE(0,a,b,c,0,0x25)         /* c = a |  b */
369 #define M_XOR(a,b,c)            M_RTYPE(0,a,b,c,0,0x26)         /* c = a ^  b */
370
371 #define M_AND_IMM(a,b,c)        M_ITYPE(0x0c,a,c,b)             /* c = a &  b */
372 #define M_OR_IMM( a,b,c)        M_ITYPE(0x0d,a,c,b)             /* c = a |  b */
373 #define M_XOR_IMM(a,b,c)        M_ITYPE(0x0e,a,c,b)             /* c = a ^  b */
374
375 #define M_CZEXT(a,c)            M_AND_IMM(a,0xffff,c)           /* c = zext(a)*/
376
377 #define M_ISLL(a,b,c)           M_RTYPE(0,b,a,c,0,0x04)         /* c = a << b */
378 #define M_ISRL(a,b,c)           M_RTYPE(0,b,a,c,0,0x06)         /* c = a >>>b */
379 #define M_ISRA(a,b,c)           M_RTYPE(0,b,a,c,0,0x07)         /* c = a >> b */
380 #define M_LSLL(a,b,c)           M_RTYPE(0,b,a,c,0,0x14)         /* c = a << b */
381 #define M_LSRL(a,b,c)           M_RTYPE(0,b,a,c,0,0x16)         /* c = a >>>b */
382 #define M_LSRA(a,b,c)           M_RTYPE(0,b,a,c,0,0x17)         /* c = a >> b */
383
384 #define M_ISLL_IMM(a,b,c)       M_RTYPE(0,0,a,c,(b)&31,0x00)    /* c = a << b */
385 #define M_ISRL_IMM(a,b,c)       M_RTYPE(0,0,a,c,(b)&31,0x02)    /* c = a >>>b */
386 #define M_ISRA_IMM(a,b,c)       M_RTYPE(0,0,a,c,(b)&31,0x03)    /* c = a >> b */
387 #define M_LSLL_IMM(a,b,c) M_RTYPE(0,0,a,c,(b)&31,0x38+((b)>>3&4)) /*c = a << b*/
388 #define M_LSRL_IMM(a,b,c) M_RTYPE(0,0,a,c,(b)&31,0x3a+((b)>>3&4)) /*c = a >>>b*/
389 #define M_LSRA_IMM(a,b,c) M_RTYPE(0,0,a,c,(b)&31,0x3b+((b)>>3&4)) /*c = a >> b*/
390
391 #define M_MOV(a,c)              M_OR(a,0,c)                     /* c = a      */
392 #define M_CLR(c)                M_OR(0,0,c)                     /* c = 0      */
393 #define M_NOP                   M_ISLL_IMM(0,0,0)               /* ;          */
394
395 /* floating point macros use the form OPERATION(source, source, dest)         */
396
397 #define M_FADD(a,b,c)           M_FP3(0x00,FMT_F,a,b,c)         /* flt add    */
398 #define M_DADD(a,b,c)           M_FP3(0x00,FMT_D,a,b,c)         /* dbl add    */
399 #define M_FSUB(a,b,c)           M_FP3(0x01,FMT_F,a,b,c)         /* flt sub    */
400 #define M_DSUB(a,b,c)           M_FP3(0x01,FMT_D,a,b,c)         /* dbl sub    */
401 #define M_FMUL(a,b,c)           M_FP3(0x02,FMT_F,a,b,c)         /* flt mul    */
402 #define M_DMUL(a,b,c)           M_FP3(0x02,FMT_D,a,b,c)         /* dbl mul    */
403 #define M_FDIV(a,b,c)           M_FP3(0x03,FMT_F,a,b,c)         /* flt div    */
404 #define M_DDIV(a,b,c)           M_FP3(0x03,FMT_D,a,b,c)         /* dbl div    */
405
406 #define M_FSQRT(a,c)            M_FP2(0x04,FMT_F,a,c)           /* flt sqrt   */
407 #define M_DSQRT(a,c)            M_FP2(0x04,FMT_D,a,c)           /* dbl sqrt   */
408 #define M_FABS(a,c)             M_FP2(0x05,FMT_F,a,c)           /* flt abs    */
409 #define M_DABS(a,c)             M_FP2(0x05,FMT_D,a,c)           /* dbl abs    */
410 #define M_FMOV(a,c)             M_FP2(0x06,FMT_F,a,c)           /* flt mov    */
411 #define M_DMOV(a,c)             M_FP2(0x06,FMT_D,a,c)           /* dbl mov    */
412 #define M_FNEG(a,c)             M_FP2(0x07,FMT_F,a,c)           /* flt neg    */
413 #define M_DNEG(a,c)             M_FP2(0x07,FMT_D,a,c)           /* dbl neg    */
414
415 #define M_ROUNDFI(a,c)          M_FP2(0x0c,FMT_F,a,c)           /* flt roundi */
416 #define M_ROUNDDI(a,c)          M_FP2(0x0c,FMT_D,a,c)           /* dbl roundi */
417 #define M_TRUNCFI(a,c)          M_FP2(0x0d,FMT_F,a,c)           /* flt trunci */
418 #define M_TRUNCDI(a,c)          M_FP2(0x0d,FMT_D,a,c)           /* dbl trunci */
419 #define M_CEILFI(a,c)           M_FP2(0x0e,FMT_F,a,c)           /* flt ceili  */
420 #define M_CEILDI(a,c)           M_FP2(0x0e,FMT_D,a,c)           /* dbl ceili  */
421 #define M_FLOORFI(a,c)          M_FP2(0x0f,FMT_F,a,c)           /* flt trunci */
422 #define M_FLOORDI(a,c)          M_FP2(0x0f,FMT_D,a,c)           /* dbl trunci */
423
424 #define M_ROUNDFL(a,c)          M_FP2(0x08,FMT_F,a,c)           /* flt roundl */
425 #define M_ROUNDDL(a,c)          M_FP2(0x08,FMT_D,a,c)           /* dbl roundl */
426 #define M_TRUNCFL(a,c)          M_FP2(0x09,FMT_F,a,c)           /* flt truncl */
427 #define M_TRUNCDL(a,c)          M_FP2(0x09,FMT_D,a,c)           /* dbl truncl */
428 #define M_CEILFL(a,c)           M_FP2(0x0a,FMT_F,a,c)           /* flt ceill  */
429 #define M_CEILDL(a,c)           M_FP2(0x0a,FMT_D,a,c)           /* dbl ceill  */
430 #define M_FLOORFL(a,c)          M_FP2(0x0b,FMT_F,a,c)           /* flt truncl */
431 #define M_FLOORDL(a,c)          M_FP2(0x0b,FMT_D,a,c)           /* dbl truncl */
432
433 #define M_CVTDF(a,c)            M_FP2(0x20,FMT_D,a,c)           /* dbl2flt    */
434 #define M_CVTIF(a,c)            M_FP2(0x20,FMT_I,a,c)           /* int2flt    */
435 #define M_CVTLF(a,c)            M_FP2(0x20,FMT_L,a,c)           /* long2flt   */
436 #define M_CVTFD(a,c)            M_FP2(0x21,FMT_F,a,c)           /* flt2dbl    */
437 #define M_CVTID(a,c)            M_FP2(0x21,FMT_I,a,c)           /* int2dbl    */
438 #define M_CVTLD(a,c)            M_FP2(0x21,FMT_L,a,c)           /* long2dbl   */
439 #define M_CVTFI(a,c)            M_FP2(0x24,FMT_F,a,c)           /* flt2int    */
440 #define M_CVTDI(a,c)            M_FP2(0x24,FMT_D,a,c)           /* dbl2int    */
441 #define M_CVTFL(a,c)            M_FP2(0x25,FMT_F,a,c)           /* flt2long   */
442 #define M_CVTDL(a,c)            M_FP2(0x25,FMT_D,a,c)           /* dbl2long   */
443
444 #define M_MOVDI(d,i)            M_FP3(0,0,d,i,0)                /* i = d      */
445 #define M_MOVDL(d,l)            M_FP3(0,1,d,l,0)                /* l = d      */
446 #define M_MOVID(i,d)            M_FP3(0,4,d,i,0)                /* d = i      */
447 #define M_MOVLD(l,d)            M_FP3(0,5,d,l,0)                /* d = l      */
448
449 #define M_DMFC1(l,f)            M_FP3(0,1,f,l,0)
450 #define M_DMTC1(l,f)            M_FP3(0,5,f,l,0)
451
452 #define M_FCMPFF(a,b)           M_FP3(0x30,FMT_F,a,b,0)         /* c = a == b */
453 #define M_FCMPFD(a,b)           M_FP3(0x30,FMT_D,a,b,0)         /* c = a == b */
454 #define M_FCMPUNF(a,b)          M_FP3(0x31,FMT_F,a,b,0)         /* c = a == b */
455 #define M_FCMPUND(a,b)          M_FP3(0x31,FMT_D,a,b,0)         /* c = a == b */
456 #define M_FCMPEQF(a,b)          M_FP3(0x32,FMT_F,a,b,0)         /* c = a == b */
457 #define M_FCMPEQD(a,b)          M_FP3(0x32,FMT_D,a,b,0)         /* c = a == b */
458 #define M_FCMPUEQF(a,b)         M_FP3(0x33,FMT_F,a,b,0)         /* c = a == b */
459 #define M_FCMPUEQD(a,b)         M_FP3(0x33,FMT_D,a,b,0)         /* c = a == b */
460 #define M_FCMPOLTF(a,b)         M_FP3(0x34,FMT_F,a,b,0)         /* c = a <  b */
461 #define M_FCMPOLTD(a,b)         M_FP3(0x34,FMT_D,a,b,0)         /* c = a <  b */
462 #define M_FCMPULTF(a,b)         M_FP3(0x35,FMT_F,a,b,0)         /* c = a <  b */
463 #define M_FCMPULTD(a,b)         M_FP3(0x35,FMT_D,a,b,0)         /* c = a <  b */
464 #define M_FCMPOLEF(a,b)         M_FP3(0x36,FMT_F,a,b,0)         /* c = a <= b */
465 #define M_FCMPOLED(a,b)         M_FP3(0x36,FMT_D,a,b,0)         /* c = a <= b */
466 #define M_FCMPULEF(a,b)         M_FP3(0x37,FMT_F,a,b,0)         /* c = a <= b */
467 #define M_FCMPULED(a,b)         M_FP3(0x37,FMT_D,a,b,0)         /* c = a <= b */
468
469 #define M_FBF(disp)             M_ITYPE(0x11,8,0,disp)          /* br false   */
470 #define M_FBT(disp)             M_ITYPE(0x11,8,1,disp)          /* br true    */
471 #define M_FBFL(disp)            M_ITYPE(0x11,8,2,disp)          /* br false   */
472 #define M_FBTL(disp)            M_ITYPE(0x11,8,3,disp)          /* br true    */
473
474 #define M_CMOVF(a,b)                    M_RTYPE(0x00,a,0,b,0,1)
475 #define M_CMOVT(a,b)                    M_RTYPE(0x00,a,1,b,0,1)
476
477
478 /*
479  * Load Address pseudo instruction:
480  * -n32 addressing mode -> 32 bit addrs, -64 addressing mode -> 64 bit addrs
481  */
482 #if SIZEOF_VOID_P == 8
483
484 #define POINTERSHIFT 3
485
486 #define M_ALD_INTERN(a,b,disp)  M_LLD_INTERN(a,b,disp)
487 #define M_ALD(a,b,disp)         M_LLD(a,b,disp)
488 #define M_AST_INTERN(a,b,disp)  M_LST_INTERN(a,b,disp)
489 #define M_AST(a,b,disp)         M_LST(a,b,disp)
490 #define M_AADD(a,b,c)           M_LADD(a,b,c)
491 #define M_AADD_IMM(a,b,c)       M_LADD_IMM(a,b,c)
492 #define M_ASUB_IMM(a,b,c)       M_LSUB_IMM(a,b,c)
493 #define M_ASLL_IMM(a,b,c)       M_LSLL_IMM(a,b,c)
494
495 #else /* SIZEOF_VOID_P == 8 */
496
497 #define POINTERSHIFT 2
498
499 #define M_ALD_INTERN(a,b,disp)  M_ILD_INTERN(a,b,disp)
500 #define M_ALD(a,b,disp)         M_ILD(a,b,disp)
501 #define M_AST_INTERN(a,b,disp)  M_IST_INTERN(a,b,disp)
502 #define M_AST(a,b,disp)         M_IST(a,b,disp)
503 #define M_AADD(a,b,c)           M_IADD(a,b,c)
504 #define M_AADD_IMM(a,b,c)       M_IADD_IMM(a,b,c)
505 #define M_ASUB_IMM(a,b,c)       M_ISUB_IMM(a,b,c)
506 #define M_ASLL_IMM(a,b,c)       M_ISLL_IMM(a,b,c)
507
508 #endif /* SIZEOF_VOID_P == 8 */
509
510
511 /* function gen_resolvebranch **************************************************
512
513         backpatches a branch instruction; MIPS branch instructions are very
514         regular, so it is only necessary to overwrite some fixed bits in the
515         instruction.
516
517         parameters: ip ... pointer to instruction after branch (void*)
518                     so ... offset of instruction after branch  (s4)
519                     to ... offset of branch target             (s4)
520
521 *******************************************************************************/
522
523 #define gen_resolvebranch(ip,so,to) \
524     do { \
525         s4 offset; \
526         \
527         offset = ((s4) (to) - (so)) >> 2; \
528         \
529         /* On the MIPS we can only branch signed 16-bit instruction words */ \
530         /* (signed 18-bit = 32KB = +/- 16KB). Check this!                 */ \
531         \
532         if ((offset < (s4) 0xffff8000) || (offset > (s4) 0x00007fff)) { \
533             throw_cacao_exception_exit(string_java_lang_InternalError, \
534                                        "Jump offset is out of range: %d > +/-%d", \
535                                        offset, 0x00007fff); \
536         } \
537         \
538         ((s4 *) (ip))[-1] |= (offset & 0x0000ffff); \
539     } while (0)
540
541
542 /* function prototypes ********************************************************/
543
544 void docacheflush(u1 *p, long bytelen);
545
546 #endif /* _CODEGEN_H */
547
548
549 /*
550  * These are local overrides for various environment variables in Emacs.
551  * Please do not remove this and leave it at the end of the file, where
552  * Emacs will automagically detect them.
553  * ---------------------------------------------------------------------
554  * Local variables:
555  * mode: c
556  * indent-tabs-mode: t
557  * c-basic-offset: 4
558  * tab-width: 4
559  * End:
560  */