X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=deps%2Flightning%2Finclude%2Flightning%2Fjit_private.h;h=9f8caf654bada186699e61c5498298fc4063d08f;hb=d481fb64f2aac7a36532142cda11fa43f5ca792f;hp=e00e74d69ef5b84a6342ead0c44480d4d150c387;hpb=47e92264b0bcdd851e8b0973cd5036cc6ca8e4ba;p=pcsx_rearmed.git diff --git a/deps/lightning/include/lightning/jit_private.h b/deps/lightning/include/lightning/jit_private.h index e00e74d6..9f8caf65 100644 --- a/deps/lightning/include/lightning/jit_private.h +++ b/deps/lightning/include/lightning/jit_private.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2019 Free Software Foundation, Inc. + * Copyright (C) 2012-2023 Free Software Foundation, Inc. * * This file is part of GNU lightning. * @@ -55,6 +55,26 @@ # define HIDDEN /**/ #endif +#if PACKED_STACK || STRONG_TYPE_CHECKING +# define assert_arg_type(code, expect) \ + do assert((code) == (expect)); while (0) +# define assert_putarg_type(code, expect) \ + do \ + assert((((code) - jit_code_putargr_c) >> 2) == \ + ((expect) - jit_code_arg_c)); \ + while (0) +#else +# define assert_arg_type(code, expect) \ + do assert((int)(code) == (int)(expect) || \ + (code) == jit_code_arg); while (0) +# define assert_putarg_type(code, expect) \ + do \ + assert(((((code) - jit_code_putargr_c) >> 2) == \ + ((expect) - jit_code_arg_c)) || \ + ((code) == jit_code_arg)); \ + while (0) +#endif + #define rc(value) jit_class_##value #define rn(reg) (jit_regno(_rvs[jit_regno(reg)].spec)) @@ -150,6 +170,13 @@ typedef jit_uint64_t jit_regset_t; # define JIT_RET _A0 # define JIT_FRET _FA0 typedef jit_uint64_t jit_regset_t; +#elif defined(__loongarch__) +# define JIT_RA0 _A0 +# define JIT_FA0 _FA0 +# define JIT_SP _SP +# define JIT_RET _A0 +# define JIT_FRET _FA0 +typedef jit_uint64_t jit_regset_t; #endif #define jit_data(u,v,w) _jit_data(_jit,u,v,w) @@ -167,48 +194,104 @@ extern jit_node_t *_jit_data(jit_state_t*, const void*, (!jit_regset_tstbit(&_jitc->regarg, regno) && \ !jit_regset_tstbit(&_jitc->regsav, regno)) -#define jit_inc_synth(code) \ +#define jit_code_inc_synth(code) \ do { \ - (void)jit_new_node(jit_code_##code); \ + (void)jit_new_node(code); \ jit_synth_inc(); \ } while (0) -#define jit_inc_synth_w(code, u) \ +#define jit_inc_synth(name) \ + jit_code_inc_synth(jit_code_##name) +#define jit_code_inc_synth_w(code, u) \ do { \ - (void)jit_new_node_w(jit_code_##code, u); \ + (void)jit_new_node_w(code, u); \ jit_synth_inc(); \ } while (0) -#define jit_inc_synth_f(code, u) \ +#define jit_inc_synth_w(name, u) \ + jit_code_inc_synth_w(jit_code_##name, u) +#define jit_code_inc_synth_f(code, u) \ do { \ - (void)jit_new_node_f(jit_code_##code, u); \ + (void)jit_new_node_f(code, u); \ jit_synth_inc(); \ } while (0) -#define jit_inc_synth_d(code, u) \ +#define jit_inc_synth_f(name, u) \ + jit_code_inc_synth_f(jit_code_##name, u) +#define jit_code_inc_synth_d(code, u) \ do { \ - (void)jit_new_node_d(jit_code_##code, u); \ + (void)jit_new_node_d(code, u); \ jit_synth_inc(); \ } while (0) -#define jit_inc_synth_ww(code, u, v) \ +#define jit_inc_synth_d(name, u) \ + jit_code_inc_synth_d(jit_code_##name, u) +#define jit_code_inc_synth_ww(code, u, v) \ do { \ - (void)jit_new_node_ww(jit_code_##code, u, v); \ + (void)jit_new_node_ww(code, u, v); \ jit_synth_inc(); \ } while (0) -#define jit_inc_synth_wp(code, u, v) \ +#define jit_inc_synth_ww(name, u, v) \ + jit_code_inc_synth_ww(jit_code_##name, u, v) +#define jit_code_inc_synth_wp(code, u, v) \ do { \ - (void)jit_new_node_wp(jit_code_##code, u, v); \ + (void)jit_new_node_wp(code, u, v); \ jit_synth_inc(); \ } while (0) -#define jit_inc_synth_fp(code, u, v) \ +#define jit_inc_synth_wp(name, u, v) \ + jit_code_inc_synth_wp(jit_code_##name, u, v) +#define jit_code_inc_synth_fp(code, u, v) \ do { \ - (void)jit_new_node_fp(jit_code_##code, u, v); \ + (void)jit_new_node_fp(code, u, v); \ jit_synth_inc(); \ } while (0) -#define jit_inc_synth_dp(code, u, v) \ +#define jit_inc_synth_fp(name, u, v) \ + jit_code_inc_synth_fp(jit_code_##name, u, v) +#define jit_code_inc_synth_dp(code, u, v) \ do { \ - (void)jit_new_node_dp(jit_code_##code, u, v); \ + (void)jit_new_node_dp(code, u, v); \ + jit_synth_inc(); \ + } while (0) +#define jit_inc_synth_dp(name, u, v) \ + jit_code_inc_synth_dp(jit_code_##name, u, v) +#define jit_inc_synth_wf(name, u, v) \ + jit_code_inc_synth_wf(jit_code_##name, u, v) +#define jit_code_inc_synth_wf(code, u, v) \ + do { \ + (void)jit_new_node_wf(code, u, v); \ + jit_synth_inc(); \ + } while (0) +#define jit_inc_synth_wqf(name, u, v, w, x) \ + do { \ + (void)jit_new_node_wqf(jit_code_##name, u, v, w, x); \ + jit_synth_inc(); \ + } while (0) +#define jit_inc_synth_wd(name, u, v) \ + jit_code_inc_synth_wd(jit_code_##name, u, v) +#define jit_inc_synth_wqd(name, u, v, w, x) \ + do { \ + (void)jit_new_node_wqd(jit_code_##name, u, v, w, x); \ + jit_synth_inc(); \ + } while (0) +#define jit_code_inc_synth_wd(code, u, v) \ + do { \ + (void)jit_new_node_wd(code, u, v); \ jit_synth_inc(); \ } while (0) #define jit_dec_synth() jit_synth_dec() +#define jit_link_alist(node) \ + do { \ + node->link = _jitc->function->alist; \ + _jitc->function->alist = node; \ + } while (0) +#define jit_check_frame() \ + do { \ + if (!_jitc->function->need_frame) { \ + _jitc->again = 1; \ + _jitc->function->need_frame = 1; \ + } \ + } while (0) +#define jit_diffsize() (stack_framesize - _jitc->framesize) +#define jit_framesize() (stack_framesize - jit_diffsize()) +#define jit_selfsize() (_jitc->function->self.size - jit_diffsize()) + #define jit_link_prolog() \ do { \ _jitc->tail->link = _jitc->function->prolog->link; \ @@ -241,8 +324,8 @@ extern jit_node_t *_jit_data(jit_state_t*, const void*, #define jit_class_xpr 0x80000000 /* float / vector */ /* Used on sparc64 where %f0-%f31 can be encode for single float * but %f32 to %f62 only as double precision */ -#define jit_class_sng 0x10000000 /* Single precision float */ -#define jit_class_dbl 0x20000000 /* Only double precision float */ +#define jit_class_sng 0x00010000 /* Single precision float */ +#define jit_class_dbl 0x00020000 /* Only double precision float */ #define jit_regno_patch 0x00008000 /* this is a register * returned by a "user" call * to jit_get_reg() */ @@ -264,17 +347,20 @@ extern jit_node_t *_jit_data(jit_state_t*, const void*, #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_a0_cnd 0x00000100 /* arg1 is a conditinally set register */ +#define jit_cc_a1_reg 0x00000200 /* arg1 is a register */ +#define jit_cc_a1_chg 0x00000400 /* arg1 is modified */ +#define jit_cc_a1_int 0x00000800 /* arg1 is immediate word */ +#define jit_cc_a1_flt 0x00001000 /* arg1 is immediate float */ +#define jit_cc_a1_dbl 0x00002000 /* arg1 is immediate double */ +#define jit_cc_a1_arg 0x00004000 /* arg1 is an argument node */ +#define jit_cc_a1_rlh 0x00008000 /* arg1 is a register pair */ #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 */ +#define jit_cc_a2_rlh 0x00800000 /* arg2 is a register pair */ #if __ia64__ || (__sparc__ && __WORDSIZE == 64) extern void @@ -363,6 +449,8 @@ typedef struct jit_register jit_register_t; # if DISASSEMBLER typedef struct jit_data_info jit_data_info_t; # endif +#elif __riscv +typedef struct jit_const jit_const_t; #endif union jit_data { @@ -412,6 +500,9 @@ struct jit_block { jit_node_t *label; jit_regset_t reglive; jit_regset_t regmask; + jit_bool_t again; /* Flag need to rebuild regset masks + * due to changes in live and unknown + * state. */ }; struct jit_value { @@ -434,6 +525,12 @@ struct jit_data_info { jit_uword_t code; /* pointer in code buffer */ jit_word_t length; /* length of constant vector */ }; +#elif __riscv && __WORDSIZE == 64 +struct jit_const { + jit_word_t value; + jit_word_t address; + jit_const_t *next; +}; #endif struct jit_function { @@ -454,9 +551,14 @@ struct jit_function { } call; jit_node_t *prolog; jit_node_t *epilog; + jit_node_t *alist; jit_int32_t *regoff; jit_regset_t regset; jit_int32_t stack; +#if !defined(__arm__) + jit_int32_t cvt_offset; /* allocai'd offset for x87<->xmm or + * fpr<->gpr transfer using the stack */ +#endif /* Helper for common jit generation pattern, used in GNU Smalltalk * and possibly others, where a static frame layout is required or @@ -465,11 +567,25 @@ struct jit_function { jit_uint32_t define_frame : 1; jit_uint32_t assume_frame : 1; + jit_uint32_t need_frame : 1; /* need frame pointer? */ + jit_uint32_t need_stack : 1; /* need stack pointer? */ + jit_uint32_t need_return : 1; /* not a leaf function */ + /* alloca offset offset */ jit_int32_t aoffoff; /* uses allocar flag */ jit_uint32_t allocar : 1; +#if __arm__ + /* If will, or might use float registers and vfp is not available. + * Use the first 64 bytes always, as the access to the virtual float + * registers use hardcoded instructions that can only reach 64 byte + * displacements, and to keep code simpler, do not use temporaries. */ + jit_uint32_t swf_offset : 1; + /* If need to call C functions for some operation, or variadic function */ + jit_uint32_t save_reg_args : 1; +#endif + /* varargs state offsets */ jit_int32_t vaoff; /* offset of jit_va_list */ jit_int32_t vagp; /* first gp va argument */ @@ -489,8 +605,15 @@ struct jit_compiler { jit_int32_t rout; /* first output register */ jit_int32_t breg; /* base register for prolog/epilog */ #endif +#if __mips__ + struct { + jit_int32_t op; /* pending instruction, candidate + * to be inserted in a delay slot */ + jit_bool_t pend; /* non zero if need to emit op */ + } inst; +#endif #if __mips__ || __ia64__ || __alpha__ || \ - (__sparc__ && __WORDSIZE == 64) || __riscv + (__sparc__ && __WORDSIZE == 64) || __riscv || __loongarch__ jit_int32_t carry; #define jit_carry _jitc->carry #endif @@ -508,11 +631,20 @@ struct jit_compiler { #endif jit_uint32_t no_data : 1; jit_uint32_t no_note : 1; + /* FIXME undocumented, might be moved to a jit_cpu field or a better + * configuration api. + * These are switches to a different unld* or unst*. + * Defaults are the algorithms that generate shorter code*/ + jit_uint32_t unld_algorithm : 1; + jit_uint32_t unst_algorithm : 1; + jit_int32_t framesize; /* space for callee save registers, + * frame pointer and return address */ jit_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 */ + jit_regset_t explive; /* explicitly marked as live */ struct { jit_uint8_t *end; } code; @@ -593,6 +725,27 @@ struct jit_compiler { jit_word_t length; } prolog; jit_bool_t jump; +#elif __riscv && __WORDSIZE == 64 + struct { + /* Hash table for constants to be resolved and patched */ + struct { + jit_const_t **table; /* very simple hash table */ + jit_word_t size; /* number of vectors in table */ + jit_word_t count; /* number of distinct entries */ + } hash; + struct { + jit_const_t **ptr; /* keep a single pointer */ + jit_const_t *list; /* free list */ + jit_word_t length; /* length of pool */ + } pool; + /* Linear list for constants that cannot be encoded easily */ + struct { + jit_word_t *instrs; /* list of direct movi instructions */ + jit_word_t *values; /* list of direct movi constants */ + jit_word_t offset; /* offset in instrs/values vector */ + jit_word_t length; /* length of instrs/values vector */ + } vector; + } consts; #endif #if GET_JIT_SIZE /* Temporary storage to calculate instructions length */ @@ -616,6 +769,8 @@ struct jit_state { struct { jit_uint8_t *ptr; jit_word_t length; + /* PROTECTED bytes starting at PTR are mprotect'd. */ + jit_word_t protect; } code; struct { jit_uint8_t *ptr; @@ -718,6 +873,7 @@ _emit_ldxi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); extern void _emit_stxi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +extern void jit_init_print(void); extern void jit_init_debug(const char*); extern void jit_finish_debug(void);