1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-25 20:50:31 +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>
* include/lightning.h: Minor extra preprocessor testing

View file

@ -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);

View file

@ -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],,,)

View file

@ -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

View file

@ -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;

View file

@ -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 */

View file

@ -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

View file

@ -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, "<none>" },
};
@ -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

View file

@ -18,9 +18,15 @@
#include <lightning.h>
#include <lightning/jit_private.h>
#include <sys/mman.h>
#if defined(__sgi)
# include <fcntl.h>
#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();