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

Adapt PowerPC port to work in Darwin 32 bit and Linux 64 bit.

* include/lightning.h: Add check for __powerpc__ defined
	in Linux, while Darwin defines __ppc__.

	* include/lightning/jit_ppc.h: Adjust register definitions
	for Darwin 32 bit and Linux 64 bit ppc usage and/or ABI.

	* include/lightning/jit_private.h: Add proper check for
	Linux __powerpc__ and an data definition for an workaround
	to properly handle code that starts with a jump to a "main"
	label.

	* lib/jit_disasm.c: Add extra disassembler initialization
	for __powerpc64__.

	* lib/jit_ppc-cpu.c: Add extra macros and functions, and
	correct/adapt previous ones to handle powerpc64.

	* lib/jit_ppc-fpu.c: Adapt for 64 bit wordsize. Basically
	add conversion from/to int32/int64 and proper handling of
	load/store offsets too large for 32 bit.

	* lib/jit_ppc.c: Add calls to 64 bit codes and adaptation
	for the PowerPC 64 bit Linux ABI.

	* lib/jit_arm.c, lib/jit_mips.c, lib/jit_sparc, lib/jit_x86.c,
	lib/lightning.c: Correct off by one error when restarting jit
	of a function due to finding too late that needs to spill/reload
	some register. Problem was found by accident on a very special
	condition during PowerPC 64 code adaptation.
This commit is contained in:
pcpa 2013-03-10 15:36:25 -03:00
parent 19123bae5d
commit 7ef8060fb2
13 changed files with 1038 additions and 123 deletions

View file

@ -1,3 +1,35 @@
2013-03-10 Paulo Andrade <pcpa@gnu.org>
* include/lightning.h: Add check for __powerpc__ defined
in Linux, while Darwin defines __ppc__.
* include/lightning/jit_ppc.h: Adjust register definitions
for Darwin 32 bit and Linux 64 bit ppc usage and/or ABI.
* include/lightning/jit_private.h: Add proper check for
Linux __powerpc__ and an data definition for an workaround
to properly handle code that starts with a jump to a "main"
label.
* lib/jit_disasm.c: Add extra disassembler initialization
for __powerpc64__.
* lib/jit_ppc-cpu.c: Add extra macros and functions, and
correct/adapt previous ones to handle powerpc64.
* lib/jit_ppc-fpu.c: Adapt for 64 bit wordsize. Basically
add conversion from/to int32/int64 and proper handling of
load/store offsets too large for 32 bit.
* lib/jit_ppc.c: Add calls to 64 bit codes and adaptation
for the PowerPC 64 bit Linux ABI.
* lib/jit_arm.c, lib/jit_mips.c, lib/jit_sparc, lib/jit_x86.c,
lib/lightning.c: Correct off by one error when restarting jit
of a function due to finding too late that needs to spill/reload
some register. Problem was found by accident on a very special
condition during PowerPC 64 code adaptation.
2013-03-08 Paulo Andrade <pcpa@gnu.org>
* check/lightning.c: Add missing ppc preprocessor definition.

View file

@ -70,7 +70,7 @@ typedef jit_int32_t jit_fpr_t;
# include <lightning/jit_mips.h>
#elif defined(__arm__)
# include <lightning/jit_arm.h>
#elif defined(__ppc__)
#elif defined(__ppc__) || defined(__powerpc__)
# include <lightning/jit_ppc.h>
#elif defined(__sparc__)
# include <lightning/jit_sparc.h>

View file

@ -28,34 +28,46 @@ typedef enum {
#define jit_arg_reg_p(i) ((i) >= 0 && (i) < 8)
#define jit_r(i) (_R11 + (i))
#define jit_r_num() 3
#if __WORDSIZE == 32
# define jit_v(i) (_R30 - (i))
# define jit_v_num() 17
#else
# define jit_v(i) (_R27 - (i))
# define jit_v_num() 14
#endif
#define jit_arg_f_reg_p(i) ((i) >= 0 && (i) < 13)
#define jit_f(i) (_F14 + (i))
#define jit_f_num() 6
_R0,
#if __WORDSIZE == 32
# define JIT_R0 _R11
# define JIT_R1 _R12
# define JIT_R2 _R13
#define JIT_R3 _R2
#else
# define JIT_R0 _R28
# define JIT_R1 _R29
# define JIT_R2 _R30
#endif
_R11, _R12, _R13, _R2,
#define JIT_V0 _R30
#define JIT_V1 _R29
#define JIT_V2 _R28
#define JIT_V3 _R28
#define JIT_V4 _R26
#define JIT_V5 _R25
#define JIT_V6 _R24
#define JIT_V7 _R23
#define JIT_V8 _R22
#define JIT_V9 _R21
#define JIT_V10 _R20
#define JIT_V11 _R19
#define JIT_V12 _R18
#define JIT_V13 _R17
#define JIT_V14 _R16
#define JIT_V15 _R15
#define JIT_V16 _R14
#define JIT_V0 jit_v(0)
#define JIT_V1 jit_v(1)
#define JIT_V2 jit_v(2)
#define JIT_V3 jit_v(3)
#define JIT_V4 jit_v(4)
#define JIT_V5 jit_v(5)
#define JIT_V6 jit_v(6)
#define JIT_V7 jit_v(7)
#define JIT_V8 jit_v(8)
#define JIT_V9 jit_v(9)
#define JIT_V10 jit_v(10)
#define JIT_V11 jit_v(11)
#define JIT_V12 jit_v(12)
#define JIT_V13 jit_v(13)
#if __WORDSIZE == 32
# define JIT_V14 jit_v(14)
# define JIT_V15 jit_v(15)
# define JIT_V16 jit_v(16)
#endif
_R14, _R15, _R16, _R17, _R18, _R19, _R20, _R21,
_R22, _R23, _R24, _R25, _R26, _R27, _R28, _R29,
_R30,

View file

@ -66,7 +66,7 @@
# else
# define JIT_FRET _R0
# endif
#elif defined(__ppc__)
#elif defined(__ppc__) || defined(__powerpc__)
# define JIT_SP _R1
# define JIT_RET _R3
# define JIT_FRET _F1
@ -347,6 +347,16 @@ struct jit_compiler {
jit_int32_t values[1024]; /* pending constants */
jit_word_t patches[2048];
} consts;
#elif __powerpc64__
/* Keep track of prolog addresses, just for the sake of making
* jit that starts with a jump to a "main" label work like other
* backends. */
struct {
jit_word_t *ptr;
jit_word_t offset;
jit_word_t length;
} prolog;
jit_bool_t jump;
#endif
};

View file

@ -1437,6 +1437,7 @@ _emit_code(jit_state_t *_jit)
temp->code == jit_code_epilog)
temp->flag &= ~jit_flag_patch;
}
temp->flag &= ~jit_flag_patch;
node = undo.node;
_jit->pc.w = undo.word;
invalidate_consts();

View file

@ -81,6 +81,12 @@ jit_init_debug(void)
if (jit_cpu.thumb)
disasm_info.disassembler_options = "force-thumb";
# endif
# if defined(__powerpc64__)
disasm_info.arch = bfd_arch_powerpc;
disasm_info.mach = bfd_mach_ppc64;
disasm_info.disassembler_options = "64";
disassemble_init_powerpc(&disasm_info);
# endif
# if defined(__sparc__)
disasm_info.endian = disasm_info.display_endian = BFD_ENDIAN_BIG;
#endif

View file

@ -1186,6 +1186,7 @@ _emit_code(jit_state_t *_jit)
temp->code == jit_code_epilog)
temp->flag &= ~jit_flag_patch;
}
temp->flag &= ~jit_flag_patch;
node = undo.node;
_jit->pc.w = undo.word;
_jitc->patches.offset = undo.patch_offset;

File diff suppressed because it is too large Load diff

View file

@ -36,6 +36,10 @@ static void _FXFL(jit_state_t*,int,int,int,int,int);
# define FCTIW_(d,b) FX_(63,d,0,b,14)
# define FCTIWZ(d,b) FX(63,d,0,b,15)
# define FCTIWZ_(d,b) FX_(63,d,0,b,15)
# define FCTID(d,b) FX(63,d,0,b,814)
# define FCTID_(d,b) FX_(63,d,0,b,814)
# define FCTIDZ(d,b) FX(63,d,0,b,815)
# define FCTIDZ_(d,b) FX_(63,d,0,b,815)
# define FDIV(d,a,b) FA(63,d,a,b,0,18)
# define FDIV_(d,a,b) FA_(63,d,a,b,0,18)
# define FDIVS(d,a,b) FA(59,d,a,b,0,18)
@ -121,10 +125,20 @@ static void _movi_d(jit_state_t*,jit_int32_t,jit_float64_t*);
# define extr_f(r0,r1) extr_d(r0,r1)
# define extr_d(r0,r1) _extr_d(_jit,r0,r1)
static void _extr_d(jit_state_t*,jit_int32_t,jit_int32_t);
# define truncr_f_i(r0,r1) truncr_d(r0,r1)
# define truncr_d_i(r0,r1) truncr_d(r0,r1)
# define truncr_d(r0,r1) _truncr_d(_jit,r0,r1)
static void _truncr_d(jit_state_t*,jit_int32_t,jit_int32_t);
# define truncr_f(r0,r1) truncr_d(r0,r1)
# define truncr_f_i(r0,r1) truncr_d_i(r0,r1)
# define truncr_d_i(r0,r1) _truncr_d_i(_jit,r0,r1)
static void _truncr_d_i(jit_state_t*,jit_int32_t,jit_int32_t);
# if __WORDSIZE == 32
# define truncr_d(r0,r1) truncr_d_i(r0,r1)
# else
# define truncr_d(r0,r1) truncr_d_l(r0,r1)
# define truncr_f_l(r0,r1) truncr_d_l(r0,r1)
# define truncr_d_l(r0,r1) _truncr_d_l(_jit,r0,r1)
static void _truncr_d_l(jit_state_t*,jit_int32_t,jit_int32_t);
# endif
# define extr_d_f(r0,r1) FRSP(r0,r1)
# define extr_f_d(r0,r1) movr_d(r0,r1)
@ -436,6 +450,7 @@ _movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0)
static void
_extr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
# if __WORDSIZE == 32
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
rshi(rn(reg), r1, 31);
@ -443,22 +458,39 @@ _extr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
stxi(alloca_offset - 4, _FP_REGNO, r1);
stxi(alloca_offset - 8, _FP_REGNO, rn(reg));
jit_unget_reg(reg);
# else
stxi(alloca_offset - 8, _FP_REGNO, r1);
# endif
ldxi_d(r0, _FP_REGNO, alloca_offset - 8);
FCFID(r0, r0);
}
static void
_truncr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
_truncr_d_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg;
reg = jit_get_reg(jit_class_fpr);
FCTIWZ(rn(reg), r1);
/* use reserved 8 bytes area */
stxi_d(alloca_offset - 8, _FP_REGNO, rn(reg));
ldxi(r0, _FP_REGNO, alloca_offset - 4);
ldxi_i(r0, _FP_REGNO, alloca_offset - 4);
jit_unget_reg(reg);
}
# if __WORDSIZE == 64
static void
_truncr_d_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg;
reg = jit_get_reg(jit_class_fpr);
FCTIDZ(rn(reg), r1);
/* use reserved 8 bytes area */
stxi_d(alloca_offset - 8, _FP_REGNO, rn(reg));
ldxi(r0, _FP_REGNO, alloca_offset - 8);
jit_unget_reg(reg);
}
# endif
# define fpr_opi(name, type, size) \
static void \
_##name##i_##type(jit_state_t *_jit, \
@ -843,8 +875,8 @@ _ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
jit_word_t lo, hi;
if (can_sign_extend_short_p(i0))
LFS(r0, _R0_REGNO, i0);
else {
hi = (i0 >> 16) + ((jit_uint16_t)i0 >> 15);
else if (can_sign_extend_int_p(i0)) {
hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15));
lo = (jit_int16_t)(i0 - (hi << 16));
reg = jit_get_reg(jit_class_gpr);
if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr);
@ -853,6 +885,12 @@ _ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
jit_unget_reg(reg);
if (inv) jit_unget_reg(_R0);
}
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
ldr_f(r0, rn(reg));
jit_unget_reg(reg);
}
}
static void
@ -863,8 +901,8 @@ _ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
jit_word_t lo, hi;
if (can_sign_extend_short_p(i0))
LFD(r0, _R0_REGNO, i0);
else {
hi = (i0 >> 16) + ((jit_uint16_t)i0 >> 15);
else if (can_sign_extend_int_p(i0)) {
hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15));
lo = (jit_int16_t)(i0 - (hi << 16));
reg = jit_get_reg(jit_class_gpr);
if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr);
@ -873,6 +911,12 @@ _ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
jit_unget_reg(reg);
if (inv) jit_unget_reg(_R0);
}
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
ldr_d(r0, rn(reg));
jit_unget_reg(reg);
}
}
static void
@ -967,8 +1011,8 @@ _sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
jit_word_t lo, hi;
if (can_sign_extend_short_p(i0))
STFS(r0, _R0_REGNO, i0);
else {
hi = (i0 >> 16) + ((jit_uint16_t)i0 >> 15);
else if (can_sign_extend_int_p(i0)) {
hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15));
lo = (jit_int16_t)(i0 - (hi << 16));
reg = jit_get_reg(jit_class_gpr);
if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr);
@ -977,6 +1021,12 @@ _sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
jit_unget_reg(reg);
if (inv) jit_unget_reg(_R0);
}
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
str_f(rn(reg), r0);
jit_unget_reg(reg);
}
}
static void
@ -987,8 +1037,8 @@ _sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
jit_word_t lo, hi;
if (can_sign_extend_short_p(i0))
STFD(r0, _R0_REGNO, i0);
else {
hi = (i0 >> 16) + ((jit_uint16_t)i0 >> 15);
else if (can_sign_extend_int_p(i0)) {
hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15));
lo = (jit_int16_t)(i0 - (hi << 16));
reg = jit_get_reg(jit_class_gpr);
if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr);
@ -997,6 +1047,12 @@ _sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
jit_unget_reg(reg);
if (inv) jit_unget_reg(_R0);
}
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
str_d(rn(reg), r0);
jit_unget_reg(reg);
}
}
static void

View file

@ -37,10 +37,17 @@ extern void __clear_cache(void *, void *);
*/
jit_register_t _rvs[] = {
{ rc(gpr) | 0, "r0" },
#if __WORDSIZE == 32
{ rc(gpr) | 11, "r11" },
{ rc(gpr) | 12, "r12" },
{ rc(gpr) | 13, "r13" },
{ rc(gpr) | 2, "r2" },
#else
{ rc(sav) | 11, "r11" }, /* env */
{ rc(sav) | 12, "r12" }, /* exception */
{ rc(sav) | 13, "r13" }, /* thread */
{ rc(sav) | 2, "r2" }, /* toc */
#endif
{ rc(sav) | rc(gpr) | 14, "r14" },
{ rc(sav) | rc(gpr) | 15, "r15" },
{ rc(sav) | rc(gpr) | 16, "r16" },
@ -270,16 +277,21 @@ _jit_arg_f(jit_state_t *_jit)
assert(_jitc->function);
if (_jitc->function->self.argf < 13)
offset = _jitc->function->self.argf++;
else
else {
#if __WORDSIZE == 32
offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_float32_t);
#else
offset = _jitc->function->self.size + 4;
#endif
}
_jitc->function->self.size += sizeof(jit_word_t);
return (jit_new_node_w(jit_code_arg_f, offset));
}
jit_bool_t
_jit_arg_f_reg_p(jit_state_t *_jit, jit_int32_t offset)
{
return (jit_arg_d_reg_p(offset));
return (offset >= 0 && offset < 13);
}
jit_node_t *
@ -298,7 +310,7 @@ _jit_arg_d(jit_state_t *_jit)
jit_bool_t
_jit_arg_d_reg_p(jit_state_t *_jit, jit_int32_t offset)
{
return (offset >= 0 && offset < 13);
return (jit_arg_f_reg_p(offset));
}
void
@ -364,8 +376,13 @@ _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)
{
if (v->u.w < 8)
if (v->u.w < 8) {
#if __WORDSIZE == 32
jit_movr(u, JIT_RA0 - v->u.w);
#else
jit_extr_i(u, JIT_RA0 - v->u.w);
#endif
}
else {
#if __BYTE_ORDER == __LITTLE_ENDIAN
jit_ldxi_i(u, JIT_FP, v->u.w);
@ -460,9 +477,14 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
++_jitc->function->call.argf;
if (!(_jitc->function->call.call & jit_call_varargs)) {
/* in case of excess arguments */
if (_jitc->function->call.argi < 8)
if (_jitc->function->call.argi < 8) {
#if __WORDSIZE == 32
_jitc->function->call.argi += 2;
_jitc->function->call.size += sizeof(jit_float32_t);
#else
_jitc->function->call.argi++;
#endif
}
_jitc->function->call.size += sizeof(jit_word_t);
return;
}
}
@ -472,13 +494,21 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
alloca_offset - 8);
_jitc->function->call.argi++;
#if __WORDSIZE == 32
jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
alloca_offset - 4);
_jitc->function->call.argi++;
#endif
}
else
else {
#if __WORDSIZE == 32
jit_stxi_f(_jitc->function->call.size + params_offset, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_float32_t);
#else
jit_stxi_f(_jitc->function->call.size + params_offset + 4,
JIT_SP, u);
#endif
}
_jitc->function->call.size += sizeof(jit_word_t);
}
void
@ -492,9 +522,14 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
++_jitc->function->call.argf;
if (!(_jitc->function->call.call & jit_call_varargs)) {
/* in case of excess arguments */
if (_jitc->function->call.argi < 8)
if (_jitc->function->call.argi < 8) {
#if __WORDSIZE == 32
_jitc->function->call.argi += 2;
_jitc->function->call.size += sizeof(jit_float32_t);
#else
_jitc->function->call.argi++;
#endif
}
_jitc->function->call.size += sizeof(jit_word_t);
return;
}
}
@ -506,13 +541,21 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
alloca_offset - 8);
_jitc->function->call.argi++;
#if __WORDSIZE == 32
jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
alloca_offset - 4);
_jitc->function->call.argi++;
#endif
}
else
else {
#if __WORDSIZE == 32
jit_stxi_f(_jitc->function->call.size + params_offset, JIT_SP, regno);
_jitc->function->call.size += sizeof(jit_float32_t);
#else
jit_stxi_f(_jitc->function->call.size + params_offset + 4,
JIT_SP, regno);
#endif
}
_jitc->function->call.size += sizeof(jit_word_t);
jit_unget_reg(regno);
}
@ -525,8 +568,13 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
++_jitc->function->call.argf;
if (!(_jitc->function->call.call & jit_call_varargs)) {
/* in case of excess arguments */
if (_jitc->function->call.argi < 8)
if (_jitc->function->call.argi < 8) {
#if __WORDSIZE == 32
_jitc->function->call.argi += 2;
#else
_jitc->function->call.argi++;
#endif
}
_jitc->function->call.size += sizeof(jit_float64_t);
return;
}
@ -537,9 +585,11 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
alloca_offset - 8);
_jitc->function->call.argi++;
#if __WORDSIZE == 32
jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
alloca_offset - 4);
_jitc->function->call.argi++;
#endif
}
else
jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, u);
@ -557,8 +607,13 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
++_jitc->function->call.argf;
if (!(_jitc->function->call.call & jit_call_varargs)) {
/* in case of excess arguments */
if (_jitc->function->call.argi < 8)
if (_jitc->function->call.argi < 8) {
#if __WORDSIZE == 32
_jitc->function->call.argi += 2;
#else
_jitc->function->call.argi++;
#endif
}
_jitc->function->call.size += sizeof(jit_float64_t);
return;
}
@ -571,9 +626,11 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
alloca_offset - 8);
_jitc->function->call.argi++;
#if __WORDSIZE == 32
jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
alloca_offset - 4);
_jitc->function->call.argi++;
#endif
}
else
jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, regno);
@ -704,7 +761,10 @@ _emit_code(jit_state_t *_jit)
struct {
jit_node_t *node;
jit_word_t word;
jit_int32_t patch_offset;
jit_word_t patch_offset;
#if __powerpc64__
jit_word_t prolog_offset;
#endif
} undo;
_jitc->function = NULL;
@ -714,6 +774,14 @@ _emit_code(jit_state_t *_jit)
undo.word = 0;
undo.node = NULL;
undo.patch_offset = 0;
#if __powerpc64__
undo.prolog_offset = 0;
/* code may start with a jump so add an initial function descriptor */
il(_jit->pc.w + 24); /* addr */
il(0); /* toc */
il(0); /* env */
#endif
#define case_rr(name, type) \
case jit_code_##name##r##type: \
@ -859,6 +927,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(hton,);
case_rr(neg,);
case_rr(com,);
@ -882,6 +954,10 @@ _emit_code(jit_state_t *_jit)
break;
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);
@ -962,6 +1038,16 @@ _emit_code(jit_state_t *_jit)
case_rw(ld, _i);
case_rrr(ldx, _i);
case_rrw(ldx, _i);
#if __WORDSIZE == 64
case_rr(ld, _ui);
case_rw(ld, _ui);
case_rrr(ldx, _ui);
case_rrw(ldx, _ui);
case_rr(ld, _l);
case_rw(ld, _l);
case_rrr(ldx, _l);
case_rrw(ldx, _l);
#endif
case_rr(st, _c);
case_wr(st, _c);
case_rrr(stx, _c);
@ -974,6 +1060,12 @@ _emit_code(jit_state_t *_jit)
case_wr(st, _i);
case_rrr(stx, _i);
case_wrr(stx, _i);
#if __WORDSIZE == 64
case_rr(st, _l);
case_wr(st, _l);
case_rrr(stx, _l);
case_wrr(stx, _l);
#endif
case_rr(mov, _f);
case jit_code_movi_f:
assert(node->flag & jit_flag_data);
@ -1142,6 +1234,10 @@ _emit_code(jit_state_t *_jit)
jmpr(rn(node->u.w));
break;
case jit_code_jmpi:
#if __powerpc64__
if (_jit->pc.uc == _jit->code.ptr + 24)
_jitc->jump = 1;
#endif
temp = node->u.n;
assert(temp->code == jit_code_label ||
temp->code == jit_code_epilog);
@ -1173,8 +1269,29 @@ _emit_code(jit_state_t *_jit)
undo.node = node;
undo.word = _jit->pc.w;
undo.patch_offset = _jitc->patches.offset;
#if __powerpc64__
undo.prolog_offset = _jitc->prolog.offset;
#endif
restart_function:
_jitc->again = 0;
#if __powerpc64__
if (_jitc->jump) {
/* remember prolog to hide offset adjustment for a jump
* to the start of a function, what is expected to be
* a common practice as first jit instruction */
if (_jitc->prolog.offset >= _jitc->prolog.length) {
_jitc->prolog.length += 16;
_jitc->prolog.ptr = realloc(_jitc->prolog.ptr,
_jitc->prolog.length *
sizeof(jit_word_t));
}
_jitc->prolog.ptr[_jitc->prolog.offset++] = _jit->pc.w;
/* function descriptor */
il(_jit->pc.w + 24); /* addr */
il(0); /* toc */
il(0); /* env */
}
#endif
prolog(node);
break;
case jit_code_epilog:
@ -1186,9 +1303,13 @@ _emit_code(jit_state_t *_jit)
temp->code == jit_code_epilog)
temp->flag &= ~jit_flag_patch;
}
temp->flag &= ~jit_flag_patch;
node = undo.node;
_jit->pc.w = undo.word;
_jitc->patches.offset = undo.patch_offset;
#if __powerpc64__
_jitc->prolog.offset = undo.prolog_offset;
#endif
goto restart_function;
}
/* remember label is defined */

View file

@ -1076,6 +1076,7 @@ _emit_code(jit_state_t *_jit)
temp->code == jit_code_epilog)
temp->flag &= ~jit_flag_patch;
}
temp->flag &= ~jit_flag_patch;
node = undo.node;
_jit->pc.w = undo.word;
_jitc->patches.offset = undo.patch_offset;

View file

@ -1575,6 +1575,7 @@ _emit_code(jit_state_t *_jit)
temp->code == jit_code_epilog)
temp->flag &= ~jit_flag_patch;
}
temp->flag &= ~jit_flag_patch;
node = undo.node;
_jit->pc.w = undo.word;
_jitc->patches.offset = undo.patch_offset;

View file

@ -587,6 +587,11 @@ _jit_clear_state(jit_state_t *_jit)
_jitc->data_info.ptr = NULL;
#endif
#if __powerpc64__
free(_jitc->prolog.ptr);
_jitc->prolog.ptr = NULL;
#endif
free(_jitc);
}
@ -1402,7 +1407,9 @@ _jit_emit(jit_state_t *_jit)
for (;;) {
if ((code = emit_code()) == NULL) {
for (node = _jitc->head; node; node = node->next) {
if (node->code == jit_code_label && node->link)
if (node->link &&
(node->code == jit_code_label ||
node->code == jit_code_epilog))
node->flag &= ~jit_flag_patch;
}
++mult;
@ -1439,7 +1446,7 @@ _jit_emit(jit_state_t *_jit)
result = mprotect(_jit->code.ptr, _jit->code.length, PROT_READ | PROT_EXEC);
assert(result == 0);
return (code);
return (_jit->code.ptr);
}
/* Compute initial reglive and regmask set values of a basic block.
@ -2605,7 +2612,7 @@ _patch_register(jit_state_t *_jit, jit_node_t *node, jit_node_t *link,
# include "jit_mips.c"
#elif defined(__arm__)
# include "jit_arm.c"
#elif defined(__ppc__)
#elif defined(__ppc__) || defined(__powerpc__)
# include "jit_ppc.c"
#elif defined(__sparc__)
# include "jit_sparc.c"