1 /* vm/jit/mips/codegen.h - code generation macros and definitions for mips
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 Institut f. Computersprachen, TU Wien
5 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
6 M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
7 P. Tomsich, J. Wenninger
9 This file is part of CACAO.
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2, or (at
14 your option) any later version.
16 This program is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
26 Contact: cacao@complang.tuwien.ac.at
28 Authors: Andreas Krall
30 $Id: codegen.h 1638 2004-12-01 10:42:28Z twisti $
38 #include "vm/jit/mips/types.h"
41 /* additional functions and macros to generate code ***************************/
43 /* #define BlockPtrOfPC(pc) block+block_index[pc] */
44 #define BlockPtrOfPC(pc) ((basicblock *) iptr->target)
48 #define COUNT_SPILLS count_spills++
54 /* gen_nullptr_check(objreg) */
56 #define gen_nullptr_check(objreg) \
58 M_BEQZ((objreg), 0); \
59 codegen_addxnullrefs(cd, mcodeptr); \
63 #define gen_bound_check \
65 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size)); \
66 M_CMPULT(s2, REG_ITMP3, REG_ITMP3); \
67 M_BEQZ(REG_ITMP3, 0); \
68 codegen_addxboundrefs(cd, mcodeptr, s2); \
73 /* MCODECHECK(icnt) */
75 #define MCODECHECK(icnt) \
76 if ((mcodeptr + (icnt)) > cd->mcodeend) \
77 mcodeptr = codegen_increase(cd, (u1 *) mcodeptr)
80 #define ALIGNCODENOP \
81 if ((int) ((long) mcodeptr & 7)) { \
87 generates an integer-move from register a to b.
88 if a and b are the same int-register, no code will be generated.
91 #define M_INTMOVE(a,b) if (a != b) { M_MOV(a, b); }
95 generates a floating-point-move from register a to b.
96 if a and b are the same float-register, no code will be generated
99 #define M_FLTMOVE(a,b) if (a != b) { M_DMOV(a, b); }
101 #define M_TFLTMOVE(t,a,b) \
105 else {M_FMOV(a,b);} \
108 #define M_TFLD(t,a,b,disp) \
114 #define M_TFST(t,a,b,disp) \
120 #define M_CCFLTMOVE(t1,t2,a,b) \
122 {M_TFLTMOVE(t1,a,b);} \
124 if ((t1)==TYPE_DBL) \
129 #define M_CCFLD(t1,t2,a,b,disp) \
133 M_DLD(REG_FTMP1,b,disp); \
134 if ((t1)==TYPE_DBL) \
135 {M_CVTDF(REG_FTMP1,a);} \
137 {M_CVTFD(REG_FTMP1,a);} \
140 #define M_CCFST(t1,t2,a,b,disp) \
144 if ((t1)==TYPE_DBL) \
145 {M_CVTDF(a,REG_FTMP1);} \
147 {M_CVTFD(a,REG_FTMP1);} \
148 M_DST(REG_FTMP1,b,disp); \
153 this function generates code to fetch data from a pseudo-register
154 into a real register.
155 If the pseudo-register has actually been assigned to a real
156 register, no code will be emitted, since following operations
157 can use this register directly.
159 v: pseudoregister to be fetched from
160 tempregnum: temporary register to be used if v is actually spilled to ram
162 return: the register number, where the operand can be found after
163 fetching (this wil be either tempregnum or the register
164 number allready given to v)
167 #define var_to_reg_int(regnr,v,tempnr) { \
168 if ((v)->flags & INMEMORY) { \
170 M_LLD(tempnr, REG_SP, 8 * (v)->regoff); \
172 } else regnr = (v)->regoff; \
176 #define var_to_reg_flt(regnr,v,tempnr) { \
177 if ((v)->flags & INMEMORY) { \
179 M_DLD(tempnr, REG_SP, 8 * (v)->regoff); \
181 } else regnr = (v)->regoff; \
185 /* store_reg_to_var_xxx:
186 This function generates the code to store the result of an operation
187 back into a spilled pseudo-variable.
188 If the pseudo-variable has not been spilled in the first place, this
189 function will generate nothing.
191 v ............ Pseudovariable
192 tempregnum ... Number of the temporary registers as returned by
196 #define store_reg_to_var_int(sptr, tempregnum) { \
197 if ((sptr)->flags & INMEMORY) { \
199 M_LST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
203 #define store_reg_to_var_flt(sptr, tempregnum) { \
204 if ((sptr)->flags & INMEMORY) { \
206 M_DST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
211 #define M_COPY(from,to) \
212 d = reg_of_var(rd, to, REG_IFTMP); \
213 if ((from->regoff != to->regoff) || \
214 ((from->flags ^ to->flags) & INMEMORY)) { \
215 if (IS_FLT_DBL_TYPE(from->type)) { \
216 var_to_reg_flt(s1, from, d); \
217 M_TFLTMOVE(from->type, s1, d); \
218 store_reg_to_var_flt(to, d); \
220 var_to_reg_int(s1, from, d); \
222 store_reg_to_var_int(to, d); \
227 #define ICONST(r,c) \
228 if ((c) >= -32768 && (c) <= 32767) { \
229 M_IADD_IMM(REG_ZERO, (c), (r)); \
230 } else if ((c) >= 0 && (c) <= 0xffff) { \
231 M_OR_IMM(REG_ZERO, (c), (r)); \
233 a = dseg_adds4(cd, (c)); \
234 M_ILD((r), REG_PV, a); \
237 #define LCONST(r,c) \
238 if ((c) >= -32768 && (c) <= 32767) { \
239 M_LADD_IMM(REG_ZERO, (c), (r)); \
240 } else if ((c) >= 0 && (c) <= 0xffff) { \
241 M_OR_IMM(REG_ZERO, (c), (r)); \
243 a = dseg_adds8(cd, (c)); \
244 M_LLD((r), REG_PV, a); \
248 /* macros to create code ******************************************************/
250 /* code generation macros operands:
252 fu ..... function-number
253 rs ..... register number source 1
254 rt ..... register number or constant integer source 2
255 rd ..... register number destination
256 imm .... immediate/offset
257 sa ..... shift amount
261 #define M_ITYPE(op, rs, rt, imm)\
262 *(mcodeptr++) = (((op)<<26)|((rs)<<21)|((rt)<<16)|((imm)&0xffff))
264 #define M_JTYPE(op, imm)\
265 *(mcodeptr++) = (((op)<<26)|((off)&0x3ffffff))
267 #define M_RTYPE(op, rs, rt, rd, sa, fu)\
268 *(mcodeptr++) = (((op)<<26)|((rs)<<21)|((rt)<<16)|((rd)<<11)|((sa)<<6)|(fu))
270 #define M_FP2(fu, fmt, fs, fd) M_RTYPE(0x11, fmt, 0, fs, fd, fu)
271 #define M_FP3(fu, fmt, fs, ft, fd) M_RTYPE(0x11, fmt, ft, fs, fd, fu)
278 /* macros for all used commands (see a MIPS-manual for description) ***********/
280 /* load/store macros use the form OPERATION(source/dest, base, offset) */
282 #define M_BLDS(a,b,disp) M_ITYPE(0x20,b,a,disp) /* 8 load */
283 #define M_BLDU(a,b,disp) M_ITYPE(0x24,b,a,disp) /* 8 load */
284 #define M_SLDS(a,b,disp) M_ITYPE(0x21,b,a,disp) /* 16 load */
285 #define M_SLDU(a,b,disp) M_ITYPE(0x25,b,a,disp) /* 16 load */
286 #define M_ILD(a,b,disp) M_ITYPE(0x23,b,a,disp) /* 32 load */
287 #define M_LLD(a,b,disp) M_ITYPE(0x37,b,a,disp) /* 64 load */
288 #define M_BST(a,b,disp) M_ITYPE(0x28,b,a,disp) /* 8 store */
289 #define M_SST(a,b,disp) M_ITYPE(0x29,b,a,disp) /* 16 store */
290 #define M_IST(a,b,disp) M_ITYPE(0x2b,b,a,disp) /* 32 store */
291 #define M_LST(a,b,disp) M_ITYPE(0x3f,b,a,disp) /* 64 store */
293 #define M_FLD(a,b,disp) M_ITYPE(0x31,b,a,disp) /* load flt */
294 #define M_DLD(a,b,disp) M_ITYPE(0x35,b,a,disp) /* load dbl */
295 #define M_FST(a,b,disp) M_ITYPE(0x39,b,a,disp) /* store flt */
296 #define M_DST(a,b,disp) M_ITYPE(0x3d,b,a,disp) /* store dbl */
298 #define M_BEQ(a,b,disp) M_ITYPE(0x04,a,b,disp) /* br a == b */
299 #define M_BNE(a,b,disp) M_ITYPE(0x05,a,b,disp) /* br a != b */
300 #define M_BEQZ(a,disp) M_ITYPE(0x04,a,0,disp) /* br a == 0 */
301 #define M_BLTZ(a,disp) M_ITYPE(0x01,a,0,disp) /* br a < 0 */
302 #define M_BLEZ(a,disp) M_ITYPE(0x06,a,0,disp) /* br a <= 0 */
303 #define M_BNEZ(a,disp) M_ITYPE(0x05,a,0,disp) /* br a != 0 */
304 #define M_BGEZ(a,disp) M_ITYPE(0x01,a,1,disp) /* br a >= 0 */
305 #define M_BGTZ(a,disp) M_ITYPE(0x07,a,0,disp) /* br a > 0 */
307 #define M_BEQL(a,b,disp) M_ITYPE(0x14,a,b,disp) /* br a == b */
308 #define M_BNEL(a,b,disp) M_ITYPE(0x15,a,b,disp) /* br a != b */
309 #define M_BEQZL(a,disp) M_ITYPE(0x14,a,0,disp) /* br a == 0 */
310 #define M_BLTZL(a,disp) M_ITYPE(0x01,a,2,disp) /* br a < 0 */
311 #define M_BLEZL(a,disp) M_ITYPE(0x16,a,0,disp) /* br a <= 0 */
312 #define M_BNEZL(a,disp) M_ITYPE(0x15,a,0,disp) /* br a != 0 */
313 #define M_BGEZL(a,disp) M_ITYPE(0x01,a,3,disp) /* br a >= 0 */
314 #define M_BGTZL(a,disp) M_ITYPE(0x17,a,0,disp) /* br a > 0 */
316 #define M_BR(disp) M_ITYPE(0x04,0,0,disp) /* branch */
317 #define M_BRS(disp) M_ITYPE(0x01,0,17,disp) /* branch sbr */
319 #define M_JMP(a) M_RTYPE(0,a,0,0,0,0x08) /* jump */
320 #define M_JSR(r,a) M_RTYPE(0,a,0,r,0,0x09) /* call */
321 #define M_RET(a) M_RTYPE(0,a,0,0,0,0x08) /* return */
323 #define M_TGE(a,b,code) M_RTYPE(0,a,b,0,code&3ff,0x30) /* trp a >= b */
324 #define M_TGEU(a,b,code) M_RTYPE(0,a,b,0,code&3ff,0x31) /* trp a >= b */
325 #define M_TLT(a,b,code) M_RTYPE(0,a,b,0,code&3ff,0x32) /* trp a < b */
326 #define M_TLTU(a,b,code) M_RTYPE(0,a,b,0,code&3ff,0x33) /* trp a < b */
327 #define M_TEQ(a,b,code) M_RTYPE(0,a,b,0,code&3ff,0x34) /* trp a == b */
328 #define M_TNE(a,b,code) M_RTYPE(0,a,b,0,code&3ff,0x36) /* trp a != b */
329 #define M_TLE(a,b,code) M_RTYPE(0,b,a,0,code&3ff,0x30) /* trp a <= b */
330 #define M_TLEU(a,b,code) M_RTYPE(0,b,a,0,code&3ff,0x31) /* trp a <= b */
331 #define M_TGT(a,b,code) M_RTYPE(0,b,a,0,code&3ff,0x32) /* trp a > b */
332 #define M_TGTU(a,b,code) M_RTYPE(0,b,a,0,code&3ff,0x33) /* trp a > b */
334 #define M_TGE_IMM(a,b) M_ITYPE(1,a,0x08,b) /* trp a >= b */
335 #define M_TGEU_IMM(a,b) M_ITYPE(1,a,0x09,b) /* trp a >= b */
336 #define M_TLT_IMM(a,b) M_ITYPE(1,a,0x0a,b) /* trp a < b */
337 #define M_TLTU_IMM(a,b) M_ITYPE(1,a,0x0b,b) /* trp a < b */
338 #define M_TEQ_IMM(a,b) M_ITYPE(1,a,0x0c,b) /* trp a == b */
339 #define M_TNE_IMM(a,b) M_ITYPE(1,a,0x0e,b) /* trp a != b */
341 #define M_TGT_IMM(a,b) M_ITYPE(1,a,0x08,b+1) /* trp a > b */
342 #define M_TGTU_IMM(a,b) M_ITYPE(1,a,0x09,b+1) /* trp a > b */
343 #define M_TLE_IMM(a,b) M_ITYPE(1,a,0x0a,b+1) /* trp a <= b */
344 #define M_TLEU_IMM(a,b) M_ITYPE(1,a,0x0b,b+1) /* trp a <= b */
347 /* arithmetic macros use the form OPERATION(source, source/immediate, dest) */
349 #define M_IADD(a,b,c) M_RTYPE(0,a,b,c,0,0x21) /* 32 add */
350 #define M_LADD(a,b,c) M_RTYPE(0,a,b,c,0,0x2d) /* 64 add */
351 #define M_ISUB(a,b,c) M_RTYPE(0,a,b,c,0,0x23) /* 32 sub */
352 #define M_LSUB(a,b,c) M_RTYPE(0,a,b,c,0,0x2f) /* 64 sub */
353 #define M_IMUL(a,b) M_ITYPE(0,a,b,0x18) /* 32 mul */
354 #define M_LMUL(a,b) M_ITYPE(0,a,b,0x1c) /* 64 mul */
355 #define M_IDIV(a,b) M_ITYPE(0,a,b,0x1a) /* 32 div */
356 #define M_LDIV(a,b) M_ITYPE(0,a,b,0x1e) /* 64 div */
358 #define M_MFLO(a) M_RTYPE(0,0,0,a,0,0x12) /* quotient */
359 #define M_MFHI(a) M_RTYPE(0,0,0,a,0,0x10) /* remainder */
361 #define M_IADD_IMM(a,b,c) M_ITYPE(0x09,a,c,b) /* 32 add */
362 #define M_LADD_IMM(a,b,c) M_ITYPE(0x19,a,c,b) /* 64 add */
363 #define M_ISUB_IMM(a,b,c) M_ITYPE(0x09,a,c,-(b)) /* 32 sub */
364 #define M_LSUB_IMM(a,b,c) M_ITYPE(0x19,a,c,-(b)) /* 64 sub */
366 #define M_LUI(a,imm) M_ITYPE(0x0f,0,a,imm) /* a = imm<<16*/
368 #define M_CMPLT(a,b,c) M_RTYPE(0,a,b,c,0,0x2a) /* c = a < b */
369 #define M_CMPGT(a,b,c) M_RTYPE(0,b,a,c,0,0x2a) /* c = a > b */
371 #define M_CMPULT(a,b,c) M_RTYPE(0,a,b,c,0,0x2b) /* c = a < b */
372 #define M_CMPUGT(a,b,c) M_RTYPE(0,b,a,c,0,0x2b) /* c = a > b */
374 #define M_CMPLT_IMM(a,b,c) M_ITYPE(0x0a,a,c,b) /* c = a < b */
375 #define M_CMPULT_IMM(a,b,c) M_ITYPE(0x0b,a,c,b) /* c = a < b */
377 #define M_AND(a,b,c) M_RTYPE(0,a,b,c,0,0x24) /* c = a & b */
378 #define M_OR( a,b,c) M_RTYPE(0,a,b,c,0,0x25) /* c = a | b */
379 #define M_XOR(a,b,c) M_RTYPE(0,a,b,c,0,0x26) /* c = a ^ b */
381 #define M_AND_IMM(a,b,c) M_ITYPE(0x0c,a,c,b) /* c = a & b */
382 #define M_OR_IMM( a,b,c) M_ITYPE(0x0d,a,c,b) /* c = a | b */
383 #define M_XOR_IMM(a,b,c) M_ITYPE(0x0e,a,c,b) /* c = a ^ b */
385 #define M_CZEXT(a,c) M_AND_IMM(a,0xffff,c) /* c = zext(a)*/
387 #define M_ISLL(a,b,c) M_RTYPE(0,b,a,c,0,0x04) /* c = a << b */
388 #define M_ISRL(a,b,c) M_RTYPE(0,b,a,c,0,0x06) /* c = a >>>b */
389 #define M_ISRA(a,b,c) M_RTYPE(0,b,a,c,0,0x07) /* c = a >> b */
390 #define M_LSLL(a,b,c) M_RTYPE(0,b,a,c,0,0x14) /* c = a << b */
391 #define M_LSRL(a,b,c) M_RTYPE(0,b,a,c,0,0x16) /* c = a >>>b */
392 #define M_LSRA(a,b,c) M_RTYPE(0,b,a,c,0,0x17) /* c = a >> b */
394 #define M_ISLL_IMM(a,b,c) M_RTYPE(0,0,a,c,(b)&31,0x00) /* c = a << b */
395 #define M_ISRL_IMM(a,b,c) M_RTYPE(0,0,a,c,(b)&31,0x02) /* c = a >>>b */
396 #define M_ISRA_IMM(a,b,c) M_RTYPE(0,0,a,c,(b)&31,0x03) /* c = a >> b */
397 #define M_LSLL_IMM(a,b,c) M_RTYPE(0,0,a,c,(b)&31,0x38+((b)>>3&4)) /*c = a << b*/
398 #define M_LSRL_IMM(a,b,c) M_RTYPE(0,0,a,c,(b)&31,0x3a+((b)>>3&4)) /*c = a >>>b*/
399 #define M_LSRA_IMM(a,b,c) M_RTYPE(0,0,a,c,(b)&31,0x3b+((b)>>3&4)) /*c = a >> b*/
401 #define M_MOV(a,c) M_OR(a,0,c) /* c = a */
402 #define M_CLR(c) M_OR(0,0,c) /* c = 0 */
403 #define M_NOP M_ISLL_IMM(0,0,0) /* ; */
405 /* floating point macros use the form OPERATION(source, source, dest) */
407 #define M_FADD(a,b,c) M_FP3(0x00,FMT_F,a,b,c) /* flt add */
408 #define M_DADD(a,b,c) M_FP3(0x00,FMT_D,a,b,c) /* dbl add */
409 #define M_FSUB(a,b,c) M_FP3(0x01,FMT_F,a,b,c) /* flt sub */
410 #define M_DSUB(a,b,c) M_FP3(0x01,FMT_D,a,b,c) /* dbl sub */
411 #define M_FMUL(a,b,c) M_FP3(0x02,FMT_F,a,b,c) /* flt mul */
412 #define M_DMUL(a,b,c) M_FP3(0x02,FMT_D,a,b,c) /* dbl mul */
413 #define M_FDIV(a,b,c) M_FP3(0x03,FMT_F,a,b,c) /* flt div */
414 #define M_DDIV(a,b,c) M_FP3(0x03,FMT_D,a,b,c) /* dbl div */
416 #define M_FSQRT(a,c) M_FP2(0x04,FMT_F,a,c) /* flt sqrt */
417 #define M_DSQRT(a,c) M_FP2(0x04,FMT_D,a,c) /* dbl sqrt */
418 #define M_FABS(a,c) M_FP2(0x05,FMT_F,a,c) /* flt abs */
419 #define M_DABS(a,c) M_FP2(0x05,FMT_D,a,c) /* dbl abs */
420 #define M_FMOV(a,c) M_FP2(0x06,FMT_F,a,c) /* flt mov */
421 #define M_DMOV(a,c) M_FP2(0x06,FMT_D,a,c) /* dbl mov */
422 #define M_FNEG(a,c) M_FP2(0x07,FMT_F,a,c) /* flt neg */
423 #define M_DNEG(a,c) M_FP2(0x07,FMT_D,a,c) /* dbl neg */
425 #define M_ROUNDFI(a,c) M_FP2(0x0c,FMT_F,a,c) /* flt roundi */
426 #define M_ROUNDDI(a,c) M_FP2(0x0c,FMT_D,a,c) /* dbl roundi */
427 #define M_TRUNCFI(a,c) M_FP2(0x0d,FMT_F,a,c) /* flt trunci */
428 #define M_TRUNCDI(a,c) M_FP2(0x0d,FMT_D,a,c) /* dbl trunci */
429 #define M_CEILFI(a,c) M_FP2(0x0e,FMT_F,a,c) /* flt ceili */
430 #define M_CEILDI(a,c) M_FP2(0x0e,FMT_D,a,c) /* dbl ceili */
431 #define M_FLOORFI(a,c) M_FP2(0x0f,FMT_F,a,c) /* flt trunci */
432 #define M_FLOORDI(a,c) M_FP2(0x0f,FMT_D,a,c) /* dbl trunci */
434 #define M_ROUNDFL(a,c) M_FP2(0x08,FMT_F,a,c) /* flt roundl */
435 #define M_ROUNDDL(a,c) M_FP2(0x08,FMT_D,a,c) /* dbl roundl */
436 #define M_TRUNCFL(a,c) M_FP2(0x09,FMT_F,a,c) /* flt truncl */
437 #define M_TRUNCDL(a,c) M_FP2(0x09,FMT_D,a,c) /* dbl truncl */
438 #define M_CEILFL(a,c) M_FP2(0x0a,FMT_F,a,c) /* flt ceill */
439 #define M_CEILDL(a,c) M_FP2(0x0a,FMT_D,a,c) /* dbl ceill */
440 #define M_FLOORFL(a,c) M_FP2(0x0b,FMT_F,a,c) /* flt truncl */
441 #define M_FLOORDL(a,c) M_FP2(0x0b,FMT_D,a,c) /* dbl truncl */
443 #define M_CVTDF(a,c) M_FP2(0x20,FMT_D,a,c) /* dbl2flt */
444 #define M_CVTIF(a,c) M_FP2(0x20,FMT_I,a,c) /* int2flt */
445 #define M_CVTLF(a,c) M_FP2(0x20,FMT_L,a,c) /* long2flt */
446 #define M_CVTFD(a,c) M_FP2(0x21,FMT_F,a,c) /* flt2dbl */
447 #define M_CVTID(a,c) M_FP2(0x21,FMT_I,a,c) /* int2dbl */
448 #define M_CVTLD(a,c) M_FP2(0x21,FMT_L,a,c) /* long2dbl */
449 #define M_CVTFI(a,c) M_FP2(0x24,FMT_F,a,c) /* flt2int */
450 #define M_CVTDI(a,c) M_FP2(0x24,FMT_D,a,c) /* dbl2int */
451 #define M_CVTFL(a,c) M_FP2(0x25,FMT_F,a,c) /* flt2long */
452 #define M_CVTDL(a,c) M_FP2(0x25,FMT_D,a,c) /* dbl2long */
454 #define M_MOVDI(d,i) M_FP3(0,0,d,i,0) /* i = d */
455 #define M_MOVDL(d,l) M_FP3(0,1,d,l,0) /* l = d */
456 #define M_MOVID(i,d) M_FP3(0,4,d,i,0) /* d = i */
457 #define M_MOVLD(l,d) M_FP3(0,5,d,l,0) /* d = l */
459 #define M_DMFC1(l,f) M_FP3(0,1,f,l,0)
460 #define M_DMTC1(l,f) M_FP3(0,5,f,l,0)
462 #define M_FCMPFF(a,b) M_FP3(0x30,FMT_F,a,b,0) /* c = a == b */
463 #define M_FCMPFD(a,b) M_FP3(0x30,FMT_D,a,b,0) /* c = a == b */
464 #define M_FCMPUNF(a,b) M_FP3(0x31,FMT_F,a,b,0) /* c = a == b */
465 #define M_FCMPUND(a,b) M_FP3(0x31,FMT_D,a,b,0) /* c = a == b */
466 #define M_FCMPEQF(a,b) M_FP3(0x32,FMT_F,a,b,0) /* c = a == b */
467 #define M_FCMPEQD(a,b) M_FP3(0x32,FMT_D,a,b,0) /* c = a == b */
468 #define M_FCMPUEQF(a,b) M_FP3(0x33,FMT_F,a,b,0) /* c = a == b */
469 #define M_FCMPUEQD(a,b) M_FP3(0x33,FMT_D,a,b,0) /* c = a == b */
470 #define M_FCMPOLTF(a,b) M_FP3(0x34,FMT_F,a,b,0) /* c = a < b */
471 #define M_FCMPOLTD(a,b) M_FP3(0x34,FMT_D,a,b,0) /* c = a < b */
472 #define M_FCMPULTF(a,b) M_FP3(0x35,FMT_F,a,b,0) /* c = a < b */
473 #define M_FCMPULTD(a,b) M_FP3(0x35,FMT_D,a,b,0) /* c = a < b */
474 #define M_FCMPOLEF(a,b) M_FP3(0x36,FMT_F,a,b,0) /* c = a <= b */
475 #define M_FCMPOLED(a,b) M_FP3(0x36,FMT_D,a,b,0) /* c = a <= b */
476 #define M_FCMPULEF(a,b) M_FP3(0x37,FMT_F,a,b,0) /* c = a <= b */
477 #define M_FCMPULED(a,b) M_FP3(0x37,FMT_D,a,b,0) /* c = a <= b */
479 #define M_FBF(disp) M_ITYPE(0x11,8,0,disp) /* br false */
480 #define M_FBT(disp) M_ITYPE(0x11,8,1,disp) /* br true */
481 #define M_FBFL(disp) M_ITYPE(0x11,8,2,disp) /* br false */
482 #define M_FBTL(disp) M_ITYPE(0x11,8,3,disp) /* br true */
484 #define M_CMOVF(a,b) M_RTYPE(0x00,a,0,b,0,1)
485 #define M_CMOVT(a,b) M_RTYPE(0x00,a,1,b,0,1)
488 * Load Address pseudo instruction:
489 * -n32 addressing mode -> 32 bit addrs, -64 addressing mode -> 64 bit addrs
492 #define POINTERSHIFT 3
493 #define M_ALD(a,b,disp) M_LLD(a,b,disp)
494 #define M_AST(a,b,disp) M_LST(a,b,disp)
495 #define M_AADD(a,b,c) M_LADD(a,b,c)
496 #define M_ASLL_IMM(a,b,c) M_LSLL_IMM(a,b,c)
497 #define M_LDA(a,b,disp) M_LADD_IMM(b,disp,a) /* a = b+disp */
499 #define POINTERSHIFT 2
500 #define M_ALD(a,b,disp) M_ILD(a,b,disp)
501 #define M_AST(a,b,disp) M_IST(a,b,disp)
502 #define M_AADD(a,b,c) M_IADD(a,b,c)
503 #define M_ASLL_IMM(a,b,c) M_ISLL_IMM(a,b,c)
504 #define M_LDA(a,b,disp) M_IADD_IMM(b,disp,a) /* a = b+disp */
507 /* macros for special commands (see an Alpha-manual for description) **********/
510 #define M_CMOVEQ(a,b,c) M_OP3 (0x11,0x24, a,b,c,0) /* a==0 ? c=b */
511 #define M_CMOVNE(a,b,c) M_OP3 (0x11,0x26, a,b,c,0) /* a!=0 ? c=b */
512 #define M_CMOVLT(a,b,c) M_OP3 (0x11,0x44, a,b,c,0) /* a< 0 ? c=b */
513 #define M_CMOVGE(a,b,c) M_OP3 (0x11,0x46, a,b,c,0) /* a>=0 ? c=b */
514 #define M_CMOVLE(a,b,c) M_OP3 (0x11,0x64, a,b,c,0) /* a<=0 ? c=b */
515 #define M_CMOVGT(a,b,c) M_OP3 (0x11,0x66, a,b,c,0) /* a> 0 ? c=b */
517 #define M_CMOVEQ_IMM(a,b,c) M_OP3 (0x11,0x24, a,b,c,1) /* a==0 ? c=b */
518 #define M_CMOVNE_IMM(a,b,c) M_OP3 (0x11,0x26, a,b,c,1) /* a!=0 ? c=b */
519 #define M_CMOVLT_IMM(a,b,c) M_OP3 (0x11,0x44, a,b,c,1) /* a< 0 ? c=b */
520 #define M_CMOVGE_IMM(a,b,c) M_OP3 (0x11,0x46, a,b,c,1) /* a>=0 ? c=b */
521 #define M_CMOVLE_IMM(a,b,c) M_OP3 (0x11,0x64, a,b,c,1) /* a<=0 ? c=b */
522 #define M_CMOVGT_IMM(a,b,c) M_OP3 (0x11,0x66, a,b,c,1) /* a> 0 ? c=b */
525 /* function gen_resolvebranch **************************************************
527 backpatches a branch instruction; MIPS branch instructions are very
528 regular, so it is only necessary to overwrite some fixed bits in the
531 parameters: ip ... pointer to instruction after branch (void*)
532 so ... offset of instruction after branch (s4)
533 to ... offset of branch target (s4)
535 *******************************************************************************/
537 #define gen_resolvebranch(ip,so,to) \
538 ((s4 *) (ip))[-1] |= ((s4) (to) - (so)) >> 2 & 0xffff
541 /* function prototypes */
543 void docacheflush(u1 *p, long bytelen);
545 #endif /* _CODEGEN_H */
549 * These are local overrides for various environment variables in Emacs.
550 * Please do not remove this and leave it at the end of the file, where
551 * Emacs will automagically detect them.
552 * ---------------------------------------------------------------------
555 * indent-tabs-mode: t