-rw-r--r-- | include/lightning/jit_loongarch.h | 11 | ||||
-rw-r--r-- | lib/jit_loongarch-cpu.c | 69 | ||||
-rw-r--r-- | lib/jit_loongarch-fpu.c | 70 | ||||
-rw-r--r-- | lib/jit_loongarch.c | 33 |
diff --git a/include/lightning/jit_loongarch.h b/include/lightning/jit_loongarch.h index 89b1a86..72e9f1f 100644 --- a/include/lightning/jit_loongarch.h +++ b/include/lightning/jit_loongarch.h @@ -74,4 +74,15 @@ typedef enum { _NOREG, } jit_reg_t; +typedef struct { + /* generate special instructions for unaligned load/store? */ + /* It is not guaranteed unaligned memory access is supported. */ + jit_uint32_t unaligned : 1; +} jit_cpu_t; + +/* + * Initialization + */ +extern jit_cpu_t jit_cpu; + #endif /* _jit_loongarch_h */ diff --git a/lib/jit_loongarch-cpu.c b/lib/jit_loongarch-cpu.c index 3c9d93f..ef8261f 100644 --- a/lib/jit_loongarch-cpu.c +++ b/lib/jit_loongarch-cpu.c @@ -18,6 +18,7 @@ */ #if PROTO +# define jit_unaligned_p() (jit_cpu.unaligned) # define ii(i) *_jit->pc.ui++ = (i) # define can_sign_extend_si12_p(s12) ((s12) <= 2047 && (s12) >= -2048) # define can_zero_extend_u12_p(u12) ((u12) <= 4095 && (u12) >= 0) @@ -476,6 +477,14 @@ static void _ldxi_ui(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); # define ldxr_l(r0, r1, r2) LDX_D(r0, r1, r2) # define ldxi_l(r0, r1, i0) _ldxi_l(_jit, r0, r1, i0) static void _ldxi_l(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define unldr(r0, r1, i0) _unldr(_jit, r0, r1, i0) +static void _unldr(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define unldi(r0, i0, i1) _unldi(_jit, r0, i0, i1) +static void _unldi(jit_state_t*, jit_int32_t, jit_word_t, jit_word_t); +# define unldr_u(r0, r1, i0) _unldr_u(_jit, r0, r1, i0) +static void _unldr_u(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define unldi_u(r0, i0, i1) _unldi_u(_jit, r0, i0, i1) +static void _unldi_u(jit_state_t*, jit_int32_t, jit_word_t, jit_word_t); # define str_c(r0, r1) ST_B(r1, r0, 0) # define sti_c(i0, r0) _sti_c(_jit, i0, r0) static void _sti_c(jit_state_t*, jit_word_t, jit_int32_t); @@ -500,6 +509,10 @@ static void _stxi_i(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); # define stxr_l(r0, r1, r2) STX_D(r2, r1, r0) # define stxi_l(i0, r0, r1) _stxi_l(_jit, i0, r0, r1) static void _stxi_l(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +#define unstr(r0, r1, i0) _unstr(_jit, r0, r1, i0) +static void _unstr(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +#define unsti(i0, r0, i1) _unsti(_jit, i0, r0, i1) +static void _unsti(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); # define bswapr_us(r0,r1) _bswapr_us(_jit,r0,r1) static void _bswapr_us(jit_state_t*, jit_int32_t, jit_int32_t); # define bswapr_ui(r0,r1) _bswapr_ui(_jit,r0,r1) @@ -1594,6 +1607,44 @@ _ldxi_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) } static void +_unldr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (jit_unaligned_p()) + fallback_unldr(r0, r1, i0); + else + generic_unldr(r0, r1, i0); +} + +static void +_unldi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0, jit_word_t i1) +{ + jit_int32_t t0, r2; + if (jit_unaligned_p()) + fallback_unldi(r0, i0, i1); + else + generic_unldi(r0, i0, i1); +} + +static void +_unldr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (jit_unaligned_p()) + fallback_unldr_u(r0, r1, i0); + else + generic_unldr_u(r0, r1, i0); +} + +static void +_unldi_u(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0, jit_word_t i1) +{ + jit_int32_t t0, r2; + if (jit_unaligned_p()) + fallback_unldi_u(r0, i0, i1); + else + generic_unldi_u(r0, i0, i1); +} + +static void _sti_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) { jit_int32_t reg; @@ -1706,6 +1757,24 @@ _stxi_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) } static void +_unstr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (jit_unaligned_p()) + fallback_unstr(r0, r1, i0); + else + generic_unstr(r0, r1, i0); +} + +static void +_unsti(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + if (jit_unaligned_p()) + fallback_unsti(i0, r0, i1); + else + generic_unsti(i0, r0, i1); +} + +static void _bswapr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) { REVB_2H(r0, r1); diff --git a/lib/jit_loongarch-fpu.c b/lib/jit_loongarch-fpu.c index 2871de3..9e019d2 100644 --- a/lib/jit_loongarch-fpu.c +++ b/lib/jit_loongarch-fpu.c @@ -223,18 +223,24 @@ static void _ldi_f(jit_state_t*, jit_int32_t, jit_word_t); # define ldxr_f(r0, r1, r2) FLDX_S(r0, r1, r2) # define ldxi_f(r0, r1, i0) _ldxi_f(_jit, r0, r1, i0) static void _ldxi_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define unldr_x(r0, r1, i0) _unldr_x(_jit, r0, r1, i0) +static void _unldr_x(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define unldi_x(r0, i0, i1) _unldi_x(_jit, r0, i0, i1) +static void _unldi_x(jit_state_t*, jit_int32_t, jit_word_t, jit_word_t); # define str_f(r0, r1) FST_S(r1, r0, 0) # define sti_f(i0, r0) _sti_f(_jit, i0, r0) static void _sti_f(jit_state_t*, jit_word_t, jit_int32_t); # define stxr_f(r0, r1, r2) FSTX_S(r2, r1, r0) # define stxi_f(i0, r0, r1) _stxi_f(_jit, i0, r0, r1) static void _stxi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +#define unstr_x(r0, r1, i0) _unstr_x(_jit, r0, r1, i0) +static void _unstr_x(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +#define unsti_x(i0, r0, i1) _unsti_x(_jit, i0, r0, i1) +static void _unsti_x(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); # define movr_f(r0, r1) FMOV_S(r0, r1) # define movi_f(r0, i0) _movi_f(_jit, r0, i0) static void _movi_f(jit_state_t*, jit_int32_t, jit_float32_t); # define movr_f_w(r0, r1) MOVFR2GR_S(r0, r1) -# define movi_f_w(r0, im) _movi_f_w(_jit, r0, im) -static void _movi_f_w(jit_state_t*, jit_int32_t, jit_float32_t); # define movr_w_f(r0, r1) MOVGR2FR_W(r0, r1) # define extr_d_f(r0, r1) FCVT_S_D(r0, r1) # define ltr_f(r0, r1, r2) _ltr_f(_jit, r0, r1, r2) @@ -385,8 +391,6 @@ static void _stxi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); # define movi_d(r0, i0) _movi_d(_jit, r0, i0) static void _movi_d(jit_state_t*, jit_int32_t, jit_float64_t); # define movr_d_w(r0, r1) MOVFR2GR_D(r0, r1) -# define movi_d_w(r0, im) _movi_d_w(_jit, r0, im) -static void _movi_d_w(jit_state_t*, jit_int32_t, jit_float64_t); # define movr_w_d(r0, r1) MOVGR2FR_D(r0, r1) # define extr_f_d(r0, r1) FCVT_D_S(r0, r1) # define ltr_d(r0, r1, r2) _ltr_d(_jit, r0, r1, r2) @@ -615,6 +619,24 @@ _ldxi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) } static void +_unldr_x(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (jit_unaligned_p()) + fallback_unldr_x(r0, r1, i0); + else + generic_unldr_x(r0, r1, i0); +} + +static void +_unldi_x(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0, jit_word_t i1) +{ + if (jit_unaligned_p()) + fallback_unldi_x(r0, i0, i1); + else + generic_unldi_x(r0, i0, i1); +} + +static void _sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) { jit_int32_t t0; @@ -643,6 +665,24 @@ _stxi_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) } static void +_unstr_x(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (jit_unaligned_p()) + fallback_unstr_x(r0, r1, i0); + else + generic_unstr_x(r0, r1, i0); +} + +static void +_unsti_x(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + if (jit_unaligned_p()) + fallback_unsti_x(i0, r0, i1); + else + fallback_unsti_x(i0, r0, i1); +} + +static void _movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t i0) { union { @@ -662,17 +702,6 @@ _movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t i0) } static void -_movi_f_w(jit_state_t *_jit, jit_int32_t r0, jit_float32_t i0) -{ - union { - jit_int32_t i; - jit_float32_t f; - } data; - data.f = i0; - movi(r0, data.i); -} - -static void _ltr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) { FCMP_SLT_S(0, r1, r2); @@ -1028,17 +1057,6 @@ _movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t i0) } static void -_movi_d_w(jit_state_t *_jit, jit_int32_t r0, jit_float64_t i0) -{ - union { - jit_int64_t l; - jit_float64_t d; - } data; - data.d = i0; - movi(r0, data.l); -} - -static void _ltr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) { FCMP_SLT_D(0, r1, r2); diff --git a/lib/jit_loongarch.c b/lib/jit_loongarch.c index f8853fe..1ee828a 100644 --- a/lib/jit_loongarch.c +++ b/lib/jit_loongarch.c @@ -46,6 +46,7 @@ static void _patch(jit_state_t*,jit_word_t,jit_node_t*); /* * Initialization */ +jit_cpu_t jit_cpu; jit_register_t _rvs[] = { { rc(gpr) | 0x14, "$t8" }, { rc(gpr) | 0x13, "$t7" }, @@ -135,6 +136,8 @@ _jit_init(jit_state_t *_jit) { _jitc->reglen = jit_size(_rvs) - 1; jit_carry = _NOREG; + /* By default assume kernel or cpu will handle unaligned load/store */ + jit_cpu.unaligned = 0; } void @@ -1178,6 +1181,18 @@ _emit_code(jit_state_t *_jit) case_rrw(ldx, _ui); case_rrr(ldx, _l); case_rrw(ldx, _l); + case jit_code_unldr: + unldr(rn(node->u.w), rn(node->v.w), node->w.w); + break; + case jit_code_unldi: + unldi(rn(node->u.w), node->v.w, node->w.w); + break; + case jit_code_unldr_u: + unldr_u(rn(node->u.w), rn(node->v.w), node->w.w); + break; + case jit_code_unldi_u: + unldi_u(rn(node->u.w), node->v.w, node->w.w); + break; case_rr(st, _c); case_wr(st, _c); case_rr(st, _s); @@ -1194,6 +1209,12 @@ _emit_code(jit_state_t *_jit) case_wrr(stx, _i); case_rrr(stx, _l); case_wrr(stx, _l); + case jit_code_unstr: + unstr(rn(node->u.w), rn(node->v.w), node->w.w); + break; + case jit_code_unsti: + unsti(node->u.w, rn(node->v.w), node->w.w); + break; case_rr(hton, _us); case_rr(hton, _ui); case_rr(hton, _ul); @@ -1323,10 +1344,22 @@ _emit_code(jit_state_t *_jit) case_rw(ld, _f); case_rrr(ldx, _f); case_rrw(ldx, _f); + case jit_code_unldr_x: + unldr_x(rn(node->u.w), rn(node->v.w), node->w.w); + break; + case jit_code_unldi_x: + unldi_x(rn(node->u.w), node->v.w, node->w.w); + break; case_rr(st, _f); case_wr(st, _f); case_rrr(stx, _f); case_wrr(stx, _f); + case jit_code_unstr_x: + unstr_x(rn(node->u.w), rn(node->v.w), node->w.w); + break; + case jit_code_unsti_x: + unsti_x(node->u.w, rn(node->v.w), node->w.w); + break; case_rr(mov, _f); case jit_code_movi_f: assert_data(node); |