mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-06 20:20:20 +02:00
PPC: Add initial powerpc le support.
This commit is contained in:
parent
3f397228f5
commit
6e34a532ae
4 changed files with 57 additions and 10 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
2014-11-20 Paulo Andrade <pcpa@gnu.org>
|
||||||
|
|
||||||
|
* include/lightning/jit_ppc.h, lib/jit_ppc-cpu.c,
|
||||||
|
lib/jit_ppc.c: Add initial powerpc le support.
|
||||||
|
|
||||||
2014-11-20 Paulo Andrade <pcpa@gnu.org>
|
2014-11-20 Paulo Andrade <pcpa@gnu.org>
|
||||||
|
|
||||||
* lib/jit_disasm.c: Change thumb or arm disassemble based on
|
* lib/jit_disasm.c: Change thumb or arm disassemble based on
|
||||||
|
|
|
@ -23,6 +23,13 @@
|
||||||
#define JIT_HASH_CONSTS 1
|
#define JIT_HASH_CONSTS 1
|
||||||
#define JIT_NUM_OPERANDS 3
|
#define JIT_NUM_OPERANDS 3
|
||||||
|
|
||||||
|
#if __powerpc__
|
||||||
|
# if _CALL_ELF == 2
|
||||||
|
/* __BYTE_ORDER == __LITTLE_ENDIAN */
|
||||||
|
# define ABI_ELFv2 1
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Types
|
* Types
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
# define _SP_REGNO 1
|
# define _SP_REGNO 1
|
||||||
# define _R2_REGNO 2
|
# define _R2_REGNO 2
|
||||||
# define _R11_REGNO 11
|
# define _R11_REGNO 11
|
||||||
|
# define _R12_REGNO 12
|
||||||
# define _FP_REGNO 31
|
# define _FP_REGNO 31
|
||||||
# if __WORDSIZE == 32
|
# if __WORDSIZE == 32
|
||||||
# define ldr(r0,r1) ldr_i(r0,r1)
|
# define ldr(r0,r1) ldr_i(r0,r1)
|
||||||
|
@ -325,8 +326,8 @@ static void _FXS(jit_state_t*,int,int,int,int,int,int,int);
|
||||||
# define NOP() ORI(0,0,0)
|
# define NOP() ORI(0,0,0)
|
||||||
# define ORIS(d,a,u) FDu(25,a,d,u)
|
# define ORIS(d,a,u) FDu(25,a,d,u)
|
||||||
# define RFI() FXL(19,0,0,50)
|
# define RFI() FXL(19,0,0,50)
|
||||||
# define RLWIMI(d,s,h,b,e) FM(20,s,a,h,b,e,0)
|
# define RLWIMI(d,s,h,b,e) FM(20,s,d,h,b,e,0)
|
||||||
# define RLWIMI_(d,s,h,b,e) FM(20,s,a,h,b,e,1)
|
# define RLWIMI_(d,s,h,b,e) FM(20,s,d,h,b,e,1)
|
||||||
# define INSLWI(a,s,n,b) RLWIMI(a,s,32-b,b,b+n-1)
|
# define INSLWI(a,s,n,b) RLWIMI(a,s,32-b,b,b+n-1)
|
||||||
# define INSRWI(a,s,n,b) RLWIMI(a,s,32-(b+n),b,(b+n)-1)
|
# define INSRWI(a,s,n,b) RLWIMI(a,s,32-(b+n),b,(b+n)-1)
|
||||||
# define RLWINM(a,s,h,b,e) FM(21,s,a,h,b,e,0)
|
# define RLWINM(a,s,h,b,e) FM(21,s,a,h,b,e,0)
|
||||||
|
@ -472,7 +473,8 @@ static jit_word_t _movi_p(jit_state_t*,jit_int32_t,jit_word_t);
|
||||||
# if __BYTE_ORDER == __BIG_ENDIAN
|
# if __BYTE_ORDER == __BIG_ENDIAN
|
||||||
# define htonr(r0,r1) movr(r0,r1)
|
# define htonr(r0,r1) movr(r0,r1)
|
||||||
# else
|
# else
|
||||||
# error need htonr implementation
|
# define htonr(r0,r1) _htonr(_jit,r0,r1)
|
||||||
|
static void _htonr(jit_state_t*,jit_int32_t,jit_int32_t);
|
||||||
# endif
|
# endif
|
||||||
# define addr(r0,r1,r2) ADD(r0,r1,r2)
|
# define addr(r0,r1,r2) ADD(r0,r1,r2)
|
||||||
# define addi(r0,r1,i0) _addi(_jit,r0,r1,i0)
|
# define addi(r0,r1,i0) _addi(_jit,r0,r1,i0)
|
||||||
|
@ -1044,6 +1046,35 @@ _movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
|
||||||
return (word);
|
return (word);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||||
|
static void
|
||||||
|
_htonr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
|
||||||
|
{
|
||||||
|
jit_int32_t reg;
|
||||||
|
# if __WORDSIZE == 64
|
||||||
|
jit_int32_t top;
|
||||||
|
top = jit_get_reg(jit_class_gpr);
|
||||||
|
rshi_u(rn(top), r1, 32);
|
||||||
|
# endif
|
||||||
|
reg = jit_get_reg(jit_class_gpr);
|
||||||
|
ROTLWI(rn(reg), r1, 8);
|
||||||
|
RLWIMI(rn(reg), r1, 24, 0, 7);
|
||||||
|
RLWIMI(rn(reg), r1, 24, 16, 23);
|
||||||
|
# if __WORDSIZE == 32
|
||||||
|
CLRLDI(r0, rn(reg), 32);
|
||||||
|
# else
|
||||||
|
lshi(r0, rn(reg), 32);
|
||||||
|
ROTLWI(rn(reg), rn(top), 8);
|
||||||
|
RLWIMI(rn(reg), rn(top), 24, 0, 7);
|
||||||
|
RLWIMI(rn(reg), rn(top), 24, 16, 23);
|
||||||
|
orr(r0, r0, rn(reg));
|
||||||
|
movr(r0, rn(top));
|
||||||
|
jit_unget_reg(top);
|
||||||
|
# endif
|
||||||
|
jit_unget_reg(reg);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_addi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
_addi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
||||||
{
|
{
|
||||||
|
@ -3030,6 +3061,9 @@ static void
|
||||||
_callr(jit_state_t *_jit, jit_int32_t r0)
|
_callr(jit_state_t *_jit, jit_int32_t r0)
|
||||||
{
|
{
|
||||||
# if __powerpc__
|
# if __powerpc__
|
||||||
|
# if ABI_ELFv2
|
||||||
|
movr(_R12_REGNO, r0);
|
||||||
|
# else
|
||||||
stxi(sizeof(void*) * 5, _SP_REGNO, _R2_REGNO);
|
stxi(sizeof(void*) * 5, _SP_REGNO, _R2_REGNO);
|
||||||
/* FIXME Pretend to not know about r11? */
|
/* FIXME Pretend to not know about r11? */
|
||||||
if (r0 == _R0_REGNO) {
|
if (r0 == _R0_REGNO) {
|
||||||
|
@ -3042,12 +3076,13 @@ _callr(jit_state_t *_jit, jit_int32_t r0)
|
||||||
ldxi(_R11_REGNO, r0, sizeof(void*) * 2);
|
ldxi(_R11_REGNO, r0, sizeof(void*) * 2);
|
||||||
}
|
}
|
||||||
ldr(r0, r0);
|
ldr(r0, r0);
|
||||||
|
# endif
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
MTCTR(r0);
|
MTCTR(r0);
|
||||||
BCTRL();
|
BCTRL();
|
||||||
|
|
||||||
# if __powerpc__
|
# if __powerpc__ && !ABI_ELFv2
|
||||||
ldxi(_R2_REGNO, _SP_REGNO, sizeof(void*) * 5);
|
ldxi(_R2_REGNO, _SP_REGNO, sizeof(void*) * 5);
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
@ -3219,7 +3254,7 @@ _patch_at(jit_state_t *_jit, jit_word_t instr, jit_word_t label)
|
||||||
u.i[0] = (u.i[0] & ~0xfffd) | (d & 0xfffe);
|
u.i[0] = (u.i[0] & ~0xfffd) | (d & 0xfffe);
|
||||||
break;
|
break;
|
||||||
case 18: /* Bx */
|
case 18: /* Bx */
|
||||||
#if __powerpc__
|
#if __powerpc__ && !ABI_ELFv2
|
||||||
if (_jitc->jump && (!(u.i[0] & 1))) { /* jmpi label */
|
if (_jitc->jump && (!(u.i[0] & 1))) { /* jmpi label */
|
||||||
/* zero is used for toc and env, so, quick check
|
/* zero is used for toc and env, so, quick check
|
||||||
* if this is a "jmpi main" like initial jit
|
* if this is a "jmpi main" like initial jit
|
||||||
|
|
|
@ -776,7 +776,7 @@ _emit_code(jit_state_t *_jit)
|
||||||
undo.node = NULL;
|
undo.node = NULL;
|
||||||
undo.patch_offset = 0;
|
undo.patch_offset = 0;
|
||||||
|
|
||||||
#if __powerpc__
|
#if __powerpc__ && !ABI_ELFv2
|
||||||
undo.prolog_offset = 0;
|
undo.prolog_offset = 0;
|
||||||
for (node = _jitc->head; node; node = node->next)
|
for (node = _jitc->head; node; node = node->next)
|
||||||
if (node->code != jit_code_label &&
|
if (node->code != jit_code_label &&
|
||||||
|
@ -1255,7 +1255,7 @@ _emit_code(jit_state_t *_jit)
|
||||||
break;
|
break;
|
||||||
case jit_code_jmpi:
|
case jit_code_jmpi:
|
||||||
if (node->flag & jit_flag_node) {
|
if (node->flag & jit_flag_node) {
|
||||||
#if __powerpc__
|
#if __powerpc__ && !ABI_ELFv2
|
||||||
if (_jit->pc.uc == _jit->code.ptr + sizeof(void*) * 3)
|
if (_jit->pc.uc == _jit->code.ptr + sizeof(void*) * 3)
|
||||||
_jitc->jump = 1;
|
_jitc->jump = 1;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1292,12 +1292,12 @@ _emit_code(jit_state_t *_jit)
|
||||||
undo.node = node;
|
undo.node = node;
|
||||||
undo.word = _jit->pc.w;
|
undo.word = _jit->pc.w;
|
||||||
undo.patch_offset = _jitc->patches.offset;
|
undo.patch_offset = _jitc->patches.offset;
|
||||||
#if __powerpc__
|
#if __powerpc__ && !ABI_ELFv2
|
||||||
undo.prolog_offset = _jitc->prolog.offset;
|
undo.prolog_offset = _jitc->prolog.offset;
|
||||||
#endif
|
#endif
|
||||||
restart_function:
|
restart_function:
|
||||||
_jitc->again = 0;
|
_jitc->again = 0;
|
||||||
#if __powerpc__
|
#if __powerpc__ && !ABI_ELFv2
|
||||||
if (_jitc->jump && !_jitc->function->assume_frame) {
|
if (_jitc->jump && !_jitc->function->assume_frame) {
|
||||||
/* remember prolog to hide offset adjustment for a jump
|
/* remember prolog to hide offset adjustment for a jump
|
||||||
* to the start of a function, what is expected to be
|
* to the start of a function, what is expected to be
|
||||||
|
@ -1332,7 +1332,7 @@ _emit_code(jit_state_t *_jit)
|
||||||
node = undo.node;
|
node = undo.node;
|
||||||
_jit->pc.w = undo.word;
|
_jit->pc.w = undo.word;
|
||||||
_jitc->patches.offset = undo.patch_offset;
|
_jitc->patches.offset = undo.patch_offset;
|
||||||
#if __powerpc__
|
#if __powerpc__ && !ABI_ELFv2
|
||||||
_jitc->prolog.offset = undo.prolog_offset;
|
_jitc->prolog.offset = undo.prolog_offset;
|
||||||
#endif
|
#endif
|
||||||
goto restart_function;
|
goto restart_function;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue