diff --git a/ChangeLog b/ChangeLog index 15157f87d..81fc943bb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2013-06-22 Paulo Andrade + + * check/lightning.c, configure.ac, include/lightning.h, + lib/lightning.c: Add tests and quirks to build/detect + and/or work on Irix. + + * include/lightning/jit_mips.h, lib/jit_mips-cpu.c, + lib/jit_mips-fpu.c, lib/jit_mips.c: Adapt code to run + in big endian mips, using the n32 abi. + 2013-06-18 Paulo Andrade * include/lightning.h: Minor extra preprocessor testing diff --git a/check/lightning.c b/check/lightning.c index aa29e38a0..4c18d27d2 100644 --- a/check/lightning.c +++ b/check/lightning.c @@ -40,6 +40,8 @@ #if defined(__hpux) # define DL_HANDLE RTLD_NEXT +#elif defined(__sgi) +static void *DL_HANDLE; #else # define DL_HANDLE RTLD_DEFAULT #endif @@ -3702,6 +3704,8 @@ get_symbol_by_name(char *name) { symbol_t **symbol_pointer; + if (symbols == NULL) + return (NULL); symbol_pointer = (symbol_t **)bsearch(name, symbols, symbol_offset, sizeof(symbol_t *), bcmp_symbols); @@ -3788,7 +3792,7 @@ rehash(hash_t *hash) static void usage(void) { -#if HAVE_GETOPT_H +#if HAVE_GETOPT_LONG_ONLY fprintf(stderr, "\ Usage: %s [jit assembler options] file [jit program options]\n\ Jit assembler options:\n\ @@ -3823,7 +3827,7 @@ Jit assembler options:\n\ int main(int argc, char *argv[]) { -#if HAVE_GETOPT_H +#if HAVE_GETOPT_LONG_ONLY static const char *short_options = "v::"; static struct option long_options[] = { { "help", 0, 0, 'h' }, @@ -3842,7 +3846,7 @@ main(int argc, char *argv[]) { 0, 0, 0, 0 } }; #else -#endif /* HAVE_GETOPT_H */ +#endif /* HAVE_GETOPT_LONG_ONLY */ int offset; char *endptr; int opt_index; @@ -3853,7 +3857,11 @@ main(int argc, char *argv[]) init_jit(progname); -#if HAVE_GETOPT_H +#if defined(__sgi) + DL_HANDLE = dlopen(NULL, RTLD_LAZY); +#endif + +#if HAVE_GETOPT_LONG_ONLY for (;;) { if ((opt_short = getopt_long_only(argc, argv, short_options, long_options, &opt_index)) < 0) @@ -4029,6 +4037,11 @@ main(int argc, char *argv[]) opt_short += snprintf(cmdline + opt_short, sizeof(cmdline) - opt_short, " -D_AIX=1"); +#endif +#if defined(__sgi__) + opt_short += snprintf(cmdline + opt_short, + sizeof(cmdline) - opt_short, + " -D__sgi__=1"); #endif if ((parser.fp = popen(cmdline, "r")) == NULL) error("cannot execute %s", cmdline); diff --git a/configure.ac b/configure.ac index bf4a2c033..eb750efd1 100644 --- a/configure.ac +++ b/configure.ac @@ -28,6 +28,12 @@ case "$target_cpu" in *hpux*) CFLAGS="$CFLAGS -mlp64" ;; *) ;; esac ;; + *mips*) + case "$host_os" in + # Extra flags to build with gcc 3.x + *irix*) CFLAGS="$CFLAGS -D__c99 -Drestrict=" ;; + *) ;; + esac ;; *) ;; esac @@ -35,7 +41,7 @@ AC_PROG_CC AC_PROG_INSTALL AC_PROG_LIBTOOL -AC_CHECK_FUNCS(mremap ffsl,,) +AC_CHECK_FUNCS(mremap ffsl getopt_long_only,,) AC_CHECK_HEADERS([getopt.h],,,) diff --git a/include/lightning.h b/include/lightning.h index e097a4e2b..8e8e4859c 100644 --- a/include/lightning.h +++ b/include/lightning.h @@ -40,6 +40,12 @@ # define __WORDSIZE 32 # elif defined(_LP64) /* ia64 hp-ux (with cc +DD64) */ # define __WORDSIZE 64 +# elif defined(_MIPS_SZPTR) /* mips irix */ +# if _MIPS_SZPTR == 32 +# define __WORDSIZE 32 +# else +# define __WORDSIZE 64 +# endif # else # error cannot figure __WORDSIZE # endif @@ -69,10 +75,12 @@ # define __BYTE_ORDER __BYTE_ORDER__ # elif defined(_BIG_ENDIAN) /* hppa hp-ux */ # define __BYTE_ORDER __BIG_ENDIAN -# elif defined(__BIG_ENDIAN__ ) /* ia64 hp-ux */ +# elif defined(__BIG_ENDIAN__) /* ia64 hp-ux */ +# define __BYTE_ORDER __BIG_ENDIAN +# elif defined(__i386__) /* x86 solaris */ +# define __BYTE_ORDER __LITTLE_ENDIAN +# elif defined(__MIPSEB) /* mips irix */ # define __BYTE_ORDER __BIG_ENDIAN -# elif defined(__i386__) -# define __BYTE_ORDER __LITTLE_ENDIAN /* x86 solaris */ # else # error cannot figure __BYTE_ORDER # endif diff --git a/include/lightning/jit_mips.h b/include/lightning/jit_mips.h index f367f4dc4..282867507 100644 --- a/include/lightning/jit_mips.h +++ b/include/lightning/jit_mips.h @@ -21,14 +21,23 @@ #define JIT_HASH_CONSTS 1 #define JIT_NUM_OPERANDS 3 +#if defined(_ABIN32) +# define NEW_ABI 1 +#endif + /* * Types */ #define JIT_FP _FP typedef enum { -#define jit_arg_reg_p(i) ((i) >= 0 && (i) < 4) #define jit_r(i) (_V0 + (i)) -#define jit_r_num() 12 +#if NEW_ABI +# define jit_arg_reg_p(i) ((i) >= 0 && (i) < 4) +# define jit_r_num() 8 +#else +# define jit_arg_reg_p(i) ((i) >= 0 && (i) < 4) +# define jit_r_num() 12 +#endif #define jit_v(i) (_S0 + (i)) #define jit_v_num() 8 #define jit_arg_f_reg_p(i) ((i) >= 0 && (i) < 4) @@ -37,35 +46,28 @@ typedef enum { _AT, #define JIT_R0 _V0 #define JIT_R1 _V1 -#define JIT_R2 _T0 -#define JIT_R3 _T1 -#define JIT_R4 _T2 -#define JIT_R5 _T3 -#define JIT_R6 _T4 -#define JIT_R7 _T5 -#define JIT_R8 _T6 -#define JIT_R9 _T7 -#define JIT_R10 _T8 -#define JIT_R11 _T9 /* must point to PIC function */ - _V0, _V1, _T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9, +#if NEW_ABI +# define JIT_R2 _T4 +#else +# define JIT_R2 _T0 +#endif + _V0, _V1, +#if !NEW_ABI + _T0, _T1, _T2, _T3, +#endif + _T4, _T5, _T6, _T7, _T8, _T9, #define JIT_V0 _S0 #define JIT_V1 _S1 #define JIT_V2 _S2 -#define JIT_V3 _S3 -#define JIT_V4 _S4 -#define JIT_V5 _S5 -#define JIT_V6 _S6 -#define JIT_V7 _S7 _S0, _S1, _S2, _S3, _S4, _S5, _S6, _S7, _ZERO, _K0, _K1, _RA, - _GP, /* FIXME use to point to jit data */ + _GP, _SP, _FP, -# define JIT_RA0 _A0 -# define JIT_RA1 _A1 -# define JIT_RA2 _A2 -# define JIT_RA3 _A3 +#define JIT_RA0 _A0 +#if NEW_ABI + _A7, _A6, _A5, _A4, +#endif _A3, _A2, _A1, _A0, - #define JIT_F0 _F0 #define JIT_F1 _F2 #define JIT_F2 _F4 @@ -74,18 +76,16 @@ typedef enum { #define JIT_F5 _F10 _F0, _F2, _F4, _F6, _F8, _F10, /* callee save float registers */ -#define JIT_FS0 _F16 -#define JIT_FS1 _F18 -#define JIT_FS2 _F20 -#define JIT_FS3 _F22 -#define JIT_FS4 _F24 -#define JIT_FS5 _F26 -#define JIT_FS6 _F28 -#define JIT_FS7 _F30 - _F16, _F18, _F20, _F22, _F24, _F26, _F28, _F30, +#if !NEW_ABI + _F16, _F18, +#endif + _F20, _F22, _F24, _F26, _F28, _F30, #define JIT_FA0 _F12 -#define JIT_FA1 _F14 +#if NEW_ABI + _F19, _F18, _F17, _F16, _F15, _F14, _F13, _F12, +#else _F14, _F12, +#endif #define JIT_NOREG _NOREG _NOREG, } jit_reg_t; diff --git a/lib/jit_mips-cpu.c b/lib/jit_mips-cpu.c index 372505eb3..e41ba6afd 100644 --- a/lib/jit_mips-cpu.c +++ b/lib/jit_mips-cpu.c @@ -17,6 +17,7 @@ #if PROTO typedef union { +#if __BYTE_ORDER == __LITTLE_ENDIAN struct { jit_uint32_t _:26; jit_uint32_t b : 6; } hc; struct { jit_uint32_t _:21; jit_uint32_t b : 5; } rs; struct { jit_uint32_t _:21; jit_uint32_t b : 5; } fm; @@ -32,12 +33,27 @@ typedef union { struct { jit_uint32_t b : 11; } cc; struct { jit_uint32_t b : 16; } is; struct { jit_uint32_t b : 26; } ii; - int op; +#else + struct { jit_uint32_t b : 6; } hc; + struct { jit_uint32_t _: 6; jit_uint32_t b : 5; } rs; + struct { jit_uint32_t _: 6; jit_uint32_t b : 5; } fm; + struct { jit_uint32_t _:11; jit_uint32_t b : 5; } rt; + struct { jit_uint32_t _:11; jit_uint32_t b : 5; } ft; + struct { jit_uint32_t _:16; jit_uint32_t b : 5; } rd; + struct { jit_uint32_t _:16; jit_uint32_t b : 5; } fs; + struct { jit_uint32_t _:21; jit_uint32_t b : 5; } ic; + struct { jit_uint32_t _:21; jit_uint32_t b : 5; } fd; + struct { jit_uint32_t _:21; jit_uint32_t b : 10; } tr; + struct { jit_uint32_t _:21; jit_uint32_t b : 20; } br; + struct { jit_uint32_t _:26; jit_uint32_t b : 6; } tc; + struct { jit_uint32_t _:21; jit_uint32_t b : 11; } cc; + struct { jit_uint32_t _:16; jit_uint32_t b : 16; } is; + struct { jit_uint32_t _: 6; jit_uint32_t b : 26; } ii; +#endif + int op; } jit_instr_t; - /* FIXME */ # define jit_mips2_p() 0 - # define _ZERO_REGNO 0 # define _T0_REGNO 0x08 # define _T1_REGNO 0x09 @@ -68,9 +84,12 @@ typedef union { # define _F26_REGNO 26 # define _F28_REGNO 28 # define _F30_REGNO 30 - # if __WORDSIZE == 32 -# define stack_framesize 104 +# if NEW_ABI +# define stack_framesize 96 +# else +# define stack_framesize 112 +# endif # define ldi(u, v) ldi_i(u, v) # define ldxi(u, v, w) ldxi_i(u, v, w) # define sti(u, v) sti_i(u, v) @@ -82,7 +101,6 @@ typedef union { # define sti(u, v) sti_l(u, v) # define stxi(u, v, w) stxi_l(u, v, w) # endif - # define can_sign_extend_short_p(im) ((im) >= -32678 && (im) <= 32767) # define can_zero_extend_short_p(im) ((im) >= 0 && (im) <= 65535) # if __WORDSIZE == 32 @@ -94,7 +112,6 @@ typedef union { ((im) < 0 && (im) >= -0x80000000L)) # define can_zero_extend_int_p(im) ((im) >= 0 && (im) <= 0xffffffff) # endif - # define MIPS_SPECIAL 0x00 # define MIPS_REGIMM 0x01 # define MIPS_J 0x02 @@ -157,7 +174,6 @@ typedef union { # define MIPS_SWC1 0x39 # define MIPS_SWC2 0x3a # define MIPS_SD 0x3f - # define MIPS_MF 0x00 # define MIPS_DMF 0x01 # define MIPS_CF 0x02 @@ -170,7 +186,6 @@ typedef union { # define MIPS_WRPGPR 0x0e # define MIPS_BGZAL 0x11 # define MIPS_MFMC0 0x11 - # define MIPS_BCF 0x00 # define MIPS_BLTZ 0x00 # define MIPS_BCT 0x01 @@ -190,13 +205,11 @@ typedef union { # define MIPS_BLTZALL 0x12 # define MIPS_BGEZALL 0x13 # define MIPS_SYNCI 0x1f - # define MIPS_WSBH 0x02 # define MIPS_DBSH 0x02 # define MIPS_DSHD 0x05 # define MIPS_SEB 0x10 # define MIPS_SEH 0x18 - # define MIPS_MADD 0x00 # define MIPS_SLL 0x00 # define MIPS_EXT 0x00 @@ -278,7 +291,6 @@ typedef union { # define MIPS_DSRA32 0x3f # define MIPS_SDBPP 0x3f # define ii(i) *_jit->pc.ui++ = i - static void _hrrrit(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t, jit_int32_t, jit_int32_t); @@ -309,7 +321,7 @@ static void _nop(jit_state_t*,jit_int32_t); # define SRLV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_SRLV) # define SRL(rd,rt,sa) rrit(rt,rd,sa,MIPS_SRL) # define ROTR(rd,rt,sa) hrrrit(MIPS_SPECIAL,1,rt,rd,sa,MIPS_DSRL) -# define INS(rt,rs,pos,size) hrriit(MIPS_SPECIAL3,rs,rt,pos,pos+size-1,MIPS_DINS) +# define INS(rt,rs,pos,size) hrrrit(MIPS_SPECIAL3,rs,rt,pos,pos+size-1,MIPS_DINS) # else # define ADDU(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_DADDU) # define ADDIU(rt,rs,im) hrri(MIPS_DADDIU,rs,rt,im) @@ -325,7 +337,7 @@ static void _nop(jit_state_t*,jit_int32_t); # define SRLV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_DSRLV) # define SRL(rd,rt,sa) rrit(rt,rd,sa,MIPS_DSRL) # define ROTR(rd,rt,sa) hrrrit(MIPS_SPECIAL,1,rt,rd,sa,MIPS_SRL) -# define INS(rt,rs,pos,size) hrriit(MIPS_SPECIAL3,rs,rt,pos,pos+size-1,MIPS_INS) +# define INS(rt,rs,pos,size) hrrrit(MIPS_SPECIAL3,rs,rt,pos,pos+size-1,MIPS_INS) # endif # define MFHI(rd) rrr_t(_ZERO_REGNO,_ZERO_REGNO,rd,MIPS_MFHI) # define MFLO(rd) rrr_t(_ZERO_REGNO,_ZERO_REGNO,rd,MIPS_MFLO) @@ -514,7 +526,7 @@ static void _sti_i(jit_state_t*,jit_word_t,jit_int32_t); # if __WORDSIZE == 64 # define str_l(r0, r1) SD(r0, 0, r1) # define sti_l(i0, r0) _sti_l(_jit, i0, r0) -static void _sti_l(jit_state_t*,jit_int32_t,jit_word_t); +static void _sti_l(jit_state_t*,jit_word_t,jit_int32_t); # endif # define stxr_c(r0, r1, r2) _stxr_c(_jit, r0, r1, r2) static void _stxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); @@ -1634,7 +1646,7 @@ static void _extr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) { movr(r0, r1); - INS(r0, _RZERO_REGNO, 32, 32); + INS(r0, _ZERO_REGNO, 32, 32); } # endif @@ -2770,166 +2782,74 @@ _calli_p(jit_state_t *_jit, jit_word_t i0) return (word); } +static jit_int32_t fregs[] = { + _F30, _F28, _F26, _F24, _F22, _F20, +#if !NEW_ABI + _F18, _F16, +#endif +}; + +static jit_int32_t iregs[] = { + _S7, _S6, _S5, _S4, _S3, _S2, _S1, _S0, +}; + static void _prolog(jit_state_t *_jit, jit_node_t *node) { + jit_int32_t index; + jit_int32_t offset; +#if NEW_ABI + _jitc->function->stack = ((_jitc->function->self.alen - + /* align stack at 16 bytes */ + _jitc->function->self.aoff) + 15) & -16; +#else _jitc->function->stack = ((/* first 16 bytes must be allocated */ (_jitc->function->self.alen > 16 ? _jitc->function->self.alen : 16) - /* align stack at 8 bytes */ _jitc->function->self.aoff) + 7) & -8; +#endif /* callee save registers */ subi(_SP_REGNO, _SP_REGNO, stack_framesize); -#if __WORDSIZE == 32 - if (jit_regset_tstbit(&_jitc->function->regset, _F30)) - stxi_d(96, _SP_REGNO, _F30_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _F28)) - stxi_d(88, _SP_REGNO, _F28_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _F26)) - stxi_d(80, _SP_REGNO, _F26_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _F24)) - stxi_d(72, _SP_REGNO, _F24_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _F22)) - stxi_d(64, _SP_REGNO, _F22_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _F20)) - stxi_d(56, _SP_REGNO, _F20_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _F18)) - stxi_d(48, _SP_REGNO, _F18_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _F16)) - stxi_d(40, _SP_REGNO, _F16_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _S7)) - stxi(36, _SP_REGNO, _S7_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _S6)) - stxi(32, _SP_REGNO, _S6_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _S5)) - stxi(28, _SP_REGNO, _S5_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _S4)) - stxi(24, _SP_REGNO, _S4_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _S3)) - stxi(20, _SP_REGNO, _S3_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _S2)) - stxi(16, _SP_REGNO, _S2_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _S1)) - stxi(12, _SP_REGNO, _S1_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _S0)) - stxi( 8, _SP_REGNO, _S0_REGNO); - stxi( 4, _SP_REGNO, _RA_REGNO); -#else - if (jit_regset_tstbit(&_jitc->function->regset, _F30)) - stxi_d(136, _SP_REGNO, _F30_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _F28)) - stxi_d(128, _SP_REGNO, _F28_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _F26)) - stxi_d(120, _SP_REGNO, _F26_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _F24)) - stxi_d(112, _SP_REGNO, _F24_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _F22)) - stxi_d(104, _SP_REGNO, _F22_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _F20)) - stxi_d(96, _SP_REGNO, _F20_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _F18)) - stxi_d(88, _SP_REGNO, _F18_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _F16)) - stxi_d(80, _SP_REGNO, _F16_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _S7)) - stxi(72, _SP_REGNO, _S7_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _S6)) - stxi(64, _SP_REGNO, _S6_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _S5)) - stxi(56, _SP_REGNO, _S5_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _S4)) - stxi(48, _SP_REGNO, _S4_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _S3)) - stxi(40, _SP_REGNO, _S3_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _S2)) - stxi(32, _SP_REGNO, _S2_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _S1)) - stxi(24, _SP_REGNO, _S1_REGNO); - if (jit_regset_tstbit(&_jitc->function->regset, _S0)) - stxi(16, _SP_REGNO, _S0_REGNO); - stxi( 8, _SP_REGNO, _RA_REGNO); -#endif + offset = stack_framesize - (sizeof(jit_word_t) << 1); + for (index = 0; index < jit_size(fregs); index++, offset -= 8) { + if (jit_regset_tstbit(&_jitc->function->regset, fregs[index])) + stxi_d(offset, _SP_REGNO, rn(fregs[index])); + } + for (index = 0; index < jit_size(iregs); + index++, offset -= sizeof(jit_word_t)) { + if (jit_regset_tstbit(&_jitc->function->regset, iregs[index])) + stxi(offset, _SP_REGNO, rn(iregs[index])); + } + assert(offset >= sizeof(jit_word_t)); + stxi(offset, _SP_REGNO, _RA_REGNO); stxi(0, _SP_REGNO, _BP_REGNO); movr(_BP_REGNO, _SP_REGNO); /* alloca */ - subi(_SP_REGNO, _SP_REGNO, _jitc->function->stack); + if (_jitc->function->stack) + subi(_SP_REGNO, _SP_REGNO, _jitc->function->stack); } static void _epilog(jit_state_t *_jit, jit_node_t *node) { + jit_int32_t index; + jit_int32_t offset; /* callee save registers */ movr(_SP_REGNO, _BP_REGNO); -#if __WORDSIZE == 32 - if (jit_regset_tstbit(&_jitc->function->regset, _F30)) - ldxi_d(_F30_REGNO, _SP_REGNO, 96); - if (jit_regset_tstbit(&_jitc->function->regset, _F28)) - ldxi_d(_F28_REGNO, _SP_REGNO, 88); - if (jit_regset_tstbit(&_jitc->function->regset, _F26)) - ldxi_d(_F26_REGNO, _SP_REGNO, 80); - if (jit_regset_tstbit(&_jitc->function->regset, _F24)) - ldxi_d(_F24_REGNO, _SP_REGNO, 72); - if (jit_regset_tstbit(&_jitc->function->regset, _F22)) - ldxi_d(_F22_REGNO, _SP_REGNO, 64); - if (jit_regset_tstbit(&_jitc->function->regset, _F20)) - ldxi_d(_F20_REGNO, _SP_REGNO, 56); - if (jit_regset_tstbit(&_jitc->function->regset, _F18)) - ldxi_d(_F18_REGNO, _SP_REGNO, 48); - if (jit_regset_tstbit(&_jitc->function->regset, _F16)) - ldxi_d(_F16_REGNO, _SP_REGNO, 40); - if (jit_regset_tstbit(&_jitc->function->regset, _S7)) - ldxi(_S7_REGNO, _SP_REGNO, 36); - if (jit_regset_tstbit(&_jitc->function->regset, _S6)) - ldxi(_S6_REGNO, _SP_REGNO, 32); - if (jit_regset_tstbit(&_jitc->function->regset, _S5)) - ldxi(_S5_REGNO, _SP_REGNO, 28); - if (jit_regset_tstbit(&_jitc->function->regset, _S4)) - ldxi(_S4_REGNO, _SP_REGNO, 24); - if (jit_regset_tstbit(&_jitc->function->regset, _S3)) - ldxi(_S3_REGNO, _SP_REGNO, 20); - if (jit_regset_tstbit(&_jitc->function->regset, _S2)) - ldxi(_S2_REGNO, _SP_REGNO, 16); - if (jit_regset_tstbit(&_jitc->function->regset, _S1)) - ldxi(_S1_REGNO, _SP_REGNO, 12); - if (jit_regset_tstbit(&_jitc->function->regset, _S0)) - ldxi(_S0_REGNO, _SP_REGNO, 8); - ldxi(_RA_REGNO, _SP_REGNO, 4); -#else - if (jit_regset_tstbit(&_jitc->function->regset, _F30)) - ldxi_d(_F30_REGNO, _SP_REGNO, 136); - if (jit_regset_tstbit(&_jitc->function->regset, _F28)) - ldxi_d(_F28_REGNO, _SP_REGNO, 128); - if (jit_regset_tstbit(&_jitc->function->regset, _F26)) - ldxi_d(_F26_REGNO, _SP_REGNO, 120); - if (jit_regset_tstbit(&_jitc->function->regset, _F24)) - ldxi_d(_F24_REGNO, _SP_REGNO, 112); - if (jit_regset_tstbit(&_jitc->function->regset, _F22)) - ldxi_d(_F22_REGNO, _SP_REGNO, 104); - if (jit_regset_tstbit(&_jitc->function->regset, _F20)) - ldxi_d(_F20_REGNO, _SP_REGNO, 96); - if (jit_regset_tstbit(&_jitc->function->regset, _F18)) - ldxi_d(_F18_REGNO, _SP_REGNO, 88); - if (jit_regset_tstbit(&_jitc->function->regset, _F16)) - ldxi_d(_F16_REGNO, _SP_REGNO, 80); - if (jit_regset_tstbit(&_jitc->function->regset, _S7)) - ldxi(_S7_REGNO, _SP_REGNO, 72); - if (jit_regset_tstbit(&_jitc->function->regset, _S6)) - ldxi(_S6_REGNO, _SP_REGNO, 64); - if (jit_regset_tstbit(&_jitc->function->regset, _S5)) - ldxi(_S5_REGNO, _SP_REGNO, 56); - if (jit_regset_tstbit(&_jitc->function->regset, _S4)) - ldxi(_S4_REGNO, _SP_REGNO, 48); - if (jit_regset_tstbit(&_jitc->function->regset, _S3)) - ldxi(_S3_REGNO, _SP_REGNO, 40); - if (jit_regset_tstbit(&_jitc->function->regset, _S2)) - ldxi(_S2_REGNO, _SP_REGNO, 32); - if (jit_regset_tstbit(&_jitc->function->regset, _S1)) - ldxi(_S1_REGNO, _SP_REGNO, 24); - if (jit_regset_tstbit(&_jitc->function->regset, _S0)) - ldxi(_S0_REGNO, _SP_REGNO, 16); - ldxi(_RA_REGNO, _SP_REGNO, 8); -#endif + offset = stack_framesize - (sizeof(jit_word_t) << 1); + for (index = 0; index < jit_size(fregs); index++, offset -= 8) { + if (jit_regset_tstbit(&_jitc->function->regset, fregs[index])) + ldxi_d(rn(fregs[index]), _SP_REGNO, offset); + } + for (index = 0; index < jit_size(iregs); + index++, offset -= sizeof(jit_word_t)) { + if (jit_regset_tstbit(&_jitc->function->regset, iregs[index])) + ldxi(rn(iregs[index]), _SP_REGNO, offset); + } + assert(offset >= sizeof(jit_word_t)); + ldxi(_RA_REGNO, _SP_REGNO, offset); ldxi(_BP_REGNO, _SP_REGNO, 0); JR(_RA_REGNO); /* delay slot */ diff --git a/lib/jit_mips-fpu.c b/lib/jit_mips-fpu.c index 9b83804b7..98e473ba3 100644 --- a/lib/jit_mips-fpu.c +++ b/lib/jit_mips-fpu.c @@ -23,7 +23,6 @@ # define MIPS_fmt_PS 0x16 /* 2 x float32 */ # define MIPS_fmt_S_PU 0x20 # define MIPS_fmt_S_PL 0x26 - # define MIPS_ADD_fmt 0x00 # define MIPS_LWXC1 0x00 # define MIPS_SUB_fmt 0x01 @@ -69,7 +68,6 @@ # define MIPS_NMSUB_fmt_S (0x38 | MIPS_fmt_S) # define MIPS_NMSUB_fmt_D (0x38 | MIPS_fmt_D) # define MIPS_NMSUB_fmt_PS (0x38 | MIPS_fmt_PS) - # define MIPS_cond_F 0x30 # define MIPS_cond_UN 0x31 # define MIPS_cond_EQ 0x32 @@ -86,7 +84,6 @@ # define MIPS_cond_NGE 0x3d # define MIPS_cond_LE 0x3e # define MIPS_cond_UGT 0x3f - # define ADD_S(fd,fs,ft) hrrrit(MIPS_COP1,MIPS_fmt_S,ft,fs,fd,MIPS_ADD_fmt) # define ADD_D(fd,fs,ft) hrrrit(MIPS_COP1,MIPS_fmt_D,ft,fs,fd,MIPS_ADD_fmt) # define SUB_S(fd,fs,ft) hrrrit(MIPS_COP1,MIPS_fmt_S,ft,fs,fd,MIPS_SUB_fmt) @@ -212,7 +209,9 @@ static void _divi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); # define negr_d(r0,r1) NEG_D(r0,r1) # define sqrtr_f(r0,r1) SQRT_S(r0,r1) # define sqrtr_d(r0,r1) SQRT_D(r0,r1) -# define movr_w_f(r0, r1) MTC1(r1, r0) +# if !NEW_ABI +# define movr_w_f(r0, r1) MTC1(r1, r0) +# endif # define movr_f_w(r0, r1) MFC1(r1, r0) # define movi_f_w(r0, i0) _movi_f_w(_jit, r0, i0) static void _movi_f_w(jit_state_t*,jit_int32_t,jit_float32_t*); @@ -243,12 +242,18 @@ static void _stxi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); static void _movr_f(jit_state_t*,jit_int32_t,jit_int32_t); # define movi_f(r0, i0) _movi_f(_jit, r0, i0) static void _movi_f(jit_state_t*,jit_int32_t,jit_float32_t*); -# define movr_ww_d(r0, r1, r2) _movr_ww_d(_jit, r0, r1, r2) +# if NEW_ABI +# define movr_d_w(r0, r1) DMFC1(r0, r1) +# define movi_d_w(r0, i0) _movi_d_w(_jit,r0,i0) +static void _movi_d_w(jit_state_t*,jit_int32_t,jit_float64_t*); +# else +# define movr_ww_d(r0, r1, r2) _movr_ww_d(_jit, r0, r1, r2) static void _movr_ww_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); -# define movr_d_ww(r0, r1, r2) _movr_d_ww(_jit, r0, r1, r2) +# define movr_d_ww(r0, r1, r2) _movr_d_ww(_jit, r0, r1, r2) static void _movr_d_ww(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); -# define movi_d_ww(r0, r1, i0) _movi_d_ww(_jit, r0, r1, i0) +# define movi_d_ww(r0, r1, i0) _movi_d_ww(_jit, r0, r1, i0) static void _movi_d_ww(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# endif # define extr_d(r0, r1) _extr_d(_jit, r0, r1) static void _extr_d(jit_state_t*,jit_int32_t,jit_int32_t); # define truncr_d_i(r0, r1) _truncr_d_i(_jit, r0, r1) @@ -619,7 +624,7 @@ _truncr_f_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) # if __WORDSIZE == 64 static void -_truncr_f_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +_truncr_f_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) { jit_int32_t t0; t0 = jit_get_reg(jit_class_fpr); @@ -732,6 +737,21 @@ dopi(sub) dopi(mul) dopi(div) +#if NEW_ABI +static void +_movi_d_w(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0) +{ + jit_word_t w; + w = (jit_word_t)i0; + if (can_sign_extend_short_p(w)) + LD(r0, w, _ZERO_REGNO); + else { + movi(r0, w); + LD(r0, 0, r0); + } +} + +#else static void _movr_ww_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) { @@ -761,6 +781,7 @@ _movi_d_ww(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_float64_t *i0) movi(r0, data.i[0]); movi(r1, data.i[1]); } +#endif static void _extr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) @@ -802,7 +823,7 @@ _truncr_d_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) static void _ldr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) { -# if __WORDSIZE == 64 +# if __WORDSIZE == 64 || NEW_ABI LDC1(r0, 0, r1); # else LWC1(r0, 0, r1); @@ -814,7 +835,7 @@ static void _ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) { jit_int32_t reg; -# if __WORDSIZE == 64 +# if __WORDSIZE == 64 || NEW_ABI if (can_sign_extend_short_p(i0)) LDC1(r0, i0, _ZERO_REGNO); else { @@ -852,7 +873,7 @@ static void _ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) { jit_int32_t reg; -# if __WORDSIZE == 64 +# if __WORDSIZE == 64 || NEW_ABI if (can_sign_extend_short_p(i0)) LDC1(r0, i0, r1); # else @@ -872,7 +893,7 @@ _ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) static void _str_d(jit_state_t *_jit,jit_int32_t r0, jit_int32_t r1) { -# if __WORDSIZE == 64 +# if __WORDSIZE == 64 || NEW_ABI SDC1(r1, 0, r0); # else SWC1(r1, 0, r0); @@ -884,7 +905,7 @@ static void _sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) { jit_int32_t reg; -# if __WORDSIZE == 64 +# if __WORDSIZE == 64 || NEW_ABI if (can_sign_extend_short_p(i0)) SDC1(r0, i0, _ZERO_REGNO); # else @@ -915,7 +936,7 @@ static void _stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) { jit_int32_t reg; -# if __WORDSIZE == 64 +# if __WORDSIZE == 64 || NEW_ABI if (can_sign_extend_int_p(i0)) SDC1(r1, i0, r0); # else @@ -949,7 +970,7 @@ _movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0) } data; data.d = *i0; -# if __WORDSIZE == 64 +# if __WORDSIZE == 64 || NEW_ABI if (data.l) ldi_d(r0, (jit_word_t)i0); else diff --git a/lib/jit_mips.c b/lib/jit_mips.c index 815d8bf96..1bdf28abb 100644 --- a/lib/jit_mips.c +++ b/lib/jit_mips.c @@ -22,7 +22,24 @@ #define rc(value) jit_class_##value #define rn(reg) (jit_regno(_rvs[jit_regno(reg)].spec)) -/* initial, mipsel 32 bits code only */ +/* FIXME Need to detect (from /proc on Linux?) if a Loongson or Godson, + * because n32 and n64 mandate that float registers are 64 bit, and + * on the later, registers are 32 bit. + */ +#if NEW_ABI +# define NUM_WORD_ARGS 8 +# define STACK_SLOT 8 +# define STACK_SHIFT 3 +#else +# define NUM_WORD_ARGS 4 +# define STACK_SLOT 4 +# define STACK_SHIFT 2 +#endif +#if __BYTE_ORDER == __BIG_ENDIAN && __WORDSIZE == 32 +# define WORD_ADJUST 4 +#else +# define WORD_ADJUST 0 +#endif /* * Prototypes @@ -42,10 +59,12 @@ jit_register_t _rvs[] = { { rc(gpr) | 0x01, "at" }, { rc(gpr) | 0x02, "v0" }, { rc(gpr) | 0x03, "v1" }, +#if !NEW_ABI { rc(gpr) | 0x08, "t0" }, { rc(gpr) | 0x09, "t1" }, { rc(gpr) | 0x0a, "t2" }, { rc(gpr) | 0x0b, "t3" }, +#endif { rc(gpr) | 0x0c, "t4" }, { rc(gpr) | 0x0d, "t5" }, { rc(gpr) | 0x0e, "t6" }, @@ -67,6 +86,12 @@ jit_register_t _rvs[] = { { rc(sav) | 0x1c, "gp" }, { rc(sav) | 0x1d, "sp" }, { rc(sav) | 0x1e, "fp" }, +#if NEW_ABI + { rc(gpr) | 0x0b, "a7" }, + { rc(gpr) | 0x0a, "a6" }, + { rc(gpr) | 0x09, "a5" }, + { rc(gpr) | 0x08, "a4" }, +#endif { rc(arg) | rc(gpr) | 0x07, "a3" }, { rc(arg) | rc(gpr) | 0x06, "a2" }, { rc(arg) | rc(gpr) | 0x05, "a1" }, @@ -77,16 +102,29 @@ jit_register_t _rvs[] = { { rc(fpr) | 0x06, "$f6" }, { rc(fpr) | 0x08, "$f8" }, { rc(fpr) | 0x0a, "$f10" }, +#if !NEW_ABI { rc(sav) | rc(fpr) | 0x10, "$f16" }, { rc(sav) | rc(fpr) | 0x12, "$f18" }, +#endif { rc(sav) | rc(fpr) | 0x14, "$f20" }, { rc(sav) | rc(fpr) | 0x16, "$f22" }, { rc(sav) | rc(fpr) | 0x18, "$f24" }, { rc(sav) | rc(fpr) | 0x1a, "$f26" }, { rc(sav) | rc(fpr) | 0x1c, "$f28" }, { rc(sav) | rc(fpr) | 0x1e, "$f30" }, +#if NEW_ABI + { rc(arg) | rc(fpr) | 0x13, "$f19" }, + { rc(arg) | rc(fpr) | 0x12, "$f18" }, + { rc(arg) | rc(fpr) | 0x11, "$f17" }, + { rc(arg) | rc(fpr) | 0x10, "$f16" }, + { rc(arg) | rc(fpr) | 0x0f, "$f15" }, + { rc(arg) | rc(fpr) | 0x0e, "$f14" }, + { rc(arg) | rc(fpr) | 0x0d, "$f13" }, + { rc(arg) | rc(fpr) | 0x0c, "$f12" }, +#else { rc(arg) | rc(fpr) | 0x0e, "$f14" }, { rc(arg) | rc(fpr) | 0x0c, "$f12" }, +#endif { _NOREG, "" }, }; @@ -239,28 +277,43 @@ jit_node_t * _jit_arg(jit_state_t *_jit) { jit_int32_t offset; - assert(_jitc->function); +#if NEW_ABI + if (_jitc->function->self.argi < NUM_WORD_ARGS) + offset = _jitc->function->self.argi++; + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += STACK_SLOT; + } +#else offset = (_jitc->function->self.size - stack_framesize) >> 2; _jitc->function->self.argi = 1; if (offset >= 4) offset = _jitc->function->self.size; - _jitc->function->self.size += sizeof(jit_word_t); + _jitc->function->self.size += STACK_SLOT; +#endif return (jit_new_node_w(jit_code_arg, offset)); } jit_bool_t _jit_arg_reg_p(jit_state_t *_jit, jit_int32_t offset) { - return (offset >= 0 && offset < 4); + return (offset >= 0 && offset < NUM_WORD_ARGS); } jit_node_t * _jit_arg_f(jit_state_t *_jit) { jit_int32_t offset; - assert(_jitc->function); +#if NEW_ABI + if (_jitc->function->self.argi < NUM_WORD_ARGS) + offset = _jitc->function->self.argi++; + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += STACK_SLOT; + } +#else offset = (_jitc->function->self.size - stack_framesize) >> 2; if (offset < 4) { if (!_jitc->function->self.argi) { @@ -274,8 +327,8 @@ _jit_arg_f(jit_state_t *_jit) } else offset = _jitc->function->self.size; - _jitc->function->self.size += sizeof(jit_float32_t); - + _jitc->function->self.size += STACK_SLOT; +#endif return (jit_new_node_w(jit_code_arg_f, offset)); } @@ -290,8 +343,15 @@ jit_node_t * _jit_arg_d(jit_state_t *_jit) { jit_int32_t offset; - assert(_jitc->function); +#if NEW_ABI + if (_jitc->function->self.argi < NUM_WORD_ARGS) + offset = _jitc->function->self.argi++; + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += STACK_SLOT; + } +#else if (_jitc->function->self.size & 7) { _jitc->function->self.size += 4; _jitc->function->self.argi = 1; @@ -303,7 +363,8 @@ _jit_arg_d(jit_state_t *_jit) } else offset = _jitc->function->self.size; - _jitc->function->self.size += sizeof(jit_float64_t); + _jitc->function->self.size += STACK_SLOT; +#endif return (jit_new_node_w(jit_code_arg_d, offset)); } @@ -316,67 +377,97 @@ _jit_arg_d_reg_p(jit_state_t *_jit, jit_int32_t offset) void _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { - if (v->u.w < 4) + if (v->u.w < NUM_WORD_ARGS) jit_extr_c(u, _A0 - v->u.w); - else + else { +#if __BYTE_ORDER == __LITTLE__ENDIAN jit_ldxi_c(u, _FP, v->u.w); +#else + jit_ldxi_c(u, JIT_FP, v->u.w + STACK_SLOT - sizeof(jit_int8_t)); + } +#endif } void _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { - if (v->u.w < 4) + if (v->u.w < NUM_WORD_ARGS) jit_extr_uc(u, _A0 - v->u.w); - else + else { +#if __BYTE_ORDER == __LITTLE__ENDIAN jit_ldxi_uc(u, _FP, v->u.w); +#else + jit_ldxi_uc(u, JIT_FP, v->u.w + STACK_SLOT - sizeof(jit_uint8_t)); + } +#endif } void _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { - if (v->u.w < 4) + if (v->u.w < NUM_WORD_ARGS) jit_extr_s(u, _A0 - v->u.w); - else + else { +#if __BYTE_ORDER == __LITTLE__ENDIAN jit_ldxi_s(u, _FP, v->u.w); +#else + jit_ldxi_s(u, JIT_FP, v->u.w + STACK_SLOT - sizeof(jit_int16_t)); + } +#endif } void _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { - if (v->u.w < 4) + if (v->u.w < NUM_WORD_ARGS) jit_extr_us(u, _A0 - v->u.w); - else + else { +#if __BYTE_ORDER == __LITTLE__ENDIAN jit_ldxi_us(u, _FP, v->u.w); +#else + jit_ldxi_us(u, JIT_FP, v->u.w + STACK_SLOT - sizeof(jit_uint16_t)); + } +#endif } void _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { - if (v->u.w < 4) { + if (v->u.w < NUM_WORD_ARGS) { #if __WORDSIZE == 64 jit_extr_i(u, _A0 - v->u.w); #else jit_movr(u, _A0 - v->u.w); #endif } - else + else { +#if __BYTE_ORDER == __LITTLE__ENDIAN jit_ldxi_i(u, _FP, v->u.w); +#else + jit_ldxi_i(u, JIT_FP, v->u.w + STACK_SLOT - sizeof(jit_int32_t)); + } +#endif } #if __WORDSIZE == 64 void _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { - if (v->u.w < 4) + if (v->u.w < NUM_WORD_ARGS) jit_extr_ui(u, _A0 - v->u.w); - else + else { +# if __BYTE_ORDER == __LITTLE__ENDIAN jit_ldxi_ui(u, _FP, v->u.w); +# else + jit_ldxi_ui(u, JIT_FP, v->u.w + STACK_SLOT - sizeof(jit_uint32_t)); + } +# endif } void _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { - if (v->u.w < 4) + if (v->u.w < NUM_WORD_ARGS) jit_movr(u, _A0 - v->u.w); else jit_ldxi_l(u, _FP, v->u.w); @@ -386,10 +477,15 @@ _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) void _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { +#if NEW_ABI + if (v->u.w < NUM_WORD_ARGS) + jit_movr_f(u, _F12 - v->u.w); +#else if (v->u.w < 4) jit_movr_w_f(u, _A0 - v->u.w); else if (v->u.w < 8) jit_movr_f(u, _F12 - ((v->u.w - 4) >> 1)); +#endif else jit_ldxi_f(u, _FP, v->u.w); } @@ -397,10 +493,15 @@ _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) void _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { +#if NEW_ABI + if (v->u.w < NUM_WORD_ARGS) + jit_movr_d(u, _F12 - v->u.w); +#else if (v->u.w < 4) jit_movr_ww_d(u, _A0 - v->u.w, _A0 - (v->u.w + 1)); else if (v->u.w < 8) jit_movr_d(u, _F12 - ((v->u.w - 4) >> 1)); +#endif else jit_ldxi_d(u, _FP, v->u.w); } @@ -408,28 +509,53 @@ _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) void _jit_pushargr(jit_state_t *_jit, jit_int32_t u) { - jit_word_t offset; - +#if NEW_ABI assert(_jitc->function); - offset = _jitc->function->call.size >> 2; + if (_jitc->function->call.argi < NUM_WORD_ARGS) { + jit_movr(_A0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + jit_stxi(_jitc->function->call.size + WORD_ADJUST, JIT_SP, u); + _jitc->function->call.size += STACK_SLOT; + } +#else + jit_word_t offset; + assert(_jitc->function); + offset = _jitc->function->call.size >> STACK_SHIFT; _jitc->function->call.argi = 1; - if (offset < 4) + if (offset < NUM_WORD_ARGS) jit_movr(_A0 - offset, u); else jit_stxi(_jitc->function->call.size, JIT_SP, u); - _jitc->function->call.size += sizeof(jit_word_t); + _jitc->function->call.size += STACK_SLOT; +#endif } void _jit_pushargi(jit_state_t *_jit, jit_word_t u) { +#if NEW_ABI + jit_int32_t regno; + assert(_jitc->function); + if (_jitc->function->call.argi < NUM_WORD_ARGS) { + jit_movi(_A0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(_jitc->function->call.size + WORD_ADJUST, JIT_SP, regno); + _jitc->function->call.size += STACK_SLOT; + jit_unget_reg(regno); + } +#else jit_int32_t regno; jit_word_t offset; - assert(_jitc->function); - offset = _jitc->function->call.size >> 2; + offset = _jitc->function->call.size >> STACK_SHIFT; ++_jitc->function->call.argi; - if (offset < 4) + if (offset < NUM_WORD_ARGS) jit_movi(_A0 - offset, u); else { regno = jit_get_reg(jit_class_gpr); @@ -437,16 +563,30 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u) jit_stxi(_jitc->function->call.size, JIT_SP, regno); jit_unget_reg(regno); } - _jitc->function->call.size += sizeof(jit_word_t); + _jitc->function->call.size += STACK_SLOT; +#endif } void _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) { - jit_word_t offset; - +#if NEW_ABI assert(_jitc->function); - offset = _jitc->function->call.size >> 2; + if (_jitc->function->call.argi < NUM_WORD_ARGS) { + if (!(_jitc->function->call.call & jit_call_varargs)) + jit_movr_f(_F12 - _jitc->function->call.argi, u); + else + jit_movr_f_w(_A0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + jit_stxi_f(_jitc->function->call.size, JIT_SP, u); + _jitc->function->call.size += STACK_SLOT; + } +#else + jit_word_t offset; + assert(_jitc->function); + offset = _jitc->function->call.size >> STACK_SHIFT; if (offset < 2 && !_jitc->function->call.argi) { ++_jitc->function->call.argf; jit_movr_f(_F12 - offset, u); @@ -457,17 +597,34 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) } else jit_stxi_f(_jitc->function->call.size, JIT_SP, u); - _jitc->function->call.size += sizeof(jit_float32_t); + _jitc->function->call.size += STACK_SLOT; +#endif } void _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) { jit_int32_t regno; - jit_word_t offset; - +#if NEW_ABI assert(_jitc->function); - offset = _jitc->function->call.size >> 2; + if (_jitc->function->call.argi < NUM_WORD_ARGS) { + if (!(_jitc->function->call.call & jit_call_varargs)) + jit_movi_f(_F12 - _jitc->function->call.argi, u); + else + jit_movi_f_w(_A0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_stxi_f(_jitc->function->call.size, JIT_SP, regno); + _jitc->function->call.size += STACK_SLOT; + jit_unget_reg(regno); + } +#else + jit_word_t offset; + assert(_jitc->function); + offset = _jitc->function->call.size >> STACK_SHIFT; if (offset < 2 && !_jitc->function->call.argi) { ++_jitc->function->call.argf; jit_movi_f(_F12 - offset, u); @@ -482,15 +639,29 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) jit_stxi_f(_jitc->function->call.size, JIT_SP, regno); jit_unget_reg(regno); } - _jitc->function->call.size += sizeof(jit_float32_t); + _jitc->function->call.size += STACK_SLOT; +#endif } void _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) { +#if NEW_ABI + assert(_jitc->function); + if (_jitc->function->call.argi < NUM_WORD_ARGS) { + if (!(_jitc->function->call.call & jit_call_varargs)) + jit_movr_d(_F12 - _jitc->function->call.argi, u); + else + jit_movr_d_w(_A0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + jit_stxi_d(_jitc->function->call.size, JIT_SP, u); + _jitc->function->call.size += STACK_SLOT; + } +#else jit_bool_t adjust; jit_word_t offset; - assert(_jitc->function); adjust = !!_jitc->function->call.argi; if (_jitc->function->call.size & 7) { @@ -510,23 +681,40 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) } else jit_stxi_d(_jitc->function->call.size, JIT_SP, u); - _jitc->function->call.size += sizeof(jit_float64_t); + _jitc->function->call.size += STACK_SLOT; +#endif } void _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) { jit_int32_t regno; +#if NEW_ABI + assert(_jitc->function); + if (_jitc->function->call.argi < NUM_WORD_ARGS) { + if (!(_jitc->function->call.call & jit_call_varargs)) + jit_movi_d(_F12 - _jitc->function->call.argi, u); + else + jit_movi_d_w(_A0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_stxi_d(_jitc->function->call.size, JIT_SP, regno); + _jitc->function->call.size += STACK_SLOT; + jit_unget_reg(regno); + } +#else jit_bool_t adjust; jit_word_t offset; - assert(_jitc->function); adjust = !!_jitc->function->call.argi; if (_jitc->function->call.size & 7) { _jitc->function->call.size += 4; adjust = 1; } - offset = _jitc->function->call.size >> 2; + offset = _jitc->function->call.size >> STACK_SHIFT; if (offset < 3) { if (adjust) { jit_movi_d_ww(_A0 - offset, _A0 - (offset + 1), u); @@ -543,7 +731,8 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) jit_stxi_d(_jitc->function->call.size, JIT_SP, regno); jit_unget_reg(regno); } - _jitc->function->call.size += sizeof(jit_float64_t); + _jitc->function->call.size += STACK_SLOT; +#endif } jit_bool_t @@ -579,7 +768,11 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0) jit_movr(_T9, r0); call = jit_callr(_T9); call->v.w = _jitc->function->self.argi; +#if NEW_ABI + call->w.w = call->v.w; +#else call->w.w = _jitc->function->self.argf; +#endif _jitc->function->call.argi = _jitc->function->call.argf = _jitc->function->call.size = 0; _jitc->prepare = 0; @@ -597,7 +790,11 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0) node = jit_movi(_T9, (jit_word_t)i0); call = jit_callr(_T9); call->v.w = _jitc->function->call.argi; +#if NEW_ABI + call->w.w = call->v.w; +#else call->w.w = _jitc->function->call.argf; +#endif _jitc->function->call.argi = _jitc->function->call.argf = _jitc->function->call.size = 0; _jitc->prepare = 0; @@ -892,6 +1089,10 @@ _emit_code(jit_state_t *_jit) case_rr(ext, _uc); case_rr(ext, _s); case_rr(ext, _us); +#if __WORDSIZE == 64 + case_rr(ext, _i); + case_rr(ext, _ui); +#endif case_rr(mov,); case jit_code_movi: if (node->flag & jit_flag_node) { @@ -1195,9 +1396,11 @@ _emit_code(jit_state_t *_jit) epilog(node); _jitc->function = NULL; break; +#if !NEW_ABI case jit_code_movr_w_f: movr_w_f(rn(node->u.w), rn(node->v.w)); break; +#endif case jit_code_movr_f_w: movr_f_w(rn(node->u.w), rn(node->v.w)); break; @@ -1205,6 +1408,15 @@ _emit_code(jit_state_t *_jit) assert(node->flag & jit_flag_data); movi_f_w(rn(node->u.w), (jit_float32_t *)node->v.n->u.w); break; +#if NEW_ABI + case jit_code_movr_d_w: + movr_d_w(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_movi_d_w: + assert(node->flag & jit_flag_data); + movi_d_w(rn(node->u.w), (jit_float64_t *)node->v.n->u.w); + break; +#else case jit_code_movr_ww_d: movr_ww_d(rn(node->u.w), rn(node->v.w), rn(node->w.w)); break; @@ -1216,6 +1428,7 @@ _emit_code(jit_state_t *_jit) movi_d_ww(rn(node->u.w), rn(node->v.w), (jit_float64_t *)node->w.n->u.w); break; +#endif case jit_code_live: case jit_code_arg: case jit_code_arg_f: case jit_code_arg_d: @@ -1273,21 +1486,13 @@ _emit_code(jit_state_t *_jit) void _emit_ldxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) { -#if __WORDSIZE == 32 - ldxi_i(rn(r0), rn(r1), i0); -#else - ldxi_l(rn(r0), rn(r1), i0); -#endif + ldxi(rn(r0), rn(r1), i0); } void _emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) { -#if __WORDSIZE == 32 - stxi_i(i0, rn(r0), rn(r1)); -#else - stxi_l(i0, rn(r0), rn(r1)); -#endif + stxi(i0, rn(r0), rn(r1)); } void diff --git a/lib/lightning.c b/lib/lightning.c index f5ba7a4b3..8d844e7e7 100644 --- a/lib/lightning.c +++ b/lib/lightning.c @@ -18,9 +18,15 @@ #include #include #include +#if defined(__sgi) +# include +#endif #ifndef MAP_ANON # define MAP_ANON MAP_ANONYMOUS +# ifndef MAP_ANONYMOUS +# define MAP_ANONYMOUS 0 +# endif #endif #define jit_regload_reload 0 /* convert to reload */ @@ -159,6 +165,9 @@ _patch_register(jit_state_t *jit, jit_node_t *node, jit_node_t *link, * Initialization */ const char *jit_progname; +#if !defined(__sgi) +#define mmap_fd -1 +#endif /* * Implementation @@ -1375,6 +1384,9 @@ _jit_optimize(jit_state_t *_jit) jit_node_t *node; jit_block_t *block; jit_word_t offset; +#if defined(__sgi) + int mmap_fd; +#endif _jitc->function = NULL; @@ -1491,10 +1503,16 @@ _jit_optimize(jit_state_t *_jit) _jit->data.length = (_jitc->data.offset + /* reserve space for annotations */ _jitc->note.size + 4095) & -4096; +#if defined(__sgi) + mmap_fd = open("/dev/zero", O_RDWR); +#endif ptr = mmap(NULL, _jit->data.length, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON, -1, 0); + MAP_PRIVATE | MAP_ANON, mmap_fd, 0); assert(ptr != MAP_FAILED); +#if defined(__sgi) + close(mmap_fd); +#endif memcpy(ptr, _jit->data.ptr, _jitc->data.offset); jit_free((jit_pointer_t *)&_jit->data.ptr); _jit->data.ptr = ptr; @@ -1648,6 +1666,9 @@ _jit_emit(jit_state_t *_jit) jit_node_t *node; size_t length; int result; +#if defined(__sgi) + int mmap_fd; +#endif if (_jitc->function) jit_epilog(); @@ -1660,9 +1681,12 @@ _jit_emit(jit_state_t *_jit) _jit->code.length = _jitc->pool.length * 1024 * _jitc->mult; +#if defined(__sgi) + mmap_fd = open("/dev/zero", O_RDWR); +#endif _jit->code.ptr = mmap(NULL, _jit->code.length, PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON, -1, 0); + MAP_PRIVATE | MAP_ANON, mmap_fd, 0); assert(_jit->code.ptr != MAP_FAILED); _jitc->code.end = _jit->code.ptr + _jit->code.length - 64; _jit->pc.uc = _jit->code.ptr; @@ -1688,7 +1712,7 @@ _jit_emit(jit_state_t *_jit) #else _jit->code.ptr = mmap(NULL, length, PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON, -1, 0); + MAP_PRIVATE | MAP_ANON, mmap_fd, 0); #endif assert(_jit->code.ptr != MAP_FAILED); @@ -1701,6 +1725,10 @@ _jit_emit(jit_state_t *_jit) break; } +#if defined(__sgi) + close(mmap_fd); +#endif + _jitc->done = 1; jit_annotate();