1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 03:40:34 +02:00

Build and pass all tests on 32 and 64 bit sparc

* include/lightning/jit_private.h: Add new register classes to
	flag float registers and double only registers, required for sparc64
	where only low 32 bit fpr registers can be used for single precision
	operations.
	Add new 128 bit jit_regset_t type for sparc64 register set.

	* include/lightning/jit_sparc.h, lib/jit_sparc-cpu.c, lib/jit_sparc-fpu.c,
	lib/jit_sparc-sz.c, lib/jit_sparc.c: Update for 64 bits sparc.

	* lib/lightning.c: Update for new jit_regset_t required for sparc64.
This commit is contained in:
Paulo Andrade 2018-04-20 10:37:37 -03:00
parent ed5589ce59
commit 2cea99361b
8 changed files with 2754 additions and 246 deletions

View file

@ -1,3 +1,16 @@
2018-04-20 Paulo Andrade <pcpa@gnu.org>
* include/lightning/jit_private.h: Add new register classes to
flag float registers and double only registers, required for sparc64
where only low 32 bit fpr registers can be used for single precision
operations.
Add new 128 bit jit_regset_t type for sparc64 register set.
* include/lightning/jit_sparc.h, lib/jit_sparc-cpu.c, lib/jit_sparc-fpu.c,
lib/jit_sparc-sz.c, lib/jit_sparc.c: Update for 64 bits sparc.
* lib/lightning.c: Update for new jit_regset_t required for sparc64.
2018-02-26 Paulo Andrade <pcpa@gnu.org>
* check/lightning.c, include/lightning.h: Add the new jit_va_push

View file

@ -95,7 +95,14 @@ typedef jit_uint64_t jit_regset_t;
# define JIT_SP _SP
# define JIT_RET _I0
# define JIT_FRET _F0
# if __WORDSIZE == 32
typedef jit_uint64_t jit_regset_t;
# else
typedef struct {
jit_uint64_t rl;
jit_uint64_t rh;
} jit_regset_t;
# endif
#elif defined(__ia64__)
# define JIT_SP _R12
# define JIT_RET _R8
@ -217,6 +224,10 @@ extern jit_node_t *_jit_data(jit_state_t*, const void*,
#define jit_class_sft 0x01000000 /* not a hardware register */
#define jit_class_rg8 0x04000000 /* x86 8 bits */
#define jit_class_xpr 0x80000000 /* float / vector */
/* Used on sparc64 where %f0-%f31 can be encode for single float
* but %f32 to %f62 only as double precision */
#define jit_class_sng 0x10000000 /* Single precision float */
#define jit_class_dbl 0x20000000 /* Only double precision float */
#define jit_regno_patch 0x00008000 /* this is a register
* returned by a "user" call
* to jit_get_reg() */
@ -250,7 +261,7 @@ extern jit_node_t *_jit_data(jit_state_t*, const void*,
#define jit_cc_a2_flt 0x00200000 /* arg2 is immediate float */
#define jit_cc_a2_dbl 0x00400000 /* arg2 is immediate double */
#if __ia64__
#if __ia64__ || (__sparc__ && __WORDSIZE == 64)
extern void
jit_regset_com(jit_regset_t*, jit_regset_t*);
@ -286,10 +297,17 @@ jit_regset_setbit(jit_regset_t*, jit_int32_t);
extern jit_bool_t
jit_regset_tstbit(jit_regset_t*, jit_int32_t);
# define jit_regset_new(set) \
# if __sparc__ && __WORDSIZE == 64
# define jit_regset_new(set) \
do { (set)->rl = (set)->rh = 0; } while (0)
# define jit_regset_del(set) \
do { (set)->rl = (set)->rh = 0; } while (0)
# else
# define jit_regset_new(set) \
do { (set)->rl = (set)->rh = (set)->fl = (set)->fh = 0; } while (0)
# define jit_regset_del(set) \
# define jit_regset_del(set) \
do { (set)->rl = (set)->rh = (set)->fl = (set)->fh = 0; } while (0)
# endif
#else
# define jit_regset_com(u, v) (*(u) = ~*(v))
# define jit_regset_and(u, v, w) (*(u) = *(v) & *(w))
@ -457,7 +475,7 @@ struct jit_compiler {
jit_int32_t rout; /* first output register */
jit_int32_t breg; /* base register for prolog/epilog */
#endif
#if __mips__ || __ia64__ || __alpha__
#if __mips__ || __ia64__ || __alpha__ || (__sparc__ && __WORDSIZE == 64)
jit_int32_t carry;
#define jit_carry _jitc->carry
#endif

View file

@ -32,8 +32,13 @@ typedef enum {
#define jit_r_num() 3
#define jit_v(i) (_L0 + (i))
#define jit_v_num() 8
#define jit_f(i) (_F0 + ((i) << 1))
#define jit_f_num() 8
#if __WORDSIZE == 32
# define jit_f(i) (_F0 + ((i) << 1))
# define jit_f_num() 8
#else
# define jit_f(i) (_F32 - (i))
# define jit_f_num() 16
#endif
#define JIT_R0 _G2
#define JIT_R1 _G3
#define JIT_R2 _G4
@ -49,16 +54,47 @@ typedef enum {
_O0, _O1, _O2, _O3, _O4, _O5, _SP, _O7,
_L0, _L1, _L2, _L3, _L4, _L5, _L6, _L7,
_I0, _I1, _I2, _I3, _I4, _I5, _FP, _I7,
#define JIT_F0 _F0
#define JIT_F1 _F2
#define JIT_F2 _F4
#define JIT_F3 _F6
#define JIT_F4 _F8
#define JIT_F5 _F10
#define JIT_F6 _F12
#define JIT_F7 _F14
#if __WORDSIZE == 32
# define JIT_F0 _F0
# define JIT_F1 _F2
# define JIT_F2 _F4
# define JIT_F3 _F6
# define JIT_F4 _F8
# define JIT_F5 _F10
# define JIT_F6 _F12
# define JIT_F7 _F14
_F0, _F1, _F2, _F3, _F4, _F5, _F6, _F7,
_F8, _F9, _F10, _F11, _F12, _F13, _F14, _F15,
#else
/* All single precision operations have a high cost due to being
* stored on registers only encodable as double precision.
* The cost is due to needing to move values to a register with
* value <= 31.
* This is a limitation due to using fixed named registers in
* lightning. */
# define JIT_F0 _F32
# define JIT_F1 _F34
# define JIT_F2 _F36
# define JIT_F3 _F38
# define JIT_F4 _F40
# define JIT_F5 _F42
# define JIT_F6 _F44
# define JIT_F7 _F46
# define JIT_F8 _F48
# define JIT_F9 _F50
# define JIT_F10 _F52
# define JIT_F11 _F54
# define JIT_F12 _F56
# define JIT_F13 _F58
# define JIT_F14 _F60
# define JIT_F15 _F62
_F62, _F60, _F58, _F56, _F54, _F52, _F50, _F48,
_F46, _F44, _F42, _F40, _F38, _F36, _F34, _F32,
_F31, _F30, _F29, _F28, _F27, _F26, _F25, _F24,
_F23, _F22, _F21, _F20, _F19, _F18, _F17, _F16,
_F15, _F14, _F13, _F12, _F11, _F10, _F9, _F8,
_F7, _F6, _F5, _F4, _F3, _F2, _F1, _F0,
#endif
#define JIT_NOREG _NOREG
_NOREG,
} jit_reg_t;

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,4 @@
#if __WORDSIZE == 32
#if WORDSIZE == 32
#define JIT_INSTR_MAX 40
0, /* data */
0, /* live */
@ -400,3 +399,405 @@
0, /* movr_d_w */
0, /* movi_d_w */
#endif /* __WORDSIZE */
#if __WORDSIZE == 64
#define JIT_INSTR_MAX 64
0, /* data */
0, /* live */
4, /* align */
0, /* save */
0, /* load */
0, /* #name */
0, /* #note */
4, /* label */
36, /* prolog */
0, /* ellipsis */
0, /* va_push */
0, /* allocai */
0, /* allocar */
0, /* arg */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
0, /* getarg_us */
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr */
0, /* putargi */
4, /* va_start */
8, /* va_arg */
8, /* va_arg_d */
0, /* va_end */
4, /* addr */
28, /* addi */
24, /* addcr */
48, /* addci */
52, /* addxr */
52, /* addxi */
4, /* subr */
28, /* subi */
24, /* subcr */
48, /* subci */
52, /* subxr */
52, /* subxi */
32, /* rsbi */
4, /* mulr */
28, /* muli */
48, /* qmulr */
64, /* qmuli */
48, /* qmulr_u */
64, /* qmuli_u */
4, /* divr */
28, /* divi */
4, /* divr_u */
28, /* divi_u */
20, /* qdivr */
16, /* qdivi */
20, /* qdivr_u */
16, /* qdivi_u */
12, /* remr */
36, /* remi */
12, /* remr_u */
36, /* remi_u */
4, /* andr */
28, /* andi */
4, /* orr */
28, /* ori */
4, /* xorr */
28, /* xori */
4, /* lshr */
4, /* lshi */
4, /* rshr */
4, /* rshi */
4, /* rshr_u */
4, /* rshi_u */
4, /* negr */
4, /* comr */
16, /* ltr */
16, /* lti */
16, /* ltr_u */
16, /* lti_u */
16, /* ler */
16, /* lei */
16, /* ler_u */
16, /* lei_u */
16, /* eqr */
16, /* eqi */
16, /* ger */
16, /* gei */
16, /* ger_u */
16, /* gei_u */
16, /* gtr */
16, /* gti */
16, /* gtr_u */
16, /* gti_u */
16, /* ner */
16, /* nei */
4, /* movr */
24, /* movi */
8, /* extr_c */
4, /* extr_uc */
8, /* extr_s */
8, /* extr_us */
8, /* extr_i */
8, /* extr_ui */
8, /* htonr_us */
8, /* htonr_ui */
4, /* htonr_ul */
4, /* ldr_c */
28, /* ldi_c */
4, /* ldr_uc */
28, /* ldi_uc */
4, /* ldr_s */
28, /* ldi_s */
4, /* ldr_us */
28, /* ldi_us */
4, /* ldr_i */
28, /* ldi_i */
4, /* ldr_ui */
28, /* ldi_ui */
4, /* ldr_l */
28, /* ldi_l */
4, /* ldxr_c */
24, /* ldxi_c */
4, /* ldxr_uc */
24, /* ldxi_uc */
4, /* ldxr_s */
24, /* ldxi_s */
4, /* ldxr_us */
24, /* ldxi_us */
4, /* ldxr_i */
24, /* ldxi_i */
4, /* ldxr_ui */
24, /* ldxi_ui */
4, /* ldxr_l */
24, /* ldxi_l */
4, /* str_c */
28, /* sti_c */
4, /* str_s */
28, /* sti_s */
4, /* str_i */
28, /* sti_i */
4, /* str_l */
28, /* sti_l */
4, /* stxr_c */
24, /* stxi_c */
4, /* stxr_s */
24, /* stxi_s */
4, /* stxr_i */
24, /* stxi_i */
4, /* stxr_l */
24, /* stxi_l */
12, /* bltr */
12, /* blti */
12, /* bltr_u */
12, /* blti_u */
12, /* bler */
12, /* blei */
12, /* bler_u */
12, /* blei_u */
12, /* beqr */
36, /* beqi */
12, /* bger */
12, /* bgei */
12, /* bger_u */
12, /* bgei_u */
12, /* bgtr */
12, /* bgti */
12, /* bgtr_u */
12, /* bgti_u */
12, /* bner */
36, /* bnei */
12, /* bmsr */
12, /* bmsi */
12, /* bmcr */
12, /* bmci */
12, /* boaddr */
12, /* boaddi */
12, /* boaddr_u */
12, /* boaddi_u */
12, /* bxaddr */
12, /* bxaddi */
12, /* bxaddr_u */
12, /* bxaddi_u */
12, /* bosubr */
12, /* bosubi */
12, /* bosubr_u */
12, /* bosubi_u */
12, /* bxsubr */
12, /* bxsubi */
12, /* bxsubr_u */
12, /* bxsubi_u */
8, /* jmpr */
32, /* jmpi */
8, /* callr */
32, /* calli */
0, /* prepare */
0, /* pushargr */
0, /* pushargi */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr */
0, /* reti */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
0, /* retval_us */
0, /* retval_i */
0, /* retval_ui */
0, /* retval_l */
44, /* epilog */
0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
16, /* addr_f */
40, /* addi_f */
24, /* subr_f */
40, /* subi_f */
40, /* rsbi_f */
16, /* mulr_f */
40, /* muli_f */
16, /* divr_f */
40, /* divi_f */
12, /* negr_f */
12, /* absr_f */
12, /* sqrtr_f */
24, /* ltr_f */
48, /* lti_f */
24, /* ler_f */
48, /* lei_f */
24, /* eqr_f */
48, /* eqi_f */
24, /* ger_f */
48, /* gei_f */
24, /* gtr_f */
48, /* gti_f */
24, /* ner_f */
48, /* nei_f */
24, /* unltr_f */
48, /* unlti_f */
24, /* unler_f */
48, /* unlei_f */
24, /* uneqr_f */
48, /* uneqi_f */
24, /* unger_f */
48, /* ungei_f */
24, /* ungtr_f */
48, /* ungti_f */
24, /* ltgtr_f */
48, /* ltgti_f */
24, /* ordr_f */
48, /* ordi_f */
24, /* unordr_f */
48, /* unordi_f */
16, /* truncr_f_i */
16, /* truncr_f_l */
20, /* extr_f */
12, /* extr_d_f */
16, /* movr_f */
32, /* movi_f */
8, /* ldr_f */
32, /* ldi_f */
8, /* ldxr_f */
28, /* ldxi_f */
8, /* str_f */
32, /* sti_f */
8, /* stxr_f */
28, /* stxi_f */
20, /* bltr_f */
44, /* blti_f */
20, /* bler_f */
44, /* blei_f */
28, /* beqr_f */
60, /* beqi_f */
20, /* bger_f */
44, /* bgei_f */
20, /* bgtr_f */
44, /* bgti_f */
20, /* bner_f */
44, /* bnei_f */
20, /* bunltr_f */
44, /* bunlti_f */
20, /* bunler_f */
44, /* bunlei_f */
20, /* buneqr_f */
44, /* buneqi_f */
20, /* bunger_f */
44, /* bungei_f */
20, /* bungtr_f */
44, /* bungti_f */
20, /* bltgtr_f */
44, /* bltgti_f */
20, /* bordr_f */
44, /* bordi_f */
20, /* bunordr_f */
44, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
4, /* addr_d */
32, /* addi_d */
4, /* subr_d */
32, /* subi_d */
32, /* rsbi_d */
4, /* mulr_d */
32, /* muli_d */
4, /* divr_d */
32, /* divi_d */
4, /* negr_d */
4, /* absr_d */
4, /* sqrtr_d */
16, /* ltr_d */
48, /* lti_d */
16, /* ler_d */
48, /* lei_d */
16, /* eqr_d */
48, /* eqi_d */
16, /* ger_d */
48, /* gei_d */
16, /* gtr_d */
48, /* gti_d */
16, /* ner_d */
48, /* nei_d */
16, /* unltr_d */
48, /* unlti_d */
16, /* unler_d */
48, /* unlei_d */
16, /* uneqr_d */
48, /* uneqi_d */
16, /* unger_d */
48, /* ungei_d */
16, /* ungtr_d */
48, /* ungti_d */
16, /* ltgtr_d */
48, /* ltgti_d */
16, /* ordr_d */
48, /* ordi_d */
16, /* unordr_d */
48, /* unordi_d */
16, /* truncr_d_i */
12, /* truncr_d_l */
12, /* extr_d */
8, /* extr_f_d */
4, /* movr_d */
32, /* movi_d */
4, /* ldr_d */
28, /* ldi_d */
4, /* ldxr_d */
24, /* ldxi_d */
4, /* str_d */
28, /* sti_d */
4, /* stxr_d */
24, /* stxi_d */
12, /* bltr_d */
40, /* blti_d */
12, /* bler_d */
40, /* blei_d */
12, /* beqr_d */
40, /* beqi_d */
12, /* bger_d */
40, /* bgei_d */
12, /* bgtr_d */
40, /* bgti_d */
12, /* bner_d */
44, /* bnei_d */
12, /* bunltr_d */
44, /* bunlti_d */
12, /* bunler_d */
44, /* bunlei_d */
12, /* buneqr_d */
44, /* buneqi_d */
12, /* bunger_d */
44, /* bungei_d */
12, /* bungtr_d */
44, /* bungti_d */
12, /* bltgtr_d */
40, /* bltgti_d */
12, /* bordr_d */
40, /* bordi_d */
12, /* bunordr_d */
44, /* bunordi_d */
0, /* pushargr_d */
0, /* pushargi_d */
0, /* retr_d */
0, /* reti_d */
0, /* retval_d */
0, /* movr_w_f */
0, /* movr_ww_d */
0, /* movr_w_d */
0, /* movr_f_w */
0, /* movi_f_w */
0, /* movr_d_ww */
0, /* movi_d_ww */
0, /* movr_d_w */
0, /* movi_d_w */
#endif /* __WORDSIZE */

View file

@ -18,7 +18,13 @@
*/
#define jit_arg_reg_p(i) ((i) >= 0 && (i) < 6)
#define jit_arg_d_reg_p(i) ((i) >= 0 && (i) < 5)
#if __WORDSIZE == 32
# define jit_arg_d_reg_p(i) ((i) >= 0 && (i) < 5)
# define BIAS(n) (n)
#else
# define jit_arg_d_reg_p(i) ((i) >= 0 && (i) < 16)
# define BIAS(n) ((n) + 2047)
#endif
/*
* Types
@ -72,6 +78,7 @@ jit_register_t _rvs[] = {
{ 0x1d, "%i5" },
{ rc(sav) | 0x1e, "%fp" },
{ 0x1f, "%i7" },
# if __WORDSIZE == 32
{ rc(fpr) | 0x00, "%f0" },
{ 0x01, "%f1" },
{ rc(fpr) | 0x02, "%f2" },
@ -79,7 +86,7 @@ jit_register_t _rvs[] = {
{ rc(fpr) | 0x04, "%f4" },
{ 0x05, "%f5" },
{ rc(fpr) | 0x06, "%f6" },
{ 0x06, "%f7" },
{ 0x07, "%f7" },
{ rc(fpr) | 0x08, "%f8" },
{ 0x09, "%f9" },
{ rc(fpr) | 0x0a, "%f10" },
@ -88,6 +95,56 @@ jit_register_t _rvs[] = {
{ 0x0d, "%f13" },
{ rc(fpr) | 0x0e, "%f14" },
{ 0x0f, "%f15" },
# else
{ rc(fpr) | rc(dbl) | 0x3e, "%f62" },
{ rc(fpr) | rc(dbl) | 0x3c, "%f60" },
{ rc(fpr) | rc(dbl) | 0x3a, "%f58" },
{ rc(fpr) | rc(dbl) | 0x38, "%f56" },
{ rc(fpr) | rc(dbl) | 0x36, "%f54" },
{ rc(fpr) | rc(dbl) | 0x34, "%f52" },
{ rc(fpr) | rc(dbl) | 0x32, "%f50" },
{ rc(fpr) | rc(dbl) | 0x30, "%f48" },
{ rc(fpr) | rc(dbl) | 0x2e, "%f46" },
{ rc(fpr) | rc(dbl) | 0x2c, "%f44" },
{ rc(fpr) | rc(dbl) | 0x2a, "%f42" },
{ rc(fpr) | rc(dbl) | 0x28, "%f40" },
{ rc(fpr) | rc(dbl) | 0x26, "%f38" },
{ rc(fpr) | rc(dbl) | 0x24, "%f36" },
{ rc(fpr) | rc(dbl) | 0x22, "%f34" },
{ rc(fpr) | rc(dbl) | 0x20, "%f32" },
{ 0x1f, "%f31" },
{ rc(arg)|rc(fpr)|rc(sng)|0x1e, "%f30" },
{ 0x1d, "%f29" },
{ rc(arg)|rc(fpr)|rc(sng)|0x1c, "%f28" },
{ 0x1b, "%f27" },
{ rc(arg)|rc(fpr)|rc(sng)|0x1a, "%f26" },
{ 0x19, "%f25" },
{ rc(arg)|rc(fpr)|rc(sng)|0x18, "%f24" },
{ 0x17, "%f23" },
{ rc(arg)|rc(fpr)|rc(sng)|0x16, "%f22" },
{ 0x15, "%f21" },
{ rc(arg)|rc(fpr)|rc(sng)|0x14, "%f20" },
{ 0x13, "%f19" },
{ rc(arg)|rc(fpr)|rc(sng)|0x12, "%f18" },
{ 0x11, "%f17" },
{ rc(arg)|rc(fpr)|rc(sng)|0x10, "%f16" },
{ 0x0f, "%f15" },
{ rc(arg)|rc(fpr)|rc(sng)|0x0e, "%f14" },
{ 0x0d, "%f13" },
{ rc(arg)|rc(fpr)|rc(sng)|0x0c, "%f12" },
{ 0x0b, "%f11" },
{ rc(arg)|rc(fpr)|rc(sng)|0x0a, "%f10" },
{ 0x09, "%f9" },
{ rc(arg)|rc(fpr)|rc(sng)|0x08, "%f8" },
{ 0x07, "%f7" },
{ rc(arg)|rc(fpr)|rc(sng)|0x06, "%f6" },
{ 0x05, "%f5" },
{ rc(arg)|rc(fpr)|rc(sng)|0x04, "%f4" },
{ 0x03, "%f3" },
{ rc(arg)|rc(fpr)|rc(sng)|0x02, "%f2" },
{ 0x01, "%f1" },
{ rc(arg)|rc(fpr)|rc(sng)|0x00, "%f0" },
# endif
{ _NOREG, "<none>" },
};
@ -103,6 +160,9 @@ void
_jit_init(jit_state_t *_jit)
{
_jitc->reglen = jit_size(_rvs) - 1;
# if __WORDSIZE == 64
jit_carry = _NOREG;
# endif
}
void
@ -126,7 +186,12 @@ _jit_prolog(jit_state_t *_jit)
_jitc->function->self.argi = _jitc->function->self.argf =
_jitc->function->self.aoff = _jitc->function->self.alen = 0;
/* float conversion */
# if __WORDSIZE == 32
_jitc->function->self.aoff = -8;
# else
/* extra slots in case qmul is called */
_jitc->function->self.aoff = -24;
# endif
_jitc->function->self.call = jit_call_default;
jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
_jitc->reglen * sizeof(jit_int32_t));
@ -163,7 +228,7 @@ _jit_allocai(jit_state_t *_jit, jit_int32_t length)
jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
jit_dec_synth();
}
return (_jitc->function->self.aoff);
return (BIAS(_jitc->function->self.aoff));
}
void
@ -273,10 +338,17 @@ _jit_epilog(jit_state_t *_jit)
jit_bool_t
_jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
{
# if __WORDSIZE == 32
if (u->code == jit_code_arg || u->code == jit_code_arg_f)
return (jit_arg_reg_p(u->u.w));
assert(u->code == jit_code_arg_d);
return (jit_arg_d_reg_p(u->u.w));
# else
if (u->code == jit_code_arg)
return (jit_arg_reg_p(u->u.w));
assert(u->code == jit_code_arg_d || u->code == jit_code_arg_f);
return (jit_arg_d_reg_p(u->u.w));
# endif
}
void
@ -315,12 +387,16 @@ _jit_arg(jit_state_t *_jit)
if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++;
else {
offset = _jitc->function->self.size;
# if __WORDSIZE == 64
if (jit_arg_d_reg_p(_jitc->function->self.argi))
++_jitc->function->self.argi;
# endif
offset = BIAS(_jitc->function->self.size);
_jitc->function->self.size += sizeof(jit_word_t);
}
node = jit_new_node_ww(jit_code_arg, offset,
++_jitc->function->self.argn);
jit_link_prepare();
jit_link_prolog();
return (node);
}
@ -329,16 +405,29 @@ _jit_arg_f(jit_state_t *_jit)
{
jit_node_t *node;
jit_int32_t offset;
# if __WORDSIZE == 64
jit_bool_t inc;
# endif
assert(_jitc->function);
# if __WORDSIZE == 32
if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++;
else {
offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_float32_t);
_jitc->function->self.size += sizeof(jit_word_t);
}
# else
inc = !jit_arg_reg_p(_jitc->function->self.argi);
if (jit_arg_d_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++;
else
offset = BIAS(_jitc->function->self.size);
if (inc)
_jitc->function->self.size += sizeof(jit_word_t);
# endif
node = jit_new_node_ww(jit_code_arg_f, offset,
++_jitc->function->self.argn);
jit_link_prepare();
jit_link_prolog();
return (node);
}
@ -347,7 +436,11 @@ _jit_arg_d(jit_state_t *_jit)
{
jit_node_t *node;
jit_int32_t offset;
# if __WORDSIZE == 64
jit_bool_t inc;
# endif
assert(_jitc->function);
# if __WORDSIZE == 32
if (jit_arg_d_reg_p(_jitc->function->self.argi)) {
offset = _jitc->function->self.argi;
_jitc->function->self.argi += 2;
@ -360,9 +453,18 @@ _jit_arg_d(jit_state_t *_jit)
offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_float64_t);
}
# else
inc = !jit_arg_reg_p(_jitc->function->self.argi);
if (jit_arg_d_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++;
else
offset = BIAS(_jitc->function->self.size);
if (inc)
_jitc->function->self.size += sizeof(jit_word_t);
# endif
node = jit_new_node_ww(jit_code_arg_d, offset,
++_jitc->function->self.argn);
jit_link_prepare();
jit_link_prolog();
return (node);
}
@ -420,15 +522,48 @@ _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
void
_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_i, u, v);
if (jit_arg_reg_p(v->u.w)) {
# if __WORDSIZE == 64
jit_extr_i(u, _I0 + v->u.w);
# else
jit_movr(u, _I0 + v->u.w);
# endif
}
else
jit_ldxi_i(u, JIT_FP,
v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int32_t));
jit_dec_synth();
}
# if __WORDSIZE == 64
void
_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_i, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_ui(u, _I0 + v->u.w);
else
jit_ldxi_ui(u, JIT_FP,
v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int32_t));
jit_dec_synth();
}
void
_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_i, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movr(u, _I0 + v->u.w);
else
jit_ldxi_i(u, JIT_FP, v->u.w);
jit_ldxi_l(u, JIT_FP, v->u.w);
jit_dec_synth();
}
# endif
void
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
@ -465,12 +600,20 @@ _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
assert(v->code == jit_code_arg_f);
assert(_jitc->function);
jit_inc_synth_wp(getarg_f, u, v);
# if __WORDSIZE == 32
if (jit_arg_reg_p(v->u.w)) {
jit_stxi(-4, JIT_FP, _I0 + v->u.w);
jit_stxi_i(-4, JIT_FP, _I0 + v->u.w);
jit_ldxi_f(u, JIT_FP, -4);
}
# else
if (jit_arg_d_reg_p(v->u.w)) {
jit_live(_F0 - (v->u.w << 1)); /* pair of registers is live */
jit_movr_f(u, (_F0 - (v->u.w << 1)) - 1);
}
# endif
else
jit_ldxi_f(u, JIT_FP, v->u.w);
jit_ldxi_f(u, JIT_FP, v->u.w + (__WORDSIZE >> 3) -
sizeof(jit_float32_t));
jit_dec_synth();
}
@ -479,12 +622,20 @@ _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(putargr_f, u, v);
# if __WORDSIZE == 32
if (jit_arg_reg_p(v->u.w)) {
jit_stxi_f(-4, JIT_FP, u);
jit_ldxi(_I0 + v->u.w, JIT_FP, -4);
jit_ldxi_i(_I0 + v->u.w, JIT_FP, -4);
}
# else
if (jit_arg_d_reg_p(v->u.w)) {
jit_live(_F0 - (v->u.w << 1)); /* pair of registers is live */
jit_movr_f((_F0 - (v->u.w << 1)) - 1, u);
}
# endif
else
jit_stxi_f(v->u.w, JIT_FP, u);
jit_stxi_f(v->u.w + (__WORDSIZE >> 3) -
sizeof(jit_float32_t), JIT_FP, u);
jit_dec_synth();
}
@ -494,15 +645,29 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
jit_int32_t regno;
assert(v->code == jit_code_arg_f);
jit_inc_synth_fp(putargi_f, u, v);
# if __WORDSIZE == 32
regno = jit_get_reg(jit_class_fpr);
jit_movi_f(regno, u);
if (jit_arg_reg_p(v->u.w)) {
jit_stxi_f(-4, JIT_FP, regno);
jit_ldxi(_I0 + v->u.w, JIT_FP, -4);
jit_ldxi_i(_I0 + v->u.w, JIT_FP, -4);
}
else
jit_stxi_f(v->u.w, JIT_FP, regno);
jit_unget_reg(regno);
# else
if (jit_arg_d_reg_p(v->u.w)) {
jit_live(_F0 - (v->u.w << 1)); /* pair of registers is live */
jit_movi_f((_F0 - (v->u.w << 1)) - 1, u);
}
else {
regno = jit_get_reg(jit_class_fpr | jit_class_sng);
jit_movi_f(regno, u);
jit_stxi_f(v->u.w + (__WORDSIZE >> 3) -
sizeof(jit_float32_t), JIT_FP, regno);
jit_unget_reg(regno);
}
# endif
jit_dec_synth();
}
@ -513,18 +678,28 @@ _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
assert(_jitc->function);
jit_inc_synth_wp(getarg_d, u, v);
if (jit_arg_d_reg_p(v->u.w)) {
# if __WORDSIZE == 32
jit_stxi(-8, JIT_FP, _I0 + v->u.w);
jit_stxi(-4, JIT_FP, _I0 + v->u.w + 1);
jit_ldxi_d(u, JIT_FP, -8);
# else
jit_movr_d(u, _F0 - (v->u.w << 1));
# endif
}
# if __WORDSIZE == 32
else if (jit_arg_reg_p(v->u.w)) {
jit_stxi(-8, JIT_FP, _I0 + v->u.w);
jit_ldxi_f(u, JIT_FP, -8);
jit_ldxi_f(u + 1, JIT_FP, stack_framesize);
}
# endif
else {
# if __WORDSIZE == 32
jit_ldxi_f(u, JIT_FP, v->u.w);
jit_ldxi_f(u + 1, JIT_FP, v->u.w + 4);
# else
jit_ldxi_d(u, JIT_FP, v->u.w);
# endif
}
jit_dec_synth();
}
@ -532,9 +707,10 @@ _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
void
_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
jit_int32_t regno;
jit_int32_t regno;
assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(putargr_d, u, v);
# if __WORDSIZE == 32
if (jit_arg_d_reg_p(v->u.w)) {
jit_stxi_d(-8, JIT_FP, u);
jit_ldxi(_I0 + v->u.w, JIT_FP, -8);
@ -559,15 +735,25 @@ _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
jit_stxi(v->u.w + 4, JIT_FP, regno);
jit_unget_reg(regno);
}
# else
if (jit_arg_d_reg_p(v->u.w))
jit_movr_d(_F0 - (v->u.w << 1), u);
else
jit_stxi_d(v->u.w, JIT_FP, u);
# endif
jit_dec_synth();
}
void
_jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
{
jit_int32_t regno, gpr;
# if __WORDSIZE == 32
jit_int32_t gpr;
# endif
jit_int32_t regno;
assert(v->code == jit_code_arg_d);
jit_inc_synth_dp(putargi_d, u, v);
# if __WORDSIZE == 32
regno = jit_get_reg(jit_class_fpr);
jit_movi_d(regno, u);
if (jit_arg_d_reg_p(v->u.w)) {
@ -595,6 +781,16 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
jit_unget_reg(gpr);
}
jit_unget_reg(regno);
# else
if (jit_arg_d_reg_p(v->u.w))
jit_movi_d(_F0 - (v->u.w << 1), u);
else {
regno = jit_get_reg(jit_class_fpr | jit_class_dbl);
jit_movi_d(regno, u);
jit_stxi_d(v->u.w, JIT_FP, regno);
jit_unget_reg(regno);
}
# endif
jit_dec_synth();
}
@ -608,7 +804,12 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
++_jitc->function->call.argi;
}
else {
jit_stxi(_jitc->function->call.size + stack_framesize, JIT_SP, u);
# if __WORDSIZE == 64
if (jit_arg_d_reg_p(_jitc->function->call.argi))
++_jitc->function->call.argi;
# endif
jit_stxi(BIAS(_jitc->function->call.size + stack_framesize),
JIT_SP, u);
_jitc->function->call.size += sizeof(jit_word_t);
}
jit_dec_synth();
@ -625,9 +826,14 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
++_jitc->function->call.argi;
}
else {
# if __WORDSIZE == 64
if (jit_arg_d_reg_p(_jitc->function->call.argi))
++_jitc->function->call.argi;
# endif
regno = jit_get_reg(jit_class_gpr);
jit_movi(regno, u);
jit_stxi(_jitc->function->call.size + stack_framesize, JIT_SP, regno);
jit_stxi(BIAS(_jitc->function->call.size + stack_framesize),
JIT_SP, regno);
jit_unget_reg(regno);
_jitc->function->call.size += sizeof(jit_word_t);
}
@ -639,15 +845,39 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(pushargr_f, u);
jit_link_prepare();
# if __WORDSIZE == 32
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_stxi_f(-4, JIT_FP, u);
jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -4);
jit_stxi_f(-8, JIT_FP, u);
jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -8);
++_jitc->function->call.argi;
}
else {
jit_stxi_f(_jitc->function->call.size + stack_framesize, JIT_SP, u);
jit_stxi_f(_jitc->function->call.size + stack_framesize,
JIT_SP, u);
_jitc->function->call.size += sizeof(jit_float32_t);
}
# else
if ((_jitc->function->call.call & jit_call_varargs) &&
jit_arg_reg_p(_jitc->function->call.argi)) {
jit_stxi_f(BIAS(-8), JIT_FP, u);
jit_ldxi_i(_O0 + _jitc->function->call.argi, JIT_FP, BIAS(-8));
++_jitc->function->call.argi;
}
else if (!(_jitc->function->call.call & jit_call_varargs) &&
jit_arg_d_reg_p(_jitc->function->call.argi)) {
/* pair of registers is live */
jit_live(_F0 - (_jitc->function->call.argi << 1));
jit_movr_f((_F0 - (_jitc->function->call.argi << 1)) - 1, u);
if (!jit_arg_reg_p(_jitc->function->call.argi))
_jitc->function->call.size += sizeof(jit_float64_t);
++_jitc->function->call.argi;
}
else {
jit_stxi_f(BIAS(_jitc->function->call.size + stack_framesize + 4),
JIT_SP, u);
_jitc->function->call.size += sizeof(jit_float64_t);
}
# endif
jit_dec_synth();
}
@ -657,18 +887,48 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
jit_int32_t regno;
jit_inc_synth_f(pushargi_f, u);
jit_link_prepare();
# if __WORDSIZE == 32
regno = jit_get_reg(jit_class_fpr);
jit_movi_f(regno, u);
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_stxi_f(-4, JIT_FP, regno);
jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -4);
++_jitc->function->call.argi;
jit_stxi_f(-8, JIT_FP, regno);
jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -8);
_jitc->function->call.argi++;
}
else {
jit_stxi_f(_jitc->function->call.size + stack_framesize, JIT_SP, regno);
jit_stxi_f(_jitc->function->call.size + stack_framesize,
JIT_SP, regno);
_jitc->function->call.size += sizeof(jit_float32_t);
}
jit_unget_reg(regno);
# else
if ((_jitc->function->call.call & jit_call_varargs) &&
jit_arg_reg_p(_jitc->function->call.argi)) {
regno = jit_get_reg(jit_class_fpr | jit_class_sng);
jit_movi_f(regno, u);
jit_stxi_f(BIAS(-8), JIT_FP, regno);
jit_ldxi_i(_O0 + _jitc->function->call.argi, JIT_FP, BIAS(-8));
++_jitc->function->call.argi;
jit_unget_reg(regno);
}
else if (!(_jitc->function->call.call & jit_call_varargs) &&
jit_arg_d_reg_p(_jitc->function->call.argi)) {
/* pair of registers is live */
jit_live(_F0 - (_jitc->function->call.argi << 1));
jit_movi_f((_F0 - (_jitc->function->call.argi << 1)) - 1, u);
if (!jit_arg_reg_p(_jitc->function->call.argi))
_jitc->function->call.size += sizeof(jit_float64_t);
++_jitc->function->call.argi;
}
else {
regno = jit_get_reg(jit_class_fpr | jit_class_sng);
jit_movi_f(regno, u);
jit_stxi_f(BIAS(_jitc->function->call.size + stack_framesize + 4),
JIT_SP, regno);
jit_unget_reg(regno);
_jitc->function->call.size += sizeof(jit_float64_t);
}
# endif
jit_dec_synth();
}
@ -677,9 +937,10 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(pushargr_d, u);
jit_link_prepare();
# if __WORDSIZE == 32
if (jit_arg_d_reg_p(_jitc->function->call.argi)) {
jit_stxi_d(-8, JIT_FP, u);
jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -8);
jit_stxi_d(BIAS(-8), JIT_FP, u);
jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, BIAS(-8));
jit_ldxi(_O0 + _jitc->function->call.argi + 1, JIT_FP, -4);
_jitc->function->call.argi += 2;
}
@ -697,6 +958,26 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
JIT_SP, u + 1);
_jitc->function->call.size += sizeof(jit_float64_t);
}
# else
if ((_jitc->function->call.call & jit_call_varargs) &&
jit_arg_reg_p(_jitc->function->call.argi)) {
jit_stxi_d(BIAS(-8), JIT_FP, u);
jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, BIAS(-8));
++_jitc->function->call.argi;
}
else if (!(_jitc->function->call.call & jit_call_varargs) &&
jit_arg_d_reg_p(_jitc->function->call.argi)) {
jit_movr_d(_F0 - (_jitc->function->call.argi << 1), u);
if (!jit_arg_reg_p(_jitc->function->call.argi))
_jitc->function->call.size += sizeof(jit_float64_t);
++_jitc->function->call.argi;
}
else {
jit_stxi_d(BIAS(_jitc->function->call.size + stack_framesize),
JIT_SP, u);
_jitc->function->call.size += sizeof(jit_float64_t);
}
# endif
jit_dec_synth();
}
@ -706,11 +987,12 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
jit_int32_t regno;
jit_inc_synth_d(pushargi_d, u);
jit_link_prepare();
# if __WORDSIZE == 32
regno = jit_get_reg(jit_class_fpr);
jit_movi_d(regno, u);
if (jit_arg_d_reg_p(_jitc->function->call.argi)) {
jit_stxi_d(-8, JIT_FP, regno);
jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -8);
jit_stxi_d(BIAS(-8), JIT_FP, regno);
jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, BIAS(-8));
jit_ldxi(_O0 + _jitc->function->call.argi + 1, JIT_FP, -4);
_jitc->function->call.argi += 2;
}
@ -718,7 +1000,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
jit_stxi_f(-8, JIT_FP, regno);
jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -8);
++_jitc->function->call.argi;
jit_stxi_f(stack_framesize, JIT_SP, regno + 1);
jit_stxi_f(stack_framesize, JIT_SP, u + 1);
_jitc->function->call.size += sizeof(jit_float32_t);
}
else {
@ -729,6 +1011,32 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
_jitc->function->call.size += sizeof(jit_float64_t);
}
jit_unget_reg(regno);
# else
if ((_jitc->function->call.call & jit_call_varargs) &&
jit_arg_reg_p(_jitc->function->call.argi)) {
regno = jit_get_reg(jit_class_fpr | jit_class_dbl);
jit_movi_d(regno, u);
jit_stxi_d(BIAS(-8), JIT_FP, regno);
jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, BIAS(-8));
++_jitc->function->call.argi;
jit_unget_reg(regno);
}
else if (!(_jitc->function->call.call & jit_call_varargs) &&
jit_arg_d_reg_p(_jitc->function->call.argi)) {
jit_movi_d(_F0 - (_jitc->function->call.argi << 1), u);
if (!jit_arg_reg_p(_jitc->function->call.argi))
_jitc->function->call.size += sizeof(jit_float64_t);
++_jitc->function->call.argi;
}
else {
regno = jit_get_reg(jit_class_fpr | jit_class_dbl);
jit_movi_d(regno, u);
jit_stxi_d(BIAS(_jitc->function->call.size + stack_framesize),
JIT_SP, regno);
jit_unget_reg(regno);
_jitc->function->call.size += sizeof(jit_float64_t);
}
# endif
jit_dec_synth();
}
@ -740,10 +1048,18 @@ _jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno)
spec = jit_class(_rvs[regno].spec);
if ((spec & (jit_class_arg|jit_class_gpr)) ==
(jit_class_arg|jit_class_gpr)) {
regno = _O0 - regno;
regno -= _O0;
if (regno >= 0 && regno < node->v.w)
return (1);
}
# if __WORDSIZE == 64
if ((spec & (jit_class_arg|jit_class_fpr)) ==
(jit_class_arg|jit_class_fpr)) {
regno = _F0 - (regno >> 1);
if (regno >= 0 && regno < node->v.w)
return (1);
}
# endif
return (0);
}
@ -817,12 +1133,36 @@ _jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
void
_jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_i, r0);
# if __WORDSIZE == 32
if (r0 != _O0)
jit_movr(r0, _O0);
# else
jit_extr_i(r0, _O0);
# endif
jit_dec_synth();
}
# if __WORDSIZE == 64
void
_jit_retval_ui(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_i, r0);
if (r0 != _O0)
jit_extr_ui(r0, _O0);
jit_dec_synth();
}
void
_jit_retval_l(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_i, r0);
if (r0 != _O0)
jit_movr(r0, _O0);
jit_dec_synth();
}
# endif
void
_jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
@ -1043,6 +1383,10 @@ _emit_code(jit_state_t *_jit)
case_rrw(rsh, _u);
case_rr(trunc, _f_i);
case_rr(trunc, _d_i);
#if __WORDSIZE == 64
case_rr(trunc, _f_l);
case_rr(trunc, _d_l);
#endif
case_rrr(lt,);
case_rrw(lt,);
case_rrr(lt, _u);
@ -1073,6 +1417,12 @@ _emit_code(jit_state_t *_jit)
case_rw(ld, _us);
case_rr(ld, _i);
case_rw(ld, _i);
#if __WORDSIZE == 64
case_rr(ld, _ui);
case_rw(ld, _ui);
case_rr(ld, _l);
case_rw(ld, _l);
#endif
case_rrr(ldx, _c);
case_rrw(ldx, _c);
case_rrr(ldx, _uc);
@ -1083,24 +1433,45 @@ _emit_code(jit_state_t *_jit)
case_rrw(ldx, _us);
case_rrr(ldx, _i);
case_rrw(ldx, _i);
#if __WORDSIZE == 64
case_rrr(ldx, _ui);
case_rrw(ldx, _ui);
case_rrr(ldx, _l);
case_rrw(ldx, _l);
#endif
case_rr(st, _c);
case_wr(st, _c);
case_rr(st, _s);
case_wr(st, _s);
case_rr(st, _i);
case_wr(st, _i);
#if __WORDSIZE == 64
case_rr(st, _l);
case_wr(st, _l);
#endif
case_rrr(stx, _c);
case_wrr(stx, _c);
case_rrr(stx, _s);
case_wrr(stx, _s);
case_rrr(stx, _i);
case_wrr(stx, _i);
#if __WORDSIZE == 64
case_rrr(stx, _l);
case_wrr(stx, _l);
#endif
case_rr(hton, _us);
case_rr(hton, _ui);
#if __WORDSIZE == 64
case_rr(hton, _ul);
#endif
case_rr(ext, _c);
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) {
@ -1418,6 +1789,9 @@ _emit_code(jit_state_t *_jit)
case jit_code_getarg_c: case jit_code_getarg_uc:
case jit_code_getarg_s: case jit_code_getarg_us:
case jit_code_getarg_i:
#if __WORDSIZE == 64
case jit_code_getarg_ui: case jit_code_getarg_l:
#endif
case jit_code_getarg_f: case jit_code_getarg_d:
case jit_code_putargr: case jit_code_putargi:
case jit_code_putargr_f: case jit_code_putargi_f:
@ -1428,6 +1802,9 @@ _emit_code(jit_state_t *_jit)
case jit_code_retval_c: case jit_code_retval_uc:
case jit_code_retval_s: case jit_code_retval_us:
case jit_code_retval_i:
#if __WORDSIZE == 64
case jit_code_retval_ui: case jit_code_retval_l:
#endif
case jit_code_retval_f: case jit_code_retval_d:
case jit_code_prepare:
case jit_code_finishr: case jit_code_finishi:
@ -1435,9 +1812,34 @@ _emit_code(jit_state_t *_jit)
default:
abort();
}
# if __WORDSIZE == 64
if (jit_carry != _NOREG) {
switch (node->code) {
case jit_code_note:
case jit_code_addcr: case jit_code_addci:
case jit_code_addxr: case jit_code_addxi:
case jit_code_subcr: case jit_code_subci:
case jit_code_subxr: case jit_code_subxi:
break;
default:
jit_unget_reg(jit_carry);
jit_carry = _NOREG;
break;
}
}
# endif
jit_regarg_clr(node, value);
# if __WORDSIZE == 64
if (jit_carry == _NOREG)
assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0);
else {
assert(jit_regset_scan1(&_jitc->regarg, 0) == jit_carry);
assert(jit_regset_scan1(&_jitc->regarg, jit_carry + 1) == ULONG_MAX);
}
assert(_jitc->synth == 0);
# else
assert(_jitc->regarg == 0 && _jitc->synth == 0);
/* update register live state */
# endif
jit_reglive(node);
}
#undef case_brf
@ -1478,13 +1880,13 @@ jit_flush(void *fptr, void *tptr)
void
_emit_ldxi(jit_state_t *_jit, jit_gpr_t r0, jit_gpr_t r1, jit_word_t i0)
{
ldxi_i(rn(r0), rn(r1), i0);
ldxi(rn(r0), rn(r1), i0);
}
void
_emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_gpr_t r1)
{
stxi_i(i0, rn(r0), rn(r1));
stxi(i0, rn(r0), rn(r1));
}
void

View file

@ -497,6 +497,120 @@ jit_regset_scan1(jit_regset_t *set, jit_int32_t offset)
}
return (ULONG_MAX);
}
#elif __sparc__ && __WORDSIZE == 64
void
jit_regset_com(jit_regset_t *u, jit_regset_t *v)
{
u->rl = ~v->rl; u->rh = ~v->rh;
}
void
jit_regset_and(jit_regset_t *u, jit_regset_t *v, jit_regset_t *w)
{
u->rl = v->rl & w->rl; u->rh = v->rh & w->rh;
}
void
jit_regset_ior(jit_regset_t *u, jit_regset_t *v, jit_regset_t *w)
{
u->rl = v->rl | w->rl; u->rh = v->rh | w->rh;
}
void
jit_regset_xor(jit_regset_t *u, jit_regset_t *v, jit_regset_t *w)
{
u->rl = v->rl ^ w->rl; u->rh = v->rh ^ w->rh;
}
void
jit_regset_set(jit_regset_t *u, jit_regset_t *v)
{
u->rl = v->rl; u->rh = v->rh;
}
void
jit_regset_set_mask(jit_regset_t *u, jit_int32_t v)
{
jit_bool_t w = !!(v & (v - 1));
assert(v >= 0 && v <= 128);
if (v == 0)
u->rl = u->rh = -1LL;
else if (v <= 64) {
u->rl = w ? (1LL << v) - 1 : -1LL;
u->rh = 0;
}
else {
u->rl = -1LL;
u->rh = w ? (1LL << (v - 64)) - 1 : -1LL;
}
}
jit_bool_t
jit_regset_cmp_ui(jit_regset_t *u, jit_word_t v)
{
return !((u->rl == v && u->rh == 0));
}
void
jit_regset_set_ui(jit_regset_t *u, jit_word_t v)
{
u->rl = v;
u->rh = 0;
}
jit_bool_t
jit_regset_set_p(jit_regset_t *u)
{
return (u->rl || u->rh);
}
void
jit_regset_clrbit(jit_regset_t *set, jit_int32_t bit)
{
assert(bit >= 0 && bit <= 128);
if (bit < 64)
set->rl &= ~(1LL << bit);
else
set->rh &= ~(1LL << (bit - 64));
}
void
jit_regset_setbit(jit_regset_t *set, jit_int32_t bit)
{
assert(bit >= 0 && bit <= 127);
if (bit < 64)
set->rl |= 1LL << bit;
else
set->rh |= 1LL << (bit - 64);
}
jit_bool_t
jit_regset_tstbit(jit_regset_t *set, jit_int32_t bit)
{
assert(bit >= 0 && bit <= 127);
if (bit < 64)
return (!!(set->rl & (1LL << bit)));
else
return (!!(set->rh & (1LL << (bit - 64))));
}
unsigned long
jit_regset_scan1(jit_regset_t *set, jit_int32_t offset)
{
assert(offset >= 0 && offset <= 127);
for (; offset < 64; offset++) {
if (set->rl & (1LL << offset))
return (offset);
}
for (; offset < 128; offset++) {
if (set->rh & (1LL << (offset - 64)))
return (offset);
}
return (ULONG_MAX);
}
#else
unsigned long
jit_regset_scan1(jit_regset_t *set, jit_int32_t offset)