1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-24 20:30:28 +02:00

Build and pass all tests on big endian Irix mips using the n32 abi.

* 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.
This commit is contained in:
pcpa 2013-06-22 19:44:00 -03:00
parent dbe0fb9bfa
commit d6110f6cf3
9 changed files with 480 additions and 269 deletions

View file

@ -1,3 +1,13 @@
2013-06-22 Paulo Andrade <pcpa@gnu.org>
* 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 <pcpa@gnu.org> 2013-06-18 Paulo Andrade <pcpa@gnu.org>
* include/lightning.h: Minor extra preprocessor testing * include/lightning.h: Minor extra preprocessor testing

View file

@ -40,6 +40,8 @@
#if defined(__hpux) #if defined(__hpux)
# define DL_HANDLE RTLD_NEXT # define DL_HANDLE RTLD_NEXT
#elif defined(__sgi)
static void *DL_HANDLE;
#else #else
# define DL_HANDLE RTLD_DEFAULT # define DL_HANDLE RTLD_DEFAULT
#endif #endif
@ -3702,6 +3704,8 @@ get_symbol_by_name(char *name)
{ {
symbol_t **symbol_pointer; symbol_t **symbol_pointer;
if (symbols == NULL)
return (NULL);
symbol_pointer = (symbol_t **)bsearch(name, symbols, symbol_offset, symbol_pointer = (symbol_t **)bsearch(name, symbols, symbol_offset,
sizeof(symbol_t *), bcmp_symbols); sizeof(symbol_t *), bcmp_symbols);
@ -3788,7 +3792,7 @@ rehash(hash_t *hash)
static void static void
usage(void) usage(void)
{ {
#if HAVE_GETOPT_H #if HAVE_GETOPT_LONG_ONLY
fprintf(stderr, "\ fprintf(stderr, "\
Usage: %s [jit assembler options] file [jit program options]\n\ Usage: %s [jit assembler options] file [jit program options]\n\
Jit assembler options:\n\ Jit assembler options:\n\
@ -3823,7 +3827,7 @@ Jit assembler options:\n\
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
#if HAVE_GETOPT_H #if HAVE_GETOPT_LONG_ONLY
static const char *short_options = "v::"; static const char *short_options = "v::";
static struct option long_options[] = { static struct option long_options[] = {
{ "help", 0, 0, 'h' }, { "help", 0, 0, 'h' },
@ -3842,7 +3846,7 @@ main(int argc, char *argv[])
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
}; };
#else #else
#endif /* HAVE_GETOPT_H */ #endif /* HAVE_GETOPT_LONG_ONLY */
int offset; int offset;
char *endptr; char *endptr;
int opt_index; int opt_index;
@ -3853,7 +3857,11 @@ main(int argc, char *argv[])
init_jit(progname); init_jit(progname);
#if HAVE_GETOPT_H #if defined(__sgi)
DL_HANDLE = dlopen(NULL, RTLD_LAZY);
#endif
#if HAVE_GETOPT_LONG_ONLY
for (;;) { for (;;) {
if ((opt_short = getopt_long_only(argc, argv, short_options, if ((opt_short = getopt_long_only(argc, argv, short_options,
long_options, &opt_index)) < 0) long_options, &opt_index)) < 0)
@ -4029,6 +4037,11 @@ main(int argc, char *argv[])
opt_short += snprintf(cmdline + opt_short, opt_short += snprintf(cmdline + opt_short,
sizeof(cmdline) - opt_short, sizeof(cmdline) - opt_short,
" -D_AIX=1"); " -D_AIX=1");
#endif
#if defined(__sgi__)
opt_short += snprintf(cmdline + opt_short,
sizeof(cmdline) - opt_short,
" -D__sgi__=1");
#endif #endif
if ((parser.fp = popen(cmdline, "r")) == NULL) if ((parser.fp = popen(cmdline, "r")) == NULL)
error("cannot execute %s", cmdline); error("cannot execute %s", cmdline);

View file

@ -28,6 +28,12 @@ case "$target_cpu" in
*hpux*) CFLAGS="$CFLAGS -mlp64" ;; *hpux*) CFLAGS="$CFLAGS -mlp64" ;;
*) ;; *) ;;
esac ;; esac ;;
*mips*)
case "$host_os" in
# Extra flags to build with gcc 3.x
*irix*) CFLAGS="$CFLAGS -D__c99 -Drestrict=" ;;
*) ;;
esac ;;
*) ;; *) ;;
esac esac
@ -35,7 +41,7 @@ AC_PROG_CC
AC_PROG_INSTALL AC_PROG_INSTALL
AC_PROG_LIBTOOL AC_PROG_LIBTOOL
AC_CHECK_FUNCS(mremap ffsl,,) AC_CHECK_FUNCS(mremap ffsl getopt_long_only,,)
AC_CHECK_HEADERS([getopt.h],,,) AC_CHECK_HEADERS([getopt.h],,,)

View file

@ -40,6 +40,12 @@
# define __WORDSIZE 32 # define __WORDSIZE 32
# elif defined(_LP64) /* ia64 hp-ux (with cc +DD64) */ # elif defined(_LP64) /* ia64 hp-ux (with cc +DD64) */
# define __WORDSIZE 64 # define __WORDSIZE 64
# elif defined(_MIPS_SZPTR) /* mips irix */
# if _MIPS_SZPTR == 32
# define __WORDSIZE 32
# else
# define __WORDSIZE 64
# endif
# else # else
# error cannot figure __WORDSIZE # error cannot figure __WORDSIZE
# endif # endif
@ -69,10 +75,12 @@
# define __BYTE_ORDER __BYTE_ORDER__ # define __BYTE_ORDER __BYTE_ORDER__
# elif defined(_BIG_ENDIAN) /* hppa hp-ux */ # elif defined(_BIG_ENDIAN) /* hppa hp-ux */
# define __BYTE_ORDER __BIG_ENDIAN # 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 # define __BYTE_ORDER __BIG_ENDIAN
# elif defined(__i386__)
# define __BYTE_ORDER __LITTLE_ENDIAN /* x86 solaris */
# else # else
# error cannot figure __BYTE_ORDER # error cannot figure __BYTE_ORDER
# endif # endif

View file

@ -21,14 +21,23 @@
#define JIT_HASH_CONSTS 1 #define JIT_HASH_CONSTS 1
#define JIT_NUM_OPERANDS 3 #define JIT_NUM_OPERANDS 3
#if defined(_ABIN32)
# define NEW_ABI 1
#endif
/* /*
* Types * Types
*/ */
#define JIT_FP _FP #define JIT_FP _FP
typedef enum { typedef enum {
#define jit_arg_reg_p(i) ((i) >= 0 && (i) < 4)
#define jit_r(i) (_V0 + (i)) #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(i) (_S0 + (i))
#define jit_v_num() 8 #define jit_v_num() 8
#define jit_arg_f_reg_p(i) ((i) >= 0 && (i) < 4) #define jit_arg_f_reg_p(i) ((i) >= 0 && (i) < 4)
@ -37,35 +46,28 @@ typedef enum {
_AT, _AT,
#define JIT_R0 _V0 #define JIT_R0 _V0
#define JIT_R1 _V1 #define JIT_R1 _V1
#define JIT_R2 _T0 #if NEW_ABI
#define JIT_R3 _T1 # define JIT_R2 _T4
#define JIT_R4 _T2 #else
#define JIT_R5 _T3 # define JIT_R2 _T0
#define JIT_R6 _T4 #endif
#define JIT_R7 _T5 _V0, _V1,
#define JIT_R8 _T6 #if !NEW_ABI
#define JIT_R9 _T7 _T0, _T1, _T2, _T3,
#define JIT_R10 _T8 #endif
#define JIT_R11 _T9 /* must point to PIC function */ _T4, _T5, _T6, _T7, _T8, _T9,
_V0, _V1, _T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9,
#define JIT_V0 _S0 #define JIT_V0 _S0
#define JIT_V1 _S1 #define JIT_V1 _S1
#define JIT_V2 _S2 #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, _S0, _S1, _S2, _S3, _S4, _S5, _S6, _S7,
_ZERO, _K0, _K1, _RA, _ZERO, _K0, _K1, _RA,
_GP, /* FIXME use to point to jit data */ _GP,
_SP, _FP, _SP, _FP,
# define JIT_RA0 _A0 #define JIT_RA0 _A0
# define JIT_RA1 _A1 #if NEW_ABI
# define JIT_RA2 _A2 _A7, _A6, _A5, _A4,
# define JIT_RA3 _A3 #endif
_A3, _A2, _A1, _A0, _A3, _A2, _A1, _A0,
#define JIT_F0 _F0 #define JIT_F0 _F0
#define JIT_F1 _F2 #define JIT_F1 _F2
#define JIT_F2 _F4 #define JIT_F2 _F4
@ -74,18 +76,16 @@ typedef enum {
#define JIT_F5 _F10 #define JIT_F5 _F10
_F0, _F2, _F4, _F6, _F8, _F10, _F0, _F2, _F4, _F6, _F8, _F10,
/* callee save float registers */ /* callee save float registers */
#define JIT_FS0 _F16 #if !NEW_ABI
#define JIT_FS1 _F18 _F16, _F18,
#define JIT_FS2 _F20 #endif
#define JIT_FS3 _F22 _F20, _F22, _F24, _F26, _F28, _F30,
#define JIT_FS4 _F24
#define JIT_FS5 _F26
#define JIT_FS6 _F28
#define JIT_FS7 _F30
_F16, _F18, _F20, _F22, _F24, _F26, _F28, _F30,
#define JIT_FA0 _F12 #define JIT_FA0 _F12
#define JIT_FA1 _F14 #if NEW_ABI
_F19, _F18, _F17, _F16, _F15, _F14, _F13, _F12,
#else
_F14, _F12, _F14, _F12,
#endif
#define JIT_NOREG _NOREG #define JIT_NOREG _NOREG
_NOREG, _NOREG,
} jit_reg_t; } jit_reg_t;

View file

@ -17,6 +17,7 @@
#if PROTO #if PROTO
typedef union { typedef union {
#if __BYTE_ORDER == __LITTLE_ENDIAN
struct { jit_uint32_t _:26; jit_uint32_t b : 6; } hc; 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; } rs;
struct { jit_uint32_t _:21; jit_uint32_t b : 5; } fm; 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 : 11; } cc;
struct { jit_uint32_t b : 16; } is; struct { jit_uint32_t b : 16; } is;
struct { jit_uint32_t b : 26; } ii; 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; } jit_instr_t;
/* FIXME */ /* FIXME */
# define jit_mips2_p() 0 # define jit_mips2_p() 0
# define _ZERO_REGNO 0 # define _ZERO_REGNO 0
# define _T0_REGNO 0x08 # define _T0_REGNO 0x08
# define _T1_REGNO 0x09 # define _T1_REGNO 0x09
@ -68,9 +84,12 @@ typedef union {
# define _F26_REGNO 26 # define _F26_REGNO 26
# define _F28_REGNO 28 # define _F28_REGNO 28
# define _F30_REGNO 30 # define _F30_REGNO 30
# if __WORDSIZE == 32 # 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 ldi(u, v) ldi_i(u, v)
# define ldxi(u, v, w) ldxi_i(u, v, w) # define ldxi(u, v, w) ldxi_i(u, v, w)
# define sti(u, v) sti_i(u, v) # define sti(u, v) sti_i(u, v)
@ -82,7 +101,6 @@ typedef union {
# define sti(u, v) sti_l(u, v) # define sti(u, v) sti_l(u, v)
# define stxi(u, v, w) stxi_l(u, v, w) # define stxi(u, v, w) stxi_l(u, v, w)
# endif # endif
# define can_sign_extend_short_p(im) ((im) >= -32678 && (im) <= 32767) # define can_sign_extend_short_p(im) ((im) >= -32678 && (im) <= 32767)
# define can_zero_extend_short_p(im) ((im) >= 0 && (im) <= 65535) # define can_zero_extend_short_p(im) ((im) >= 0 && (im) <= 65535)
# if __WORDSIZE == 32 # if __WORDSIZE == 32
@ -94,7 +112,6 @@ typedef union {
((im) < 0 && (im) >= -0x80000000L)) ((im) < 0 && (im) >= -0x80000000L))
# define can_zero_extend_int_p(im) ((im) >= 0 && (im) <= 0xffffffff) # define can_zero_extend_int_p(im) ((im) >= 0 && (im) <= 0xffffffff)
# endif # endif
# define MIPS_SPECIAL 0x00 # define MIPS_SPECIAL 0x00
# define MIPS_REGIMM 0x01 # define MIPS_REGIMM 0x01
# define MIPS_J 0x02 # define MIPS_J 0x02
@ -157,7 +174,6 @@ typedef union {
# define MIPS_SWC1 0x39 # define MIPS_SWC1 0x39
# define MIPS_SWC2 0x3a # define MIPS_SWC2 0x3a
# define MIPS_SD 0x3f # define MIPS_SD 0x3f
# define MIPS_MF 0x00 # define MIPS_MF 0x00
# define MIPS_DMF 0x01 # define MIPS_DMF 0x01
# define MIPS_CF 0x02 # define MIPS_CF 0x02
@ -170,7 +186,6 @@ typedef union {
# define MIPS_WRPGPR 0x0e # define MIPS_WRPGPR 0x0e
# define MIPS_BGZAL 0x11 # define MIPS_BGZAL 0x11
# define MIPS_MFMC0 0x11 # define MIPS_MFMC0 0x11
# define MIPS_BCF 0x00 # define MIPS_BCF 0x00
# define MIPS_BLTZ 0x00 # define MIPS_BLTZ 0x00
# define MIPS_BCT 0x01 # define MIPS_BCT 0x01
@ -190,13 +205,11 @@ typedef union {
# define MIPS_BLTZALL 0x12 # define MIPS_BLTZALL 0x12
# define MIPS_BGEZALL 0x13 # define MIPS_BGEZALL 0x13
# define MIPS_SYNCI 0x1f # define MIPS_SYNCI 0x1f
# define MIPS_WSBH 0x02 # define MIPS_WSBH 0x02
# define MIPS_DBSH 0x02 # define MIPS_DBSH 0x02
# define MIPS_DSHD 0x05 # define MIPS_DSHD 0x05
# define MIPS_SEB 0x10 # define MIPS_SEB 0x10
# define MIPS_SEH 0x18 # define MIPS_SEH 0x18
# define MIPS_MADD 0x00 # define MIPS_MADD 0x00
# define MIPS_SLL 0x00 # define MIPS_SLL 0x00
# define MIPS_EXT 0x00 # define MIPS_EXT 0x00
@ -278,7 +291,6 @@ typedef union {
# define MIPS_DSRA32 0x3f # define MIPS_DSRA32 0x3f
# define MIPS_SDBPP 0x3f # define MIPS_SDBPP 0x3f
# define ii(i) *_jit->pc.ui++ = i # define ii(i) *_jit->pc.ui++ = i
static void static void
_hrrrit(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t, _hrrrit(jit_state_t*,jit_int32_t,jit_int32_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 SRLV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_SRLV)
# define SRL(rd,rt,sa) rrit(rt,rd,sa,MIPS_SRL) # 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 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 # else
# define ADDU(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_DADDU) # define ADDU(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_DADDU)
# define ADDIU(rt,rs,im) hrri(MIPS_DADDIU,rs,rt,im) # 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 SRLV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_DSRLV)
# define SRL(rd,rt,sa) rrit(rt,rd,sa,MIPS_DSRL) # 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 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 # endif
# define MFHI(rd) rrr_t(_ZERO_REGNO,_ZERO_REGNO,rd,MIPS_MFHI) # define MFHI(rd) rrr_t(_ZERO_REGNO,_ZERO_REGNO,rd,MIPS_MFHI)
# define MFLO(rd) rrr_t(_ZERO_REGNO,_ZERO_REGNO,rd,MIPS_MFLO) # 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 # if __WORDSIZE == 64
# define str_l(r0, r1) SD(r0, 0, r1) # define str_l(r0, r1) SD(r0, 0, r1)
# define sti_l(i0, r0) _sti_l(_jit, i0, r0) # 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 # endif
# define stxr_c(r0, r1, r2) _stxr_c(_jit, r0, r1, r2) # 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); 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) _extr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{ {
movr(r0, r1); movr(r0, r1);
INS(r0, _RZERO_REGNO, 32, 32); INS(r0, _ZERO_REGNO, 32, 32);
} }
# endif # endif
@ -2770,166 +2782,74 @@ _calli_p(jit_state_t *_jit, jit_word_t i0)
return (word); 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 static void
_prolog(jit_state_t *_jit, jit_node_t *node) _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->stack = ((/* first 16 bytes must be allocated */
(_jitc->function->self.alen > 16 ? (_jitc->function->self.alen > 16 ?
_jitc->function->self.alen : 16) - _jitc->function->self.alen : 16) -
/* align stack at 8 bytes */ /* align stack at 8 bytes */
_jitc->function->self.aoff) + 7) & -8; _jitc->function->self.aoff) + 7) & -8;
#endif
/* callee save registers */ /* callee save registers */
subi(_SP_REGNO, _SP_REGNO, stack_framesize); subi(_SP_REGNO, _SP_REGNO, stack_framesize);
#if __WORDSIZE == 32 offset = stack_framesize - (sizeof(jit_word_t) << 1);
if (jit_regset_tstbit(&_jitc->function->regset, _F30)) for (index = 0; index < jit_size(fregs); index++, offset -= 8) {
stxi_d(96, _SP_REGNO, _F30_REGNO); if (jit_regset_tstbit(&_jitc->function->regset, fregs[index]))
if (jit_regset_tstbit(&_jitc->function->regset, _F28)) stxi_d(offset, _SP_REGNO, rn(fregs[index]));
stxi_d(88, _SP_REGNO, _F28_REGNO); }
if (jit_regset_tstbit(&_jitc->function->regset, _F26)) for (index = 0; index < jit_size(iregs);
stxi_d(80, _SP_REGNO, _F26_REGNO); index++, offset -= sizeof(jit_word_t)) {
if (jit_regset_tstbit(&_jitc->function->regset, _F24)) if (jit_regset_tstbit(&_jitc->function->regset, iregs[index]))
stxi_d(72, _SP_REGNO, _F24_REGNO); stxi(offset, _SP_REGNO, rn(iregs[index]));
if (jit_regset_tstbit(&_jitc->function->regset, _F22)) }
stxi_d(64, _SP_REGNO, _F22_REGNO); assert(offset >= sizeof(jit_word_t));
if (jit_regset_tstbit(&_jitc->function->regset, _F20)) stxi(offset, _SP_REGNO, _RA_REGNO);
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
stxi(0, _SP_REGNO, _BP_REGNO); stxi(0, _SP_REGNO, _BP_REGNO);
movr(_BP_REGNO, _SP_REGNO); movr(_BP_REGNO, _SP_REGNO);
/* alloca */ /* alloca */
subi(_SP_REGNO, _SP_REGNO, _jitc->function->stack); if (_jitc->function->stack)
subi(_SP_REGNO, _SP_REGNO, _jitc->function->stack);
} }
static void static void
_epilog(jit_state_t *_jit, jit_node_t *node) _epilog(jit_state_t *_jit, jit_node_t *node)
{ {
jit_int32_t index;
jit_int32_t offset;
/* callee save registers */ /* callee save registers */
movr(_SP_REGNO, _BP_REGNO); movr(_SP_REGNO, _BP_REGNO);
#if __WORDSIZE == 32 offset = stack_framesize - (sizeof(jit_word_t) << 1);
if (jit_regset_tstbit(&_jitc->function->regset, _F30)) for (index = 0; index < jit_size(fregs); index++, offset -= 8) {
ldxi_d(_F30_REGNO, _SP_REGNO, 96); if (jit_regset_tstbit(&_jitc->function->regset, fregs[index]))
if (jit_regset_tstbit(&_jitc->function->regset, _F28)) ldxi_d(rn(fregs[index]), _SP_REGNO, offset);
ldxi_d(_F28_REGNO, _SP_REGNO, 88); }
if (jit_regset_tstbit(&_jitc->function->regset, _F26)) for (index = 0; index < jit_size(iregs);
ldxi_d(_F26_REGNO, _SP_REGNO, 80); index++, offset -= sizeof(jit_word_t)) {
if (jit_regset_tstbit(&_jitc->function->regset, _F24)) if (jit_regset_tstbit(&_jitc->function->regset, iregs[index]))
ldxi_d(_F24_REGNO, _SP_REGNO, 72); ldxi(rn(iregs[index]), _SP_REGNO, offset);
if (jit_regset_tstbit(&_jitc->function->regset, _F22)) }
ldxi_d(_F22_REGNO, _SP_REGNO, 64); assert(offset >= sizeof(jit_word_t));
if (jit_regset_tstbit(&_jitc->function->regset, _F20)) ldxi(_RA_REGNO, _SP_REGNO, offset);
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
ldxi(_BP_REGNO, _SP_REGNO, 0); ldxi(_BP_REGNO, _SP_REGNO, 0);
JR(_RA_REGNO); JR(_RA_REGNO);
/* delay slot */ /* delay slot */

View file

@ -23,7 +23,6 @@
# define MIPS_fmt_PS 0x16 /* 2 x float32 */ # define MIPS_fmt_PS 0x16 /* 2 x float32 */
# define MIPS_fmt_S_PU 0x20 # define MIPS_fmt_S_PU 0x20
# define MIPS_fmt_S_PL 0x26 # define MIPS_fmt_S_PL 0x26
# define MIPS_ADD_fmt 0x00 # define MIPS_ADD_fmt 0x00
# define MIPS_LWXC1 0x00 # define MIPS_LWXC1 0x00
# define MIPS_SUB_fmt 0x01 # define MIPS_SUB_fmt 0x01
@ -69,7 +68,6 @@
# define MIPS_NMSUB_fmt_S (0x38 | MIPS_fmt_S) # define MIPS_NMSUB_fmt_S (0x38 | MIPS_fmt_S)
# define MIPS_NMSUB_fmt_D (0x38 | MIPS_fmt_D) # define MIPS_NMSUB_fmt_D (0x38 | MIPS_fmt_D)
# define MIPS_NMSUB_fmt_PS (0x38 | MIPS_fmt_PS) # define MIPS_NMSUB_fmt_PS (0x38 | MIPS_fmt_PS)
# define MIPS_cond_F 0x30 # define MIPS_cond_F 0x30
# define MIPS_cond_UN 0x31 # define MIPS_cond_UN 0x31
# define MIPS_cond_EQ 0x32 # define MIPS_cond_EQ 0x32
@ -86,7 +84,6 @@
# define MIPS_cond_NGE 0x3d # define MIPS_cond_NGE 0x3d
# define MIPS_cond_LE 0x3e # define MIPS_cond_LE 0x3e
# define MIPS_cond_UGT 0x3f # 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_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 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) # 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 negr_d(r0,r1) NEG_D(r0,r1)
# define sqrtr_f(r0,r1) SQRT_S(r0,r1) # define sqrtr_f(r0,r1) SQRT_S(r0,r1)
# define sqrtr_d(r0,r1) SQRT_D(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 movr_f_w(r0, r1) MFC1(r1, r0)
# define movi_f_w(r0, i0) _movi_f_w(_jit, r0, i0) # 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*); 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); static void _movr_f(jit_state_t*,jit_int32_t,jit_int32_t);
# define movi_f(r0, i0) _movi_f(_jit, r0, i0) # define movi_f(r0, i0) _movi_f(_jit, r0, i0)
static void _movi_f(jit_state_t*,jit_int32_t,jit_float32_t*); 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); 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); 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*); 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) # define extr_d(r0, r1) _extr_d(_jit, r0, r1)
static void _extr_d(jit_state_t*,jit_int32_t,jit_int32_t); 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) # 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 # if __WORDSIZE == 64
static void 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; jit_int32_t t0;
t0 = jit_get_reg(jit_class_fpr); t0 = jit_get_reg(jit_class_fpr);
@ -732,6 +737,21 @@ dopi(sub)
dopi(mul) dopi(mul)
dopi(div) 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 static void
_movr_ww_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) _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(r0, data.i[0]);
movi(r1, data.i[1]); movi(r1, data.i[1]);
} }
#endif
static void static void
_extr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) _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 static void
_ldr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) _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); LDC1(r0, 0, r1);
# else # else
LWC1(r0, 0, r1); LWC1(r0, 0, r1);
@ -814,7 +835,7 @@ static void
_ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) _ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
{ {
jit_int32_t reg; jit_int32_t reg;
# if __WORDSIZE == 64 # if __WORDSIZE == 64 || NEW_ABI
if (can_sign_extend_short_p(i0)) if (can_sign_extend_short_p(i0))
LDC1(r0, i0, _ZERO_REGNO); LDC1(r0, i0, _ZERO_REGNO);
else { 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) _ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{ {
jit_int32_t reg; jit_int32_t reg;
# if __WORDSIZE == 64 # if __WORDSIZE == 64 || NEW_ABI
if (can_sign_extend_short_p(i0)) if (can_sign_extend_short_p(i0))
LDC1(r0, i0, r1); LDC1(r0, i0, r1);
# else # 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 static void
_str_d(jit_state_t *_jit,jit_int32_t r0, jit_int32_t r1) _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); SDC1(r1, 0, r0);
# else # else
SWC1(r1, 0, r0); SWC1(r1, 0, r0);
@ -884,7 +905,7 @@ static void
_sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) _sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
{ {
jit_int32_t reg; jit_int32_t reg;
# if __WORDSIZE == 64 # if __WORDSIZE == 64 || NEW_ABI
if (can_sign_extend_short_p(i0)) if (can_sign_extend_short_p(i0))
SDC1(r0, i0, _ZERO_REGNO); SDC1(r0, i0, _ZERO_REGNO);
# else # 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) _stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{ {
jit_int32_t reg; jit_int32_t reg;
# if __WORDSIZE == 64 # if __WORDSIZE == 64 || NEW_ABI
if (can_sign_extend_int_p(i0)) if (can_sign_extend_int_p(i0))
SDC1(r1, i0, r0); SDC1(r1, i0, r0);
# else # else
@ -949,7 +970,7 @@ _movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0)
} data; } data;
data.d = *i0; data.d = *i0;
# if __WORDSIZE == 64 # if __WORDSIZE == 64 || NEW_ABI
if (data.l) if (data.l)
ldi_d(r0, (jit_word_t)i0); ldi_d(r0, (jit_word_t)i0);
else else

View file

@ -22,7 +22,24 @@
#define rc(value) jit_class_##value #define rc(value) jit_class_##value
#define rn(reg) (jit_regno(_rvs[jit_regno(reg)].spec)) #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 * Prototypes
@ -42,10 +59,12 @@ jit_register_t _rvs[] = {
{ rc(gpr) | 0x01, "at" }, { rc(gpr) | 0x01, "at" },
{ rc(gpr) | 0x02, "v0" }, { rc(gpr) | 0x02, "v0" },
{ rc(gpr) | 0x03, "v1" }, { rc(gpr) | 0x03, "v1" },
#if !NEW_ABI
{ rc(gpr) | 0x08, "t0" }, { rc(gpr) | 0x08, "t0" },
{ rc(gpr) | 0x09, "t1" }, { rc(gpr) | 0x09, "t1" },
{ rc(gpr) | 0x0a, "t2" }, { rc(gpr) | 0x0a, "t2" },
{ rc(gpr) | 0x0b, "t3" }, { rc(gpr) | 0x0b, "t3" },
#endif
{ rc(gpr) | 0x0c, "t4" }, { rc(gpr) | 0x0c, "t4" },
{ rc(gpr) | 0x0d, "t5" }, { rc(gpr) | 0x0d, "t5" },
{ rc(gpr) | 0x0e, "t6" }, { rc(gpr) | 0x0e, "t6" },
@ -67,6 +86,12 @@ jit_register_t _rvs[] = {
{ rc(sav) | 0x1c, "gp" }, { rc(sav) | 0x1c, "gp" },
{ rc(sav) | 0x1d, "sp" }, { rc(sav) | 0x1d, "sp" },
{ rc(sav) | 0x1e, "fp" }, { 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) | 0x07, "a3" },
{ rc(arg) | rc(gpr) | 0x06, "a2" }, { rc(arg) | rc(gpr) | 0x06, "a2" },
{ rc(arg) | rc(gpr) | 0x05, "a1" }, { rc(arg) | rc(gpr) | 0x05, "a1" },
@ -77,16 +102,29 @@ jit_register_t _rvs[] = {
{ rc(fpr) | 0x06, "$f6" }, { rc(fpr) | 0x06, "$f6" },
{ rc(fpr) | 0x08, "$f8" }, { rc(fpr) | 0x08, "$f8" },
{ rc(fpr) | 0x0a, "$f10" }, { rc(fpr) | 0x0a, "$f10" },
#if !NEW_ABI
{ rc(sav) | rc(fpr) | 0x10, "$f16" }, { rc(sav) | rc(fpr) | 0x10, "$f16" },
{ rc(sav) | rc(fpr) | 0x12, "$f18" }, { rc(sav) | rc(fpr) | 0x12, "$f18" },
#endif
{ rc(sav) | rc(fpr) | 0x14, "$f20" }, { rc(sav) | rc(fpr) | 0x14, "$f20" },
{ rc(sav) | rc(fpr) | 0x16, "$f22" }, { rc(sav) | rc(fpr) | 0x16, "$f22" },
{ rc(sav) | rc(fpr) | 0x18, "$f24" }, { rc(sav) | rc(fpr) | 0x18, "$f24" },
{ rc(sav) | rc(fpr) | 0x1a, "$f26" }, { rc(sav) | rc(fpr) | 0x1a, "$f26" },
{ rc(sav) | rc(fpr) | 0x1c, "$f28" }, { rc(sav) | rc(fpr) | 0x1c, "$f28" },
{ rc(sav) | rc(fpr) | 0x1e, "$f30" }, { 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) | 0x0e, "$f14" },
{ rc(arg) | rc(fpr) | 0x0c, "$f12" }, { rc(arg) | rc(fpr) | 0x0c, "$f12" },
#endif
{ _NOREG, "<none>" }, { _NOREG, "<none>" },
}; };
@ -239,28 +277,43 @@ jit_node_t *
_jit_arg(jit_state_t *_jit) _jit_arg(jit_state_t *_jit)
{ {
jit_int32_t offset; jit_int32_t offset;
assert(_jitc->function); 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; offset = (_jitc->function->self.size - stack_framesize) >> 2;
_jitc->function->self.argi = 1; _jitc->function->self.argi = 1;
if (offset >= 4) if (offset >= 4)
offset = _jitc->function->self.size; 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)); return (jit_new_node_w(jit_code_arg, offset));
} }
jit_bool_t jit_bool_t
_jit_arg_reg_p(jit_state_t *_jit, jit_int32_t offset) _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_node_t *
_jit_arg_f(jit_state_t *_jit) _jit_arg_f(jit_state_t *_jit)
{ {
jit_int32_t offset; jit_int32_t offset;
assert(_jitc->function); 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; offset = (_jitc->function->self.size - stack_framesize) >> 2;
if (offset < 4) { if (offset < 4) {
if (!_jitc->function->self.argi) { if (!_jitc->function->self.argi) {
@ -274,8 +327,8 @@ _jit_arg_f(jit_state_t *_jit)
} }
else else
offset = _jitc->function->self.size; 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)); 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_arg_d(jit_state_t *_jit)
{ {
jit_int32_t offset; jit_int32_t offset;
assert(_jitc->function); 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) { if (_jitc->function->self.size & 7) {
_jitc->function->self.size += 4; _jitc->function->self.size += 4;
_jitc->function->self.argi = 1; _jitc->function->self.argi = 1;
@ -303,7 +363,8 @@ _jit_arg_d(jit_state_t *_jit)
} }
else else
offset = _jitc->function->self.size; 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)); 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 void
_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _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); jit_extr_c(u, _A0 - v->u.w);
else else {
#if __BYTE_ORDER == __LITTLE__ENDIAN
jit_ldxi_c(u, _FP, v->u.w); 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 void
_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _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); jit_extr_uc(u, _A0 - v->u.w);
else else {
#if __BYTE_ORDER == __LITTLE__ENDIAN
jit_ldxi_uc(u, _FP, v->u.w); 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 void
_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _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); jit_extr_s(u, _A0 - v->u.w);
else else {
#if __BYTE_ORDER == __LITTLE__ENDIAN
jit_ldxi_s(u, _FP, v->u.w); 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 void
_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _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); jit_extr_us(u, _A0 - v->u.w);
else else {
#if __BYTE_ORDER == __LITTLE__ENDIAN
jit_ldxi_us(u, _FP, v->u.w); 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 void
_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _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 #if __WORDSIZE == 64
jit_extr_i(u, _A0 - v->u.w); jit_extr_i(u, _A0 - v->u.w);
#else #else
jit_movr(u, _A0 - v->u.w); jit_movr(u, _A0 - v->u.w);
#endif #endif
} }
else else {
#if __BYTE_ORDER == __LITTLE__ENDIAN
jit_ldxi_i(u, _FP, v->u.w); 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 #if __WORDSIZE == 64
void void
_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _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); jit_extr_ui(u, _A0 - v->u.w);
else else {
# if __BYTE_ORDER == __LITTLE__ENDIAN
jit_ldxi_ui(u, _FP, v->u.w); 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 void
_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _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); jit_movr(u, _A0 - v->u.w);
else else
jit_ldxi_l(u, _FP, v->u.w); 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 void
_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _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) if (v->u.w < 4)
jit_movr_w_f(u, _A0 - v->u.w); jit_movr_w_f(u, _A0 - v->u.w);
else if (v->u.w < 8) else if (v->u.w < 8)
jit_movr_f(u, _F12 - ((v->u.w - 4) >> 1)); jit_movr_f(u, _F12 - ((v->u.w - 4) >> 1));
#endif
else else
jit_ldxi_f(u, _FP, v->u.w); 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 void
_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _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) if (v->u.w < 4)
jit_movr_ww_d(u, _A0 - v->u.w, _A0 - (v->u.w + 1)); jit_movr_ww_d(u, _A0 - v->u.w, _A0 - (v->u.w + 1));
else if (v->u.w < 8) else if (v->u.w < 8)
jit_movr_d(u, _F12 - ((v->u.w - 4) >> 1)); jit_movr_d(u, _F12 - ((v->u.w - 4) >> 1));
#endif
else else
jit_ldxi_d(u, _FP, v->u.w); 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 void
_jit_pushargr(jit_state_t *_jit, jit_int32_t u) _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
{ {
jit_word_t offset; #if NEW_ABI
assert(_jitc->function); 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; _jitc->function->call.argi = 1;
if (offset < 4) if (offset < NUM_WORD_ARGS)
jit_movr(_A0 - offset, u); jit_movr(_A0 - offset, u);
else else
jit_stxi(_jitc->function->call.size, JIT_SP, u); 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 void
_jit_pushargi(jit_state_t *_jit, jit_word_t u) _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_int32_t regno;
jit_word_t offset; jit_word_t offset;
assert(_jitc->function); assert(_jitc->function);
offset = _jitc->function->call.size >> 2; offset = _jitc->function->call.size >> STACK_SHIFT;
++_jitc->function->call.argi; ++_jitc->function->call.argi;
if (offset < 4) if (offset < NUM_WORD_ARGS)
jit_movi(_A0 - offset, u); jit_movi(_A0 - offset, u);
else { else {
regno = jit_get_reg(jit_class_gpr); 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_stxi(_jitc->function->call.size, JIT_SP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
_jitc->function->call.size += sizeof(jit_word_t); _jitc->function->call.size += STACK_SLOT;
#endif
} }
void void
_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
{ {
jit_word_t offset; #if NEW_ABI
assert(_jitc->function); 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) { if (offset < 2 && !_jitc->function->call.argi) {
++_jitc->function->call.argf; ++_jitc->function->call.argf;
jit_movr_f(_F12 - offset, u); jit_movr_f(_F12 - offset, u);
@ -457,17 +597,34 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
} }
else else
jit_stxi_f(_jitc->function->call.size, JIT_SP, u); 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 void
_jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
jit_word_t offset; #if NEW_ABI
assert(_jitc->function); 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) { if (offset < 2 && !_jitc->function->call.argi) {
++_jitc->function->call.argf; ++_jitc->function->call.argf;
jit_movi_f(_F12 - offset, u); 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_stxi_f(_jitc->function->call.size, JIT_SP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
_jitc->function->call.size += sizeof(jit_float32_t); _jitc->function->call.size += STACK_SLOT;
#endif
} }
void void
_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) _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_bool_t adjust;
jit_word_t offset; jit_word_t offset;
assert(_jitc->function); assert(_jitc->function);
adjust = !!_jitc->function->call.argi; adjust = !!_jitc->function->call.argi;
if (_jitc->function->call.size & 7) { if (_jitc->function->call.size & 7) {
@ -510,23 +681,40 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
} }
else else
jit_stxi_d(_jitc->function->call.size, JIT_SP, u); 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 void
_jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
{ {
jit_int32_t regno; 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_bool_t adjust;
jit_word_t offset; jit_word_t offset;
assert(_jitc->function); assert(_jitc->function);
adjust = !!_jitc->function->call.argi; adjust = !!_jitc->function->call.argi;
if (_jitc->function->call.size & 7) { if (_jitc->function->call.size & 7) {
_jitc->function->call.size += 4; _jitc->function->call.size += 4;
adjust = 1; adjust = 1;
} }
offset = _jitc->function->call.size >> 2; offset = _jitc->function->call.size >> STACK_SHIFT;
if (offset < 3) { if (offset < 3) {
if (adjust) { if (adjust) {
jit_movi_d_ww(_A0 - offset, _A0 - (offset + 1), u); 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_stxi_d(_jitc->function->call.size, JIT_SP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
_jitc->function->call.size += sizeof(jit_float64_t); _jitc->function->call.size += STACK_SLOT;
#endif
} }
jit_bool_t jit_bool_t
@ -579,7 +768,11 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
jit_movr(_T9, r0); jit_movr(_T9, r0);
call = jit_callr(_T9); call = jit_callr(_T9);
call->v.w = _jitc->function->self.argi; call->v.w = _jitc->function->self.argi;
#if NEW_ABI
call->w.w = call->v.w;
#else
call->w.w = _jitc->function->self.argf; call->w.w = _jitc->function->self.argf;
#endif
_jitc->function->call.argi = _jitc->function->call.argf = _jitc->function->call.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0; _jitc->function->call.size = 0;
_jitc->prepare = 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); node = jit_movi(_T9, (jit_word_t)i0);
call = jit_callr(_T9); call = jit_callr(_T9);
call->v.w = _jitc->function->call.argi; call->v.w = _jitc->function->call.argi;
#if NEW_ABI
call->w.w = call->v.w;
#else
call->w.w = _jitc->function->call.argf; call->w.w = _jitc->function->call.argf;
#endif
_jitc->function->call.argi = _jitc->function->call.argf = _jitc->function->call.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0; _jitc->function->call.size = 0;
_jitc->prepare = 0; _jitc->prepare = 0;
@ -892,6 +1089,10 @@ _emit_code(jit_state_t *_jit)
case_rr(ext, _uc); case_rr(ext, _uc);
case_rr(ext, _s); case_rr(ext, _s);
case_rr(ext, _us); case_rr(ext, _us);
#if __WORDSIZE == 64
case_rr(ext, _i);
case_rr(ext, _ui);
#endif
case_rr(mov,); case_rr(mov,);
case jit_code_movi: case jit_code_movi:
if (node->flag & jit_flag_node) { if (node->flag & jit_flag_node) {
@ -1195,9 +1396,11 @@ _emit_code(jit_state_t *_jit)
epilog(node); epilog(node);
_jitc->function = NULL; _jitc->function = NULL;
break; break;
#if !NEW_ABI
case jit_code_movr_w_f: case jit_code_movr_w_f:
movr_w_f(rn(node->u.w), rn(node->v.w)); movr_w_f(rn(node->u.w), rn(node->v.w));
break; break;
#endif
case jit_code_movr_f_w: case jit_code_movr_f_w:
movr_f_w(rn(node->u.w), rn(node->v.w)); movr_f_w(rn(node->u.w), rn(node->v.w));
break; break;
@ -1205,6 +1408,15 @@ _emit_code(jit_state_t *_jit)
assert(node->flag & jit_flag_data); assert(node->flag & jit_flag_data);
movi_f_w(rn(node->u.w), (jit_float32_t *)node->v.n->u.w); movi_f_w(rn(node->u.w), (jit_float32_t *)node->v.n->u.w);
break; 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: case jit_code_movr_ww_d:
movr_ww_d(rn(node->u.w), rn(node->v.w), rn(node->w.w)); movr_ww_d(rn(node->u.w), rn(node->v.w), rn(node->w.w));
break; break;
@ -1216,6 +1428,7 @@ _emit_code(jit_state_t *_jit)
movi_d_ww(rn(node->u.w), rn(node->v.w), movi_d_ww(rn(node->u.w), rn(node->v.w),
(jit_float64_t *)node->w.n->u.w); (jit_float64_t *)node->w.n->u.w);
break; break;
#endif
case jit_code_live: case jit_code_live:
case jit_code_arg: case jit_code_arg:
case jit_code_arg_f: case jit_code_arg_d: case jit_code_arg_f: case jit_code_arg_d:
@ -1273,21 +1486,13 @@ _emit_code(jit_state_t *_jit)
void void
_emit_ldxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) _emit_ldxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{ {
#if __WORDSIZE == 32 ldxi(rn(r0), rn(r1), i0);
ldxi_i(rn(r0), rn(r1), i0);
#else
ldxi_l(rn(r0), rn(r1), i0);
#endif
} }
void void
_emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) _emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{ {
#if __WORDSIZE == 32 stxi(i0, rn(r0), rn(r1));
stxi_i(i0, rn(r0), rn(r1));
#else
stxi_l(i0, rn(r0), rn(r1));
#endif
} }
void void

View file

@ -18,9 +18,15 @@
#include <lightning.h> #include <lightning.h>
#include <lightning/jit_private.h> #include <lightning/jit_private.h>
#include <sys/mman.h> #include <sys/mman.h>
#if defined(__sgi)
# include <fcntl.h>
#endif
#ifndef MAP_ANON #ifndef MAP_ANON
# define MAP_ANON MAP_ANONYMOUS # define MAP_ANON MAP_ANONYMOUS
# ifndef MAP_ANONYMOUS
# define MAP_ANONYMOUS 0
# endif
#endif #endif
#define jit_regload_reload 0 /* convert to reload */ #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 * Initialization
*/ */
const char *jit_progname; const char *jit_progname;
#if !defined(__sgi)
#define mmap_fd -1
#endif
/* /*
* Implementation * Implementation
@ -1375,6 +1384,9 @@ _jit_optimize(jit_state_t *_jit)
jit_node_t *node; jit_node_t *node;
jit_block_t *block; jit_block_t *block;
jit_word_t offset; jit_word_t offset;
#if defined(__sgi)
int mmap_fd;
#endif
_jitc->function = NULL; _jitc->function = NULL;
@ -1491,10 +1503,16 @@ _jit_optimize(jit_state_t *_jit)
_jit->data.length = (_jitc->data.offset + _jit->data.length = (_jitc->data.offset +
/* reserve space for annotations */ /* reserve space for annotations */
_jitc->note.size + 4095) & -4096; _jitc->note.size + 4095) & -4096;
#if defined(__sgi)
mmap_fd = open("/dev/zero", O_RDWR);
#endif
ptr = mmap(NULL, _jit->data.length, ptr = mmap(NULL, _jit->data.length,
PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON, -1, 0); MAP_PRIVATE | MAP_ANON, mmap_fd, 0);
assert(ptr != MAP_FAILED); assert(ptr != MAP_FAILED);
#if defined(__sgi)
close(mmap_fd);
#endif
memcpy(ptr, _jit->data.ptr, _jitc->data.offset); memcpy(ptr, _jit->data.ptr, _jitc->data.offset);
jit_free((jit_pointer_t *)&_jit->data.ptr); jit_free((jit_pointer_t *)&_jit->data.ptr);
_jit->data.ptr = ptr; _jit->data.ptr = ptr;
@ -1648,6 +1666,9 @@ _jit_emit(jit_state_t *_jit)
jit_node_t *node; jit_node_t *node;
size_t length; size_t length;
int result; int result;
#if defined(__sgi)
int mmap_fd;
#endif
if (_jitc->function) if (_jitc->function)
jit_epilog(); jit_epilog();
@ -1660,9 +1681,12 @@ _jit_emit(jit_state_t *_jit)
_jit->code.length = _jitc->pool.length * 1024 * _jitc->mult; _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, _jit->code.ptr = mmap(NULL, _jit->code.length,
PROT_EXEC | PROT_READ | PROT_WRITE, 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); assert(_jit->code.ptr != MAP_FAILED);
_jitc->code.end = _jit->code.ptr + _jit->code.length - 64; _jitc->code.end = _jit->code.ptr + _jit->code.length - 64;
_jit->pc.uc = _jit->code.ptr; _jit->pc.uc = _jit->code.ptr;
@ -1688,7 +1712,7 @@ _jit_emit(jit_state_t *_jit)
#else #else
_jit->code.ptr = mmap(NULL, length, _jit->code.ptr = mmap(NULL, length,
PROT_EXEC | PROT_READ | PROT_WRITE, PROT_EXEC | PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON, -1, 0); MAP_PRIVATE | MAP_ANON, mmap_fd, 0);
#endif #endif
assert(_jit->code.ptr != MAP_FAILED); assert(_jit->code.ptr != MAP_FAILED);
@ -1701,6 +1725,10 @@ _jit_emit(jit_state_t *_jit)
break; break;
} }
#if defined(__sgi)
close(mmap_fd);
#endif
_jitc->done = 1; _jitc->done = 1;
jit_annotate(); jit_annotate();