[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Guile-commits] 20/86: Trim unneded bits from jit.c
From: |
Andy Wingo |
Subject: |
[Guile-commits] 20/86: Trim unneded bits from jit.c |
Date: |
Wed, 3 Apr 2019 11:38:51 -0400 (EDT) |
wingo pushed a commit to branch lightening
in repository guile.
commit 0d78447d85661c917bc8a235251e9bd04e2b0c30
Author: Andy Wingo <address@hidden>
Date: Wed Oct 31 19:33:26 2018 +0100
Trim unneded bits from jit.c
---
jit.h | 6 +-
jit/jit.c | 3371 +--------------------------------------------------------
jit/private.h | 605 +----------
3 files changed, 65 insertions(+), 3917 deletions(-)
diff --git a/jit.h b/jit.h
index 901321a..140c390 100644
--- a/jit.h
+++ b/jit.h
@@ -110,9 +110,9 @@ extern void init_jit(void);
extern jit_state_t *jit_new_state(void);
extern void jit_destroy_state(jit_state_t*);
-extern void jit_begin(jit_state_t*);
-extern void jit_end(jit_state_t*, jit_addr_t*, size_t*);
+extern void jit_begin(jit_state_t*, jit_addr_t, size_t);
extern void jit_reset(jit_state_t*);
+extern jit_addr_t jit_end(jit_state_t*, size_t*);
extern void jit_align(jit_state_t*, unsigned);
extern void jit_allocai(jit_state_t*, size_t);
@@ -123,7 +123,7 @@ extern void jit_patch_here(jit_state_t*, jit_reloc_t);
extern void jit_patch_there(jit_state_t*, jit_reloc_t, jit_pointer_t);
extern void jit_calli(jit_state_t *, jit_pointer_t f,
- size_t argc, const jit_arg_t *argv);
+ size_t argc, const jit_arg_t *argv);
extern void jit_callr(jit_state_t *, jit_gpr_t f,
size_t argc, const jit_arg_t *argv);
extern void jit_receive(jit_state_t*, size_t argc, jit_arg_t *argv);
diff --git a/jit/jit.c b/jit/jit.c
index da630b0..1f53514 100644
--- a/jit/jit.c
+++ b/jit/jit.c
@@ -22,8 +22,8 @@
# include <fcntl.h>
#endif
-#include "jit.h"
-#include "jit/jit_private.h"
+#include "../jit.h"
+#include "private.h"
#ifndef MAP_ANON
# define MAP_ANON MAP_ANONYMOUS
@@ -32,3373 +32,120 @@
# endif
#endif
+#if !defined(__sgi)
+#define mmap_fd -1
+#endif
+
#define jit_regload_reload 0 /* convert to reload */
#define jit_regload_delete 1 /* just remove node */
#define jit_regload_isdead 2 /* delete and unset live bit */
-#if __WORDSIZE == 32
-# define bmp_shift 5
-#else
-# define bmp_shift 6
-#endif
-
-/*
- * Prototypes
- */
-static jit_word_t hash_data(const void*, jit_word_t);
-
-#define new_pool() _new_pool(_jit)
-static void _new_pool(jit_state_t*);
-
-#define new_node(u) _new_node(_jit, u)
-static jit_node_t *_new_node(jit_state_t*, jit_code_t);
-
-#define link_node(u) _link_node(_jit, u)
-static inline jit_node_t *_link_node(jit_state_t*, jit_node_t*);
-
-#define del_node(u, v) _del_node(_jit, u, v)
-static inline void _del_node(jit_state_t*, jit_node_t*, jit_node_t*);
-
-#define free_node(u) _free_node(_jit, u)
-static inline void _free_node(jit_state_t*, jit_node_t*);
-
-#define del_label(u, v) _del_label(_jit, u, v)
-static void _del_label(jit_state_t*, jit_node_t*, jit_node_t*);
-
-#define bmp_init() _bmp_init(_jit)
-static void _bmp_init(jit_state_t*);
-
-#define bmp_clear() _bmp_clear(_jit)
-static void _bmp_clear(jit_state_t*);
-
-#define bmp_zero() \
- memset(_jitc->blockmask.ptr, 0, \
- _jitc->blockmask.length * sizeof(jit_word_t))
-
-#define bmp_set(bit) _bmp_set(_jit, bit)
-static void _bmp_set(jit_state_t*, jit_word_t);
-
-#define bmp_clr(bit) _bmp_clr(_jit, bit)
-static void _bmp_clr(jit_state_t*, jit_word_t) maybe_unused;
-
-#define bmp_tst(bit) _bmp_tst(_jit, bit)
-static jit_bool_t _bmp_tst(jit_state_t*, jit_word_t);
-
-#define jit_dataset() _jit_dataset(_jit)
-static void
-_jit_dataset(jit_state_t *_jit);
-
-#define jit_setup(block) _jit_setup(_jit, block)
-static void
-_jit_setup(jit_state_t *_jit, jit_block_t *block);
-
-#define jit_update(node, live, mask, r) _jit_update(_jit, node, live,
mask, r)
-static void
-_jit_update(jit_state_t *_jit, jit_node_t *node,
- jit_regset_t *live, jit_regset_t *mask, jit_bool_t recurse);
-
-#define thread_jumps() _thread_jumps(_jit)
-static void
-_thread_jumps(jit_state_t *_jit);
-
-#define sequential_labels() _sequential_labels(_jit)
-static void
-_sequential_labels(jit_state_t *_jit);
-
-#define shortcut_jump(prev, node) _shortcut_jump(_jit, prev, node)
-static jit_bool_t
-_shortcut_jump(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node);
-
-#define redundant_jump(prev, node) _redundant_jump(_jit, prev, node)
-static jit_bool_t
-_redundant_jump(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node);
-
-static jit_code_t
-reverse_jump_code(jit_code_t code);
-
-#define reverse_jump(prev, node) _reverse_jump(_jit, prev, node)
-static jit_bool_t
-_reverse_jump(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node);
-
-#define redundant_store(node, jump) _redundant_store(_jit, node, jump)
-static void
-_redundant_store(jit_state_t *_jit, jit_node_t *node, jit_bool_t jump);
-
-#define simplify_movr(p, n, k, s) _simplify_movr(_jit, p, n, k, s)
-static jit_bool_t
-_simplify_movr(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node,
- int32_t kind, jit_int32_t size);
-
-#define simplify_movi(p, n, k, s) _simplify_movi(_jit, p, n, k, s)
-static jit_bool_t
-_simplify_movi(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node,
- int32_t kind, jit_int32_t size);
-
-#define simplify_ldxi(prev, node) _simplify_ldxi(_jit, prev, node)
-static jit_bool_t
-_simplify_ldxi(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node);
-
-#define simplify_stxi(prev, node) _simplify_stxi(_jit, prev, node)
-static jit_bool_t
-_simplify_stxi(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node);
-
-#define simplify_spill(node, regno) _simplify_spill(_jit, node, regno)
-static void
-_simplify_spill(jit_state_t *_jit, jit_node_t *node, int32_t regno);
-
-#define simplify() _simplify(_jit)
-static void
-_simplify(jit_state_t *_jit);
-
-#define jit_reg_undef -1
-#define jit_reg_static 0
-#define jit_reg_change 1
-#define register_change_p(n, l, r) _register_change_p(_jit, n, l, r)
-static int32_t
-_register_change_p(jit_state_t *_jit, jit_node_t *node, jit_node_t *link,
- int32_t regno);
-
-#define spill_reglive_p(node, regno) _spill_reglive_p(_jit, node, regno)
-static jit_bool_t
-_spill_reglive_p(jit_state_t *_jit, jit_node_t *node, int32_t regno);
-
-#define patch_registers() _patch_registers(_jit)
-static void
-_patch_registers(jit_state_t *_jit);
-
-#define patch_register(n,l,r,p) _patch_register(_jit,n,l,r,p)
-static void
-_patch_register(jit_state_t *jit, jit_node_t *node, jit_node_t *link,
- int32_t regno, jit_int32_t patch);
-
-/*
- * Initialization
- */
-#if !defined(__sgi)
-#define mmap_fd -1
-#endif
/*
* Implementation
*/
void
-init_jit(const char *progname)
+init_jit(void)
{
jit_get_cpu();
- jit_init_debug(progname);
- jit_init_size();
-}
-
-void
-finish_jit(void)
-{
- jit_finish_debug();
- jit_finish_size();
-}
-
-int32_t
-_jit_get_reg(jit_state_t *_jit, int32_t regspec)
-{
- int32_t spec;
- int32_t regno;
-
- spec = regspec & ~(jit_class_chk|jit_class_nospill);
- if (spec & jit_class_named) {
- regno = jit_regno(spec);
- if (jit_regset_tstbit(&_jitc->regsav, regno))
- /* fail if register is spilled */
- goto fail;
- if (jit_regset_tstbit(&_jitc->regarg, regno))
- /* fail if register is an argument to current instruction */
- goto fail;
- if (jit_regset_tstbit(&_jitc->reglive, regno)) {
- if (regspec & jit_class_nospill)
- /* fail if register is live and should not spill/reload */
- goto fail;
- goto spill;
- }
- jit_regset_setbit(&_jitc->regarg, regno);
- return (regno);
- }
- else
- assert(jit_class(spec) != 0);
-
- if (_jitc->emit) {
- /* search for a free register matching spec */
- for (regno = 0; regno < _jitc->reglen; regno++) {
- if ((jit_class(_rvs[regno].spec) & spec) == spec &&
- !jit_regset_tstbit(&_jitc->regarg, regno) &&
- !jit_regset_tstbit(&_jitc->reglive, regno))
- goto regarg;
- }
-
- /* search for a register matching spec that is not an argument
- * for the current instruction */
- for (regno = 0; regno < _jitc->reglen; regno++) {
- if ((jit_class(_rvs[regno].spec) & spec) == spec &&
- !jit_regset_tstbit(&_jitc->regsav, regno) &&
- !jit_regset_tstbit(&_jitc->regarg, regno) &&
- !(regspec & jit_class_nospill)) {
- spill:
- assert(_jitc->function != NULL);
- if (spec & jit_class_gpr) {
- if (!_jitc->function->regoff[regno]) {
- _jitc->function->regoff[regno] =
- jit_allocai(sizeof(jit_word_t));
- _jitc->again = 1;
- }
-#if DEBUG
- /* emit_stxi must not need temporary registers */
- assert(!_jitc->getreg);
- _jitc->getreg = 1;
-#endif
- emit_stxi(_jitc->function->regoff[regno], JIT_FP, regno);
-#if DEBUG
- _jitc->getreg = 0;
-#endif
- }
- else {
- if (!_jitc->function->regoff[regno]) {
- _jitc->function->regoff[regno] =
- jit_allocai(sizeof(jit_float64_t));
- _jitc->again = 1;
- }
-#if DEBUG
- /* emit_stxi must not need temporary registers */
- assert(!_jitc->getreg);
- _jitc->getreg = 1;
-#endif
- emit_stxi_d(_jitc->function->regoff[regno], JIT_FP, regno);
-#if DEBUG
- _jitc->getreg = 0;
-#endif
- }
- jit_regset_setbit(&_jitc->regsav, regno);
- regarg:
- jit_regset_setbit(&_jitc->regarg, regno);
- if (jit_class(_rvs[regno].spec) & jit_class_sav) {
- /* if will modify callee save registers without a
- * function prolog, better patch this assertion */
- assert(_jitc->function != NULL);
- if (!jit_regset_tstbit(&_jitc->function->regset, regno)) {
- jit_regset_setbit(&_jitc->function->regset, regno);
- _jitc->again = 1;
- }
- }
- return (regno);
- }
- }
- }
- else {
- /* nospill hint only valid during emit" */
- assert(!(regspec & jit_class_nospill));
- for (regno = 0; regno < _jitc->reglen; regno++) {
- if ((jit_class(_rvs[regno].spec) & spec) == spec &&
- !jit_regset_tstbit(&_jitc->regsav, regno) &&
- !jit_regset_tstbit(&_jitc->regarg, regno)) {
- jit_regset_setbit(&_jitc->regarg, regno);
- jit_regset_setbit(&_jitc->regsav, regno);
- jit_save(regno);
- return (jit_regno_patch|regno);
- }
- }
- }
-
- /* Out of hardware registers */
-fail:
- assert(regspec & jit_class_chk);
- return (JIT_NOREG);
-}
-
-void
-_jit_unget_reg(jit_state_t *_jit, int32_t regno)
-{
- regno = jit_regno(regno);
- if (jit_regset_tstbit(&_jitc->regsav, regno)) {
- if (_jitc->emit) {
-#if DEBUG
- /* emit_ldxi must not need a temporary register */
- assert(!_jitc->getreg);
- _jitc->getreg = 1;
-#endif
- if (jit_class(_rvs[regno].spec) & jit_class_gpr)
- emit_ldxi(regno, JIT_FP, _jitc->function->regoff[regno]);
- else
- emit_ldxi_d(regno, JIT_FP, _jitc->function->regoff[regno]);
-#if DEBUG
- /* emit_ldxi must not need a temporary register */
- _jitc->getreg = 0;
-#endif
- }
- else
- jit_load(regno);
- jit_regset_clrbit(&_jitc->regsav, regno);
- }
- assert(jit_regset_tstbit(&_jitc->regarg, regno) != 0);
- jit_regset_clrbit(&_jitc->regarg, regno);
-}
-
-jit_bool_t
-_jit_callee_save_p(jit_state_t *_jit, int32_t regno)
-{
- assert(regno >= 0 && regno < JIT_NOREG);
- return (!!(_rvs[regno].spec & jit_class_sav));
-}
-
-extern jit_bool_t
-_jit_pointer_p(jit_state_t *_jit, jit_pointer_t address)
-{
- return ((uint8_t *)address >= _jit->code.ptr &&
- (jit_word_t)address < _jit->pc.w);
-}
-
-#if __ia64__
-void
-jit_regset_com(jit_regset_t *u, jit_regset_t *v)
-{
- u->rl = ~v->rl; u->rh = ~v->rh;
- u->fl = ~v->fl; u->fh = ~v->fh;
-}
-
-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;
- u->fl = v->fl & w->fl; u->fh = v->fh & w->fh;
-}
-
-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;
- u->fl = v->fl | w->fl; u->fh = v->fh | w->fh;
-}
-
-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;
- u->fl = v->fl ^ w->fl; u->fh = v->fh ^ w->fh;
-}
-
-void
-jit_regset_set(jit_regset_t *u, jit_regset_t *v)
-{
- u->rl = v->rl; u->rh = v->rh;
- u->fl = v->fl; u->fh = v->fh;
-}
-
-void
-jit_regset_set_mask(jit_regset_t *u, int32_t v)
-{
- jit_bool_t w = !!(v & (v - 1));
-
- assert(v >= 0 && v <= 256);
- if (v == 0)
- u->rl = u->rh = u->fl = u->fh = -1LL;
- else if (v <= 64) {
- u->rl = w ? (1LL << v) - 1 : -1LL;
- u->rh = u->fl = u->fh = 0;
- }
- else if (v <= 128) {
- u->rl = -1LL;
- u->rh = w ? (1LL << (v - 64)) - 1 : -1LL;
- u->fl = u->fh = 0;
- }
- else if (v <= 192) {
- u->rl = u->rh = -1LL;
- u->fl = w ? (1LL << (v - 128)) - 1 : -1LL;
- u->fh = 0;
- }
- else {
- u->rl = u->rh = u->fl = -1LL;
- u->fh = w ? (1LL << (v - 128)) - 1 : -1LL;
- }
-}
-
-jit_bool_t
-jit_regset_cmp_ui(jit_regset_t *u, jit_word_t v)
-{
- return !((u->rl == v && u->rh == 0 && u->fl == 0 && u->fh == 0));
-}
-
-void
-jit_regset_set_ui(jit_regset_t *u, jit_word_t v)
-{
- u->rl = v;
- u->rh = u->fl = u->fh = 0;
-}
-
-jit_bool_t
-jit_regset_set_p(jit_regset_t *u)
-{
- return (u->rl || u->rh || u->fl || u->fh);
-}
-
-void
-jit_regset_clrbit(jit_regset_t *set, int32_t bit)
-{
- assert(bit >= 0 && bit <= 255);
- if (bit < 64)
- set->rl &= ~(1LL << bit);
- else if (bit < 128)
- set->rh &= ~(1LL << (bit - 64));
- else if (bit < 192)
- set->fl &= ~(1LL << (bit - 128));
- else
- set->fh &= ~(1LL << (bit - 192));
-}
-
-void
-jit_regset_setbit(jit_regset_t *set, int32_t bit)
-{
- assert(bit >= 0 && bit <= 255);
- if (bit < 64)
- set->rl |= 1LL << bit;
- else if (bit < 128)
- set->rh |= 1LL << (bit - 64);
- else if (bit < 192)
- set->fl |= 1LL << (bit - 128);
- else
- set->fh |= 1LL << (bit - 192);
-}
-
-jit_bool_t
-jit_regset_tstbit(jit_regset_t *set, int32_t bit)
-{
- assert(bit >= 0 && bit <= 255);
- if (bit < 64)
- return (!!(set->rl & (1LL << bit)));
- else if (bit < 128)
- return (!!(set->rh & (1LL << (bit - 64))));
- else if (bit < 192)
- return (!!(set->fl & (1LL << (bit - 128))));
- return (!!(set->fh & (1LL << (bit - 192))));
-}
-
-unsigned long
-jit_regset_scan1(jit_regset_t *set, int32_t offset)
-{
- assert(offset >= 0 && offset <= 255);
- for (; offset < 64; offset++) {
- if (set->rl & (1LL << offset))
- return (offset);
- }
- for (; offset < 128; offset++) {
- if (set->rh & (1LL << (offset - 64)))
- return (offset);
- }
- for (; offset < 192; offset++) {
- if (set->fl & (1LL << (offset - 128)))
- return (offset);
- }
- for (; offset < 256; offset++) {
- if (set->fh & (1LL << (offset - 192)))
- return (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)
+jit_state_t *
+jit_new_state(void)
{
- u->rl = v->rl ^ w->rl; u->rh = v->rh ^ w->rh;
-}
+ jit_state_t *_jit;
-void
-jit_regset_set(jit_regset_t *u, jit_regset_t *v)
-{
- u->rl = v->rl; u->rh = v->rh;
-}
+ _jit = malloc (sizeof (*_jit));
+ if (!_jit)
+ abort ();
-void
-jit_regset_set_mask(jit_regset_t *u, int32_t v)
-{
- jit_bool_t w = !!(v & (v - 1));
+ memset(_jit, 0, sizeof (*_jit));
- 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_init (_jit);
-jit_bool_t
-jit_regset_cmp_ui(jit_regset_t *u, jit_word_t v)
-{
- return !((u->rl == v && u->rh == 0));
+ return _jit;
}
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)
+jit_destroy_state(jit_state_t *_jit)
{
- return (u->rl || u->rh);
+ free (_jit);
}
-void
-jit_regset_clrbit(jit_regset_t *set, int32_t bit)
+jit_pointer_t
+jit_address(jit_state_t *_jit)
{
- assert(bit >= 0 && bit <= 128);
- if (bit < 64)
- set->rl &= ~(1LL << bit);
- else
- set->rh &= ~(1LL << (bit - 64));
+ /* TODO: FIXME */
+ abort ();
}
void
-jit_regset_setbit(jit_regset_t *set, 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, 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, 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, int32_t offset)
+jit_begin(jit_state_t *_jit, jit_addr_t addr, size_t length)
{
- jit_regset_t mask;
- assert(offset >= 0 && offset <= 63);
- if ((mask = *set >> offset)) {
- for (;;) {
- if (mask & 1)
- return (offset);
- mask >>= 1;
- ++offset;
- }
- }
- return (ULONG_MAX);
-}
-#endif
+ ASSERT (!_jit->start);
-void
-_jit_save(jit_state_t *_jit, int32_t reg)
-{
- reg = jit_regno(reg);
- assert(!_jitc->realize);
- _jitc->spill[reg] = jit_new_node_w(jit_code_save, reg);
+ _jit->start = addr;
+ _jit->limit = _jit->start + length;
+ jit_reset(_jit);
}
void
-_jit_load(jit_state_t *_jit, int32_t reg)
-{
- jit_node_t *node;
-
- reg = jit_regno(reg);
- assert(!_jitc->realize);
- assert(_jitc->spill[reg] != NULL);
- node = jit_new_node_w(jit_code_load, reg);
- /* create a path to flag the save/load is not required */
- node->link = _jitc->spill[reg];
- node->link->link = node;
- _jitc->spill[reg] = NULL;
-}
-
-static jit_word_t
-hash_data(const void *data, jit_word_t length)
-{
- const uint8_t *ptr;
- jit_word_t i, key;
- for (i = key = 0, ptr = data; i < length; i++)
- key = (key << (key & 1)) ^ ptr[i];
- return (key);
-}
-
-jit_pointer_t
-_jit_address(jit_state_t *_jit, jit_node_t *node)
-{
- assert(_jitc->done);
- assert(node != NULL &&
- /* If a node type that is documented to be a fixed marker */
- (node->code == jit_code_note || node->code == jit_code_name ||
- /* If another special fixed marker, returned by jit_indirect() */
- (node->code == jit_code_label && (node->flag & jit_flag_use) !=
0)));
- return ((jit_pointer_t)node->u.w);
-}
-
-jit_node_t *
-_jit_data(jit_state_t *_jit, const void *data,
- jit_word_t length, int32_t align)
-{
- jit_word_t key;
- jit_node_t *node;
-
- assert(!_jitc->realize);
-
- /* Ensure there is space even if asking for a duplicate */
- if (((_jitc->data.offset + 7) & -8) + length > _jit->data.length) {
- jit_word_t size;
-
- size = (_jit->data.length + length + 4096) & - 4095;
- assert(size >= _jit->data.length);
- if (_jitc->data.ptr == NULL)
- jit_alloc((jit_pointer_t *)&_jitc->data.ptr, size);
- else
- jit_realloc((jit_pointer_t *)&_jitc->data.ptr,
- _jit->data.length, size);
- _jit->data.length = size;
- }
- if (_jitc->data.table == NULL)
- jit_alloc((jit_pointer_t *)&_jitc->data.table,
- (_jitc->data.size = 16) * sizeof(jit_node_t*));
-
- key = hash_data(data, length) & (_jitc->data.size - 1);
- node = _jitc->data.table[key];
- for (; node; node = node->next) {
- if (node->v.w == length &&
- memcmp(_jitc->data.ptr + node->u.w, data, length) == 0)
- break;
- }
-
- if (!node) {
- node = jit_new_node_no_link(jit_code_data);
- if (!align)
- align = length;
- switch (align) {
- case 0: case 1:
- break;
- case 2:
- _jitc->data.offset = (_jitc->data.offset + 1) & -2;
- break;
- case 3: case 4:
- _jitc->data.offset = (_jitc->data.offset + 3) & -4;
- break;
- default:
- _jitc->data.offset = (_jitc->data.offset + 7) & -8;
- break;
- }
- node->u.w = _jitc->data.offset;
- node->v.w = length;
- jit_memcpy(_jitc->data.ptr + _jitc->data.offset, data, length);
- _jitc->data.offset += length;
-
- node->next = _jitc->data.table[key];
- _jitc->data.table[key] = node;
- ++_jitc->data.count;
-
- /* Rehash if more than 75% used table */
- if (_jitc->data.count >
- (_jitc->data.size >> 1) + (_jitc->data.size >> 2) &&
- (_jitc->data.size << 1) > _jitc->data.size) {
- jit_word_t i;
- jit_node_t **hash;
- jit_node_t *next;
- jit_node_t *temp;
-
- jit_alloc((jit_pointer_t *)&hash,
- (_jitc->data.size << 1) * sizeof(jit_node_t*));
- for (i = 0; i < _jitc->data.size; i++) {
- temp = _jitc->data.table[i];
- for (; temp; temp = next) {
- next = temp->next;
- key = hash_data(_jitc->data.ptr + temp->u.w, temp->v.w) &
- ((_jitc->data.size << 1) - 1);
- temp->next = hash[key];
- hash[key] = temp;
- }
- }
- jit_free((jit_pointer_t *)&_jitc->data.table);
- _jitc->data.table = hash;
- _jitc->data.size <<= 1;
- }
- }
-
- return (node);
-}
-
-static void
-_new_pool(jit_state_t *_jit)
-{
- jit_node_t *list;
- int32_t offset;
-
- if (_jitc->pool.offset >= _jitc->pool.length) {
- int32_t length;
-
- length = _jitc->pool.length + 16;
- jit_realloc((jit_pointer_t *)&_jitc->pool.ptr,
- _jitc->pool.length * sizeof(jit_node_t *),
- length * sizeof(jit_node_t *));
- _jitc->pool.length = length;
- }
- jit_alloc((jit_pointer_t *)(_jitc->pool.ptr + _jitc->pool.offset),
- sizeof(jit_node_t) * 1024);
- list = _jitc->pool.ptr[_jitc->pool.offset];
- for (offset = 1; offset < 1024; offset++, list++)
- list->next = list + 1;
- list->next = _jitc->list;
- _jitc->list = _jitc->pool.ptr[_jitc->pool.offset];
- ++_jitc->pool.offset;
-}
-
-static jit_node_t *
-_new_node(jit_state_t *_jit, jit_code_t code)
+jit_reset(jit_state_t *_jit)
{
- jit_node_t *node;
-
- if (_jitc->list == NULL)
- new_pool();
- node = _jitc->list;
- _jitc->list = node->next;
- if (_jitc->synth)
- node->flag |= jit_flag_synth;
- node->next = NULL;
- node->code = code;
-
- return (node);
-}
-
-static inline jit_node_t *
-_link_node(jit_state_t *_jit, jit_node_t *node)
-{
- if (_jitc->tail)
- _jitc->tail->next = node;
- else
- _jitc->head = node;
- return (_jitc->tail = node);
-}
-
-static inline void
-_del_node(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node)
-{
- if (prev == node) {
- assert(prev == _jitc->head);
- _jitc->head = node->next;
- }
- else
- prev->next = node->next;
- memset(node, 0, sizeof(jit_node_t));
- node->next = _jitc->list;
- _jitc->list = node;
-}
-
-static inline void
-_free_node(jit_state_t *_jit, jit_node_t *node)
-{
- memset(node, 0, sizeof(jit_node_t));
- node->next = _jitc->list;
- _jitc->list = node;
-}
-
-static void
-_del_label(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node)
-{
- jit_block_t *block;
-
- /* only allow call to del_label on linked labels */
- block = _jitc->blocks.ptr + node->v.w;
- assert(block->label == node);
-
- /* del_label() should only be called when optimizing.
- * This will leave an empty block index */
- jit_regset_del(&block->reglive);
- jit_regset_del(&block->regmask);
- block->label = NULL;
-
- /* redundant, should be already true */
- assert(node->link == NULL);
- del_node(prev, node);
-}
-
-static void
-_bmp_init(jit_state_t *_jit)
-{
- _jitc->blockmask.length = 16;
- jit_alloc((jit_pointer_t *)&_jitc->blockmask.ptr,
- sizeof(jit_word_t) * _jitc->blockmask.length);
+ ASSERT (_jit->start);
+ _jit->pc.uc = _jit->start = _jit->limit = NULL;
}
-static void
-_bmp_clear(jit_state_t *_jit)
+jit_addr_t
+jit_end(jit_state_t *_jit, size_t *length)
{
- _jitc->blockmask.length = 0;
- jit_free((jit_pointer_t *)&_jitc->blockmask.ptr);
-}
-
-static void
-_bmp_set(jit_state_t *_jit, jit_word_t bit)
-{
- jit_word_t woff, boff;
+ uint8_t *code = _jit->start;
+ uint8_t *end = _jit->pc.uc;
- woff = bit >> bmp_shift;
- boff = 1LL << (bit & (__WORDSIZE - 1));
- if (woff >= _jitc->blockmask.length) {
- jit_word_t length = (woff + 16) & -16;
- jit_realloc((jit_pointer_t *)&_jitc->blockmask.ptr,
- _jitc->blockmask.length * sizeof(jit_word_t),
- length * sizeof(jit_word_t));
- _jitc->blockmask.length = length;
- }
- _jitc->blockmask.ptr[woff] |= boff;
-}
+ ASSERT (code);
+ ASSERT (end > code);
+ ASSERT (end <= _jit->limit);
-static void
-_bmp_clr(jit_state_t *_jit, jit_word_t bit)
-{
- jit_word_t woff, boff;
+ jit_flush (code, end);
- woff = bit >> bmp_shift;
- boff = 1LL << (bit & (__WORDSIZE - 1));
- if (woff < _jitc->blockmask.length)
- _jitc->blockmask.ptr[woff] &= ~boff;
-}
+ if (length) {
+ *length = end - code;
+ }
-static jit_bool_t
-_bmp_tst(jit_state_t *_jit, jit_word_t bit)
-{
- jit_word_t woff, boff;
+ jit_reset (_jit);
- woff = bit >> bmp_shift;
- boff = 1LL << (bit & (__WORDSIZE - 1));
- if (woff < _jitc->blockmask.length)
- return ((_jitc->blockmask.ptr[woff] & boff) != 0);
- return (0);
+ return code;
}
-jit_state_t *
-jit_new_state(void)
+static int
+is_power_of_two (unsigned x)
{
- jit_state_t *_jit;
-
- jit_alloc((jit_pointer_t *)&_jit, sizeof(jit_state_t));
- jit_alloc((jit_pointer_t *)&_jitc, sizeof(jit_compiler_t));
- jit_regset_new(&_jitc->regarg);
- jit_regset_new(&_jitc->regsav);
- jit_regset_new(&_jitc->reglive);
- jit_regset_new(&_jitc->regmask);
- bmp_init();
-
- jit_init();
-
- jit_alloc((jit_pointer_t *)&_jitc->spill,
- _jitc->reglen * sizeof(jit_node_t*));
- jit_alloc((jit_pointer_t *)&_jitc->gen,
- _jitc->reglen * sizeof(int32_t));
- jit_alloc((jit_pointer_t *)&_jitc->values,
- _jitc->reglen * sizeof(jit_value_t));
-
- jit_alloc((jit_pointer_t *)&_jitc->patches.ptr,
- (_jitc->patches.length = 1024) * sizeof(jit_patch_t));
- jit_alloc((jit_pointer_t *)&_jitc->functions.ptr,
- (_jitc->functions.length = 16) * sizeof(jit_function_t));
- jit_alloc((jit_pointer_t *)&_jitc->pool.ptr,
- (_jitc->pool.length = 16) * sizeof(jit_node_t*));
- jit_alloc((jit_pointer_t *)&_jitc->blocks.ptr,
- (_jitc->blocks.length = 16) * sizeof(jit_block_t));
-#if __arm__ && DISASSEMBLER
- jit_alloc((jit_pointer_t *)&_jitc->data_info.ptr,
- (_jitc->data_info.length = 1024) * sizeof(jit_data_info_t));
-#endif
-
- /* allocate at most one extra note in case jit_name() is
- * never called, or called after adding at least one note */
- _jit->note.length = 1;
- _jitc->note.size = sizeof(jit_note_t);
-
- return (_jit);
+ return x && !(x & (x-1));
}
void
-_jit_clear_state(jit_state_t *_jit)
-{
-#if DEVEL_DISASSEMBLER
-# define jit_really_clear_state() _jit_really_clear_state(_jit)
-}
-
-void _jit_really_clear_state(jit_state_t *_jit)
+jit_align(jit_state_t *_jit, unsigned align)
{
-#endif
- jit_word_t offset;
- jit_function_t *function;
-
- /* release memory not required at jit execution time and set
- * pointers to NULL to explicitly know they are released */
- _jitc->head = _jitc->tail = NULL;
-
- bmp_clear();
-
- jit_free((jit_pointer_t *)&_jitc->data.table);
- _jitc->data.size = _jitc->data.count = 0;
-
- jit_free((jit_pointer_t *)&_jitc->spill);
- jit_free((jit_pointer_t *)&_jitc->gen);
- jit_free((jit_pointer_t *)&_jitc->values);
-
- jit_free((jit_pointer_t *)&_jitc->blocks.ptr);
-
- jit_free((jit_pointer_t *)&_jitc->patches.ptr);
- _jitc->patches.offset = _jitc->patches.length = 0;
-
- for (offset = 0; offset < _jitc->functions.offset; offset++) {
- function = _jitc->functions.ptr + offset;
- jit_free((jit_pointer_t *)&function->regoff);
- }
- jit_free((jit_pointer_t *)&_jitc->functions.ptr);
- _jitc->functions.offset = _jitc->functions.length = 0;
- _jitc->function = NULL;
-
- for (offset = 0; offset < _jitc->pool.offset; offset++)
- jit_free((jit_pointer_t *)(_jitc->pool.ptr + offset));
- jit_free((jit_pointer_t *)&_jitc->pool.ptr);
- _jitc->pool.offset = _jitc->pool.length = 0;
- _jitc->list = NULL;
-
- _jitc->note.head = _jitc->note.tail =
- _jitc->note.name = _jitc->note.note = NULL;
- _jitc->note.base = NULL;
-
-#if __arm__ && DISASSEMBLER
- jit_free((jit_pointer_t *)&_jitc->data_info.ptr);
-#endif
-
-#if __powerpc64__ || __ia64__
- jit_free((jit_pointer_t *)&_jitc->prolog.ptr);
-#endif
-
-#if __ia64__
- jit_regset_del(&_jitc->regs);
-#endif
-
- jit_free((jit_pointer_t *)&_jitc);
+ ASSERT (is_power_of_two (align));
+ uintptr_t here = _jit->pc.w;
+ uintptr_t there = (here + align - 1) & ~(align - 1);
+ if (there - here)
+ jit_nop(_jit, there - here);
}
void
-_jit_destroy_state(jit_state_t *_jit)
+jit_patch_here(jit_state_t *_jit, jit_reloc_t *reloc)
{
-#if DEVEL_DISASSEMBLER
- jit_really_clear_state();
-#endif
- if (!_jit->user_code)
- munmap(_jit->code.ptr, _jit->code.length);
- if (!_jit->user_data)
- munmap(_jit->data.ptr, _jit->data.length);
- jit_free((jit_pointer_t *)&_jit);
+ jit_patch_there (_jit, reloc, jit_address (_jit));
}
void
-_jit_synth_inc(jit_state_t *_jit)
-{
- assert(_jitc->synth < 8);
- ++_jitc->synth;
-}
-
-jit_node_t *
-_jit_new_node(jit_state_t *_jit, jit_code_t code)
-{
- assert(!_jitc->realize);
- return (link_node(new_node(code)));
-}
-
-jit_node_t *
-_jit_new_node_no_link(jit_state_t *_jit, jit_code_t code)
+jit_patch_there(jit_state_t* _jit, jit_reloc_t *reloc, jit_pointer_t *addr)
{
- assert(!_jitc->realize);
- return (new_node(code));
-}
-
-void
-_jit_link_node(jit_state_t *_jit, jit_node_t *node)
-{
- assert(!_jitc->realize);
- link_node(node);
-}
-
-void
-_jit_synth_dec(jit_state_t *_jit)
-{
- assert(_jitc->synth > 0);
- --_jitc->synth;
-}
-
-jit_node_t *
-_jit_new_node_w(jit_state_t *_jit, jit_code_t code,
- jit_word_t u)
-{
- jit_node_t *node = new_node(code);
- assert(!_jitc->realize);
- node->u.w = u;
- return (link_node(node));
-}
-
-jit_node_t *
-_jit_new_node_f(jit_state_t *_jit, jit_code_t code,
- jit_float32_t u)
-{
- jit_node_t *node = new_node(code);
- assert(!_jitc->realize);
- node->u.f = u;
- return (link_node(node));
-}
-
-jit_node_t *
-_jit_new_node_d(jit_state_t *_jit, jit_code_t code,
- jit_float64_t u)
-{
- jit_node_t *node = new_node(code);
- assert(!_jitc->realize);
- node->u.d = u;
- return (link_node(node));
-}
-
-jit_node_t *
-_jit_new_node_p(jit_state_t *_jit, jit_code_t code,
- jit_pointer_t u)
-{
- jit_node_t *node = new_node(code);
- assert(!_jitc->realize);
- node->u.p = u;
- return (link_node(node));
-}
-
-jit_node_t *
-_jit_new_node_ww(jit_state_t *_jit, jit_code_t code,
- jit_word_t u, jit_word_t v)
-{
- jit_node_t *node = new_node(code);
- assert(!_jitc->realize);
- node->u.w = u;
- node->v.w = v;
- return (link_node(node));
-}
-
-jit_node_t *
-_jit_new_node_wp(jit_state_t *_jit, jit_code_t code,
- jit_word_t u, jit_pointer_t v)
-{
- return (jit_new_node_ww(code, u, (jit_word_t)v));
-}
-
-jit_node_t *
-_jit_new_node_fp(jit_state_t *_jit, jit_code_t code,
- jit_float32_t u, jit_pointer_t v)
-{
- jit_node_t *node = new_node(code);
- assert(!_jitc->realize);
- node->u.f = u;
- node->v.w = (jit_word_t)v;
- return (link_node(node));
-}
-
-jit_node_t *
-_jit_new_node_dp(jit_state_t *_jit, jit_code_t code,
- jit_float64_t u, jit_pointer_t v)
-{
- jit_node_t *node = new_node(code);
- assert(!_jitc->realize);
- node->u.d = u;
- node->v.w = (jit_word_t)v;
- return (link_node(node));
-}
-
-jit_node_t *
-_jit_new_node_pw(jit_state_t *_jit, jit_code_t code,
- jit_pointer_t u, jit_word_t v)
-{
- return (jit_new_node_ww(code, (jit_word_t)u, v));
-}
-
-jit_node_t *
-_jit_new_node_wf(jit_state_t *_jit, jit_code_t code,
- jit_word_t u, jit_float32_t v)
-{
- jit_node_t *node = new_node(code);
- assert(!_jitc->realize);
- node->u.w = u;
- node->v.f = v;
- return (link_node(node));
-}
-
-jit_node_t *
-_jit_new_node_wd(jit_state_t *_jit, jit_code_t code,
- jit_word_t u, jit_float64_t v)
-{
- jit_node_t *node = new_node(code);
- assert(!_jitc->realize);
- node->u.w = u;
- node->v.d = v;
- return (link_node(node));
-}
-
-jit_node_t *
-_jit_new_node_www(jit_state_t *_jit, jit_code_t code,
- jit_word_t u, jit_word_t v, jit_word_t w)
-{
- jit_node_t *node = new_node(code);
- assert(!_jitc->realize);
- node->u.w = u;
- node->v.w = v;
- node->w.w = w;
- return (link_node(node));
-}
-
-jit_node_t *
-_jit_new_node_qww(jit_state_t *_jit, jit_code_t code,
- int32_t l, jit_int32_t h,
- jit_word_t v, jit_word_t w)
-{
- jit_node_t *node = new_node(code);
- assert(!_jitc->realize);
- assert(l != h);
- node->u.q.l = l;
- node->u.q.h = h;
- node->v.w = v;
- node->w.w = w;
- return (link_node(node));
-}
-
-jit_node_t *
-_jit_new_node_wwf(jit_state_t *_jit, jit_code_t code,
- jit_word_t u, jit_word_t v, jit_float32_t w)
-{
- jit_node_t *node = new_node(code);
- assert(!_jitc->realize);
- node->u.w = u;
- node->v.w = v;
- node->w.f = w;
- return (link_node(node));
-}
-
-jit_node_t *
-_jit_new_node_wwd(jit_state_t *_jit, jit_code_t code,
- jit_word_t u, jit_word_t v, jit_float64_t w)
-{
- jit_node_t *node = new_node(code);
- assert(!_jitc->realize);
- node->u.w = u;
- node->v.w = v;
- node->w.d = w;
- return (link_node(node));
-}
-
-jit_node_t *
-_jit_new_node_pww(jit_state_t *_jit, jit_code_t code,
- jit_pointer_t u, jit_word_t v, jit_word_t w)
-{
- jit_node_t *node = new_node(code);
- assert(!_jitc->realize);
- node->u.p = u;
- node->v.w = v;
- node->w.w = w;
- return (link_node(node));
-}
-
-jit_node_t *
-_jit_new_node_pwf(jit_state_t *_jit, jit_code_t code,
- jit_pointer_t u, jit_word_t v, jit_float32_t w)
-{
- jit_node_t *node = new_node(code);
- assert(!_jitc->realize);
- node->u.p = u;
- node->v.w = v;
- node->w.f = w;
- return (link_node(node));
-}
-
-jit_node_t *
-_jit_new_node_pwd(jit_state_t *_jit, jit_code_t code,
- jit_pointer_t u, jit_word_t v, jit_float64_t w)
-{
- jit_node_t *node = new_node(code);
- assert(!_jitc->realize);
- node->u.p = u;
- node->v.w = v;
- node->w.d = w;
- return (link_node(node));
-}
-
-jit_node_t *
-_jit_label(jit_state_t *_jit)
-{
- jit_node_t *node;
-
- if (!(node = _jitc->tail) || node->code != jit_code_label) {
- node = jit_forward();
- jit_link(node);
- }
-
- return (node);
-}
-
-jit_node_t *
-_jit_forward(jit_state_t *_jit)
-{
- return (jit_new_node_no_link(jit_code_label));
-}
-
-jit_node_t *
-_jit_indirect(jit_state_t *_jit)
-{
- jit_node_t *node;
-
- node = jit_label();
- node->flag |= jit_flag_use;
-
- return (node);
-}
-
-void
-_jit_link(jit_state_t *_jit, jit_node_t *node)
-{
- jit_block_t *block;
-
- assert((node->code == jit_code_label ||
- node->code == jit_code_prolog ||
- node->code == jit_code_epilog) && !node->next);
- jit_link_node(node);
- if (_jitc->blocks.offset >= _jitc->blocks.length) {
- jit_word_t length;
-
- length = _jitc->blocks.length + 16;
- jit_realloc((jit_pointer_t *)&_jitc->blocks.ptr,
- _jitc->blocks.length * sizeof(jit_block_t),
- length * sizeof(jit_block_t));
- _jitc->blocks.length = length;
- }
- block = _jitc->blocks.ptr + _jitc->blocks.offset;
- block->label = node;
- node->v.w = _jitc->blocks.offset;
- jit_regset_new(&block->reglive);
- jit_regset_new(&block->regmask);
- ++_jitc->blocks.offset;
-}
-
-jit_bool_t
-_jit_forward_p(jit_state_t *_jit, jit_node_t *node)
-{
- return (node->code == jit_code_label && !node->next && node !=
_jitc->tail);
-}
-
-jit_bool_t
-_jit_indirect_p(jit_state_t *_jit, jit_node_t *node)
-{
- return (node->code == jit_code_label && !!(node->flag & jit_flag_use));
-}
-
-jit_bool_t
-_jit_target_p(jit_state_t *_jit, jit_node_t *node)
-{
- return (node->code == jit_code_label && !!node->link);
-}
-
-void
-_jit_prepare(jit_state_t *_jit)
-{
- assert(_jitc->function != NULL);
- _jitc->function->call.call = jit_call_default;
- _jitc->function->call.argi =
- _jitc->function->call.argf =
- _jitc->function->call.size = 0;
- _jitc->prepare = jit_new_node(jit_code_prepare);
-}
-
-void
-_jit_patch(jit_state_t* _jit, jit_node_t *instr)
-{
- jit_node_t *label;
-
- if (!(label = _jitc->tail) || label->code != jit_code_label)
- label = jit_label();
- jit_patch_at(instr, label);
-}
-
-int32_t
-_jit_classify(jit_state_t *_jit, jit_code_t code)
-{
- int32_t mask;
-
- switch (code) {
- case jit_code_data: case jit_code_save: case jit_code_load:
- case jit_code_name: case jit_code_label: case jit_code_note:
- case jit_code_prolog: case jit_code_ellipsis: case jit_code_va_push:
- case jit_code_epilog: case jit_code_ret: case jit_code_prepare:
- mask = 0;
- break;
- case jit_code_live: case jit_code_va_end:
- case jit_code_retr: case jit_code_retr_f: case jit_code_retr_d:
- case jit_code_pushargr: case jit_code_pushargr_f:
- case jit_code_pushargr_d:
- case jit_code_finishr: /* synthesized will set jit_cc_a0_jmp */
- mask = jit_cc_a0_reg;
- break;
- case jit_code_align: case jit_code_reti: case jit_code_pushargi:
- case jit_code_finishi: /* synthesized will set jit_cc_a0_jmp */
- mask = jit_cc_a0_int;
- break;
- case jit_code_reti_f: case jit_code_pushargi_f:
- mask = jit_cc_a0_flt;
- break;
- case jit_code_reti_d: case jit_code_pushargi_d:
- mask = jit_cc_a0_dbl;
- break;
- case jit_code_allocai:
- mask = jit_cc_a0_int|jit_cc_a1_int;
- break;
- case jit_code_arg: case jit_code_arg_f: case jit_code_arg_d:
- mask = jit_cc_a0_int|jit_cc_a0_arg;
- break;
- case jit_code_calli: case jit_code_jmpi:
- mask = jit_cc_a0_jmp;
- break;
- case jit_code_callr: case jit_code_jmpr:
- mask = jit_cc_a0_reg|jit_cc_a0_jmp;
- break;
- 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: case jit_code_retval_ui:
- case jit_code_retval_l:
- case jit_code_retval_f: case jit_code_retval_d:
- case jit_code_va_start:
- mask = jit_cc_a0_reg|jit_cc_a0_chg;
- break;
- 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: case jit_code_getarg_ui:
- case jit_code_getarg_l:
- case jit_code_getarg_f: case jit_code_getarg_d:
- mask = jit_cc_a0_reg|jit_cc_a0_chg|jit_cc_a1_arg;
- break;
- case jit_code_putargr: case jit_code_putargr_f:
- case jit_code_putargr_d:
- mask = jit_cc_a0_reg|jit_cc_a1_arg;
- break;
- case jit_code_putargi:
- mask = jit_cc_a0_int|jit_cc_a1_arg;
- break;
- case jit_code_putargi_f:
- mask = jit_cc_a0_flt|jit_cc_a1_arg;
- break;
- case jit_code_putargi_d:
- mask = jit_cc_a0_dbl|jit_cc_a1_arg;
- break;
- case jit_code_movi: case jit_code_ldi_c: case jit_code_ldi_uc:
- case jit_code_ldi_s: case jit_code_ldi_us: case jit_code_ldi_i:
- case jit_code_ldi_ui: case jit_code_ldi_l: case jit_code_ldi_f:
- case jit_code_ldi_d:
- mask = jit_cc_a0_reg|jit_cc_a0_chg|jit_cc_a1_int;
- break;
- case jit_code_movi_f: case jit_code_movi_f_w:
- mask = jit_cc_a0_reg|jit_cc_a0_chg|jit_cc_a1_flt;
- break;
- case jit_code_movi_d: case jit_code_movi_d_w:
- mask = jit_cc_a0_reg|jit_cc_a0_chg|jit_cc_a1_dbl;
- break;
- case jit_code_movi_d_ww:
- mask = jit_cc_a0_reg|jit_cc_a0_chg|jit_cc_a1_reg|jit_cc_a1_chg|
- jit_cc_a2_dbl;
- break;
- case jit_code_negr: case jit_code_comr: case jit_code_movr:
- case jit_code_extr_c: case jit_code_extr_uc: case jit_code_extr_s:
- case jit_code_extr_us: case jit_code_extr_i: case jit_code_extr_ui:
- case jit_code_truncr_f_i: case
jit_code_truncr_f_l:
- case jit_code_truncr_d_i: case
jit_code_truncr_d_l:
- case jit_code_htonr_us: case jit_code_htonr_ui: case jit_code_htonr_ul:
- case jit_code_ldr_c: case jit_code_ldr_uc:
- case jit_code_ldr_s: case jit_code_ldr_us: case jit_code_ldr_i:
- case jit_code_ldr_ui: case jit_code_ldr_l: case jit_code_negr_f:
- case jit_code_absr_f: case jit_code_sqrtr_f: case jit_code_movr_f:
- case jit_code_extr_f: case jit_code_extr_d_f: case jit_code_ldr_f:
- case jit_code_negr_d: case jit_code_absr_d: case jit_code_sqrtr_d:
- case jit_code_movr_d: case jit_code_extr_d: case jit_code_extr_f_d:
- case jit_code_ldr_d:
- case jit_code_movr_w_f: case jit_code_movr_f_w:
- case jit_code_movr_w_d: case jit_code_movr_d_w:
- case jit_code_va_arg: case jit_code_va_arg_d:
- mask = jit_cc_a0_reg|jit_cc_a0_chg|jit_cc_a1_reg;
- break;
- case jit_code_movr_d_ww:
- mask = jit_cc_a0_reg|jit_cc_a0_chg|jit_cc_a1_reg|jit_cc_a1_chg|
- jit_cc_a2_reg;
- break;
- case jit_code_addi: case jit_code_addxi: case jit_code_addci:
- case jit_code_subi: case jit_code_subxi: case jit_code_subci:
- case jit_code_rsbi:
- case jit_code_muli: case jit_code_divi: case jit_code_divi_u:
- case jit_code_remi: case jit_code_remi_u: case jit_code_andi:
- case jit_code_ori: case jit_code_xori: case jit_code_lshi:
- case jit_code_rshi: case jit_code_rshi_u: case jit_code_lti:
- case jit_code_lti_u: case jit_code_lei: case jit_code_lei_u:
- case jit_code_eqi: case jit_code_gei: case jit_code_gei_u:
- case jit_code_gti: case jit_code_gti_u: case jit_code_nei:
- case jit_code_ldxi_c: case jit_code_ldxi_uc: case jit_code_ldxi_s:
- case jit_code_ldxi_us: case jit_code_ldxi_i: case jit_code_ldxi_ui:
- case jit_code_ldxi_l: case jit_code_ldxi_f: case jit_code_ldxi_d:
- mask = jit_cc_a0_reg|jit_cc_a0_chg|jit_cc_a1_reg|jit_cc_a2_int;
- break;
- case jit_code_qmuli: case jit_code_qmuli_u:
- case jit_code_qdivi: case jit_code_qdivi_u:
- mask = jit_cc_a0_reg|jit_cc_a0_rlh|jit_cc_a0_chg|
- jit_cc_a1_reg|jit_cc_a2_int;
- break;
- case jit_code_addi_f: case jit_code_subi_f: case jit_code_rsbi_f:
- case jit_code_muli_f: case jit_code_divi_f: case jit_code_lti_f:
- case jit_code_lei_f: case jit_code_eqi_f: case jit_code_gei_f:
- case jit_code_gti_f: case jit_code_nei_f: case jit_code_unlti_f:
- case jit_code_unlei_f: case jit_code_uneqi_f: case jit_code_ungei_f:
- case jit_code_ungti_f: case jit_code_ltgti_f: case jit_code_ordi_f:
- case jit_code_unordi_f:
- mask = jit_cc_a0_reg|jit_cc_a0_chg|jit_cc_a1_reg|jit_cc_a2_flt;
- break;
- case jit_code_addi_d: case jit_code_subi_d: case jit_code_rsbi_d:
- case jit_code_muli_d: case jit_code_divi_d: case jit_code_lti_d:
- case jit_code_lei_d: case jit_code_eqi_d: case jit_code_gei_d:
- case jit_code_gti_d: case jit_code_nei_d: case jit_code_unlti_d:
- case jit_code_unlei_d: case jit_code_uneqi_d: case jit_code_ungei_d:
- case jit_code_ungti_d: case jit_code_ltgti_d: case jit_code_ordi_d:
- case jit_code_unordi_d:
- mask = jit_cc_a0_reg|jit_cc_a0_chg|jit_cc_a1_reg|jit_cc_a2_dbl;
- break;
- case jit_code_addr: case jit_code_addxr: case jit_code_addcr:
- case jit_code_subr: case jit_code_subxr: case jit_code_subcr:
- case jit_code_mulr: case jit_code_divr: case jit_code_divr_u:
- case jit_code_remr: case jit_code_remr_u: case jit_code_andr:
- case jit_code_orr: case jit_code_xorr: case jit_code_lshr:
- case jit_code_rshr: case jit_code_rshr_u: case jit_code_ltr:
- case jit_code_ltr_u: case jit_code_ler: case jit_code_ler_u:
- case jit_code_eqr: case jit_code_ger: case jit_code_ger_u:
- case jit_code_gtr: case jit_code_gtr_u: case jit_code_ner:
- case jit_code_ldxr_c: case jit_code_ldxr_uc: case jit_code_ldxr_s:
- case jit_code_ldxr_us: case jit_code_ldxr_i: case jit_code_ldxr_ui:
- case jit_code_ldxr_l: case jit_code_addr_f: case jit_code_subr_f:
- case jit_code_mulr_f: case jit_code_divr_f: case jit_code_ltr_f:
- case jit_code_ler_f: case jit_code_eqr_f: case jit_code_ger_f:
- case jit_code_gtr_f: case jit_code_ner_f: case jit_code_unltr_f:
- case jit_code_unler_f: case jit_code_uneqr_f: case jit_code_unger_f:
- case jit_code_ungtr_f: case jit_code_ltgtr_f: case jit_code_ordr_f:
- case jit_code_unordr_f: case jit_code_ldxr_f: case jit_code_addr_d:
- case jit_code_subr_d: case jit_code_mulr_d: case jit_code_divr_d:
- case jit_code_ltr_d: case jit_code_ler_d: case jit_code_eqr_d:
- case jit_code_ger_d: case jit_code_gtr_d: case jit_code_ner_d:
- case jit_code_unltr_d: case jit_code_unler_d: case jit_code_uneqr_d:
- case jit_code_unger_d: case jit_code_ungtr_d: case jit_code_ltgtr_d:
- case jit_code_ordr_d: case jit_code_unordr_d: case jit_code_ldxr_d:
- case jit_code_movr_ww_d:
- mask = jit_cc_a0_reg|jit_cc_a0_chg|jit_cc_a1_reg|jit_cc_a2_reg;
- break;
- case jit_code_qmulr: case jit_code_qmulr_u:
- case jit_code_qdivr: case jit_code_qdivr_u:
- mask = jit_cc_a0_reg|jit_cc_a0_rlh|jit_cc_a0_chg|
- jit_cc_a1_reg|jit_cc_a2_reg;
- break;
- case jit_code_sti_c: case jit_code_sti_s: case jit_code_sti_i:
- case jit_code_sti_l: case jit_code_sti_f: case jit_code_sti_d:
- mask = jit_cc_a0_int|jit_cc_a1_reg;
- break;
- case jit_code_blti: case jit_code_blti_u: case jit_code_blei:
- case jit_code_blei_u: case jit_code_beqi: case jit_code_bgei:
- case jit_code_bgei_u: case jit_code_bgti: case jit_code_bgti_u:
- case jit_code_bnei: case jit_code_bmsi: case jit_code_bmci:
- mask = jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_int;
- break;
- case jit_code_blti_f: case jit_code_blei_f: case jit_code_beqi_f:
- case jit_code_bgei_f: case jit_code_bgti_f: case jit_code_bnei_f:
- case jit_code_bunlti_f: case jit_code_bunlei_f: case jit_code_buneqi_f:
- case jit_code_bungei_f: case jit_code_bungti_f: case jit_code_bltgti_f:
- case jit_code_bordi_f: case jit_code_bunordi_f:
- mask = jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_flt;
- break;
- case jit_code_blti_d: case jit_code_blei_d: case jit_code_beqi_d:
- case jit_code_bgei_d: case jit_code_bgti_d: case jit_code_bnei_d:
- case jit_code_bunlti_d: case jit_code_bunlei_d: case jit_code_buneqi_d:
- case jit_code_bungei_d: case jit_code_bungti_d: case jit_code_bltgti_d:
- case jit_code_bordi_d: case jit_code_bunordi_d:
- mask = jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_dbl;
- break;
- case jit_code_allocar: /* synthesized instructions make it
- * equivalent to jit_cc_a0_chg */
- case jit_code_str_c: case jit_code_str_s: case jit_code_str_i:
- case jit_code_str_l: case jit_code_str_f: case jit_code_str_d:
- mask = jit_cc_a0_reg|jit_cc_a1_reg;
- break;
- case jit_code_stxi_c: case jit_code_stxi_s: case jit_code_stxi_i:
- case jit_code_stxi_l: case jit_code_stxi_f: case jit_code_stxi_d:
- mask = jit_cc_a0_int|jit_cc_a1_reg|jit_cc_a2_reg;
- break;
- case jit_code_bltr: case jit_code_bltr_u: case jit_code_bler:
- case jit_code_bler_u: case jit_code_beqr: case jit_code_bger:
- case jit_code_bger_u: case jit_code_bgtr: case jit_code_bgtr_u:
- case jit_code_bner: case jit_code_bmsr: case jit_code_bmcr:
- case jit_code_bltr_f: case jit_code_bler_f: case jit_code_beqr_f:
- case jit_code_bger_f: case jit_code_bgtr_f: case jit_code_bner_f:
- case jit_code_bunltr_f: case jit_code_bunler_f: case jit_code_buneqr_f:
- case jit_code_bunger_f: case jit_code_bungtr_f: case jit_code_bltgtr_f:
- case jit_code_bordr_f: case jit_code_bunordr_f:case jit_code_bltr_d:
- case jit_code_bler_d: case jit_code_beqr_d: case jit_code_bger_d:
- case jit_code_bgtr_d: case jit_code_bner_d: case jit_code_bunltr_d:
- case jit_code_bunler_d: case jit_code_buneqr_d: case jit_code_bunger_d:
- case jit_code_bungtr_d: case jit_code_bltgtr_d: case jit_code_bordr_d:
- case jit_code_bunordr_d:
- mask = jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_reg;
- break;
- case jit_code_boaddi: case jit_code_boaddi_u: case jit_code_bxaddi:
- case jit_code_bxaddi_u: case jit_code_bosubi: case jit_code_bosubi_u:
- case jit_code_bxsubi: case jit_code_bxsubi_u:
- mask = jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a1_chg|jit_cc_a2_int;
- break;
- case jit_code_stxr_c: case jit_code_stxr_s: case jit_code_stxr_i:
- case jit_code_stxr_l: case jit_code_stxr_f: case jit_code_stxr_d:
- mask = jit_cc_a0_reg|jit_cc_a1_reg|jit_cc_a2_reg;
- break;
- case jit_code_boaddr: case jit_code_boaddr_u: case jit_code_bxaddr:
- case jit_code_bxaddr_u: case jit_code_bosubr: case jit_code_bosubr_u:
- case jit_code_bxsubr: case jit_code_bxsubr_u:
- mask = jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a1_chg|jit_cc_a2_reg;
- break;
- default:
- abort();
- }
-
- return (mask);
-}
-
-void
-_jit_patch_abs(jit_state_t *_jit, jit_node_t *instr, jit_pointer_t address)
-{
- int32_t mask;
-
- if (instr->code == jit_code_movi)
- instr->v.p = address;
- else {
- mask = jit_classify(instr->code);
- assert((mask & (jit_cc_a0_reg|jit_cc_a0_jmp)) == jit_cc_a0_jmp);
- instr->u.p = address;
- }
-}
-
-void
-_jit_patch_at(jit_state_t *_jit, jit_node_t *instr, jit_node_t *label)
-{
- int32_t mask;
-
- assert(!(instr->flag & jit_flag_node));
- instr->flag |= jit_flag_node;
- switch (instr->code) {
- case jit_code_movi:
- assert(label->code == jit_code_label ||
- label->code == jit_code_data);
- instr->v.n = label;
- if (label->code == jit_code_data)
- instr->flag |= jit_flag_data;
- break;
- case jit_code_jmpi:
- assert(label->code == jit_code_label ||
- label->code == jit_code_epilog);
- instr->u.n = label;
- break;
- default:
- mask = jit_classify(instr->code);
- assert((mask & (jit_cc_a0_reg|jit_cc_a0_jmp)) == jit_cc_a0_jmp);
- assert(label->code == jit_code_label);
- instr->u.n = label;
- break;
- }
- /* link field is used as list of nodes associated with a given label */
- instr->link = label->link;
- label->link = instr;
-}
-
-void
-_jit_optimize(jit_state_t *_jit)
-{
- jit_bool_t jump;
- int32_t mask;
- jit_node_t *node;
- jit_block_t *block;
- jit_word_t offset;
-
- _jitc->function = NULL;
-
- thread_jumps();
- sequential_labels();
-
- /* create initial mapping of live register values
- * at the start of a basic block */
- for (offset = 0; offset < _jitc->blocks.offset; offset++) {
- block = _jitc->blocks.ptr + offset;
- if (!block->label)
- continue;
- if (block->label->code != jit_code_epilog) {
- jit_setup(block);
- jit_regset_set(&block->setmask, &block->regmask);
- }
- }
- /* call jit_update resolving undefined values in reverse
- * order so that sequential code would find most data already
- * resolved when reaching the start of a new basic block */
- for (offset = _jitc->blocks.offset - 1; offset >= 0; offset--) {
- block = _jitc->blocks.ptr + offset;
- if (!block->label)
- continue;
- if (block->label->code != jit_code_epilog) {
- jit_regset_set(&_jitc->regmask, &block->regmask);
- jit_update(block->label->next, &block->reglive, &_jitc->regmask, 1);
- }
- }
- /* do a second pass from start to properly handle some conditions
- * of very long living registers that are not referenced for
- * several blocks */
- bmp_zero();
- for (offset = 0; offset < _jitc->blocks.offset; offset++) {
- block = _jitc->blocks.ptr + offset;
- if (!block->label)
- continue;
- if (block->label->code != jit_code_epilog) {
- jit_regset_set(&_jitc->regmask, &block->setmask);
- jit_update(block->label->next, &block->reglive, &_jitc->regmask, 1);
- }
- }
-
- patch_registers();
- simplify();
-
- /* figure out labels that are only reached with a jump
- * and is required to do a simple redundant_store removal
- * on jit_beqi below */
- jump = 1;
- for (node = _jitc->head; node; node = node->next) {
- switch (node->code) {
- case jit_code_label:
- if (!jump)
- node->flag |= jit_flag_head;
- break;
- case jit_code_jmpi: case jit_code_jmpr:
- case jit_code_epilog:
- jump = 1;
- break;
- case jit_code_data: case jit_code_note:
- break;
- default:
- jump = 0;
- break;
- }
- }
-
- for (node = _jitc->head; node; node = node->next) {
- mask = jit_classify(node->code);
- if (mask & jit_cc_a0_reg)
- node->u.w &= ~jit_regno_patch;
- if (mask & jit_cc_a1_reg)
- node->v.w &= ~jit_regno_patch;
- if (mask & jit_cc_a2_reg)
- node->w.w &= ~jit_regno_patch;
- switch (node->code) {
- case jit_code_prolog:
- _jitc->function = _jitc->functions.ptr + node->w.w;
- break;
- case jit_code_epilog:
- _jitc->function = NULL;
- break;
- case jit_code_beqi:
- redundant_store(node, 1);
- break;
- case jit_code_bnei:
- redundant_store(node, 0);
- break;
- default:
-#if JIT_HASH_CONSTS
- if (mask & jit_cc_a0_flt) {
- node->u.p = jit_data(&node->u.f, sizeof(jit_float32_t), 4);
- node->flag |= jit_flag_node | jit_flag_data;
- }
- else if (mask & jit_cc_a0_dbl) {
- node->u.p = jit_data(&node->u.d, sizeof(jit_float64_t), 8);
- node->flag |= jit_flag_node | jit_flag_data;
- }
- else if (mask & jit_cc_a1_flt) {
- node->v.p = jit_data(&node->v.f, sizeof(jit_float32_t), 4);
- node->flag |= jit_flag_node | jit_flag_data;
- }
- else if (mask & jit_cc_a1_dbl) {
- node->v.p = jit_data(&node->v.d, sizeof(jit_float64_t), 8);
- node->flag |= jit_flag_node | jit_flag_data;
- }
- else if (mask & jit_cc_a2_flt) {
- node->w.p = jit_data(&node->w.f, sizeof(jit_float32_t), 4);
- node->flag |= jit_flag_node | jit_flag_data;
- }
- else if (mask & jit_cc_a2_dbl) {
- node->w.p = jit_data(&node->w.d, sizeof(jit_float64_t), 8);
- node->flag |= jit_flag_node | jit_flag_data;
- }
-#endif
- if (_jitc->function) {
- if ((mask & (jit_cc_a0_reg|jit_cc_a0_chg)) ==
- (jit_cc_a0_reg|jit_cc_a0_chg)) {
- if (mask & jit_cc_a0_rlh) {
- jit_regset_setbit(&_jitc->function->regset,
- jit_regno(node->u.q.l));
- jit_regset_setbit(&_jitc->function->regset,
- jit_regno(node->u.q.h));
- }
- else
- jit_regset_setbit(&_jitc->function->regset,
- jit_regno(node->u.w));
- }
- if ((mask & (jit_cc_a1_reg|jit_cc_a1_chg)) ==
- (jit_cc_a1_reg|jit_cc_a1_chg))
- jit_regset_setbit(&_jitc->function->regset,
- jit_regno(node->v.w));
- if ((mask & (jit_cc_a2_reg|jit_cc_a2_chg)) ==
- (jit_cc_a2_reg|jit_cc_a2_chg))
- jit_regset_setbit(&_jitc->function->regset,
- jit_regno(node->w.w));
- }
- break;
- }
- }
-}
-
-void
-_jit_reglive(jit_state_t *_jit, jit_node_t *node)
-{
- int32_t spec;
- int32_t value;
- jit_block_t *block;
-
- switch (node->code) {
- case jit_code_label: case jit_code_prolog: case jit_code_epilog:
- block = _jitc->blocks.ptr + node->v.w;
- jit_regset_set(&_jitc->reglive, &block->reglive);
- break;
- case jit_code_callr:
- value = jit_regno(node->u.w);
- if (!(node->u.w & jit_regno_patch)) {
- jit_regset_setbit(&_jitc->reglive, value);
- }
- case jit_code_calli:
- for (value = 0; value < _jitc->reglen; value++) {
- spec = jit_class(_rvs[value].spec);
- if ((spec & jit_class_arg) && jit_regarg_p(node, value))
- jit_regset_setbit(&_jitc->reglive, value);
- else if (!(spec & jit_class_sav))
- jit_regset_clrbit(&_jitc->reglive, value);
- }
- break;
- default:
- value = jit_classify(node->code);
- if (value & jit_cc_a0_reg) {
- if (value & jit_cc_a0_rlh) {
- if (!(node->u.q.l & jit_regno_patch)) {
- if (value & jit_cc_a0_chg) {
- jit_regset_clrbit(&_jitc->reglive, node->u.q.l);
- jit_regset_setbit(&_jitc->regmask, node->u.q.l);
- }
- else
- jit_regset_setbit(&_jitc->reglive, node->u.q.l);
- }
- if (!(node->u.q.h & jit_regno_patch)) {
- if (value & jit_cc_a0_chg) {
- jit_regset_clrbit(&_jitc->reglive, node->u.q.h);
- jit_regset_setbit(&_jitc->regmask, node->u.q.h);
- }
- else
- jit_regset_setbit(&_jitc->reglive, node->u.q.h);
- }
- }
- else {
- if (!(node->u.w & jit_regno_patch)) {
- if (value & jit_cc_a0_chg) {
- jit_regset_clrbit(&_jitc->reglive, node->u.w);
- jit_regset_setbit(&_jitc->regmask, node->u.w);
- }
- else
- jit_regset_setbit(&_jitc->reglive, node->u.w);
- }
- }
- }
- if ((value & jit_cc_a1_reg) && !(node->v.w & jit_regno_patch)) {
- if (value & jit_cc_a1_chg) {
- jit_regset_clrbit(&_jitc->reglive, node->v.w);
- jit_regset_setbit(&_jitc->regmask, node->v.w);
- }
- else
- jit_regset_setbit(&_jitc->reglive, node->v.w);
- }
- if ((value & jit_cc_a2_reg) && !(node->w.w & jit_regno_patch)) {
- if (value & jit_cc_a2_chg) {
- jit_regset_clrbit(&_jitc->reglive, node->w.w);
- jit_regset_setbit(&_jitc->regmask, node->w.w);
- }
- else
- jit_regset_setbit(&_jitc->reglive, node->w.w);
- }
- if (jit_regset_set_p(&_jitc->regmask)) {
- bmp_zero();
- jit_update(node->next, &_jitc->reglive, &_jitc->regmask, 1);
- if (jit_regset_set_p(&_jitc->regmask)) {
- /* any unresolved live state is considered as live */
- jit_regset_ior(&_jitc->reglive,
- &_jitc->reglive, &_jitc->regmask);
- jit_regset_set_ui(&_jitc->regmask, 0);
- }
- }
- break;
- }
-}
-
-void
-_jit_regarg_set(jit_state_t *_jit, jit_node_t *node, int32_t value)
-{
-#if GET_JIT_SIZE
- jit_size_prepare();
-#endif
- if (value & jit_cc_a0_reg) {
- if (value & jit_cc_a0_rlh) {
- jit_regset_setbit(&_jitc->regarg, jit_regno(node->u.q.l));
- jit_regset_setbit(&_jitc->regarg, jit_regno(node->u.q.h));
- }
- else
- jit_regset_setbit(&_jitc->regarg, jit_regno(node->u.w));
- }
- if (value & jit_cc_a1_reg)
- jit_regset_setbit(&_jitc->regarg, jit_regno(node->v.w));
- if (value & jit_cc_a2_reg)
- jit_regset_setbit(&_jitc->regarg, jit_regno(node->w.w));
-}
-
-void
-_jit_regarg_clr(jit_state_t *_jit, jit_node_t *node, int32_t value)
-{
-#if GET_JIT_SIZE
- jit_size_collect(node);
-#endif
- if (value & jit_cc_a0_reg) {
- if (value & jit_cc_a0_rlh) {
- jit_regset_clrbit(&_jitc->regarg, jit_regno(node->u.q.l));
- jit_regset_clrbit(&_jitc->regarg, jit_regno(node->u.q.h));
- }
- else
- jit_regset_clrbit(&_jitc->regarg, jit_regno(node->u.w));
- }
- if (value & jit_cc_a1_reg)
- jit_regset_clrbit(&_jitc->regarg, jit_regno(node->v.w));
- if (value & jit_cc_a2_reg)
- jit_regset_clrbit(&_jitc->regarg, jit_regno(node->w.w));
-}
-
-void
-_jit_realize(jit_state_t *_jit)
-{
- assert(!_jitc->realize);
- if (_jitc->function)
- jit_epilog();
- jit_optimize();
- _jitc->realize = 1;
-
- /* ensure it is aligned */
- _jitc->data.offset = (_jitc->data.offset + 7) & -8;
-
-#if GET_JIT_SIZE
- /* Heuristic to guess code buffer size */
- _jitc->mult = 4;
- _jit->code.length = _jitc->pool.length * 1024 * _jitc->mult;
-#else
- _jit->code.length = jit_get_size();
-#endif
-}
-
-void
-_jit_dataset(jit_state_t *_jit)
-{
- uint8_t *ptr;
- jit_node_t *node;
- jit_word_t offset;
-#if defined(__sgi)
- int mmap_fd;
-#endif
-
- assert(!_jitc->dataset);
- if (!_jit->user_data) {
-
- /* create read only data buffer */
- _jit->data.length = (_jitc->data.offset +
- /* reserve space for annotations */
- _jitc->note.size + 4095) & -4096;
-#if defined(__sgi)
- mmap_fd = open("/dev/zero", O_RDWR);
-#endif
- _jit->data.ptr = mmap(NULL, _jit->data.length,
- PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANON, mmap_fd, 0);
- assert(_jit->data.ptr != MAP_FAILED);
-#if defined(__sgi)
- close(mmap_fd);
-#endif
- }
-
- if (!_jitc->no_data)
- jit_memcpy(_jit->data.ptr, _jitc->data.ptr, _jitc->data.offset);
-
- if (_jitc->no_note) {
- /* Space for one note is always allocated, so revert it here
- * if after jit_new_state was called, it is also requested to
- * not generate annotation information */
- _jit->note.length = 0;
- _jitc->note.size = 0;
- }
- else {
- _jitc->note.base = _jit->data.ptr;
- if (!_jitc->no_data)
- _jitc->note.base += _jitc->data.offset;
- memset(_jitc->note.base, 0, _jitc->note.size);
- }
-
- if (_jit->user_data)
- /* Need the temporary hashed data until jit_emit is finished */
- ptr = _jitc->no_data ? _jitc->data.ptr : _jit->data.ptr;
- else {
- ptr = _jit->data.ptr;
- /* Temporary hashed data no longer required */
- jit_free((jit_pointer_t *)&_jitc->data.ptr);
- }
-
- for (offset = 0; offset < _jitc->data.size; offset++) {
- for (node = _jitc->data.table[offset]; node; node = node->next) {
- node->flag |= jit_flag_patch;
- node->u.w = (jit_word_t)(ptr + node->u.w);
- }
- }
-
- _jitc->dataset = 1;
-}
-
-jit_pointer_t
-_jit_get_code(jit_state_t *_jit, jit_word_t *length)
-{
- assert(_jitc->realize);
- if (length) {
- if (_jitc->done)
- /* If code already generated, return exact size of code */
- *length = _jit->pc.uc - _jit->code.ptr;
- else
- /* Else return current size of the code buffer */
- *length = _jit->code.length;
- }
-
- return (_jit->code.ptr);
-}
-
-void
-_jit_set_code(jit_state_t *_jit, jit_pointer_t ptr, jit_word_t length)
-{
- assert(_jitc->realize);
- _jit->code.ptr = ptr;
- _jit->code.length = length;
- _jit->user_code = 1;
-}
-
-jit_pointer_t
-_jit_get_data(jit_state_t *_jit, jit_word_t *data_size, jit_word_t *note_size)
-{
- assert(_jitc->realize);
- if (data_size)
- *data_size = _jitc->data.offset;
- if (note_size)
- *note_size = _jitc->note.size;
- return (_jit->data.ptr);
-}
-
-void
-_jit_set_data(jit_state_t *_jit, jit_pointer_t ptr,
- jit_word_t length, jit_word_t flags)
-{
- assert(_jitc->realize);
- if (flags & JIT_DISABLE_DATA)
- _jitc->no_data = 1;
- else
- assert(length >= _jitc->data.offset);
- if (flags & JIT_DISABLE_NOTE)
- _jitc->no_note = 1;
- else {
- if (flags & JIT_DISABLE_DATA)
- assert(length >= _jitc->note.size);
- else
- assert(length >= _jitc->data.offset + _jitc->note.size);
- }
- _jit->data.ptr = ptr;
- _jit->data.length = length;
- _jit->user_data = 1;
-}
-
-jit_pointer_t
-_jit_emit(jit_state_t *_jit)
-{
- jit_pointer_t code;
- jit_node_t *node;
- size_t length;
- int result;
-#if defined(__sgi)
- int mmap_fd;
-#endif
-
- if (!_jitc->realize)
- jit_realize();
-
- if (!_jitc->dataset)
- jit_dataset();
-
- _jitc->emit = 1;
-
- if (!_jit->user_code) {
-#if defined(__sgi)
- mmap_fd = open("/dev/zero", O_RDWR);
-#endif
- _jit->code.ptr = mmap(NULL, _jit->code.length,
- PROT_EXEC | PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANON, mmap_fd, 0);
- assert(_jit->code.ptr != MAP_FAILED);
- }
- _jitc->code.end = _jit->code.ptr + _jit->code.length -
- jit_get_max_instr();
- _jit->pc.uc = _jit->code.ptr;
-
- for (;;) {
- if ((code = emit_code()) == NULL) {
- _jitc->patches.offset = 0;
- for (node = _jitc->head; node; node = node->next) {
- if (node->link &&
- (node->code == jit_code_label ||
- node->code == jit_code_epilog))
- node->flag &= ~jit_flag_patch;
- }
- if (_jit->user_code)
- goto fail;
-#if GET_JIT_SIZE
- ++_jitc->mult;
- length = _jitc->pool.length * 1024 * _jitc->mult;
-#else
- /* Should only happen on very special cases */
- length = _jit->code.length + 4096;
-#endif
-
-#if !HAVE_MREMAP
- munmap(_jit->code.ptr, _jit->code.length);
-#endif
-
-#if HAVE_MREMAP
-# if __NetBSD__
- _jit->code.ptr = mremap(_jit->code.ptr, _jit->code.length,
- _jit->code.ptr, length, 0);
-# else
- _jit->code.ptr = mremap(_jit->code.ptr, _jit->code.length,
- length, MREMAP_MAYMOVE, NULL);
-# endif
-#else
- _jit->code.ptr = mmap(NULL, length,
- PROT_EXEC | PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANON, mmap_fd, 0);
-#endif
-
- assert(_jit->code.ptr != MAP_FAILED);
- _jit->code.length = length;
- _jitc->code.end = _jit->code.ptr + _jit->code.length -
- jit_get_max_instr();
- _jit->pc.uc = _jit->code.ptr;
- }
- else
- break;
- }
-
-#if defined(__sgi)
- if (!_jit->user_code)
- close(mmap_fd);
-#endif
-
- _jitc->done = 1;
- if (!_jitc->no_note)
- jit_annotate();
-
- if (_jit->user_data)
- jit_free((jit_pointer_t *)&_jitc->data.ptr);
- else {
- result = mprotect(_jit->data.ptr, _jit->data.length, PROT_READ);
- assert(result == 0);
- }
- if (!_jit->user_code) {
- result = mprotect(_jit->code.ptr, _jit->code.length,
- PROT_READ | PROT_EXEC);
- assert(result == 0);
- }
-
- return (_jit->code.ptr);
-fail:
- return (NULL);
-}
-
-void
-_jit_frame(jit_state_t *_jit, int32_t frame)
-{
- jit_trampoline(frame, 1);
-}
-
-void
-_jit_tramp(jit_state_t *_jit, int32_t frame)
-{
- jit_trampoline(frame, 0);
-}
-
-void
-_jit_trampoline(jit_state_t *_jit, int32_t frame, jit_bool_t prolog)
-{
- int32_t regno;
-
- /* Must be called after prolog, actually, just to simplify
- * tests and know there is a current function and that
- * _jitc->function->self.aoff is at the before any alloca value */
- assert(_jitc->tail && _jitc->tail->code == jit_code_prolog);
-
- /* + 24 for 3 possible spilled temporaries (that could be a double) */
- frame += 24;
-#if defined(__hppa__)
- frame += _jitc->function->self.aoff;
-#else
- frame -= _jitc->function->self.aoff;
-#endif
- _jitc->function->frame = frame;
- if (prolog)
- _jitc->function->define_frame = 1;
- else
- _jitc->function->assume_frame = 1;
- for (regno = 0; regno < _jitc->reglen; regno++)
- if (jit_class(_rvs[regno].spec) & jit_class_sav)
- jit_regset_setbit(&_jitc->function->regset, regno);
-}
-
-/* Compute initial reglive and regmask set values of a basic block.
- * reglive is the set of known live registers
- * regmask is the set of registers not referenced in the block
- */
-static void
-_jit_setup(jit_state_t *_jit, jit_block_t *block)
-{
-#define reglive block->reglive
-#define regmask block->regmask
- jit_node_t *node;
- jit_bool_t live;
- jit_bool_t jump;
- unsigned long value;
-
- jump = 0;
- jit_regset_set_mask(®mask, _jitc->reglen);
- for (node = block->label->next; node; node = node->next) {
- switch (node->code) {
- case jit_code_label: case jit_code_prolog:
- case jit_code_epilog:
- return;
- default:
- value = jit_classify(node->code);
- if (value & jit_cc_a0_reg) {
- live = !(value & jit_cc_a0_chg);
- if (value & jit_cc_a0_rlh) {
- if (!(node->u.q.l & jit_regno_patch) &&
- jit_regset_tstbit(®mask, node->u.q.l)) {
- if (live || !jump)
- jit_regset_clrbit(®mask, node->u.q.l);
- if (live)
- jit_regset_setbit(®live, node->u.q.l);
- }
- if (!(node->u.q.h & jit_regno_patch) &&
- jit_regset_tstbit(®mask, node->u.q.h)) {
- if (live || !jump)
- jit_regset_clrbit(®mask, node->u.q.h);
- if (live)
- jit_regset_setbit(®live, node->u.q.h);
- }
- }
- else {
- if (!(node->u.w & jit_regno_patch) &&
- jit_regset_tstbit(®mask, node->u.w)) {
- if (live || !jump)
- jit_regset_clrbit(®mask, node->u.w);
- if (live)
- jit_regset_setbit(®live, node->u.w);
- }
- }
- }
- if ((value & jit_cc_a1_reg) &&
- !(node->v.w & jit_regno_patch) &&
- jit_regset_tstbit(®mask, node->v.w)) {
- live = !(value & jit_cc_a1_chg);
- if (live || !jump)
- jit_regset_clrbit(®mask, node->v.w);
- if (live)
- jit_regset_setbit(®live, node->v.w);
- }
- if ((value & jit_cc_a2_reg) &&
- !(node->w.w & jit_regno_patch) &&
- jit_regset_tstbit(®mask, node->w.w)) {
- live = !(value & jit_cc_a2_chg);
- if (live || !jump)
- jit_regset_clrbit(®mask, node->w.w);
- if (live)
- jit_regset_setbit(®live, node->w.w);
- }
- if (value & jit_cc_a0_jmp)
- jump = 1;
- break;
- }
- }
-#undef regmask
-#undef reglive
-}
-
-/* Remove bit of mask argument based on instructions arguments up to end
- * of code or finding a basic block boundary, if a value is used as argument,
- * also set the live bit to know value cannot be clobbered; if value is
- * modified, just remove it from the mask as if it not already in the live
- * bitmask, then the value is dead.
- */
-static void
-_jit_update(jit_state_t *_jit, jit_node_t *node,
- jit_regset_t *live, jit_regset_t *mask, jit_bool_t recurse)
-{
- int32_t spec;
- int32_t regno;
- jit_regset_t ztmp;
- jit_regset_t zmask;
- unsigned long value;
- jit_block_t *block;
- jit_node_t *label;
-
- for (; node; node = node->next) {
- restart:
- if (jit_regset_set_p(mask) == 0)
- break;
- switch (node->code) {
- case jit_code_label:
- block = _jitc->blocks.ptr + node->v.w;
- jit_regset_and(&ztmp, mask, &block->reglive);
- if (jit_regset_set_p(&ztmp)) {
- jit_regset_ior(live, live, &ztmp);
- jit_regset_com(&ztmp, &ztmp);
- jit_regset_and(mask, mask, &ztmp);
- }
- if (bmp_tst(node->v.w))
- return;
- bmp_set(node->v.w);
- break;
- case jit_code_prolog:
- jit_regset_set_ui(mask, 0);
- return;
- case jit_code_epilog:
- jit_regset_set_ui(mask, 0);
- return;
- case jit_code_callr:
- value = jit_regno(node->u.w);
- if (!(node->u.w & jit_regno_patch)) {
- if (jit_regset_tstbit(mask, value)) {
- jit_regset_clrbit(mask, value);
- jit_regset_setbit(live, value);
- }
- }
- case jit_code_calli:
- for (value = 0; value < _jitc->reglen; ++value) {
- value = jit_regset_scan1(mask, value);
- if (value >= _jitc->reglen)
- break;
- spec = jit_class(_rvs[value].spec);
- if (!(spec & jit_class_sav))
- jit_regset_clrbit(mask, value);
- if ((spec & jit_class_arg) && jit_regarg_p(node, value))
- jit_regset_setbit(live, value);
- }
- break;
- default:
- value = jit_classify(node->code);
- if (value & jit_cc_a2_reg) {
- if (!(node->w.w & jit_regno_patch)) {
- if (jit_regset_tstbit(mask, node->w.w)) {
- jit_regset_clrbit(mask, node->w.w);
- if (!(value & jit_cc_a2_chg))
- jit_regset_setbit(live, node->w.w);
- }
- }
- }
- if (value & jit_cc_a1_reg) {
- if (!(node->v.w & jit_regno_patch)) {
- if (jit_regset_tstbit(mask, node->v.w)) {
- jit_regset_clrbit(mask, node->v.w);
- if (!(value & jit_cc_a1_chg))
- jit_regset_setbit(live, node->v.w);
- }
- }
- }
- if (value & jit_cc_a0_reg) {
- if (value & jit_cc_a0_rlh) {
- if (!(node->u.q.l & jit_regno_patch)) {
- if (jit_regset_tstbit(mask, node->u.q.l)) {
- jit_regset_clrbit(mask, node->u.q.l);
- if (!(value & jit_cc_a0_chg))
- jit_regset_setbit(live, node->u.q.l);
- }
- }
- if (!(node->u.q.h & jit_regno_patch)) {
- if (jit_regset_tstbit(mask, node->u.q.h)) {
- jit_regset_clrbit(mask, node->u.q.h);
- if (!(value & jit_cc_a0_chg))
- jit_regset_setbit(live, node->u.q.h);
- }
- }
- }
- else {
- if (!(node->u.w & jit_regno_patch)) {
- if (jit_regset_tstbit(mask, node->u.w)) {
- jit_regset_clrbit(mask, node->u.w);
- if (!(value & jit_cc_a0_chg))
- jit_regset_setbit(live, node->u.w);
- }
- }
- }
- }
- if (value & jit_cc_a0_jmp) {
- if (node->flag & jit_flag_node) {
- label = node->u.n;
- if (node->code == jit_code_jmpi) {
- node = label;
- goto restart;
- }
- block = _jitc->blocks.ptr + label->v.w;
- jit_regset_and(&ztmp, mask, &block->reglive);
- if (jit_regset_set_p(&ztmp)) {
- jit_regset_ior(live, live, &ztmp);
- jit_regset_com(&ztmp, &ztmp);
- jit_regset_and(mask, mask, &ztmp);
- }
- if (bmp_tst(label->v.w))
- continue;
- bmp_set(label->v.w);
- if (jit_regset_set_p(mask) == 0)
- return;
- /* restore mask if branch is conditional */
- if (recurse) {
- jit_regset_set(&zmask, mask);
- jit_update(block->label->next, live, &zmask, 0);
- }
- else {
- node = block->label->next;
- goto restart;
- }
- jit_regset_xor(&ztmp, &zmask, mask);
- /* remove known live registers from mask */
- if (jit_regset_set_p(&ztmp)) {
- jit_regset_and(&ztmp, &ztmp, live);
- jit_regset_com(&ztmp, &ztmp);
- jit_regset_and(mask, mask, &ztmp);
- }
- continue;
- }
- /* Should not really mark as live all registers in unknown
- * state if using jit_jmpr(), or jit_jmpi(absolute_address)
- * because that would leave the register allocator with
- * no options for "nospill" temporaries (other temporaries
- * also benefit from not needing to spill/reload), so, the
- * user must ensure to either spill/reload, or only leave
- * live values on registers that are advertised as
- * callee save (as per jit_callee_save_p); on most targets
- * these are the JIT_Vn registers. */
- for (regno = 0; regno < _jitc->reglen; regno++) {
- spec = jit_class(_rvs[regno].spec);
- if (jit_regset_tstbit(mask, regno) &&
- (spec & (jit_class_gpr|jit_class_fpr)) &&
- !(spec & jit_class_sav))
- jit_regset_clrbit(mask, regno);
- }
- /* assume value is live due to jump to unknown location */
- jit_regset_ior(live, live, mask);
- jit_regset_set_ui(mask, 0);
- return;
- }
- break;
- }
- }
-}
-
-static void
-_thread_jumps(jit_state_t *_jit)
-{
- jit_node_t *prev;
- jit_node_t *node;
- jit_node_t *next;
- int32_t mask;
-
- for (prev = node = _jitc->head; node;) {
- next = node->next;
- switch (node->code) {
- case jit_code_jmpi:
- if (redundant_jump(prev, node)) {
- node = prev;
- continue;
- }
- if (shortcut_jump(prev, node))
- continue;
- break;
- case jit_code_jmpr:
- case jit_code_callr: case jit_code_calli:
- /* non optimizable jump like code */
- break;
- default:
- mask = jit_classify(node->code);
- if (mask & jit_cc_a0_jmp) {
- if (reverse_jump(prev, node) ||
- shortcut_jump(prev, node))
- continue;
- }
- break;
- }
- prev = node;
- node = next;
- }
-}
-
-static void
-_sequential_labels(jit_state_t *_jit)
-{
- jit_node_t *jump;
- jit_node_t *link;
- jit_node_t *prev;
- jit_node_t *next;
- jit_node_t *node;
-
- for (prev = node = _jitc->head; node; node = next) {
- next = node->next;
- if (node->code == jit_code_label) {
- if (!node->flag) {
- if (!node->link) {
- del_label(prev, node);
- continue;
- }
- if (prev != node && prev->code == jit_code_label) {
- if ((jump = node->link)) {
- for (; jump; jump = link) {
- link = jump->link;
- jump->u.n = prev;
- jump->link = prev->link;
- prev->link = jump;
- }
- node->link = NULL;
- }
- del_label(prev, node);
- continue;
- }
- }
- if (next && next->code == jit_code_label && !next->flag) {
- if ((jump = next->link)) {
- for (; jump; jump = link) {
- link = jump->link;
- jump->u.n = node;
- jump->link = node->link;
- node->link = jump;
- }
- next->link = NULL;
- }
- del_label(node, next);
- next = node->next;
- continue;
- }
- }
- prev = node;
- }
-}
-
-static jit_bool_t
-_shortcut_jump(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node)
-{
- jit_bool_t cond;
- jit_node_t *jump;
- jit_node_t *next;
- jit_node_t *temp;
-
- if (!(node->flag & jit_flag_node))
- return (0);
- assert(node->code != jit_code_jmpr);
- cond = node->code != jit_code_jmpi;
- jump = node->u.n;
- for (next = jump->next; next; next = next->next) {
- switch (next->code) {
- case jit_code_jmpi:
- if (!(next->flag & jit_flag_node))
- return (0);
- if (jump->link == node)
- jump->link = node->link;
- else {
- for (temp = jump->link;
- temp->link != node;
- temp = temp->link)
- assert(temp != NULL);
- temp->link = node->link;
- }
- jump = next->u.n;
- node->u.n = jump;
- node->link = jump->link;
- jump->link = node;
- return (1);
- case jit_code_jmpr:
- if (cond)
- return (0);
- node->code = jit_code_jmpr;
- node->u.w = next->u.w;
- node->link = NULL;
- node->flag &= ~jit_flag_node;
- return (1);
- case jit_code_note: case jit_code_label:
- break;
- default:
- return (0);
- }
- }
- return (0);
-}
-
-static jit_bool_t
-_redundant_jump(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node)
-{
- jit_node_t *local_prev;
- jit_node_t *local_next;
-
- if (!(node->flag & jit_flag_node))
- return (0);
- for (local_prev = node, local_next = node->next;
- local_next;
- local_prev = local_next, local_next = local_next->next) {
-
- switch (local_next->code) {
- case jit_code_label: case jit_code_epilog:
- if (node->u.n == local_next) {
- if (local_next->link == node)
- local_next->link = node->link;
- else {
- for (local_prev = local_next->link;
- local_prev->link != node;
- local_prev = local_prev->link)
- assert(local_prev != NULL);
- local_prev->link = node->link;
- }
- del_node(prev, node);
- return (1);
- }
- break;
- case jit_code_name: case jit_code_note:
- case jit_code_align:
- break;
- default:
- return (0);
- }
- }
- return (0);
-}
-
-static jit_code_t
-reverse_jump_code(jit_code_t code)
-{
- switch (code) {
- case jit_code_bltr: return (jit_code_bger);
- case jit_code_blti: return (jit_code_bgei);
- case jit_code_bltr_u: return (jit_code_bger_u);
- case jit_code_blti_u: return (jit_code_bgei_u);
- case jit_code_bler: return (jit_code_bgtr);
- case jit_code_blei: return (jit_code_bgti);
- case jit_code_bler_u: return (jit_code_bgtr_u);
- case jit_code_blei_u: return (jit_code_bgti_u);
- case jit_code_beqr: return (jit_code_bner);
- case jit_code_beqi: return (jit_code_bnei);
- case jit_code_bger: return (jit_code_bltr);
- case jit_code_bgei: return (jit_code_blti);
- case jit_code_bger_u: return (jit_code_bltr_u);
- case jit_code_bgei_u: return (jit_code_blti_u);
- case jit_code_bgtr: return (jit_code_bler);
- case jit_code_bgti: return (jit_code_blei);
- case jit_code_bgtr_u: return (jit_code_bler_u);
- case jit_code_bgti_u: return (jit_code_blei_u);
- case jit_code_bner: return (jit_code_beqr);
- case jit_code_bnei: return (jit_code_beqi);
- case jit_code_bmsr: return (jit_code_bmcr);
- case jit_code_bmsi: return (jit_code_bmci);
- case jit_code_bmcr: return (jit_code_bmsr);
- case jit_code_bmci: return (jit_code_bmsi);
- case jit_code_bltr_f: return (jit_code_bunger_f);
- case jit_code_blti_f: return (jit_code_bungei_f);
- case jit_code_bler_f: return (jit_code_bungtr_f);
- case jit_code_blei_f: return (jit_code_bungti_f);
-
- case jit_code_beqr_f: return (jit_code_bner_f);
- case jit_code_beqi_f: return (jit_code_bnei_f);
-
- case jit_code_bger_f: return (jit_code_bunltr_f);
- case jit_code_bgei_f: return (jit_code_bunlti_f);
- case jit_code_bgtr_f: return (jit_code_bunler_f);
- case jit_code_bgti_f: return (jit_code_bunlei_f);
-
- case jit_code_bner_f: return (jit_code_beqr_f);
- case jit_code_bnei_f: return (jit_code_beqr_f);
-
- case jit_code_bunltr_f: return (jit_code_bger_f);
- case jit_code_bunlti_f: return (jit_code_bgei_f);
- case jit_code_bunler_f: return (jit_code_bgtr_f);
- case jit_code_bunlei_f: return (jit_code_bgti_f);
-
- case jit_code_buneqr_f: return (jit_code_bltgtr_f);
- case jit_code_buneqi_f: return (jit_code_bltgti_f);
-
- case jit_code_bunger_f: return (jit_code_bltr_f);
- case jit_code_bungei_f: return (jit_code_blti_f);
- case jit_code_bungtr_f: return (jit_code_bler_f);
- case jit_code_bungti_f: return (jit_code_blei_f);
-
- case jit_code_bltgtr_f: return (jit_code_buneqr_f);
- case jit_code_bltgti_f: return (jit_code_buneqi_f);
-
- case jit_code_bordr_f: return (jit_code_bunordr_f);
- case jit_code_bordi_f: return (jit_code_bunordi_f);
- case jit_code_bunordr_f:return (jit_code_bordr_f);
- case jit_code_bunordi_f:return (jit_code_bordi_f);
- case jit_code_bltr_d: return (jit_code_bunger_d);
- case jit_code_blti_d: return (jit_code_bungei_d);
- case jit_code_bler_d: return (jit_code_bungtr_d);
- case jit_code_blei_d: return (jit_code_bungti_d);
-
- case jit_code_beqr_d: return (jit_code_bner_d);
- case jit_code_beqi_d: return (jit_code_bnei_d);
-
- case jit_code_bger_d: return (jit_code_bunltr_d);
- case jit_code_bgei_d: return (jit_code_bunlti_d);
- case jit_code_bgtr_d: return (jit_code_bunler_d);
- case jit_code_bgti_d: return (jit_code_bunlei_d);
-
- case jit_code_bner_d: return (jit_code_beqr_d);
- case jit_code_bnei_d: return (jit_code_beqi_d);
-
- case jit_code_bunltr_d: return (jit_code_bger_d);
- case jit_code_bunlti_d: return (jit_code_bgei_d);
- case jit_code_bunler_d: return (jit_code_bgtr_d);
- case jit_code_bunlei_d: return (jit_code_bgti_d);
-
- case jit_code_buneqr_d: return (jit_code_bltgtr_d);
- case jit_code_buneqi_d: return (jit_code_bltgti_d);
-
- case jit_code_bunger_d: return (jit_code_bltr_d);
- case jit_code_bungei_d: return (jit_code_blti_d);
- case jit_code_bungtr_d: return (jit_code_bler_d);
- case jit_code_bungti_d: return (jit_code_blei_d);
-
- case jit_code_bltgtr_d: return (jit_code_buneqr_d);
- case jit_code_bltgti_d: return (jit_code_buneqi_d);
-
- case jit_code_bordr_d: return (jit_code_bunordr_d);
- case jit_code_bordi_d: return (jit_code_bunordi_d);
- case jit_code_bunordr_d:return (jit_code_bordr_d);
- case jit_code_bunordi_d:return (jit_code_bordi_d);
- case jit_code_boaddr: return (jit_code_bxaddr);
- case jit_code_boaddi: return (jit_code_bxaddi);
- case jit_code_boaddr_u: return (jit_code_bxaddr_u);
- case jit_code_boaddi_u: return (jit_code_bxaddi_u);
- case jit_code_bxaddr: return (jit_code_boaddr);
- case jit_code_bxaddi: return (jit_code_boaddi);
- case jit_code_bxaddr_u: return (jit_code_boaddr_u);
- case jit_code_bxaddi_u: return (jit_code_boaddi_u);
- case jit_code_bosubr: return (jit_code_bxsubr);
- case jit_code_bosubi: return (jit_code_bxsubi);
- case jit_code_bosubr_u: return (jit_code_bxsubr_u);
- case jit_code_bosubi_u: return (jit_code_bxsubi_u);
- case jit_code_bxsubr: return (jit_code_bosubr);
- case jit_code_bxsubi: return (jit_code_bosubi);
- case jit_code_bxsubr_u: return (jit_code_bosubr_u);
- case jit_code_bxsubi_u: return (jit_code_bosubi_u);
- default: abort(); /* invalid jump code */
- }
-}
-
-/*
- * change common pattern:
- * <cond_jump L0> <jump L1> <label L0>
- * into
- * <reverse_cond_jump L1>
- */
-static jit_bool_t
-_reverse_jump(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node)
-{
- jit_node_t *local_prev;
- jit_node_t *local_next;
- jit_node_t *local_jump;
-
- if (!(node->flag & jit_flag_node))
- return (0);
- /* =><cond_jump L0> <jump L1> <label L0> */
- local_next = node->next;
- if (local_next->code != jit_code_jmpi ||
- !(local_next->flag & jit_flag_node))
- return (0);
- /* <cond_jump L0> =><jump L1> <label L0> */
-
- local_jump = local_next->u.n;
- for (local_prev = local_next, local_next = local_next->next;
- local_next;
- local_prev = local_next, local_next = local_next->next) {
- switch (local_next->code) {
- case jit_code_label: case jit_code_epilog:
- if (node->u.n == local_next) {
- if (local_next->link == node)
- local_next->link = node->link;
- else {
- for (local_prev = local_next->link;
- local_prev->link != node;
- local_prev = local_prev->link)
- assert(local_prev != NULL);
- local_prev->link = node->link;
- }
- del_node(node, node->next);
- node->code = reverse_jump_code(node->code);
- node->u.n = local_jump;
- node->link = local_jump->link;
- local_jump->link = node;
- return (1);
- }
- break;
- case jit_code_note:
- break;
- default:
- return (0);
- }
- }
- return (0);
-}
-
-static void
-_redundant_store(jit_state_t *_jit, jit_node_t *node, jit_bool_t jump)
-{
- jit_node_t *iter;
- jit_node_t *prev;
- jit_word_t word;
- int32_t spec;
- int32_t regno;
-
- if (jump) {
- prev = node->u.n;
- if (prev->code == jit_code_epilog)
- return;
- assert(prev->code == jit_code_label);
- if ((prev->flag & jit_flag_head) || node->link || prev->link != node)
- /* multiple sources */
- return;
- /* if there are sequential labels it will return below */
- }
- else
- prev = node;
- word = node->w.w;
- regno = jit_regno(node->v.w);
- for (iter = prev->next; iter; prev = iter, iter = iter->next) {
- switch (iter->code) {
- case jit_code_label: case jit_code_prolog:
- case jit_code_epilog:
- return;
- case jit_code_movi:
- if (regno == jit_regno(iter->u.w)) {
- if (iter->flag || iter->v.w != word)
- return;
- del_node(prev, iter);
- iter = prev;
- }
- break;
- default:
- spec = jit_classify(iter->code);
- if (spec & jit_cc_a0_jmp)
- return;
- if ((spec & (jit_cc_a0_reg|jit_cc_a0_chg)) ==
- (jit_cc_a0_reg|jit_cc_a0_chg)) {
- if (spec & jit_cc_a0_rlh) {
- if (regno == jit_regno(iter->u.q.l) ||
- regno == jit_regno(iter->u.q.h))
- return;
- }
- else {
- if (regno == jit_regno(iter->u.w))
- return;
- }
- }
- if ((spec & (jit_cc_a1_reg|jit_cc_a1_chg)) ==
- (jit_cc_a1_reg|jit_cc_a1_chg)) {
- if (regno == jit_regno(iter->v.w))
- return;
- }
- if ((spec & (jit_cc_a2_reg|jit_cc_a2_chg)) ==
- (jit_cc_a2_reg|jit_cc_a2_chg)) {
- if (regno == jit_regno(iter->w.w))
- return;
- }
- break;
- }
- }
-}
-
-static jit_bool_t
-_simplify_movr(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node,
- int32_t kind, jit_int32_t size)
-{
- int32_t regno;
- int32_t right;
- jit_value_t *value;
-
- regno = jit_regno(node->u.w);
- right = jit_regno(node->v.w);
- value = _jitc->values + regno;
- if ((value->kind == jit_kind_register &&
- jit_regno(value->base.q.l) == right &&
- value->base.q.h == _jitc->gen[right]) ||
- (value->kind == kind && _jitc->values[right].kind == kind &&
- memcmp(&value->base.w, &_jitc->values[right].base.w, size) == 0)) {
- del_node(prev, node);
- return (1);
- }
- if (_jitc->values[right].kind == jit_kind_word)
- jit_memcpy(value, _jitc->values + right, sizeof(jit_value_t));
- else {
- value->kind = jit_kind_register;
- value->base.q.l = right;
- value->base.q.h = _jitc->gen[right];
- }
- ++_jitc->gen[regno];
-
- return (0);
-}
-
-static jit_bool_t
-_simplify_movi(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node,
- int32_t kind, jit_int32_t size)
-{
- jit_value_t *value;
- int32_t spec;
- int32_t regno;
- int32_t offset;
-
- regno = jit_regno(node->u.w);
- value = _jitc->values + regno;
- if (node->flag & jit_flag_node) {
- /* set to undefined if value will be patched */
- value->kind = 0;
- ++_jitc->gen[regno];
- return (0);
- }
- if (value->kind == kind) {
- if (memcmp(&node->v.w, &value->base.w, size) == 0) {
- del_node(prev, node);
- return (1);
- }
- spec = jit_class(_rvs[regno].spec);
- if (kind == jit_kind_word)
- spec &= jit_class_gpr;
- else
- spec &= (jit_class_xpr | jit_class_fpr);
- for (offset = 0; offset < _jitc->reglen; offset++) {
- if (_jitc->values[offset].kind == kind &&
- memcmp(&node->v.w, &_jitc->values[offset].base.w, size) == 0 &&
- (jit_class(_rvs[offset].spec) & spec) == spec) {
- if (kind == jit_kind_word)
- node->code = jit_code_movr;
- else if (kind == jit_kind_float32)
- node->code = jit_code_movr_f;
- else
- node->code = jit_code_movr_d;
- node->v.w = offset;
- jit_memcpy(value, _jitc->values + offset, sizeof(jit_value_t));
- ++_jitc->gen[regno];
- return (0);
- }
- }
- }
- value->kind = kind;
- jit_memcpy(&value->base.w, &node->v.w, size);
- ++_jitc->gen[regno];
-
- return (0);
-}
-
-/* simple/safe redundandy test not checking if another register
- * holds the same value
- */
-static jit_bool_t
-_simplify_ldxi(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node)
-{
- jit_value_t *value;
- int32_t regno;
- int32_t right;
-
- regno = jit_regno(node->u.w);
- right = jit_regno(node->v.w);
- value = _jitc->values + regno;
- if (regno != right &&
- value->kind == jit_kind_code && value->code == node->code &&
- value->base.q.l == right && value->base.q.h == _jitc->gen[right] &&
- node->w.w == value->disp.w) {
- del_node(prev, node);
- return (1);
- }
- value->kind = jit_kind_code;
- value->code = node->code;
- value->base.q.l = right;
- value->base.q.h = _jitc->gen[right];
- value->disp.w = node->w.w;
- ++_jitc->gen[regno];
-
- return (0);
-}
-
-static jit_bool_t
-_simplify_stxi(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node)
-{
- jit_value_t *value;
- int32_t regno;
- int32_t right;
- int32_t offset;
-
- regno = jit_regno(node->w.w);
- right = jit_regno(node->v.w);
- value = _jitc->values + regno;
-
- /* check for redundant store after load */
- if (regno != right &&
- value->kind == jit_kind_code && value->code == node->code &&
- value->base.q.l == right && value->base.q.h == _jitc->gen[right] &&
- node->u.w == value->disp.w) {
- del_node(prev, node);
- return (1);
- }
-
- /* assume anything can alias, and invalidate tracked values */
- for (offset = 0; offset < _jitc->reglen; offset++) {
- if (_jitc->values[offset].kind == jit_kind_code) {
- _jitc->values[offset].kind = 0;
- ++_jitc->gen[offset];
- }
- }
-
- /* no multiple information, so, if set to a constant,
- * prefer to keep that information */
- if (value->kind == 0) {
- value->kind = jit_kind_code;
- switch (node->code) {
- /* no information about signed/unsigned either */
- case jit_code_stxi_c: value->code = jit_code_ldxi_c; break;
- case jit_code_stxi_s: value->code = jit_code_ldxi_s; break;
- case jit_code_stxi_i: value->code = jit_code_ldxi_i; break;
- case jit_code_stxi_l: value->code = jit_code_ldxi_l; break;
- case jit_code_stxi_f: value->code = jit_code_ldxi_f; break;
- case jit_code_stxi_d: value->code = jit_code_ldxi_d; break;
- default: abort();
- }
- value->kind = jit_kind_code;
- value->base.q.l = right;
- value->base.q.h = _jitc->gen[right];
- value->disp.w = node->u.w;
- }
-
- return (0);
-}
-
-/* usually there should be only one store in the
- * jit_get_reg/jit_unget_reg, but properly handle
- * multiple ones by moving the save node */
-static void
-_simplify_spill(jit_state_t *_jit, jit_node_t *node, int32_t regno)
-{
- jit_node_t *save;
- jit_node_t *temp;
-
- if ((temp = _jitc->spill[regno]) && (save = temp->next) != node) {
- temp->next = save->next;
- save->next = node->next;
- node->next = save;
- _jitc->spill[regno] = node;
- }
-}
-
-/* checks for simple cases where a register is set more than
- * once to the same value, and is a common pattern of calls
- * to jit_pushargi and jit_pushargr
- */
-static void
-_simplify(jit_state_t *_jit)
-{
- jit_node_t *prev;
- jit_node_t *node;
- jit_node_t *next;
- int32_t info;
- int32_t regno;
-
- for (prev = NULL, node = _jitc->head; node; prev = node, node = next) {
- next = node->next;
- switch (node->code) {
- case jit_code_label: case jit_code_prolog:
- case jit_code_callr: case jit_code_calli:
- reset:
- memset(_jitc->gen, 0, sizeof(int32_t) * _jitc->reglen);
- memset(_jitc->values, 0, sizeof(jit_value_t) * _jitc->reglen);
- break;
- case jit_code_save:
- _jitc->spill[jit_regno(node->u.w)] = prev;
- break;
- case jit_code_load:
- regno = jit_regno(node->u.w);
- if (register_change_p(node->link->next, node, regno) !=
- jit_reg_change) {
- /* spill not required due to optimizing common
- * redundancy case of calling jit_get_reg/jit_unget_reg
- * and then setting the register to the value it is
- * already holding */
- patch_register(node->link->next, node,
- jit_regno_patch|regno, regno);
- del_node(_jitc->spill[regno], node->link);
- del_node(prev, node);
- node = prev;
- }
- _jitc->spill[regno] = NULL;
- break;
- case jit_code_movr:
- regno = jit_regno(node->u.w);
- if (simplify_movr(prev, node,
- jit_kind_word, sizeof(jit_word_t)))
- simplify_spill(node = prev, regno);
- break;
- case jit_code_movi:
- regno = jit_regno(node->u.w);
- if (simplify_movi(prev, node,
- jit_kind_word, sizeof(jit_word_t)))
- simplify_spill(node = prev, regno);
- break;
- case jit_code_movr_f:
- regno = jit_regno(node->u.w);
- if (simplify_movr(prev, node,
- jit_kind_float32, sizeof(jit_float32_t)))
- simplify_spill(node = prev, regno);
- break;
- case jit_code_movi_f:
- regno = jit_regno(node->u.w);
- if (simplify_movi(prev, node,
- jit_kind_float32, sizeof(jit_float32_t)))
- simplify_spill(node = prev, regno);
- break;
- case jit_code_movr_d:
- regno = jit_regno(node->u.w);
- if (simplify_movr(prev, node,
- jit_kind_float64, sizeof(jit_float64_t)))
- simplify_spill(node = prev, regno);
- break;
- case jit_code_movi_d:
- regno = jit_regno(node->u.w);
- if (simplify_movi(prev, node,
- jit_kind_float64, sizeof(jit_float64_t)))
- simplify_spill(node = prev, regno);
- break;
- case jit_code_ldxi_c: case jit_code_ldxi_uc:
- case jit_code_ldxi_s: case jit_code_ldxi_us:
- case jit_code_ldxi_i: case jit_code_ldxi_ui:
- case jit_code_ldxi_l:
- case jit_code_ldxi_f: case jit_code_ldxi_d:
- regno = jit_regno(node->u.w);
- if (simplify_ldxi(prev, node))
- simplify_spill(node = prev, regno);
- break;
- case jit_code_stxi_c: case jit_code_stxi_s:
- case jit_code_stxi_i: case jit_code_stxi_l:
- case jit_code_stxi_f: case jit_code_stxi_d:
- regno = jit_regno(node->u.w);
- if (simplify_stxi(prev, node))
- simplify_spill(node = prev, regno);
- break;
- default:
- info = jit_classify(node->code);
- if (info & jit_cc_a0_jmp)
- /* labels are not implicitly added when not taking
- * a conditional branch */
- goto reset;
- if (info & jit_cc_a0_chg) {
- if (info & jit_cc_a0_rlh) {
- regno = jit_regno(node->u.q.l);
- _jitc->values[regno].kind = 0;
- ++_jitc->gen[regno];
- regno = jit_regno(node->u.q.h);
- _jitc->values[regno].kind = 0;
- ++_jitc->gen[regno];
- }
- else {
- regno = jit_regno(node->u.w);
- _jitc->values[regno].kind = 0;
- ++_jitc->gen[regno];
- }
- }
- if (info & jit_cc_a1_chg) {
- regno = jit_regno(node->v.w);
- _jitc->values[regno].kind = 0;
- ++_jitc->gen[regno];
- }
- if (info & jit_cc_a2_chg) {
- regno = jit_regno(node->w.w);
- _jitc->values[regno].kind = 0;
- ++_jitc->gen[regno];
- }
- break;
- }
- }
-}
-
-static int32_t
-_register_change_p(jit_state_t *_jit, jit_node_t *node, jit_node_t *link,
- int32_t regno)
-{
- int32_t value;
-
- for (; node != link; node = node->next) {
- switch (node->code) {
- case jit_code_label: case jit_code_prolog:
- /* lack of extra information so cannot say it is undefined */
- return (jit_reg_change);
- case jit_code_callr: case jit_code_calli:
- if (!(jit_class(_rvs[regno].spec) & jit_class_sav))
- return (jit_reg_undef);
- break;
- default:
- value = jit_classify(node->code);
- /* lack of extra information */
- if (value & jit_cc_a0_jmp)
- return (jit_reg_change);
- else if ((value & (jit_cc_a0_reg|jit_cc_a0_chg)) ==
- (jit_cc_a0_reg|jit_cc_a0_chg) &&
- (((value & jit_cc_a0_rlh) &&
- (node->u.q.l == regno || node->u.q.h == regno)) ||
- (!(value & jit_cc_a0_rlh) &&
- node->u.w == regno)))
- return (jit_reg_change);
- else if ((value & jit_cc_a1_reg) && node->v.w == regno &&
- (value & jit_cc_a1_chg))
- return (jit_reg_change);
- else if ((value & jit_cc_a2_reg) && node->w.w == regno &&
- (value & jit_cc_a2_chg))
- return (jit_reg_change);
- }
- }
-
- return (jit_reg_static);
-}
-
-/* most of this could be done at the same time as generating jit, but
- * avoid complications on different cpu backends and patch spill/loads
- * here, by simulating jit generation */
-static jit_bool_t
-_spill_reglive_p(jit_state_t *_jit, jit_node_t *node, int32_t regno)
-{
- if (!jit_regset_tstbit(&_jitc->reglive, regno)) {
- bmp_zero();
- jit_regset_setbit(&_jitc->regmask, regno);
- jit_update(node->next, &_jitc->reglive, &_jitc->regmask, 1);
- if (!jit_regset_tstbit(&_jitc->reglive, regno) &&
- register_change_p(node->next, node->link, regno) != jit_reg_change)
- return (0);
- }
-
- return (1);
-}
-
-static void
-_patch_registers(jit_state_t *_jit)
-{
- jit_node_t *prev;
- jit_node_t *node;
- jit_node_t *next;
- int32_t info;
- int32_t spec;
- int32_t regno;
- int32_t value;
-
- _jitc->function = NULL;
-
- jit_reglive_setup();
- for (prev = NULL, node = _jitc->head; node; node = next) {
- next = node->next;
-
- info = jit_classify(node->code);
- jit_regarg_set(node, info);
-
- switch (node->code) {
- case jit_code_save:
- regno = jit_regno(node->u.w);
- if (!spill_reglive_p(node, regno)) {
- /* register is not live, just remove spill/reload */
- jit_regarg_clr(node, info);
- node->link->v.w = jit_regload_delete;
- del_node(prev, node);
- continue;
- }
- else {
- /* try to find a free register of the same class */
- spec = jit_class(_rvs[regno].spec) & ~jit_class_arg;
- for (value = 0; value < _jitc->reglen; value++) {
- if (value != regno &&
- ((jit_class(_rvs[value].spec) & spec) &
- ~jit_class_arg) == spec &&
- !jit_regset_tstbit(&_jitc->regarg, value) &&
- !spill_reglive_p(node, value))
- break;
- }
- if (value < _jitc->reglen) {
- jit_regarg_clr(node, info);
- patch_register(node->next, node->link,
- jit_regno_patch|node->u.w,
- jit_regno_patch|value);
- /* mark as live just in case there are nested
- * register patches, so that next patch will
- * not want to use the same register */
- jit_regset_setbit(&_jitc->reglive, value);
- /* register is not live, just remove spill/reload */
- node->link->v.w = jit_regload_isdead;
- del_node(prev, node);
- continue;
- }
- else {
- /* failed to find a free register */
- if (spec & jit_class_gpr) {
- if (!_jitc->function->regoff[regno])
- _jitc->function->regoff[regno] =
- jit_allocai(sizeof(jit_word_t));
-#if __WORDSIZE == 32
- node->code = jit_code_stxi_i;
-#else
- node->code = jit_code_stxi_l;
-#endif
- }
- else {
- node->code = jit_code_stxi_d;
- if (!_jitc->function->regoff[regno])
- _jitc->function->regoff[regno] =
- jit_allocai(sizeof(jit_float64_t));
- }
- node->u.w = _jitc->function->regoff[regno];
- node->v.w = JIT_FP;
- node->w.w = regno;
- node->link = NULL;
- }
- }
- break;
- case jit_code_load:
- regno = jit_regno(node->u.w);
- if (node->v.w) {
- if (node->v.w == jit_regload_isdead)
- jit_regset_clrbit(&_jitc->reglive, regno);
- del_node(prev, node);
- continue;
- }
- spec = jit_class(_rvs[regno].spec);
- if (spec & jit_class_gpr) {
-#if __WORDSIZE == 32
- node->code = jit_code_ldxi_i;
-#else
- node->code = jit_code_ldxi_l;
-#endif
- }
- else
- node->code = jit_code_ldxi_d;
- node->v.w = regno;
- node->v.w = JIT_FP;
- node->w.w = _jitc->function->regoff[regno];
- node->link = NULL;
- break;
- case jit_code_prolog:
- _jitc->function = _jitc->functions.ptr + node->w.w;
- break;
- case jit_code_epilog:
- _jitc->function = NULL;
- break;
- default:
- break;
- }
-
- jit_regarg_clr(node, info);
- /* update register live state */
- jit_reglive(node);
- prev = node;
- }
-}
-
-static void
-_patch_register(jit_state_t *_jit, jit_node_t *node, jit_node_t *link,
- int32_t regno, jit_int32_t patch)
-{
- int32_t value;
-
- for (; node != link; node = node->next) {
- value = jit_classify(node->code);
- if (value & jit_cc_a0_reg) {
- if (value & jit_cc_a0_rlh) {
- if (node->u.q.l == regno)
- node->u.q.l = patch;
- if (node->u.q.h == regno)
- node->u.q.h = patch;
- }
- else {
- if (node->u.w == regno)
- node->u.w = patch;
- }
- }
- if ((value & jit_cc_a1_reg) && node->v.w == regno)
- node->v.w = patch;
- if ((value & jit_cc_a2_reg) && node->w.w == regno)
- node->w.w = patch;
- }
+ if (reloc == _jit->last_instruction)
+ jit_patch_last (_jit, reloc, addr);
+ else
+ jit_patch (_jit, reloc, addr);
}
#if defined(__i386__) || defined(__x86_64__)
diff --git a/jit/private.h b/jit/private.h
index c52767b..41bbdc1 100644
--- a/jit/private.h
+++ b/jit/private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2017 Free Software Foundation, Inc.
+ * Copyright (C) 2012-2018 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -55,7 +55,6 @@
# define JIT_RET _RAX
# if __X32
# define JIT_FRET _ST0
-typedef uint32_t jit_regset_t;
# else
# if __CYGWIN__
# define JIT_RA0 _RCX
@@ -64,7 +63,6 @@ typedef uint32_t jit_regset_t;
# endif
# define JIT_FA0 _XMM0
# define JIT_FRET _XMM0
-typedef uint64_t jit_regset_t;
# endif
#elif defined(__mips__)
# define JIT_RA0 _A0
@@ -72,7 +70,6 @@ typedef uint64_t jit_regset_t;
# define JIT_SP _SP
# define JIT_RET _V0
# define JIT_FRET _F0
-typedef uint64_t jit_regset_t;
#elif defined(__arm__)
# define JIT_RA0 _R0
# define JIT_FA0 _D0
@@ -83,139 +80,40 @@ typedef uint64_t jit_regset_t;
# else
# define JIT_FRET _R0
# endif
-typedef uint64_t jit_regset_t;
#elif defined(__ppc__) || defined(__powerpc__)
# define JIT_RA0 _R3
# define JIT_FA0 _F1
# define JIT_SP _R1
# define JIT_RET _R3
# define JIT_FRET _F1
-typedef uint64_t jit_regset_t;
#elif defined(__sparc__)
# define JIT_SP _SP
# define JIT_RET _I0
# define JIT_FRET _F0
-# if __WORDSIZE == 32
-typedef uint64_t jit_regset_t;
-# else
-typedef struct {
- uint64_t rl;
- uint64_t rh;
-} jit_regset_t;
-# endif
#elif defined(__ia64__)
# define JIT_SP _R12
# define JIT_RET _R8
# define JIT_FRET _F8
-typedef struct {
- uint64_t rl;
- uint64_t rh;
- uint64_t fl;
- uint64_t fh;
-} jit_regset_t;
#elif defined(__hppa__)
# define JIT_SP _R30
# define JIT_RET _R28
# define JIT_FRET _F4
-typedef uint64_t jit_regset_t;
#elif defined(__aarch64__)
# define JIT_RA0 _R0
# define JIT_FA0 _V0
# define JIT_SP _SP
# define JIT_RET _R0
# define JIT_FRET _V0
-typedef uint64_t jit_regset_t;
#elif defined(__s390__) || defined(__s390x__)
# define JIT_SP _R15
# define JIT_RET _R2
# define JIT_FRET _F0
-typedef uint32_t jit_regset_t;
#elif defined(__alpha__)
# define JIT_SP _SP
# define JIT_RET _V0
# define JIT_FRET _F0
-typedef uint64_t jit_regset_t;
#endif
-#define jit_data(u,v,w) _jit_data(_jit,u,v,w)
-extern jit_node_t *_jit_data(jit_state_t*, const void*,
- jit_word_t, int32_t);
-
-#define jit_size(vector) (sizeof(vector) / sizeof((vector)[0]))
-
-#define jit_reg_free_p(regno) \
- (!jit_regset_tstbit(&_jitc->reglive, regno) && \
- !jit_regset_tstbit(&_jitc->regarg, regno) && \
- !jit_regset_tstbit(&_jitc->regsav, regno))
-
-#define jit_reg_free_if_spill_p(regno) \
- (!jit_regset_tstbit(&_jitc->regarg, regno) && \
- !jit_regset_tstbit(&_jitc->regsav, regno))
-
-#define jit_inc_synth(code) \
- do { \
- (void)jit_new_node(jit_code_##code); \
- jit_synth_inc(); \
- } while (0)
-#define jit_inc_synth_w(code, u) \
- do { \
- (void)jit_new_node_w(jit_code_##code, u); \
- jit_synth_inc(); \
- } while (0)
-#define jit_inc_synth_f(code, u) \
- do { \
- (void)jit_new_node_f(jit_code_##code, u); \
- jit_synth_inc(); \
- } while (0)
-#define jit_inc_synth_d(code, u) \
- do { \
- (void)jit_new_node_d(jit_code_##code, u); \
- jit_synth_inc(); \
- } while (0)
-#define jit_inc_synth_ww(code, u, v) \
- do { \
- (void)jit_new_node_ww(jit_code_##code, u, v); \
- jit_synth_inc(); \
- } while (0)
-#define jit_inc_synth_wp(code, u, v) \
- do { \
- (void)jit_new_node_wp(jit_code_##code, u, v); \
- jit_synth_inc(); \
- } while (0)
-#define jit_inc_synth_fp(code, u, v) \
- do { \
- (void)jit_new_node_fp(jit_code_##code, u, v); \
- jit_synth_inc(); \
- } while (0)
-#define jit_inc_synth_dp(code, u, v) \
- do { \
- (void)jit_new_node_dp(jit_code_##code, u, v); \
- jit_synth_inc(); \
- } while (0)
-#define jit_dec_synth() jit_synth_dec()
-
-#define jit_link_prolog() \
- do { \
- _jitc->tail->link = _jitc->function->prolog->link; \
- _jitc->function->prolog->link = _jitc->tail; \
- } while (0)
-#define jit_link_prepare() \
- do { \
- _jitc->tail->link = _jitc->prepare->link; \
- _jitc->prepare->link = _jitc->tail; \
- } while (0)
-#define jit_link_reverse(where)
\
- do { \
- jit_node_t *tmp, *tail = 0; \
- while (where) { \
- tmp = (where)->link; \
- (where)->link = tail; \
- tail = where; \
- where = tmp; \
- } \
- where = tail; \
- } while (0);
-
/*
* Private jit_class bitmasks
*/
@@ -232,368 +130,11 @@ extern jit_node_t *_jit_data(jit_state_t*, const void*,
* returned by a "user" call
* to jit_get_reg() */
-#define jit_call_default 0
-#define jit_call_varargs 1
-
-#define jit_kind_register 1
-#define jit_kind_code 2
-#define jit_kind_word 3
-#define jit_kind_float32 4
-#define jit_kind_float64 5
-
-#define jit_cc_a0_reg 0x00000001 /* arg0 is a register */
-#define jit_cc_a0_chg 0x00000002 /* arg0 is modified */
-#define jit_cc_a0_jmp 0x00000004 /* arg0 is a jump target */
-#define jit_cc_a0_rlh 0x00000008 /* arg0 is a register pair */
-#define jit_cc_a0_int 0x00000010 /* arg0 is immediate word */
-#define jit_cc_a0_flt 0x00000020 /* arg0 is immediate float */
-#define jit_cc_a0_dbl 0x00000040 /* arg0 is immediate double */
-#define jit_cc_a0_arg 0x00000080 /* arg1 is an argument int id */
-#define jit_cc_a1_reg 0x00000100 /* arg1 is a register */
-#define jit_cc_a1_chg 0x00000200 /* arg1 is modified */
-#define jit_cc_a1_int 0x00001000 /* arg1 is immediate word */
-#define jit_cc_a1_flt 0x00002000 /* arg1 is immediate float */
-#define jit_cc_a1_dbl 0x00004000 /* arg1 is immediate double */
-#define jit_cc_a1_arg 0x00008000 /* arg1 is an argument node */
-#define jit_cc_a2_reg 0x00010000 /* arg2 is a register */
-#define jit_cc_a2_chg 0x00020000 /* arg2 is modified */
-#define jit_cc_a2_int 0x00100000 /* arg2 is immediate word */
-#define jit_cc_a2_flt 0x00200000 /* arg2 is immediate float */
-#define jit_cc_a2_dbl 0x00400000 /* arg2 is immediate double */
-
-#if __ia64__ || (__sparc__ && __WORDSIZE == 64)
-extern void
-jit_regset_com(jit_regset_t*, jit_regset_t*);
-
-extern void
-jit_regset_and(jit_regset_t*, jit_regset_t*, jit_regset_t*);
-
-extern void
-jit_regset_ior(jit_regset_t*, jit_regset_t*, jit_regset_t*);
-
-extern void
-jit_regset_xor(jit_regset_t*, jit_regset_t*, jit_regset_t*);
-
-extern void
-jit_regset_set(jit_regset_t*, jit_regset_t*);
-
-extern void
-jit_regset_set_mask(jit_regset_t*, int32_t);
-
-extern jit_bool_t
-jit_regset_cmp_ui(jit_regset_t*, jit_word_t);
-
-extern void
-jit_regset_set_ui(jit_regset_t*, jit_word_t);
-
-extern jit_bool_t
-jit_regset_set_p(jit_regset_t*);
-
-extern void
-jit_regset_clrbit(jit_regset_t*, int32_t);
-
-extern void
-jit_regset_setbit(jit_regset_t*, int32_t);
-
-extern jit_bool_t
-jit_regset_tstbit(jit_regset_t*, int32_t);
-# 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)
\
- 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))
-# define jit_regset_ior(u, v, w) (*(u) = *(v) | *(w))
-# define jit_regset_xor(u, v, w) (*(u) = *(v) ^ *(w))
-# define jit_regset_set(u, v) (*(u) = *(v))
-# define jit_regset_set_mask(u, v) (*(u) = (1LL << (v)) - 1)
-# define jit_regset_cmp_ui(u, v) (*(u) != (v))
-# define jit_regset_set_ui(u, v) (*(u) = (v))
-# define jit_regset_set_p(set) (*set)
-# define jit_regset_clrbit(set, bit) (*(set) &= ~(1LL << (bit)))
-# define jit_regset_setbit(set, bit) (*(set) |= 1LL << (bit))
-# define jit_regset_tstbit(set, bit) (*(set) & (1LL << (bit)))
-# define jit_regset_new(set) (*(set) = 0)
-# define jit_regset_del(set) (*(set) = 0)
-#endif
-extern unsigned long
-jit_regset_scan1(jit_regset_t*, int32_t);
-
-#define jit_reglive_setup() \
- do { \
- jit_regset_set_ui(&_jitc->reglive, 0); \
- jit_regset_set_ui(&_jitc->regmask, 0); \
- } while (0)
-
/*
* Types
*/
-typedef union jit_data jit_data_t;
-typedef struct jit_note jit_note_t;
-typedef struct jit_line jit_line_t;
-typedef struct jit_block jit_block_t;
-typedef struct jit_value jit_value_t;
-typedef struct jit_compiler jit_compiler_t;
-typedef struct jit_function jit_function_t;
typedef struct jit_register jit_register_t;
-#if __arm__
-# if DISASSEMBLER
-typedef struct jit_data_info jit_data_info_t;
-# endif
-#endif
-union jit_data {
- struct {
-#if __BYTE_ORDER == __LITTLE_ENDIAN
- int32_t l;
- int32_t h;
-#else
- int32_t h;
- int32_t l;
-#endif
- } q;
- jit_word_t w;
- jit_float32_t f;
- jit_float64_t d;
- jit_pointer_t p;
- jit_node_t *n;
-};
-
-struct jit_note {
- uint8_t *code;
- char *name;
- jit_line_t *lines;
- jit_word_t length;
- jit_word_t size; /* of code */
-};
-
-struct jit_line {
- char *file;
- int32_t *linenos;
- int32_t *offsets;
- jit_word_t length;
-};
-
-struct jit_node {
- jit_node_t *next;
- jit_code_t code;
- uint16_t flag;
- uint16_t offset; /* Used if DEVEL_DISASSEMBLER */
- jit_data_t u;
- jit_data_t v;
- jit_data_t w;
- jit_node_t *link;
-};
-
-struct jit_block {
- jit_node_t *label;
- jit_regset_t reglive;
- jit_regset_t regmask;
- jit_regset_t setmask; /* Used for forward second pass */
-};
-
-struct jit_value {
- int32_t kind;
- jit_code_t code;
- jit_data_t base;
- jit_data_t disp;
-};
-
-typedef struct {
-#if __arm__
- jit_word_t kind;
-#endif
- jit_word_t inst;
- jit_node_t *node;
-} jit_patch_t;
-
-#if __arm__ && DISASSEMBLER
-struct jit_data_info {
- jit_uword_t code; /* pointer in code buffer */
- jit_word_t length; /* length of constant vector */
-};
-#endif
-
-struct jit_function {
- struct {
- int32_t argi;
- int32_t argf;
- int32_t size;
- int32_t aoff;
- int32_t alen;
- int32_t call;
- int32_t argn; /* for debug output */
- } self;
- struct {
- int32_t argi;
- int32_t argf;
- int32_t size;
- int32_t call;
- } call;
- jit_node_t *prolog;
- jit_node_t *epilog;
- int32_t *regoff;
- jit_regset_t regset;
- int32_t stack;
-
- /* Helper for common jit generation pattern, used in GNU Smalltalk
- * and possibly others, where a static frame layout is required or
- * assumed. */
- int32_t frame;
- uint32_t define_frame : 1;
- uint32_t assume_frame : 1;
-
- /* alloca offset offset */
- int32_t aoffoff;
- /* uses allocar flag */
- uint32_t allocar : 1;
-
- /* varargs state offsets */
- int32_t vaoff; /* offset of jit_va_list */
- int32_t vagp; /* first gp va argument */
- int32_t vafp; /* first fp va argument */
-};
-
-/* data used only during jit generation */
-struct jit_compiler {
-#if __ia64__
- struct {
- uint64_t i : 41;
- uint64_t t : 4;
- } inst[3];
- jit_regset_t regs; /* changed regs since last stop */
- int32_t pred; /* changed preds last stop */
- int32_t ioff; /* offset in inst vector */
- int32_t rout; /* first output register */
- int32_t breg; /* base register for prolog/epilog */
-#endif
-#if __mips__ || __ia64__ || __alpha__ || (__sparc__ && __WORDSIZE == 64)
- int32_t carry;
-#define jit_carry _jitc->carry
-#endif
- jit_node_t *head;
- jit_node_t *tail;
- jit_node_t *prepare; /* inside prepare/finish* block */
- uint32_t realize : 1; /* jit_realize() called? */
- uint32_t dataset : 1; /* jit_dataset() called? */
- uint32_t done : 1; /* emit state finished */
- uint32_t emit : 1; /* emit state entered */
- uint32_t again : 1; /* start over emiting function */
- uint32_t synth : 8; /* emiting synthesized instructions */
-#if DEBUG
- uint32_t getreg : 1;
-#endif
- uint32_t no_data : 1;
- uint32_t no_note : 1;
- int32_t reglen; /* number of registers */
- jit_regset_t regarg; /* cannot allocate */
- jit_regset_t regsav; /* automatic spill only once */
- jit_regset_t reglive; /* known live registers at some point */
- jit_regset_t regmask; /* register mask to update reglive */
- struct {
- jit_word_t *ptr;
- jit_word_t length;
- } blockmask; /* mask of visited basic blocks */
- struct {
- uint8_t *end;
- } code;
- struct {
- uint8_t *ptr;
- jit_node_t **table; /* very simple hash table */
- jit_word_t size; /* number of vectors in table */
- jit_word_t count; /* number of hash table entries */
- jit_word_t offset; /* offset in bytes in ptr */
- } data;
- jit_node_t **spill;
- int32_t *gen; /* ssa like "register version" */
- jit_value_t *values; /* temporary jit_value_t vector
*/
- struct {
- jit_block_t *ptr;
- jit_word_t offset;
- jit_word_t length;
- } blocks; /* basic blocks */
- struct {
- jit_patch_t *ptr;
- jit_word_t offset;
- jit_word_t length;
- } patches; /* forward patch information */
- jit_function_t *function; /* current function */
- struct {
- jit_function_t *ptr;
- jit_word_t offset;
- jit_word_t length;
- } functions; /* prolog/epilogue offsets in code */
- struct {
- jit_node_t **ptr;
- jit_word_t offset;
- jit_word_t length;
- } pool;
- jit_node_t *list;
- struct {
- jit_node_t *head; /* first note node */
- jit_node_t *tail; /* linked list insertion */
- /* fields to store temporary state information */
- jit_word_t size;
- jit_node_t *name;
- jit_node_t *note;
- uint8_t *base;
- } note;
-#if __arm__
- /* prevent using thumb instructions that set flags? */
- uint32_t no_set_flags : 1;
-# if DISASSEMBLER
- struct {
- jit_data_info_t *ptr;
- jit_word_t offset;
- jit_word_t length;
- } data_info; /* constant pools information */
-# endif
- /* Note that this field is somewhat hackish, but required by most
- * ways to implement jit, unless implementing a pure one function
- * per jit, as most times it needs to start the jit buffer with a
- * jump where the "main" prolog starts, and because the initial
- * code is in "arm mode", need to make an "arm mode" patch on that
- * jump. A good example is the test suite assembler, where most
- * test cases start with a "jmpi main" call. */
- jit_uword_t thumb;
- struct {
- uint8_t *data; /* pointer to code */
- jit_word_t size; /* size data */
- jit_word_t offset; /* pending patches */
- jit_word_t length; /* number of pending constants */
- int32_t values[1024]; /* pending constants */
- jit_word_t patches[2048];
- } consts;
-#elif __powerpc__ || __ia64__
- /* 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
-#if GET_JIT_SIZE
- /* Temporary storage to calculate instructions length */
- jit_word_t size;
- /* Global flag for code buffer heuristic size computation */
- jit_word_t mult;
- /* Pointer to code to prevent miscalculation if reallocating buffer */
- uint8_t *cptr;
-#endif
-};
-
-#define _jitc _jit->comp
struct jit_state {
union {
uint8_t *uc;
@@ -604,20 +145,9 @@ struct jit_state {
} pc;
struct {
uint8_t *ptr;
+ uint8_t *end;
jit_word_t length;
} code;
- struct {
- uint8_t *ptr;
- jit_word_t length;
- } data;
- struct {
- jit_note_t *ptr;
- jit_word_t length;
- } note;
- jit_compiler_t *comp;
- /* Flags to know if user did set the code and data buffers */
- uint32_t user_code : 1;
- uint32_t user_data : 1;
};
struct jit_register {
@@ -625,138 +155,9 @@ struct jit_register {
char *name;
};
-/*
- * Prototypes
- */
extern void jit_get_cpu(void);
+extern void jit_flush(void *fptr, void *tptr);
-#define jit_init() _jit_init(_jit)
-extern void _jit_init(jit_state_t*);
-
-#define jit_synth_inc() _jit_synth_inc(_jit)
-extern void _jit_synth_inc(jit_state_t*);
-
-#define jit_new_node_no_link(u) _jit_new_node_no_link(_jit, u)
-extern jit_node_t *_jit_new_node_no_link(jit_state_t*, jit_code_t);
-
-#define jit_link_node(u) _jit_link_node(_jit, u)
-extern void _jit_link_node(jit_state_t*, jit_node_t*);
-
-#define jit_link_label(l) _jit_link_label(_jit,l)
-extern void
-_jit_link_label(jit_state_t*,jit_node_t*);
-
-#define jit_synth_dec() _jit_synth_dec(_jit)
-extern void _jit_synth_dec(jit_state_t*);
-
-#define jit_reglive(node) _jit_reglive(_jit, node)
-extern void
-_jit_reglive(jit_state_t*, jit_node_t*);
-
-#define jit_regarg_set(n,v) _jit_regarg_set(_jit,n,v)
-extern void
-_jit_regarg_set(jit_state_t*, jit_node_t*, int32_t);
-
-#define jit_regarg_clr(n,v) _jit_regarg_clr(_jit,n,v)
-extern void
-_jit_regarg_clr(jit_state_t*, jit_node_t*, int32_t);
-
-#define jit_get_reg(s) _jit_get_reg(_jit,s)
-extern int32_t
-_jit_get_reg(jit_state_t*, int32_t);
-
-#define jit_unget_reg(r) _jit_unget_reg(_jit,r)
-extern void
-_jit_unget_reg(jit_state_t*, int32_t);
-
-#define jit_save(reg) _jit_save(_jit, reg)
-extern void
-_jit_save(jit_state_t*, int32_t);
-
-#define jit_load(reg) _jit_load(_jit, reg)
-extern void
-_jit_load(jit_state_t*, int32_t);
-
-#define jit_trampoline(u,v) _jit_trampoline(_jit, u, v)
-extern void _jit_trampoline(jit_state_t*, int32_t, jit_bool_t);
-
-#define jit_optimize() _jit_optimize(_jit)
-extern void
-_jit_optimize(jit_state_t*);
-
-#define jit_classify(code) _jit_classify(_jit, code)
-extern int32_t
-_jit_classify(jit_state_t*, jit_code_t);
-
-#define jit_regarg_p(n, r) _jit_regarg_p(_jit, n, r)
-extern jit_bool_t
-_jit_regarg_p(jit_state_t*, jit_node_t*, int32_t);
-
-#define emit_code() _emit_code(_jit)
-extern jit_pointer_t
-_emit_code(jit_state_t*);
-
-extern void
-jit_flush(void *fptr, void *tptr);
-
-#define emit_ldxi(r0, r1, i0) _emit_ldxi(_jit, r0, r1, i0)
-extern void
-_emit_ldxi(jit_state_t*, int32_t, jit_int32_t, jit_word_t);
-
-#define emit_stxi(i0, r0, r1) _emit_stxi(_jit, i0, r0, r1)
-extern void
-_emit_stxi(jit_state_t*, jit_word_t, int32_t, jit_int32_t);
-
-#define emit_ldxi_d(r0, r1, i0) _emit_ldxi_d(_jit, r0, r1, i0)
-extern void
-_emit_ldxi_d(jit_state_t*, int32_t, jit_int32_t, jit_word_t);
-
-#define emit_stxi_d(i0, r0, r1) _emit_stxi_d(_jit, i0, r0, r1)
-extern void
-_emit_stxi_d(jit_state_t*, jit_word_t, int32_t, jit_int32_t);
-
-extern void jit_init_debug(const char*);
-extern void jit_finish_debug(void);
-
-extern void jit_init_note(void);
-extern void jit_finish_note(void);
-#define jit_set_note(n,u,v,w) _jit_set_note(_jit, n, u, v, w)
-extern void _jit_set_note(jit_state_t*, jit_note_t*, char*, int, int32_t);
-#define jit_annotate() _jit_annotate(_jit)
-extern void _jit_annotate(jit_state_t*);
-
-#define jit_print_node(u) _jit_print_node(_jit,u)
-extern void _jit_print_node(jit_state_t*,jit_node_t*);
-
-extern jit_pointer_t jit_memcpy(jit_pointer_t,const void*,jit_word_t);
-extern jit_pointer_t jit_memmove(jit_pointer_t,const void*,jit_word_t);
-extern void jit_alloc(jit_pointer_t*, jit_word_t);
-extern void jit_realloc(jit_pointer_t*, jit_word_t, jit_word_t);
-void jit_free(jit_pointer_t*);
-
-extern void jit_init_size(void);
-extern void jit_finish_size(void);
-
-#if GET_JIT_SIZE
-# define jit_size_prepare() _jit_size_prepare(_jit)
-extern void
-_jit_size_prepare(jit_state_t*);
-
-# define jit_size_collect(node) _jit_size_collect(_jit, node)
-extern void
-_jit_size_collect(jit_state_t*, jit_node_t*);
-#else
-# define jit_get_size() _jit_get_size(_jit)
-extern jit_word_t
-_jit_get_size(jit_state_t*);
-#endif
-
-extern jit_word_t
-jit_get_max_instr(void);
-
-/*
- * Externs
- */
extern jit_register_t _rvs[];
#endif /* _jit_private_h */
- [Guile-commits] 72/86: Add int->float tests, (continued)
- [Guile-commits] 72/86: Add int->float tests, Andy Wingo, 2019/04/03
- [Guile-commits] 54/86: Add stxi tests, Andy Wingo, 2019/04/03
- [Guile-commits] 16/86: Create beginning of stripped-down lightning interface, Andy Wingo, 2019/04/03
- [Guile-commits] 84/86: Allow users to pass custom allocators, Andy Wingo, 2019/04/03
- [Guile-commits] 85/86: Fix jit_reset to be useful, Andy Wingo, 2019/04/03
- [Guile-commits] 76/86: Implement arg shuffling for jit_call{i,r}, Andy Wingo, 2019/04/03
- [Guile-commits] 86/86: Merge from upstream Lightening, Andy Wingo, 2019/04/03
- [Guile-commits] 81/86: Change headers and files to be named "lightening" instead of "jit", Andy Wingo, 2019/04/03
- [Guile-commits] 71/86: Add float/double cast inst tests, Andy Wingo, 2019/04/03
- [Guile-commits] 60/86: Add floating-point reg/reg compare-and-branch tests, Andy Wingo, 2019/04/03
- [Guile-commits] 20/86: Trim unneded bits from jit.c,
Andy Wingo <=
- [Guile-commits] 05/86: Inline body.texi and version.texi into lightning.texi, Andy Wingo, 2019/04/03
- [Guile-commits] 77/86: Provide some type safety for jit_gpr_t and jit_fpr_t, Andy Wingo, 2019/04/03
- [Guile-commits] 79/86: Replace GNU Lightning with Lightening, Andy Wingo, 2019/04/03
- [Guile-commits] 83/86: Adapt to lightning -> lightening name change, Andy Wingo, 2019/04/03
- [Guile-commits] 13/86: Remove -sz.c files, Andy Wingo, 2019/04/03
- [Guile-commits] 07/86: Archive lightning ChangeLog, Andy Wingo, 2019/04/03
- [Guile-commits] 74/86: Remove old tests, Andy Wingo, 2019/04/03
- [Guile-commits] 24/86: Really finish stdint conversion, Andy Wingo, 2019/04/03
- [Guile-commits] 29/86: Implementation of new design, Andy Wingo, 2019/04/03
- [Guile-commits] 17/86: Replace jit_int32_t, etc with stdint types, Andy Wingo, 2019/04/06