[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Guile-commits] 377/437: aarch64: Add initial jit_va_ calls to aarch64
From: |
Andy Wingo |
Subject: |
[Guile-commits] 377/437: aarch64: Add initial jit_va_ calls to aarch64 |
Date: |
Mon, 2 Jul 2018 05:14:59 -0400 (EDT) |
wingo pushed a commit to branch lightning
in repository guile.
commit 0986ae8a862028e0acc95795de13254fe1559638
Author: pcpa <address@hidden>
Date: Thu Apr 30 17:40:14 2015 -0300
aarch64: Add initial jit_va_ calls to aarch64
* lib/jit_aarch64-cpu.c, lib/jit_aarch64-fpu.c,
lib/jit_aarch64.c: Add base support to jit vararg
functions to the aarch64 backend.
---
ChangeLog | 6 +++
lib/jit_aarch64-cpu.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++
lib/jit_aarch64-fpu.c | 55 +++++++++++++++++++++++++
lib/jit_aarch64.c | 65 +++++++++++++++++++++++++++++
4 files changed, 238 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index 0354685..7ace2c5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2015-05-30 Paulo Andrade <address@hidden>
+
+ * lib/jit_aarch64-cpu.c, lib/jit_aarch64-fpu.c,
+ lib/jit_aarch64.c: Add base support to jit vararg
+ functions to the aarch64 backend.
+
2015-05-27 Paulo Andrade <address@hidden>
* include/lightning.h, include/lightning/jit_private.h,
diff --git a/lib/jit_aarch64-cpu.c b/lib/jit_aarch64-cpu.c
index 2363d28..4b15629 100644
--- a/lib/jit_aarch64-cpu.c
+++ b/lib/jit_aarch64-cpu.c
@@ -212,6 +212,8 @@ typedef union {
} instr_t;
# define stack_framesize 160
# define ii(i) *_jit->pc.ui++ = i
+# define ldr(r0,r1) ldr_l(r0,r1)
+# define ldxr(r0,r1,r2) ldxr_l(r0,r1,r2)
# define ldxi(r0,r1,i0) ldxi_l(r0,r1,i0)
# define stxi(i0,r0,r1) stxi_l(i0,r0,r1)
# define FP_REGNO 0x1d
@@ -782,6 +784,10 @@ static jit_word_t _calli_p(jit_state_t*,jit_word_t);
static void _prolog(jit_state_t*,jit_node_t*);
# define epilog(i0) _epilog(_jit,i0)
static void _epilog(jit_state_t*,jit_node_t*);
+# define vastart(r0) _vastart(_jit, r0)
+static void _vastart(jit_state_t*, jit_int32_t);
+# define vaarg(r0, r1) _vaarg(_jit, r0, r1)
+static void _vaarg(jit_state_t*, jit_int32_t, jit_int32_t);
# define patch_at(jump,label) _patch_at(_jit,jump,label)
static void _patch_at(jit_state_t*,jit_word_t,jit_word_t);
#endif
@@ -2241,6 +2247,24 @@ _prolog(jit_state_t *_jit, jit_node_t *node)
stxi_i(_jitc->function->aoffoff, FP_REGNO, rn(reg));
jit_unget_reg(reg);
}
+
+ if (_jitc->function->self.call & jit_call_varargs) {
+ /* Save gp registers in the save area, if any is a vararg */
+ for (reg = 8 - _jitc->function->vagp / -8;
+ jit_arg_reg_p(reg); ++reg)
+ stxi(_jitc->function->vaoff + offsetof(jit_va_list_t, x0) +
+ reg * 8, FP_REGNO, rn(JIT_RA0 - reg));
+
+ for (reg = 8 - _jitc->function->vafp / -16;
+ jit_arg_f_reg_p(reg); ++reg)
+ /* Save fp registers in the save area, if any is a vararg */
+ /* Note that the full 16 byte register 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). */
+ stxi_d(_jitc->function->vaoff + offsetof(jit_va_list_t, q0) +
+ reg * 16 + offsetof(jit_qreg_t, l), FP_REGNO, rn(_V0 - reg));
+ }
}
static void
@@ -2286,6 +2310,94 @@ _epilog(jit_state_t *_jit, jit_node_t *node)
}
static void
+_vastart(jit_state_t *_jit, jit_int32_t r0)
+{
+ jit_int32_t reg;
+
+ assert(_jitc->function->self.call & jit_call_varargs);
+
+ /* Return jit_va_list_t in the register argument */
+ addi(r0, FP_REGNO, _jitc->function->vaoff);
+
+ reg = jit_get_reg(jit_class_gpr);
+
+ /* Initialize stack pointer to the first stack argument. */
+ addi(rn(reg), FP_REGNO, _jitc->function->self.size);
+ stxi(offsetof(jit_va_list_t, stack), r0, rn(reg));
+
+ /* Initialize gp top pointer to the first stack argument. */
+ addi(rn(reg), r0, va_gp_top_offset);
+ stxi(offsetof(jit_va_list_t, gptop), r0, rn(reg));
+
+ /* Initialize fp top pointer to the first stack argument. */
+ addi(rn(reg), r0, va_fp_top_offset);
+ stxi(offsetof(jit_va_list_t, fptop), r0, rn(reg));
+
+ /* Initialize gp offset in the save area. */
+ movi(rn(reg), _jitc->function->vagp);
+ stxi_i(offsetof(jit_va_list_t, gpoff), r0, rn(reg));
+
+ /* Initialize fp offset in the save area. */
+ movi(rn(reg), _jitc->function->vafp);
+ stxi_i(offsetof(jit_va_list_t, fpoff), r0, rn(reg));
+
+ jit_unget_reg(reg);
+}
+
+static void
+_vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
+{
+ jit_word_t ge_code;
+ jit_word_t lt_code;
+ jit_int32_t rg0, rg1;
+
+ 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. */
+ ge_code = bgei(_jit->pc.w, rn(rg0), 0);
+
+ /* Load the gp save pointer in the second temporary. */
+ ldxi(rn(rg1), r1, offsetof(jit_va_list_t, gptop));
+
+ /* 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. */
+ lt_code = jmpi_p(_jit->pc.w);
+
+ /* Where to land if argument is in overflow area. */
+ patch_at(ge_code, _jit->pc.w);
+
+ /* Load stack pointer. */
+ ldxi(rn(rg0), r1, offsetof(jit_va_list_t, stack));
+
+ /* Load argument. */
+ ldr(r0, rn(rg0));
+
+ /* Update stack pointer. */
+ addi(rn(rg0), rn(rg0), 8);
+ stxi(offsetof(jit_va_list_t, stack), r1, rn(rg0));
+
+ /* Where to land if argument is in gp save area. */
+ patch_at(lt_code, _jit->pc.w);
+
+ jit_unget_reg(rg0);
+}
+
+static void
_patch_at(jit_state_t *_jit, jit_word_t instr, jit_word_t label)
{
instr_t i;
diff --git a/lib/jit_aarch64-fpu.c b/lib/jit_aarch64-fpu.c
index 386f068..1f13a14 100644
--- a/lib/jit_aarch64-fpu.c
+++ b/lib/jit_aarch64-fpu.c
@@ -310,6 +310,8 @@ static jit_word_t
_bltgti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t);
# define bordi_d(i0,r0,i1) dbcci(BCC_VC,i0,r0,i1)
# define bunordr_d(i0,r0,r1) dbccr(BCC_VS,i0,r0,r1)
# define bunordi_d(i0,r0,i1) dbcci(BCC_VS,i0,r0,i1)
+# define vaarg_d(r0, r1) _vaarg_d(_jit, r0, r1)
+static void _vaarg_d(jit_state_t*, jit_int32_t, jit_int32_t);
#endif
#if CODE
@@ -856,4 +858,57 @@ _bltgtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t
r0, jit_int32_t r1)
return (w);
}
dbopi(ltgt)
+
+static void
+_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
+{
+ jit_word_t ge_code;
+ jit_word_t lt_code;
+ jit_int32_t rg0, rg1;
+
+ 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. */
+ ge_code = bgei(_jit->pc.w, rn(rg0), 0);
+
+ /* Load the gp save pointer in the second temporary. */
+ ldxi(rn(rg1), r1, offsetof(jit_va_list_t, fptop));
+
+ /* Load the vararg argument in the first argument. */
+ ldxr_d(r0, rn(rg1), rn(rg0));
+
+ /* Update the fp offset. */
+ addi(rn(rg0), rn(rg0), 16);
+ 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. */
+ lt_code = jmpi_p(_jit->pc.w);
+
+ /* Where to land if argument is in overflow area. */
+ patch_at(ge_code, _jit->pc.w);
+
+ /* Load stack pointer. */
+ ldxi(rn(rg0), r1, offsetof(jit_va_list_t, stack));
+
+ /* Load argument. */
+ ldr(r0, rn(rg0));
+
+ /* Update stack pointer. */
+ addi(rn(rg0), rn(rg0), 8);
+ stxi(offsetof(jit_va_list_t, stack), r1, rn(rg0));
+
+ /* Where to land if argument is in gp save area. */
+ patch_at(lt_code, _jit->pc.w);
+
+ jit_unget_reg(rg0);
+}
#endif
diff --git a/lib/jit_aarch64.c b/lib/jit_aarch64.c
index 77256c9..89c3eda 100644
--- a/lib/jit_aarch64.c
+++ b/lib/jit_aarch64.c
@@ -22,6 +22,41 @@
#define jit_arg_reg_p(i) ((i) >= 0 && (i) < 8)
#define jit_arg_f_reg_p(i) ((i) >= 0 && (i) < 8)
+typedef struct jit_qreg {
+ jit_float64_t l;
+ jit_float64_t h;
+} jit_qreg_t;
+
+#define va_gp_min_offset -64
+#define va_gp_top_offset offsetof(jit_va_list_t, q0)
+#define va_fp_min_offset -128
+#define va_fp_top_offset sizeof(jit_va_list_t)
+typedef struct jit_va_list {
+ jit_pointer_t stack;
+ jit_pointer_t gptop;
+ jit_pointer_t fptop;
+ jit_int32_t gpoff;
+ jit_int32_t fpoff;
+
+ jit_int64_t x0;
+ jit_int64_t x1;
+ jit_int64_t x2;
+ jit_int64_t x3;
+ jit_int64_t x4;
+ jit_int64_t x5;
+ jit_int64_t x6;
+ jit_int64_t x7;
+
+ jit_qreg_t q0;
+ jit_qreg_t q1;
+ jit_qreg_t q2;
+ jit_qreg_t q3;
+ jit_qreg_t q4;
+ jit_qreg_t q5;
+ jit_qreg_t q6;
+ jit_qreg_t q7;
+} jit_va_list_t;
+
/*
* Prototypes
*/
@@ -295,6 +330,23 @@ _jit_ellipsis(jit_state_t *_jit)
else {
assert(!(_jitc->function->self.call & jit_call_varargs));
_jitc->function->self.call |= jit_call_varargs;
+
+ /* Allocate va_list like object in the stack,
+ * with enough space to save all argument
+ * registers, and use fixed offsets for them. */
+ _jitc->function->vaoff = jit_allocai(sizeof(jit_va_list_t));
+
+ /* Initialize gp offset in save area. */
+ if (jit_arg_reg_p(_jitc->function->self.argi))
+ _jitc->function->vagp = (8 - _jitc->function->self.argi) * -8;
+ else
+ _jitc->function->vagp = va_gp_min_offset;
+
+ /* Initialize fp offset in save area. */
+ if (jit_arg_f_reg_p(_jitc->function->self.argf))
+ _jitc->function->vafp = (8 - _jitc->function->self.argf) * -16;
+ else
+ _jitc->function->vafp = va_fp_min_offset;
}
}
@@ -303,6 +355,7 @@ _jit_arg(jit_state_t *_jit)
{
jit_int32_t offset;
assert(_jitc->function);
+ assert(!(_jitc->function->self.call & jit_call_varargs));
if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++;
else {
@@ -317,6 +370,7 @@ _jit_arg_f(jit_state_t *_jit)
{
jit_int32_t offset;
assert(_jitc->function);
+ assert(!(_jitc->function->self.call & jit_call_varargs));
if (jit_arg_f_reg_p(_jitc->function->self.argf))
offset = _jitc->function->self.argf++;
else {
@@ -331,6 +385,7 @@ _jit_arg_d(jit_state_t *_jit)
{
jit_int32_t offset;
assert(_jitc->function);
+ assert(!(_jitc->function->self.call & jit_call_varargs));
if (jit_arg_f_reg_p(_jitc->function->self.argf))
offset = _jitc->function->self.argf++;
else {
@@ -1268,9 +1323,19 @@ _emit_code(jit_state_t *_jit)
epilog(node);
_jitc->function = NULL;
break;
+ case jit_code_va_start:
+ vastart(rn(node->u.w));
+ break;
+ case jit_code_va_arg:
+ vaarg(rn(node->u.w), rn(node->v.w));
+ break;
+ case jit_code_va_arg_d:
+ vaarg_d(rn(node->u.w), rn(node->v.w));
+ break;
case jit_code_live:
case jit_code_arg:
case jit_code_arg_f: case jit_code_arg_d:
+ case jit_code_va_end:
break;
default:
abort();
- [Guile-commits] 395/437: Use an actual, invalid code, as last jit code., (continued)
- [Guile-commits] 395/437: Use an actual, invalid code, as last jit code., Andy Wingo, 2018/07/02
- [Guile-commits] 344/437: ARM: Better check for constants offset overflow, Andy Wingo, 2018/07/02
- [Guile-commits] 351/437: PPC: Only call binutils function if it is available, Andy Wingo, 2018/07/02
- [Guile-commits] 278/437: x86_64: Change x86_64 to also save/restore %rbx in inline asm., Andy Wingo, 2018/07/02
- [Guile-commits] 427/437: Remove some more of the lightning build machinery, Andy Wingo, 2018/07/02
- [Guile-commits] 328/437: Update THANKS file, Andy Wingo, 2018/07/02
- [Guile-commits] 129/437: Remove previous macro files as they are no longer used., Andy Wingo, 2018/07/02
- [Guile-commits] 09/437: add autotools-generated files, Andy Wingo, 2018/07/02
- [Guile-commits] 69/437: implement long mul/div/mod for x86-64, Andy Wingo, 2018/07/02
- [Guile-commits] 162/437: Correct regressions with --with-float={soft, softfp} in the arm backend, Andy Wingo, 2018/07/02
- [Guile-commits] 377/437: aarch64: Add initial jit_va_ calls to aarch64,
Andy Wingo <=
- [Guile-commits] 298/437: ARM: Correct wrong table of instruction sizes in software float, Andy Wingo, 2018/07/02
- [Guile-commits] 99/437: always set and replace lightning_frag, Andy Wingo, 2018/07/02
- [Guile-commits] 336/437: Correct bogus git entry, Andy Wingo, 2018/07/02
- [Guile-commits] 282/437: Document the lightning customization functions., Andy Wingo, 2018/07/02
- [Guile-commits] 290/437: Do not pass null for free, memcpy and memmove, Andy Wingo, 2018/07/02
- [Guile-commits] 249/437: Make jit_get_note a public interface., Andy Wingo, 2018/07/02
- [Guile-commits] 299/437: ALPHA: Correct class of argument float registers, Andy Wingo, 2018/07/02
- [Guile-commits] 426/437: Remove empty lightning m4 directory, Andy Wingo, 2018/07/02
- [Guile-commits] 379/437: s390: Add initial jit_va_ calls to s390, Andy Wingo, 2018/07/02
- [Guile-commits] 431/437: Always enable assertions in embedded lightning, Andy Wingo, 2018/07/02