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

Beginnings of port of x86 to new design

This commit is contained in:
Andy Wingo 2018-11-04 12:18:51 +01:00
parent c51c93708a
commit 0d81c5c337
2 changed files with 2 additions and 359 deletions

View file

@ -667,18 +667,6 @@ static void _jmpr(jit_state_t*, int32_t);
static jit_word_t _jmpi(jit_state_t*, jit_word_t); static jit_word_t _jmpi(jit_state_t*, jit_word_t);
# define jmpsi(i0) _jmpsi(_jit, i0) # define jmpsi(i0) _jmpsi(_jit, i0)
static void _jmpsi(jit_state_t*, uint8_t); static void _jmpsi(jit_state_t*, uint8_t);
# define prolog(node) _prolog(_jit, node)
static void _prolog(jit_state_t*, jit_node_t*);
# define epilog(node) _epilog(_jit, node)
static void _epilog(jit_state_t*, jit_node_t*);
# define vastart(r0) _vastart(_jit, r0)
static void _vastart(jit_state_t*, int32_t);
# define vaarg(r0, r1) _vaarg(_jit, r0, r1)
static void _vaarg(jit_state_t*, int32_t, int32_t);
# define vaarg_d(r0, r1, i0) _vaarg_d(_jit, r0, r1, i0)
static void _vaarg_d(jit_state_t*, int32_t, int32_t, jit_bool_t);
# define patch_at(node, instr, label) _patch_at(_jit, node, instr, label)
static void _patch_at(jit_state_t*, jit_node_t*, jit_word_t, jit_word_t);
# if !defined(HAVE_FFSL) # if !defined(HAVE_FFSL)
# if __X32 # if __X32
# define ffsl(i) ffs(i) # define ffsl(i) ffs(i)
@ -3453,204 +3441,6 @@ _jmpsi(jit_state_t *_jit, uint8_t i0)
ic(i0); ic(i0);
} }
static void
_prolog(jit_state_t *_jit, jit_node_t *node)
{
int32_t reg;
if (_jitc->function->define_frame || _jitc->function->assume_frame) {
int32_t frame = -_jitc->function->frame;
assert(_jitc->function->self.aoff >= frame);
if (_jitc->function->assume_frame)
return;
_jitc->function->self.aoff = frame;
}
if (_jitc->function->allocar)
_jitc->function->self.aoff &= -16;
#if __X64 && __CYGWIN__
_jitc->function->stack = (((/* first 32 bytes must be allocated */
(_jitc->function->self.alen > 32 ?
_jitc->function->self.alen : 32) -
/* align stack at 16 bytes */
_jitc->function->self.aoff) + 15) & -16) +
stack_adjust;
#else
_jitc->function->stack = (((_jitc->function->self.alen -
_jitc->function->self.aoff) + 15) & -16) +
stack_adjust;
#endif
subi(_RSP_REGNO, _RSP_REGNO, stack_framesize - REAL_WORDSIZE);
/* callee save registers */
#if __X32
if (jit_regset_tstbit(&_jitc->function->regset, _RDI))
stxi(12, _RSP_REGNO, _RDI_REGNO);
if (jit_regset_tstbit(&_jitc->function->regset, _RSI))
stxi( 8, _RSP_REGNO, _RSI_REGNO);
if (jit_regset_tstbit(&_jitc->function->regset, _RBX))
stxi( 4, _RSP_REGNO, _RBX_REGNO);
#else
# if __CYGWIN__
if (jit_regset_tstbit(&_jitc->function->regset, _XMM15))
sse_stxi_d(136, _RSP_REGNO, _XMM15_REGNO);
if (jit_regset_tstbit(&_jitc->function->regset, _XMM14))
sse_stxi_d(128, _RSP_REGNO, _XMM14_REGNO);
if (jit_regset_tstbit(&_jitc->function->regset, _XMM13))
sse_stxi_d(120, _RSP_REGNO, _XMM13_REGNO);
if (jit_regset_tstbit(&_jitc->function->regset, _XMM12))
sse_stxi_d(112, _RSP_REGNO, _XMM12_REGNO);
if (jit_regset_tstbit(&_jitc->function->regset, _XMM11))
sse_stxi_d(104, _RSP_REGNO, _XMM11_REGNO);
if (jit_regset_tstbit(&_jitc->function->regset, _XMM10))
sse_stxi_d(96, _RSP_REGNO, _XMM10_REGNO);
if (jit_regset_tstbit(&_jitc->function->regset, _XMM9))
sse_stxi_d(88, _RSP_REGNO, _XMM9_REGNO);
if (jit_regset_tstbit(&_jitc->function->regset, _XMM8))
sse_stxi_d(80, _RSP_REGNO, _XMM8_REGNO);
if (jit_regset_tstbit(&_jitc->function->regset, _XMM7))
sse_stxi_d(72, _RSP_REGNO, _XMM7_REGNO);
if (jit_regset_tstbit(&_jitc->function->regset, _XMM6))
sse_stxi_d(64, _RSP_REGNO, _XMM6_REGNO);
if (jit_regset_tstbit(&_jitc->function->regset, _R15))
stxi(56, _RSP_REGNO, _R15_REGNO);
if (jit_regset_tstbit(&_jitc->function->regset, _R14))
stxi(48, _RSP_REGNO, _R14_REGNO);
if (jit_regset_tstbit(&_jitc->function->regset, _R13))
stxi(40, _RSP_REGNO, _R13_REGNO);
if (jit_regset_tstbit(&_jitc->function->regset, _R12))
stxi(32, _RSP_REGNO, _R12_REGNO);
if (jit_regset_tstbit(&_jitc->function->regset, _RSI))
stxi(24, _RSP_REGNO, _RSI_REGNO);
if (jit_regset_tstbit(&_jitc->function->regset, _RDI))
stxi(16, _RSP_REGNO, _RDI_REGNO);
if (jit_regset_tstbit(&_jitc->function->regset, _RBX))
stxi( 8, _RSP_REGNO, _RBX_REGNO);
# else
if (jit_regset_tstbit(&_jitc->function->regset, _RBX))
stxi(40, _RSP_REGNO, _RBX_REGNO);
if (jit_regset_tstbit(&_jitc->function->regset, _R12))
stxi(32, _RSP_REGNO, _R12_REGNO);
if (jit_regset_tstbit(&_jitc->function->regset, _R13))
stxi(24, _RSP_REGNO, _R13_REGNO);
if (jit_regset_tstbit(&_jitc->function->regset, _R14))
stxi(16, _RSP_REGNO, _R14_REGNO);
if (jit_regset_tstbit(&_jitc->function->regset, _R15))
stxi( 8, _RSP_REGNO, _R15_REGNO);
# endif
#endif
stxi(0, _RSP_REGNO, _RBP_REGNO);
movr(_RBP_REGNO, _RSP_REGNO);
/* alloca */
subi(_RSP_REGNO, _RSP_REGNO, _jitc->function->stack);
if (_jitc->function->allocar) {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), _jitc->function->self.aoff);
stxi_i(_jitc->function->aoffoff, _RBP_REGNO, rn(reg));
jit_unget_reg(reg);
}
#if __X64 && !__CYGWIN__
if (_jitc->function->self.call & jit_call_varargs) {
jit_word_t nofp_code;
/* Save gp registers in the save area, if any is a vararg */
for (reg = first_gp_from_offset(_jitc->function->vagp);
jit_arg_reg_p(reg); ++reg)
stxi(_jitc->function->vaoff + first_gp_offset +
reg * 8, _RBP_REGNO, rn(JIT_RA0 - reg));
reg = first_fp_from_offset(_jitc->function->vafp);
if (jit_arg_f_reg_p(reg)) {
/* Skip over if no float registers were passed as argument */
/* test %al, %al */
ic(0x84);
ic(0xc0);
jes(0);
nofp_code = _jit->pc.w;
/* Save fp registers in the save area, if any is a vararg */
/* Note that the full 16 byte xmm is not saved, because
* lightning only handles float and double, and, while
* attempting to provide a va_list compatible pointer as
* jit_va_start return, does not guarantee it (on all ports). */
for (; jit_arg_f_reg_p(reg); ++reg)
sse_stxi_d(_jitc->function->vaoff + first_fp_offset +
reg * va_fp_increment, _RBP_REGNO, rn(_XMM0 - reg));
patch_rel_char(nofp_code, _jit->pc.w);
}
}
#endif
}
static void
_epilog(jit_state_t *_jit, jit_node_t *node)
{
if (_jitc->function->assume_frame)
return;
/* callee save registers */
movr(_RSP_REGNO, _RBP_REGNO);
#if __X32
if (jit_regset_tstbit(&_jitc->function->regset, _RDI))
ldxi(_RDI_REGNO, _RSP_REGNO, 12);
if (jit_regset_tstbit(&_jitc->function->regset, _RSI))
ldxi(_RSI_REGNO, _RSP_REGNO, 8);
if (jit_regset_tstbit(&_jitc->function->regset, _RBX))
ldxi(_RBX_REGNO, _RSP_REGNO, 4);
#else
# if __CYGWIN__
if (jit_regset_tstbit(&_jitc->function->regset, _XMM15))
sse_ldxi_d(_XMM15_REGNO, _RSP_REGNO, 136);
if (jit_regset_tstbit(&_jitc->function->regset, _XMM14))
sse_ldxi_d(_XMM14_REGNO, _RSP_REGNO, 128);
if (jit_regset_tstbit(&_jitc->function->regset, _XMM13))
sse_ldxi_d(_XMM13_REGNO, _RSP_REGNO, 120);
if (jit_regset_tstbit(&_jitc->function->regset, _XMM12))
sse_ldxi_d(_XMM12_REGNO, _RSP_REGNO, 112);
if (jit_regset_tstbit(&_jitc->function->regset, _XMM11))
sse_ldxi_d(_XMM11_REGNO, _RSP_REGNO, 104);
if (jit_regset_tstbit(&_jitc->function->regset, _XMM10))
sse_ldxi_d(_XMM10_REGNO, _RSP_REGNO, 96);
if (jit_regset_tstbit(&_jitc->function->regset, _XMM9))
sse_ldxi_d(_XMM9_REGNO, _RSP_REGNO, 88);
if (jit_regset_tstbit(&_jitc->function->regset, _XMM8))
sse_ldxi_d(_XMM8_REGNO, _RSP_REGNO, 80);
if (jit_regset_tstbit(&_jitc->function->regset, _XMM7))
sse_ldxi_d(_XMM7_REGNO, _RSP_REGNO, 72);
if (jit_regset_tstbit(&_jitc->function->regset, _XMM6))
sse_ldxi_d(_XMM6_REGNO, _RSP_REGNO, 64);
if (jit_regset_tstbit(&_jitc->function->regset, _R15))
ldxi(_R15_REGNO, _RSP_REGNO, 56);
if (jit_regset_tstbit(&_jitc->function->regset, _R14))
ldxi(_R14_REGNO, _RSP_REGNO, 48);
if (jit_regset_tstbit(&_jitc->function->regset, _R13))
ldxi(_R13_REGNO, _RSP_REGNO, 40);
if (jit_regset_tstbit(&_jitc->function->regset, _R12))
ldxi(_R12_REGNO, _RSP_REGNO, 32);
if (jit_regset_tstbit(&_jitc->function->regset, _RSI))
ldxi(_RSI_REGNO, _RSP_REGNO, 24);
if (jit_regset_tstbit(&_jitc->function->regset, _RDI))
ldxi(_RDI_REGNO, _RSP_REGNO, 16);
if (jit_regset_tstbit(&_jitc->function->regset, _RBX))
ldxi(_RBX_REGNO, _RSP_REGNO, 8);
# else
if (jit_regset_tstbit(&_jitc->function->regset, _RBX))
ldxi(_RBX_REGNO, _RSP_REGNO, 40);
if (jit_regset_tstbit(&_jitc->function->regset, _R12))
ldxi(_R12_REGNO, _RSP_REGNO, 32);
if (jit_regset_tstbit(&_jitc->function->regset, _R13))
ldxi(_R13_REGNO, _RSP_REGNO, 24);
if (jit_regset_tstbit(&_jitc->function->regset, _R14))
ldxi(_R14_REGNO, _RSP_REGNO, 16);
if (jit_regset_tstbit(&_jitc->function->regset, _R15))
ldxi(_R15_REGNO, _RSP_REGNO, 8);
# endif
#endif
ldxi(_RBP_REGNO, _RSP_REGNO, 0);
addi(_RSP_REGNO, _RSP_REGNO, stack_framesize - REAL_WORDSIZE);
ic(0xc3);
}
static void static void
_vastart(jit_state_t *_jit, int32_t r0) _vastart(jit_state_t *_jit, int32_t r0)
{ {
@ -3686,158 +3476,13 @@ _vastart(jit_state_t *_jit, int32_t r0)
#endif #endif
} }
static void #define UNIMPLEMENTED() abort()
_vaarg(jit_state_t *_jit, int32_t r0, int32_t r1)
{
#if __X32 || __CYGWIN__
assert(_jitc->function->self.call & jit_call_varargs);
ldr(r0, r1);
addi(r1, r1, va_gp_increment);
#else
int32_t rg0;
int32_t rg1;
jit_word_t ge_code;
jit_word_t lt_code;
assert(_jitc->function->self.call & jit_call_varargs);
rg0 = jit_get_reg(jit_class_gpr);
rg1 = jit_get_reg(jit_class_gpr);
/* Load the gp offset in save area in the first temporary. */
ldxi_i(rn(rg0), r1, offsetof(jit_va_list_t, gpoff));
/* Jump over if there are no remaining arguments in the save area. */
icmpi(rn(rg0), va_gp_max_offset);
jaes(0);
ge_code = _jit->pc.w;
/* Load the save area pointer in the second temporary. */
ldxi(rn(rg1), r1, offsetof(jit_va_list_t, save));
/* Load the vararg argument in the first argument. */
ldxr(r0, rn(rg1), rn(rg0));
/* Update the gp offset. */
addi(rn(rg0), rn(rg0), 8);
stxi_i(offsetof(jit_va_list_t, gpoff), r1, rn(rg0));
/* Will only need one temporary register below. */
jit_unget_reg(rg1);
/* Jump over overflow code. */
jmpsi(0);
lt_code = _jit->pc.w;
/* Where to land if argument is in overflow area. */
patch_rel_char(ge_code, _jit->pc.w);
/* Load overflow pointer. */
ldxi(rn(rg0), r1, offsetof(jit_va_list_t, over));
/* Load argument. */
ldr(r0, rn(rg0));
/* Update overflow pointer. */
addi(rn(rg0), rn(rg0), va_gp_increment);
stxi(offsetof(jit_va_list_t, over), r1, rn(rg0));
/* Where to land if argument is in save area. */
patch_rel_char(lt_code, _jit->pc.w);
jit_unget_reg(rg0);
#endif
}
/* The x87 boolean argument tells if will put the result in a x87
* register if non false, in a sse register otherwise. */
static void
_vaarg_d(jit_state_t *_jit, int32_t r0, int32_t r1, jit_bool_t x87)
{
#if __X32 || __CYGWIN__
assert(_jitc->function->self.call & jit_call_varargs);
if (x87)
x87_ldr_d(r0, r1);
else
sse_ldr_d(r0, r1);
addi(r1, r1, 8);
#else
int32_t rg0;
int32_t rg1;
jit_word_t ge_code;
jit_word_t lt_code;
assert(_jitc->function->self.call & jit_call_varargs);
rg0 = jit_get_reg(jit_class_gpr);
rg1 = jit_get_reg(jit_class_gpr);
/* Load the fp offset in save area in the first temporary. */
ldxi_i(rn(rg0), r1, offsetof(jit_va_list_t, fpoff));
/* Jump over if there are no remaining arguments in the save area. */
icmpi(rn(rg0), va_fp_max_offset);
jaes(0);
ge_code = _jit->pc.w;
/* Load the save area pointer in the second temporary. */
ldxi(rn(rg1), r1, offsetof(jit_va_list_t, save));
/* Load the vararg argument in the first argument. */
if (x87)
x87_ldxr_d(r0, rn(rg1), rn(rg0));
else
sse_ldxr_d(r0, rn(rg1), rn(rg0));
/* Update the fp offset. */
addi(rn(rg0), rn(rg0), va_fp_increment);
stxi_i(offsetof(jit_va_list_t, fpoff), r1, rn(rg0));
/* Will only need one temporary register below. */
jit_unget_reg(rg1);
/* Jump over overflow code. */
jmpsi(0);
lt_code = _jit->pc.w;
/* Where to land if argument is in overflow area. */
patch_rel_char(ge_code, _jit->pc.w);
/* Load overflow pointer. */
ldxi(rn(rg0), r1, offsetof(jit_va_list_t, over));
/* Load argument. */
if (x87)
x87_ldr_d(r0, rn(rg0));
else
sse_ldr_d(r0, rn(rg0));
/* Update overflow pointer. */
addi(rn(rg0), rn(rg0), 8);
stxi(offsetof(jit_va_list_t, over), r1, rn(rg0));
/* Where to land if argument is in save area. */
patch_rel_char(lt_code, _jit->pc.w);
jit_unget_reg(rg0);
#endif
}
static void static void
_patch_at(jit_state_t *_jit, jit_node_t *node, _patch_at(jit_state_t *_jit, jit_node_t *node,
jit_word_t instr, jit_word_t label) jit_word_t instr, jit_word_t label)
{ {
switch (node->code) { UNIMPLEMENTED();
# if __X64
case jit_code_calli:
# endif
case jit_code_movi:
patch_abs(instr, label);
break;
default:
patch_rel(instr, label);
break;
}
} }
# if __X64 && !defined(HAVE_FFSL) # if __X64 && !defined(HAVE_FFSL)

View file

@ -96,8 +96,6 @@ typedef struct jit_va_list {
/* /*
* Prototypes * Prototypes
*/ */
#define patch(instr, node) _patch(_jit, instr, node)
static void _patch(jit_state_t*,jit_word_t,jit_node_t*);
#define sse_from_x87_f(r0, r1) _sse_from_x87_f(_jit, r0, r1) #define sse_from_x87_f(r0, r1) _sse_from_x87_f(_jit, r0, r1)
static void _sse_from_x87_f(jit_state_t*,int32_t,int32_t); static void _sse_from_x87_f(jit_state_t*,int32_t,int32_t);
#define sse_from_x87_d(r0, r1) _sse_from_x87_d(_jit, r0, r1) #define sse_from_x87_d(r0, r1) _sse_from_x87_d(_jit, r0, r1)