+#elif defined(__loongarch__)
+# include "jit_loongarch.c"
+#endif
+
+static maybe_unused void
+generic_bswapr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
+{
+ jit_int32_t reg = jit_get_reg(jit_class_gpr);
+
+ rshi(rn(reg), r1, 8);
+ andi(r0, r1, 0xff);
+ andi(rn(reg), rn(reg), 0xff);
+ lshi(r0, r0, 8);
+ orr(r0, r0, rn(reg));
+
+ jit_unget_reg(reg);
+}
+
+static maybe_unused void
+generic_bswapr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
+{
+ jit_int32_t reg = jit_get_reg(jit_class_gpr);
+
+ rshi(rn(reg), r1, 16);
+ bswapr_us(r0, r1);
+ bswapr_us(rn(reg), rn(reg));
+ lshi(r0, r0, 16);
+ orr(r0, r0, rn(reg));
+
+ jit_unget_reg(reg);
+}
+
+#if __WORDSIZE == 64
+static maybe_unused void
+generic_bswapr_ul(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
+{
+ jit_int32_t reg = jit_get_reg(jit_class_gpr);
+
+ rshi_u(rn(reg), r1, 32);
+ bswapr_ui(r0, r1);
+ bswapr_ui(rn(reg), rn(reg));
+ lshi(r0, r0, 32);
+ orr(r0, r0, rn(reg));
+
+ jit_unget_reg(reg);
+}
+#endif
+
+static void
+_depi(jit_state_t *_jit,
+ jit_int32_t r0, jit_word_t i0, jit_word_t i1, jit_word_t i2)
+{
+ jit_int32_t reg;
+ reg = jit_get_reg(jit_class_gpr);
+ movi(rn(reg), i0);
+ depr(r0, rn(reg), i1, i2);
+ jit_unget_reg(reg);
+}
+
+static void
+_negi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
+{
+ movi(r0, -i0);
+}
+
+static void
+_comi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
+{
+ movi(r0, ~i0);
+}
+
+static void
+_exti_c(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
+{
+ movi(r0, (jit_int8_t)i0);
+}
+
+static void
+_exti_uc(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
+{
+ movi(r0, (jit_uint8_t)i0);
+}
+
+static void
+_exti_s(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
+{
+ movi(r0, (jit_int16_t)i0);
+}
+
+static void
+_exti_us(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
+{
+ movi(r0, (jit_uint16_t)i0);
+}
+
+#if __WORDSIZE == 64
+static void
+_exti_i(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
+{
+ movi(r0, (jit_int32_t)i0);
+}
+
+static void
+_exti_ui(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
+{
+ movi(r0, (jit_uint32_t)i0);
+}
+#endif
+
+static void
+_bswapi_us(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
+{
+ union {
+ jit_uint16_t us;
+ jit_uint8_t v[2];
+ } l, h;
+ l.us = i0;
+ h.v[0] = l.v[1];
+ h.v[1] = l.v[0];
+ movi(r0, h.us);
+}
+
+static void
+_bswapi_ui(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
+{
+ union {
+ jit_uint32_t ui;
+ jit_uint8_t v[4];
+ } l, h;
+ l.ui = i0;
+ h.v[0] = l.v[3];
+ h.v[1] = l.v[2];
+ h.v[2] = l.v[1];
+ h.v[3] = l.v[0];
+ movi(r0, h.ui);
+}
+
+#if __WORDSIZE == 64
+static void
+_bswapi_ul(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
+{
+ union {
+ jit_uint64_t ul;
+ jit_uint8_t v[8];
+ } l, h;
+ l.ul = i0;
+ h.v[0] = l.v[7];
+ h.v[1] = l.v[6];
+ h.v[2] = l.v[5];
+ h.v[3] = l.v[4];
+ h.v[4] = l.v[3];
+ h.v[5] = l.v[2];
+ h.v[6] = l.v[1];
+ h.v[7] = l.v[0];
+ movi(r0, h.ul);
+}
+#endif
+
+static void
+_htoni_us(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
+{
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ bswapi_us(r0, i0);
+#else
+ exti_us(r0, i0);
+#endif
+}
+
+static void
+_htoni_ui(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
+{
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ bswapi_ui(r0, i0);
+#else
+# if __WORDSIZE == 32
+ movi(r0, i0);
+# else
+ exti_ui(r0, i0);
+# endif
+#endif
+}
+
+#if __WORDSIZE == 64
+static void
+_htoni_ul(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
+{
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ bswapi_ul(r0, i0);
+# else
+ movi(r0, i0);
+# endif
+}
+#endif
+
+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;
+#if defined(__ia64__)
+ /* Should be used only in this case (with out0 == 120) */
+ if (r0 >= 120)
+ r0 = _jitc->rout + (r0 - 120);
+#endif
+ movi(r0, data.i);
+}
+
+#if __WORDSIZE == 32
+static void
+_movi_d_ww(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_float64_t i0)
+{
+ union {
+ jit_int32_t i[2];
+ jit_float64_t d;
+ } data;
+ data.d = i0;
+ /* Mips does not change byte order of double values */
+# if __BYTE_ORDER == __LITTLE_ENDIAN || defined(__mips__)
+ movi(r0, data.i[0]);
+ movi(r1, data.i[1]);
+# else
+ movi(r1, data.i[0]);
+ movi(r0, data.i[1]);
+# endif
+}
+
+#else
+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;
+# if defined(__ia64__)
+ /* Should be used only in this case (with out0 == 120) */
+ if (r0 >= 120)
+ r0 = _jitc->rout + (r0 - 120);
+# endif
+ movi(r0, data.l);
+}
+#endif
+
+ void
+_jit_negi_f(jit_state_t *_jit, jit_fpr_t u, jit_float32_t v)
+{
+ jit_inc_synth_wf(negi_f, u, v);
+ jit_movi_f(u, v);
+ jit_negr_f(u, u);
+ jit_dec_synth();
+}
+
+void
+_jit_absi_f(jit_state_t *_jit, jit_fpr_t u, jit_float32_t v)
+{
+ jit_inc_synth_wf(absi_f, u, v);
+ jit_movi_f(u, v);
+ jit_absr_f(u, u);
+ jit_dec_synth();
+}
+
+void
+_jit_sqrti_f(jit_state_t *_jit, jit_fpr_t u, jit_float32_t v)
+{
+ jit_inc_synth_wf(sqrti_f, u, v);
+ jit_movi_f(u, v);
+ jit_sqrtr_f(u, u);
+ jit_dec_synth();
+}
+
+void
+_jit_fmai_f(jit_state_t *_jit,
+ jit_fpr_t u, jit_fpr_t v, jit_fpr_t w, jit_float32_t x)
+{
+ jit_int32_t y;
+ jit_inc_synth_wqf(fmai_f, u, v, w, x);
+ if (u != v && u != w) {
+ jit_movi_f(u, x);
+ jit_fmar_f(u, v, w, u);
+ }
+ else {
+ y = jit_get_reg(jit_class_fpr);
+ jit_movi_f(y, x);
+ jit_fmar_f(u, v, w, y);
+ jit_unget_reg(y);
+ }
+ jit_dec_synth();
+}
+
+void
+_jit_fmsi_f(jit_state_t *_jit,
+ jit_fpr_t u, jit_fpr_t v, jit_fpr_t w, jit_float32_t x)
+{
+ jit_int32_t y;
+ jit_inc_synth_wqf(fmai_f, u, v, w, x);
+ if (u != v && u != w) {
+ jit_movi_f(u, x);
+ jit_fmsr_f(u, v, w, u);
+ }
+ else {
+ y = jit_get_reg(jit_class_fpr);
+ jit_movi_f(y, x);
+ jit_fmsr_f(u, v, w, y);
+ jit_unget_reg(y);
+ }
+ jit_dec_synth();
+}
+
+void
+_jit_fnmai_f(jit_state_t *_jit,
+ jit_fpr_t u, jit_fpr_t v, jit_fpr_t w, jit_float32_t x)
+{
+ jit_int32_t y;
+ jit_inc_synth_wqf(fmai_f, u, v, w, x);
+ if (u != v && u != w) {
+ jit_movi_f(u, x);
+ jit_fnmar_f(u, v, w, u);
+ }
+ else {
+ y = jit_get_reg(jit_class_fpr);
+ jit_movi_f(y, x);
+ jit_fnmar_f(u, v, w, y);
+ jit_unget_reg(y);
+ }
+ jit_dec_synth();
+}
+
+void
+_jit_fnmsi_f(jit_state_t *_jit,
+ jit_fpr_t u, jit_fpr_t v, jit_fpr_t w, jit_float32_t x)
+{
+ jit_int32_t y;
+ jit_inc_synth_wqf(fmai_f, u, v, w, x);
+ if (u != v && u != w) {
+ jit_movi_f(u, x);
+ jit_fnmsr_f(u, v, w, u);
+ }
+ else {
+ y = jit_get_reg(jit_class_fpr);
+ jit_movi_f(y, x);
+ jit_fnmsr_f(u, v, w, y);
+ jit_unget_reg(y);
+ }
+ jit_dec_synth();
+}
+
+void
+_jit_negi_d(jit_state_t *_jit, jit_fpr_t u, jit_float64_t v)
+{
+ jit_inc_synth_wd(negi_d, u, v);
+ jit_movi_d(u, v);
+ jit_negr_d(u, u);
+ jit_dec_synth();
+}
+
+void
+_jit_absi_d(jit_state_t *_jit, jit_fpr_t u, jit_float64_t v)
+{
+ jit_inc_synth_wd(absi_d, u, v);
+ jit_movi_d(u, v);
+ jit_absr_d(u, u);
+ jit_dec_synth();
+}
+
+void
+_jit_sqrti_d(jit_state_t *_jit, jit_fpr_t u, jit_float64_t v)
+{
+ jit_inc_synth_wd(sqrti_d, u, v);
+ jit_movi_d(u, v);
+ jit_sqrtr_d(u, u);
+ jit_dec_synth();
+}
+
+void
+_jit_fmai_d(jit_state_t *_jit,
+ jit_fpr_t u, jit_fpr_t v, jit_fpr_t w, jit_float64_t x)
+{
+ jit_int32_t y;
+ jit_inc_synth_wqd(fmai_d, u, v, w, x);
+ if (u != v && u != w) {
+ jit_movi_d(u, x);
+ jit_fmar_d(u, v, w, u);
+ }
+ else {
+ y = jit_get_reg(jit_class_fpr);
+ jit_movi_d(y, x);
+ jit_fmar_d(u, v, w, y);
+ jit_unget_reg(y);
+ }
+ jit_dec_synth();
+}
+
+void
+_jit_fmsi_d(jit_state_t *_jit,
+ jit_fpr_t u, jit_fpr_t v, jit_fpr_t w, jit_float64_t x)
+{
+ jit_int32_t y;
+ jit_inc_synth_wqd(fmai_d, u, v, w, x);
+ if (u != v && u != w) {
+ jit_movi_d(u, x);
+ jit_fmsr_d(u, v, w, u);
+ }
+ else {
+ y = jit_get_reg(jit_class_fpr);
+ jit_movi_d(y, x);
+ jit_fmsr_d(u, v, w, y);
+ jit_unget_reg(y);
+ }
+ jit_dec_synth();
+}
+
+void
+_jit_fnmai_d(jit_state_t *_jit,
+ jit_fpr_t u, jit_fpr_t v, jit_fpr_t w, jit_float64_t x)
+{
+ jit_int32_t y;
+ jit_inc_synth_wqd(fmai_d, u, v, w, x);
+ if (u != v && u != w) {
+ jit_movi_d(u, x);
+ jit_fnmar_d(u, v, w, u);
+ }
+ else {
+ y = jit_get_reg(jit_class_fpr);
+ jit_movi_d(y, x);
+ jit_fnmar_d(u, v, w, y);
+ jit_unget_reg(y);
+ }
+ jit_dec_synth();
+}
+
+void
+_jit_fnmsi_d(jit_state_t *_jit,
+ jit_fpr_t u, jit_fpr_t v, jit_fpr_t w, jit_float64_t x)
+{
+ jit_int32_t y;
+ jit_inc_synth_wqd(fmai_d, u, v, w, x);
+ if (u != v && u != w) {
+ jit_movi_d(u, x);
+ jit_fnmsr_d(u, v, w, u);
+ }
+ else {
+ y = jit_get_reg(jit_class_fpr);
+ jit_movi_d(y, x);
+ jit_fnmsr_d(u, v, w, y);
+ jit_unget_reg(y);
+ }
+ jit_dec_synth();
+}
+
+static void
+_cloi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
+{
+ clzi(r0, ~i0);
+}
+
+static void
+_clzi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
+{
+#if __WORDSIZE == 64 && _WIN32
+ movi(r0, (i0) ? __builtin_clzll(i0) : __WORDSIZE);
+#else
+ movi(r0, (i0) ? __builtin_clzl(i0) : __WORDSIZE);
+#endif
+}
+
+static void
+_ctoi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
+{
+ ctzi(r0, ~i0);
+}
+
+static void
+_ctzi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
+{
+#if __WORDSIZE == 64 && _WIN32
+ movi(r0, (i0) ? __builtin_ctzll(i0) : __WORDSIZE);
+#else
+ movi(r0, (i0) ? __builtin_ctzl(i0) : __WORDSIZE);
+#endif
+}
+
+static void
+_rbiti(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
+{
+ jit_int32_t i;
+ union {
+ jit_uword_t w;
+ jit_uint8_t v[__WORDSIZE >> 3];
+ } u, v;
+ static const unsigned char swap_tab[256] = {
+ 0, 128, 64, 192, 32, 160, 96, 224,
+ 16, 144, 80, 208, 48, 176, 112, 240,
+ 8, 136, 72, 200, 40, 168, 104, 232,
+ 24, 152, 88, 216 ,56, 184, 120, 248,
+ 4, 132, 68, 196, 36, 164, 100, 228,
+ 20, 148, 84, 212, 52, 180, 116, 244,
+ 12, 140, 76, 204, 44, 172, 108, 236,
+ 28, 156, 92, 220, 60, 188, 124, 252,
+ 2, 130, 66, 194, 34, 162, 98, 226,
+ 18, 146, 82, 210, 50, 178, 114, 242,
+ 10, 138, 74, 202, 42, 170, 106, 234,
+ 26, 154, 90, 218, 58, 186, 122, 250,
+ 6, 134, 70, 198, 38, 166, 102, 230,
+ 22, 150, 86, 214, 54, 182, 118, 246,
+ 14, 142, 78, 206, 46, 174, 110, 238,
+ 30, 158, 94, 222, 62, 190, 126, 254,
+ 1, 129, 65, 193, 33, 161, 97, 225,
+ 17, 145, 81, 209, 49, 177, 113, 241,
+ 9, 137, 73, 201, 41, 169, 105, 233,
+ 25, 153, 89, 217, 57, 185, 121, 249,
+ 5, 133, 69, 197, 37, 165, 101, 229,
+ 21, 149, 85, 213, 53, 181, 117, 245,
+ 13, 141, 77, 205, 45, 173, 109, 237,
+ 29, 157, 93, 221, 61, 189, 125, 253,
+ 3, 131, 67, 195, 35, 163, 99, 227,
+ 19, 147, 83, 211, 51, 179, 115, 243,
+ 11, 139, 75, 203, 43, 171, 107, 235,
+ 27, 155, 91, 219, 59, 187, 123, 251,
+ 7, 135, 71, 199, 39, 167, 103, 231,
+ 23, 151, 87, 215, 55, 183, 119, 247,
+ 15, 143, 79, 207, 47, 175, 111, 239,
+ 31, 159, 95, 223, 63, 191, 127, 255
+ };
+ u.w = i0;
+ for (i = 0; i < sizeof(jit_word_t); ++i)
+ v.v[i] = swap_tab[u.v[sizeof(jit_word_t) - i - 1]];
+ movi(r0, v.w);
+}
+
+static void
+_popcnti(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
+{
+#if __WORDSIZE == 64 && _WIN32
+ movi(r0, (i0) ? __builtin_popcountll(i0) : __WORDSIZE);
+#else
+ movi(r0, (i0) ? __builtin_popcountl(i0) : __WORDSIZE);
+#endif
+}
+
+static void _exti(jit_state_t *_jit,
+ jit_int32_t r0, jit_word_t i0, jit_word_t i1, jit_word_t i2)
+{
+#if __BYTE_ORDER == __BIG_ENDIAN
+ i1 = __WORDSIZE - (i1 + i2);
+#endif
+ i0 <<= __WORDSIZE - (i1 + i2);
+ i0 >>= __WORDSIZE - i2;
+ movi(r0, i0);
+}
+
+static void _exti_u(jit_state_t *_jit,
+ jit_int32_t r0, jit_word_t i0, jit_word_t i1, jit_word_t i2)
+{
+ jit_word_t t;
+#if __BYTE_ORDER == __BIG_ENDIAN
+ i1 = __WORDSIZE - (i1 + i2);
+#endif
+ if (i1)
+ i0 >>= __WORDSIZE - i2;
+#if __WORDSIZE == 64 && !_WIN32
+ i0 &= (1L << i2) - 1;
+#else
+ i0 &= (1LL << i2) - 1;
+#endif
+ movi(r0, i0);
+}
+
+static void
+_generic_unldr(jit_state_t *_jit,
+ jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
+{
+ jit_int32_t t0, r2;
+ assert(i0 >= 1 && i0 <= sizeof(jit_word_t));
+ if (i0 & (i0 - 1)) {
+ t0 = jit_get_reg(jit_class_gpr);
+ r2 = rn(t0);
+ movr(r2, r1);
+ }
+ switch (i0) {
+ case 1:
+ ldr_c(r0, r1);
+ break;
+ case 2:
+ ldr_s(r0, r1);
+ break;
+ case 3:
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ ldr_us(r0, r2);
+ ldxi_c(r2, r2, 2);
+ lshi(r2, r2, 16);
+#else
+ ldr_c(r0, r2);
+ lshi(r0, r0, 16);
+ ldxi_us(r2, r2, 1);
+#endif
+ break;
+#if __WORDSIZE == 32
+ default:
+ ldr_i(r0, r1);
+ break;
+#else
+ case 4:
+ ldr_i(r0, r1);
+ break;
+ case 5:
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ ldr_ui(r0, r2);
+ ldxi_c(r2, r2, 4);
+ lshi(r2, r2, 32);
+# else
+ ldr_i(r0, r2);
+ lshi(r0, r0, 8);
+ ldxi_uc(r2, r2, 4);
+# endif
+ break;
+ case 6:
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ ldr_ui(r0, r2);
+ ldxi_s(r2, r2, 4);
+ lshi(r2, r2, 32);
+# else
+ ldr_i(r0, r2);
+ lshi(r0, r0, 16);
+ ldxi_us(r2, r2, 4);
+# endif
+ break;
+ case 7:
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ ldr_ui(r0, r2);
+ ldxi_i(r2, r2, 4);
+ lshi(r2, r2, 40);
+ rshi(r2, r2, 8);
+# else
+ ldr_i(r0, r2);
+ lshi(r0, r0, 24);
+ ldxi_ui(r2, r2, 4);
+ rshi(r2, r2, 8);
+# endif
+ break;
+ default:
+ ldr_l(r0, r1);
+ break;
+#endif
+ }
+ if (i0 & (i0 - 1)) {
+ orr(r0, r0, r2);
+ jit_unget_reg(t0);
+ }
+}
+
+static void
+_generic_unldi(jit_state_t *_jit,
+ jit_int32_t r0, jit_word_t i0, jit_word_t i1)
+{
+ jit_int32_t t0, r2;
+ assert(i1 >= 1 && i1 <= sizeof(jit_word_t));
+ if (i1 & (i1 - 1)) {
+ t0 = jit_get_reg(jit_class_gpr);
+ r2 = rn(t0);
+ }
+ switch (i1) {
+ case 1:
+ ldi_c(r0, i0);
+ break;
+ case 2:
+ ldi_s(r0, i0);
+ break;
+ case 3:
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ ldi_us(r0, i0);
+ ldi_c(r2, i0 + 2);
+ lshi(r2, r2, 16);
+# else
+ ldi_c(r0, i0);
+ lshi(r0, r0, 16);
+ ldi_us(r2, i0 + 1);
+# endif
+ break;
+# if __WORDSIZE == 32
+ default:
+ ldi_i(r0, i0);
+ break;
+# else
+ case 4:
+ ldi_i(r0, i0);
+ break;
+ case 5:
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ ldi_ui(r0, i0);
+ ldi_c(r2, i0 + 4);
+ lshi(r2, r2, 32);
+# else
+ ldi_i(r0, i0);
+ lshi(r0, r0, 8);
+ ldi_uc(r2, i0 + 4);
+# endif
+ break;
+ case 6:
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ ldi_ui(r0, i0);
+ ldi_s(r2, i0 + 4);
+ lshi(r2, r2, 32);
+# else
+ ldi_i(r0, i0);
+ lshi(r0, r0, 16);
+ ldi_us(r2, i0 + 4);
+# endif
+ break;
+ case 7:
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ ldi_ui(r0, i0);
+ ldi_i(r2, i0 + 4);
+ lshi(r2, r2, 40);
+ rshi(r2, r2, 8);
+# else
+ ldi_i(r0, i0);
+ lshi(r0, r0, 24);
+ ldi_ui(r2, i0 + 4);
+ rshi(r2, r2, 8);
+# endif
+ break;
+ default:
+ ldi_l(r0, i0);
+ break;
+# endif
+ }
+ if (i1 & (i1 - 1)) {
+ orr(r0, r0, r2);
+ jit_unget_reg(t0);
+ }
+}
+
+static void
+_generic_unldr_u(jit_state_t *_jit,
+ jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
+{
+ jit_int32_t t0, r2;
+ assert(i0 >= 1 && i0 <= sizeof(jit_word_t));
+ if (i0 & (i0 - 1)) {
+ t0 = jit_get_reg(jit_class_gpr);
+ r2 = rn(t0);
+ movr(r2, r1);
+ }
+ switch (i0) {
+ case 1:
+ ldr_uc(r0, r1);
+ break;
+ case 2:
+ ldr_us(r0, r1);
+ break;
+ case 3:
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ ldr_us(r0, r2);
+ ldxi_uc(r2, r2, 2);
+ lshi(r2, r2, 16);
+# else
+ ldr_uc(r0, r2);
+ lshi(r0, r0, 16);
+ ldxi_us(r2, r2, 1);
+# endif
+ break;
+# if __WORDSIZE == 32
+ default:
+ ldr_i(r0, r1);
+ break;
+# else
+ case 4:
+ ldr_ui(r0, r1);
+ break;
+ case 5:
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ ldr_ui(r0, r2);
+ ldxi_uc(r2, r2, 4);
+ lshi(r2, r2, 32);
+# else
+ ldr_ui(r0, r2);
+ lshi(r0, r0, 8);
+ ldxi_uc(r2, r2, 4);
+# endif
+ break;
+ case 6:
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ ldr_ui(r0, r2);
+ ldxi_us(r2, r2, 4);
+ lshi(r2, r2, 32);
+# else
+ ldr_ui(r0, r2);
+ lshi(r0, r0, 16);
+ ldxi_us(r2, r2, 4);
+# endif
+ break;
+ case 7:
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ ldr_ui(r0, r2);
+ ldxi_ui(r2, r2, 4);
+ lshi(r2, r2, 40);
+ rshi_u(r2, r2, 8);
+# else
+ ldr_ui(r0, r2);
+ lshi(r0, r0, 24);
+ ldxi_ui(r2, r2, 4);
+ rshi(r2, r2, 8);
+# endif
+ break;
+ default:
+ ldr_l(r0, r1);
+ break;
+# endif
+ }
+ if (i0 & (i0 - 1)) {
+ orr(r0, r0, r2);
+ jit_unget_reg(t0);
+ }
+}
+
+static void
+_generic_unldi_u(jit_state_t *_jit,
+ jit_int32_t r0, jit_word_t i0, jit_word_t i1)
+{
+ jit_int32_t t0, r2;
+ assert(i1 >= 1 && i1 <= sizeof(jit_word_t));
+ if (i1 & (i1 - 1)) {
+ t0 = jit_get_reg(jit_class_gpr);
+ r2 = rn(t0);
+ }
+ switch (i1) {
+ case 1:
+ ldi_uc(r0, i0);
+ break;
+ case 2:
+ ldi_us(r0, i0);
+ break;
+ case 3:
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ ldi_us(r0, i0);
+ ldi_uc(r2, i0 + 2);
+ lshi(r2, r2, 16);
+# else
+ ldi_uc(r0, i0);
+ lshi(r0, r0, 16);
+ ldi_us(r2, i0 + 1);
+# endif
+ break;
+# if __WORDSIZE == 32
+ default:
+ ldi_i(r0, i0);
+ break;
+# else
+ case 4:
+ ldi_ui(r0, i0);
+ break;
+ case 5:
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ ldi_ui(r0, i0);
+ ldi_uc(r2, i0 + 4);
+ lshi(r2, r2, 32);
+# else
+ ldi_ui(r0, i0);
+ lshi(r0, r0, 8);
+ ldi_uc(r2, i0 + 4);
+# endif
+ break;
+ case 6:
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ ldi_ui(r0, i0);
+ ldi_us(r2, i0 + 4);
+ lshi(r2, r2, 32);
+# else
+ ldi_ui(r0, i0);
+ lshi(r0, r0, 16);
+ ldi_us(r2, i0 + 4);
+# endif
+ break;
+ case 7:
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ ldi_ui(r0, i0);
+ ldi_ui(r2, i0 + 4);
+ lshi(r2, r2, 40);
+ rshi_u(r2, r2, 8);
+# else
+ ldi_ui(r0, i0);
+ lshi(r0, r0, 24);
+ ldi_ui(r2, i0 + 4);
+ rshi(r2, r2, 8);
+# endif
+ break;
+ default:
+ ldi_l(r0, i0);
+ break;
+# endif
+ }
+ if (i1 & (i1 - 1)) {
+ orr(r0, r0, r2);
+ jit_unget_reg(t0);
+ }
+}
+
+static void
+_generic_unstr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
+{
+ jit_word_t t0, r2;
+ assert(i0 > 0 && i0 <= sizeof(jit_word_t));
+ if (i0 & (i0 - 1)) {
+ t0 = jit_get_reg(jit_class_gpr);
+ r2 = rn(t0);
+ }
+ switch (i0) {
+ case 1:
+ str_c(r0, r1);
+ break;
+ case 2:
+ str_s(r0, r1);
+ break;
+ case 3:
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ str_s(r0, r1);
+ rshi(r2, r1, 16);
+ stxi_c(2, r0, r2);
+# else
+ stxi_c(2, r0, r1);
+ rshi(r2, r1, 8);
+ str_s(r0, r2);
+# endif
+ break;
+# if __WORDSIZE == 32
+ default:
+ str_i(r0, r1);
+ break;
+# else
+ case 4:
+ str_i(r0, r1);
+ break;
+ case 5:
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ str_i(r0, r1);
+ rshi(r2, r1, 32);
+ stxi_c(4, r0, r2);
+# else
+ stxi_c(4, r0, r1);
+ rshi(r2, r1, 8);
+ str_i(r0, r2);
+# endif
+ break;
+ case 6:
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ str_i(r0, r1);
+ rshi(r2, r1, 32);
+ stxi_s(4, r0, r2);
+# else
+ stxi_s(4, r0, r1);
+ rshi(r2, r1, 16);
+ str_i(r0, r2);
+# endif
+ break;
+ case 7:
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ str_i(r0, r1);
+ rshi(r2, r1, 32);
+ stxi_s(4, r0, r2);
+ rshi(r2, r2, 16);
+ stxi_c(6, r0, r2);
+# else
+ stxi_c(6, r0, r1);
+ rshi(r2, r1, 8);
+ stxi_s(4, r0, r2);
+ rshi(r2, r2, 16);
+ str_i(r0, r2);
+# endif
+ break;
+ default:
+ str_l(r0, r1);
+ break;
+# endif
+ }
+ if (i0 & (i0 - 1))
+ jit_unget_reg(t0);
+}
+
+static void
+_generic_unsti(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
+{
+ jit_word_t t0, r2;
+ assert(i1 > 0 && i1 <= sizeof(jit_word_t));
+ if (i1 & (i1 - 1)) {
+ t0 = jit_get_reg(jit_class_gpr);
+ r2 = rn(t0);
+ }
+ switch (i1) {
+ case 1:
+ sti_c(i0, r0);
+ break;
+ case 2:
+ sti_s(i0, r0);
+ break;
+ case 3:
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ sti_s(i0, r0);
+ rshi(r2, r0, 16);
+ sti_c(2 + i0, r2);
+# else
+ sti_c(2 + i0, r0);
+ rshi(r2, r0, 8);
+ sti_s(i0, r2);
+# endif
+ break;
+# if __WORDSIZE == 32
+ default:
+ sti_i(i0, r0);
+ break;
+# else
+ case 4:
+ sti_i(i0, r0);
+ break;
+ case 5:
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ sti_i(i0, r0);
+ rshi(r2, r0, 32);
+ sti_c(4 + i0, r2);
+# else
+ stxi_c(4, i0, r0);
+ rshi(r2, r0, 8);
+ sti_i(i0, r2);
+# endif
+ break;
+ case 6:
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ sti_i(i0, r0);
+ rshi(r2, r0, 32);
+ sti_s(4 + i0, r2);
+# else
+ sti_s(4 + i0, r0);
+ rshi(r2, r0, 16);
+ sti_i(i0, r2);
+# endif
+ break;
+ case 7:
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ sti_i(i0, r0);
+ rshi(r2, r0, 32);
+ sti_s(4 + i0, r2);
+ rshi(r2, r2, 16);
+ sti_c(6 + i0, r2);
+# else
+ sti_c(6 + i0, r0);
+ rshi(r2, r0, 8);
+ sti_s(4 + i0, r2);
+ rshi(r2, r2, 16);
+ sti_i(i0, r2);
+# endif
+ break;
+ default:
+ sti_l(i0, r0);
+ break;
+# endif
+ }
+ if (i1 & (i1 - 1))
+ jit_unget_reg(t0);
+}
+
+#if !defined(__i386__) && !defined(__x86_64__) && !defined(__arm__)
+static void
+_generic_unldr_x(jit_state_t *_jit,
+ jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
+{
+ assert(i0 == 4 || i0 == 8);
+ if (i0 == 4)
+ ldr_f(r0, r1);
+ else
+ ldr_d(r0, r1);
+}
+
+static void
+_generic_unldi_x(jit_state_t *_jit,
+ jit_int32_t r0, jit_word_t i0, jit_word_t i1)
+{
+ assert(i1 == 4 || i1 == 8);
+ if (i1 == 4)
+ ldi_f(r0, i0);
+ else
+ ldi_d(r0, i0);
+}
+
+static void
+_generic_unstr_x(jit_state_t *_jit,
+ jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
+{
+ assert(i0 == 4 || i0 == 8);
+ if (i0 == 4)
+ str_f(r0, r1);
+ else
+ str_d(r0, r1);
+}
+
+static void
+_generic_unsti_x(jit_state_t *_jit,
+ jit_word_t i0, jit_int32_t r0, jit_word_t i1)
+{
+ assert(i1 == 4 || i1 == 8);
+ if (i1 == 4)
+ sti_f(i0, r0);
+ else
+ sti_d(i0, r0);
+}
+#endif
+
+#if defined(stack_framesize)
+static maybe_unused void
+_patch_alist(jit_state_t *_jit, jit_bool_t revert)
+{
+ jit_int32_t diff;
+ jit_node_t *node;
+ diff = jit_diffsize();
+ if (diff) {
+ if (revert)
+ diff = -diff;
+ for (node = _jitc->function->alist; node; node = node->link) {
+ switch (node->code) {
+ 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:
+#if __WORDSIZE == 64
+ case jit_code_ldxi_ui: case jit_code_ldxi_l:
+#endif
+ case jit_code_ldxi_f: case jit_code_ldxi_d:
+ node->w.w -= diff;
+ break;
+ case jit_code_stxi_c: case jit_code_stxi_s:
+ case jit_code_stxi_i:
+#if __WORDSIZE == 64
+ case jit_code_stxi_l:
+#endif
+ case jit_code_stxi_f: case jit_code_stxi_d:
+ node->u.w -= diff;
+ break;
+ default:
+ abort();
+ }
+ }
+ }
+}