release r24
[pcsx_rearmed.git] / deps / lightning / lib / jit_mips-cpu.c
CommitLineData
4a71579b 1/*
79bfeef6 2 * Copyright (C) 2012-2023 Free Software Foundation, Inc.
4a71579b
PC
3 *
4 * This file is part of GNU lightning.
5 *
6 * GNU lightning is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation; either version 3, or (at your option)
9 * any later version.
10 *
11 * GNU lightning is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 * License for more details.
15 *
16 * Authors:
17 * Paulo Cesar Pereira de Andrade
18 */
19
20#if PROTO
ba86ff93
PC
21/* FIXME Should need qemu 7.2 -- apparently broken with qemu 7.0 */
22#define PCREL_BROKEN 1
23#define BALC_BROKEN 1
24
4a71579b
PC
25typedef union {
26#if __BYTE_ORDER == __LITTLE_ENDIAN
27 struct { jit_uint32_t _:26; jit_uint32_t b : 6; } hc;
28 struct { jit_uint32_t _:21; jit_uint32_t b : 5; } rs;
29 struct { jit_uint32_t _:21; jit_uint32_t b : 5; } fm;
ba86ff93
PC
30 struct { jit_uint32_t _:21; jit_uint32_t b : 5; } fr;
31 struct { jit_uint32_t _:18; jit_uint32_t b : 3; } pD;
32 struct { jit_uint32_t _:19; jit_uint32_t b : 2; } pW;
4a71579b
PC
33 struct { jit_uint32_t _:16; jit_uint32_t b : 5; } rt;
34 struct { jit_uint32_t _:16; jit_uint32_t b : 5; } ft;
35 struct { jit_uint32_t _:11; jit_uint32_t b : 5; } rd;
36 struct { jit_uint32_t _:11; jit_uint32_t b : 5; } fs;
79bfeef6 37 struct { jit_uint32_t _: 7; jit_uint32_t b : 9; } i9;
4a71579b
PC
38 struct { jit_uint32_t _: 6; jit_uint32_t b : 5; } ic;
39 struct { jit_uint32_t _: 6; jit_uint32_t b : 5; } fd;
4a71579b 40 struct { jit_uint32_t b : 6; } tc;
79bfeef6 41 struct { jit_uint32_t b : 5; } cn;
4a71579b
PC
42 struct { jit_uint32_t b : 11; } cc;
43 struct { jit_uint32_t b : 16; } is;
ba86ff93
PC
44 struct { jit_uint32_t b : 18; } iD;
45 struct { jit_uint32_t b : 19; } iW;
4a71579b
PC
46 struct { jit_uint32_t b : 26; } ii;
47#else
48 struct { jit_uint32_t b : 6; } hc;
49 struct { jit_uint32_t _: 6; jit_uint32_t b : 5; } rs;
50 struct { jit_uint32_t _: 6; jit_uint32_t b : 5; } fm;
ba86ff93
PC
51 struct { jit_uint32_t _: 6; jit_uint32_t b : 5; } fr;
52 struct { jit_uint32_t _:11; jit_uint32_t b : 3; } pD;
53 struct { jit_uint32_t _:11; jit_uint32_t b : 2; } pW;
4a71579b
PC
54 struct { jit_uint32_t _:11; jit_uint32_t b : 5; } rt;
55 struct { jit_uint32_t _:11; jit_uint32_t b : 5; } ft;
56 struct { jit_uint32_t _:16; jit_uint32_t b : 5; } rd;
57 struct { jit_uint32_t _:16; jit_uint32_t b : 5; } fs;
79bfeef6 58 struct { jit_uint32_t _:16; jit_uint32_t b : 9; } i9;
4a71579b
PC
59 struct { jit_uint32_t _:21; jit_uint32_t b : 5; } ic;
60 struct { jit_uint32_t _:21; jit_uint32_t b : 5; } fd;
4a71579b 61 struct { jit_uint32_t _:26; jit_uint32_t b : 6; } tc;
79bfeef6 62 struct { jit_uint32_t _:27; jit_uint32_t b : 5; } cn;
4a71579b
PC
63 struct { jit_uint32_t _:21; jit_uint32_t b : 11; } cc;
64 struct { jit_uint32_t _:16; jit_uint32_t b : 16; } is;
ba86ff93
PC
65 struct { jit_uint32_t _:14; jit_uint32_t b : 18; } iD;
66 struct { jit_uint32_t _:13; jit_uint32_t b : 19; } iW;
4a71579b
PC
67 struct { jit_uint32_t _: 6; jit_uint32_t b : 26; } ii;
68#endif
69 int op;
70} jit_instr_t;
79bfeef6
PC
71#define jit_mips2_p() (jit_cpu.release >= 2)
72#define jit_mips6_p() (jit_cpu.release >= 6)
ba86ff93 73#define jit_unaligned_p() (jit_cpu.unaligned)
4a71579b
PC
74# define _ZERO_REGNO 0
75# define _T0_REGNO 0x08
76# define _T1_REGNO 0x09
77# define _T2_REGNO 0x0a
78# define _T3_REGNO 0x0b
79# define _T4_REGNO 0x0c
80# define _T5_REGNO 0x0d
81# define _T6_REGNO 0x0e
82# define _T7_REGNO 0x0f
83# define _S0_REGNO 0x10
84# define _S1_REGNO 0x11
85# define _S2_REGNO 0x12
86# define _S3_REGNO 0x13
87# define _S4_REGNO 0x14
88# define _S5_REGNO 0x15
89# define _S6_REGNO 0x16
90# define _S7_REGNO 0x17
91# define _T8_REGNO 0x18
92# define _T9_REGNO 0x19
93# define _SP_REGNO 0x1d
94# define _BP_REGNO 0x1e
95# define _RA_REGNO 0x1f
96# define _F16_REGNO 16
97# define _F18_REGNO 18
98# define _F20_REGNO 20
99# define _F22_REGNO 22
100# define _F24_REGNO 24
101# define _F26_REGNO 26
102# define _F28_REGNO 28
103# define _F30_REGNO 30
104# if __WORDSIZE == 32
4a71579b
PC
105# define ldr(u,v) ldr_i(u,v)
106# define ldi(u,v) ldi_i(u,v)
ba86ff93 107# define ldxr(u,v,w) ldxr_i(u,v,w)
4a71579b 108# define ldxi(u,v,w) ldxi_i(u,v,w)
ba86ff93 109# define str(u,v) str_i(u,v)
4a71579b 110# define sti(u,v) sti_i(u,v)
ba86ff93 111# define stxr(u,v,w) stxr_i(u,v,w)
4a71579b
PC
112# define stxi(u,v,w) stxi_i(u,v,w)
113# else
4a71579b
PC
114# define ldr(u,v) ldr_l(u,v)
115# define ldi(u,v) ldi_l(u,v)
ba86ff93 116# define ldxr(u,v,w) ldxr_l(u,v,w)
4a71579b 117# define ldxi(u,v,w) ldxi_l(u,v,w)
ba86ff93 118# define str(u,v) str_l(u,v)
4a71579b 119# define sti(u,v) sti_l(u,v)
ba86ff93 120# define stxr(u,v,w) stxr_l(u,v,w)
4a71579b
PC
121# define stxi(u,v,w) stxi_l(u,v,w)
122# endif
79bfeef6
PC
123/* can_relative_jump_p(im) => can_sign_extend_short_p(im << 2) */
124# define can_relative_jump_p(im) ((im) >= -130712 && (im) <= 131068)
ba86ff93
PC
125/* can_compact_jump_p(im) => can_sign_extend_i26_p(im << 2) */
126# define can_compact_jump_p(im) ((im) >= -268435456 && (im) <= 268435452)
127# define can_sign_extend_short_p(im) ((im) >= -32768 && (im) <= 32767)
4a71579b 128# define can_zero_extend_short_p(im) ((im) >= 0 && (im) <= 65535)
ba86ff93
PC
129# define can_sign_extend_i18_p(im) ((im) >= -262144 && (im) <= 262143)
130# define can_sign_extend_i19_p(im) ((im) >= -524288 && (im) <= 524287)
131# define can_sign_extend_i26_p(im) ((im) >= -67108864 && (im) <= 67108863)
40a44dcb
PC
132# define is_low_mask(im) (((im) & 1) ? (__builtin_popcountl((im) + 1) <= 1) : 0)
133# define is_middle_mask(im) ((im) ? (__builtin_popcountl((im) + (1 << __builtin_ctzl(im))) <= 1) : 0)
519a9ea1
PC
134# define is_high_mask(im) ((im) ? (__builtin_popcountl((im) + (1 << __builtin_ctzl(im))) == 0) : 0)
135# define masked_bits_count(im) __builtin_popcountl(im)
136# define unmasked_bits_count(im) (__WORDSIZE - masked_bits_count(im))
4a71579b
PC
137# if __WORDSIZE == 32
138# define can_sign_extend_int_p(im) 1
139# define can_zero_extend_int_p(im) 1
140# else
141# define can_sign_extend_int_p(im) \
142 (((im) >= 0 && (im) <= 0x7fffffffL) || \
143 ((im) < 0 && (im) >= -0x80000000L))
144# define can_zero_extend_int_p(im) ((im) >= 0 && (im) <= 0xffffffff)
145# endif
146# define MIPS_SPECIAL 0x00
147# define MIPS_REGIMM 0x01
148# define MIPS_J 0x02
149# define MIPS_SRL 0x02
150# define MIPS_JAL 0x03
151# define MIPS_SRA 0x03
152# define MIPS_BEQ 0x04
153# define MIPS_BNE 0x05
154# define MIPS_BLEZ 0x06
155# define MIPS_BGTZ 0x07
156# define MIPS_ADDI 0x08
157# define MIPS_ADDIU 0x09
158# define MIPS_SLTI 0x0a
159# define MIPS_SLTIU 0x0b
160# define MIPS_ANDI 0x0c
161# define MIPS_ORI 0x0d
162# define MIPS_XORI 0x0e
163# define MIPS_LUI 0x0f
164# define MIPS_COP0 0x10
165# define MIPS_COP1 0x11
166# define MIPS_COP2 0x12
167# define MIPS_COP1X 0x13
168# define MIPS_BEQL 0x14
169# define MIPS_BNEL 0x15
170# define MIPS_BLEZL 0x16
171# define MIPS_BGTZL 0x17
172# define MIPS_DADDI 0x18
173# define MIPS_DADDIU 0x19
174# define MIPS_LDL 0x1a
175# define MIPS_LDR 0x1b
176# define MIPS_SPECIAL2 0x1c
177# define MIPS_JALX 0x1d
ba86ff93 178# define MIPS_DAUI 0x1d
4a71579b
PC
179# define MIPS_SPECIAL3 0x1f
180# define MIPS_LB 0x20
181# define MIPS_LH 0x21
182# define MIPS_LWL 0x22
183# define MIPS_LW 0x23
184# define MIPS_LBU 0x24
185# define MIPS_LHU 0x25
186# define MIPS_LWR 0x26
187# define MIPS_LWU 0x27
188# define MIPS_SB 0x28
189# define MIPS_SH 0x29
190# define MIPS_SWL 0x2a
191# define MIPS_SW 0x2b
ba86ff93
PC
192# define MIPS_SDL 0x2c
193# define MIPS_SDR 0x2d
4a71579b
PC
194# define MIPS_SWR 0x2e
195# define MIPS_CACHE 0x2f
196# define MIPS_LL 0x30
197# define MIPS_LWC1 0x31
198# define MIPS_LWC2 0x32
199# define MIPS_PREF 0x33
200# define MIPS_LLD 0x34
201# define MIPS_LDC1 0x35
202# define MIPS_LDC2 0x36
203# define MIPS_LD 0x37
204# define MIPS_SC 0x38
ba86ff93
PC
205# define MIPS_BC_R6 0x32
206# define MIPS_BALC 0x3a
207# define MIPS_PCREL 0x3b
4a71579b
PC
208# define MIPS_SCD 0x3c
209# define MIPS_SDC1 0x3d
210# define MIPS_SDC2 0x3e
211# define MIPS_SWC1 0x39
212# define MIPS_SWC2 0x3a
213# define MIPS_SD 0x3f
214# define MIPS_MF 0x00
215# define MIPS_DMF 0x01
216# define MIPS_CF 0x02
217# define MIPS_MFH 0x03
218# define MIPS_MT 0x04
219# define MIPS_DMT 0x05
220# define MIPS_CT 0x06
221# define MIPS_MTH 0x07
222# define MIPS_BC 0x08
79bfeef6
PC
223# define MIPS_BC1EQZ 0x09 /* release 6 */
224# define MIPS_BC1NEZ 0x0d /* release 6 */
4a71579b
PC
225# define MIPS_WRPGPR 0x0e
226# define MIPS_BGZAL 0x11
227# define MIPS_MFMC0 0x11
228# define MIPS_BCF 0x00
229# define MIPS_BLTZ 0x00
230# define MIPS_BCT 0x01
231# define MIPS_BGEZ 0x01
232# define MIPS_BCFL 0x02
233# define MIPS_BLTZL 0x02
234# define MIPS_BCTL 0x03
235# define MIPS_BGEZL 0x03
236# define MIPS_TGEI 0x08
237# define MIPS_TGEIU 0x09
238# define MIPS_TLTI 0x0a
239# define MIPS_TLTIU 0x0b
240# define MIPS_TEQI 0x0c
241# define MIPS_TNEI 0x0e
242# define MIPS_BLTZAL 0x10
243# define MIPS_BGEZAL 0x11
244# define MIPS_BLTZALL 0x12
245# define MIPS_BGEZALL 0x13
246# define MIPS_SYNCI 0x1f
247# define MIPS_WSBH 0x02
ba86ff93 248# define MIPS_DSBH 0x02
4a71579b
PC
249# define MIPS_DSHD 0x05
250# define MIPS_SEB 0x10
251# define MIPS_SEH 0x18
252# define MIPS_MADD 0x00
253# define MIPS_SLL 0x00
254# define MIPS_EXT 0x00
255# define MIPS_DEXTM 0x01
256# define MIPS_MADDU 0x01
257# define MIPS_MOVFT 0x01
258# define MIPS_TLBR 0x01
259# define MIPS_MUL 0x02
260# define MIPS_DEXTU 0x02
261# define MIPS_TLBWI 0x02
262# define MIPS_DEXT 0x03
263# define MIPS_SLLV 0x04
264# define MIPS_INS 0x04
265# define MIPS_MSUB 0x04
266# define MIPS_DINSM 0x05
267# define MIPS_MSUBU 0x05
268# define MIPS_SRLV 0x06
269# define MIPS_DINSU 0x06
270# define MIPS_TLBWR 0x06
271# define MIPS_SRAV 0x07
272# define MIPS_DINS 0x07
273# define MIPS_JR 0x08
274# define MIPS_TLBP 0x08
275# define MIPS_JALR 0x09
276# define MIPS_MOVZ 0x0a
277# define MIPS_MOVN 0x0b
278# define MIPS_SYSCALL 0x0c
279# define MIPS_BREAK 0x0d
280# define MIPS_PREFX 0x0f
281# define MIPS_SYNC 0x0f
282# define MIPS_MFHI 0x10
283# define MIPS_MTHI 0x11
284# define MIPS_MFLO 0x12
285# define MIPS_MTLO 0x13
286# define MIPS_DSLLV 0x14
287# define MIPS_DSRLV 0x16
288# define MIPS_DSRAV 0x17
289# define MIPS_MULT 0x18
290# define MIPS_ERET 0x18
291# define MIPS_MULTU 0x19
292# define MIPS_DIV 0x1a
293# define MIPS_DIVU 0x1b
294# define MIPS_DMULT 0x1c
295# define MIPS_DMULTU 0x1d
296# define MIPS_DDIV 0x1e
297# define MIPS_DDIVU 0x1f
298# define MIPS_DERET 0x1f
299# define MIPS_ADD 0x20
300# define MIPS_CLZ 0x20
301# define MIPS_BSHFL 0x20
302# define MIPS_ADDU 0x21
303# define MIPS_CLO 0x21
304# define MIPS_SUB 0x22
305# define MIPS_SUBU 0x23
306# define MIPS_AND 0x24
307# define MIPS_DCLZ 0x24
308# define MIPS_DBSHFL 0x24
309# define MIPS_OR 0x25
310# define MIPS_DCLO 0x25
311# define MIPS_XOR 0x26
312# define MIPS_NOR 0x27
313# define MIPS_SLT 0x2a
314# define MIPS_SLTU 0x2b
315# define MIPS_DADD 0x2c
316# define MIPS_DADDU 0x2d
317# define MIPS_DSUB 0x2e
318# define MIPS_DSUBU 0x2f
319# define MIPS_TGE 0x30
320# define MIPS_TGEU 0x31
321# define MIPS_TLT 0x32
322# define MIPS_TLTU 0x33
323# define MIPS_TEQ 0x34
324# define MIPS_TNE 0x36
325# define MIPS_DSLL 0x38
326# define MIPS_DSRL 0x3a
327# define MIPS_DSRA 0x3b
328# define MIPS_DSLL32 0x3c
329# define MIPS_DSRL32 0x3e
330# define MIPS_DSRA32 0x3f
331# define MIPS_SDBPP 0x3f
332# define ii(i) *_jit->pc.ui++ = i
79bfeef6
PC
333# define instr(op) _instr(_jit, op)
334static void _instr(jit_state_t*, jit_int32_t);
335# define flush() _flush(_jit)
336static void _flush(jit_state_t*);
337# define pending() _pending(_jit)
338static jit_int32_t _pending(jit_state_t*);
339# define delay(op) _delay(_jit,op)
340static void _delay(jit_state_t*,jit_int32_t);
341# define jit_get_reg_for_delay_slot(mask, r0,r1) \
342 _jit_get_reg_for_delay_slot(_jit,mask,r0,r1)
343static jit_int32_t _jit_get_reg_for_delay_slot(jit_state_t*,jit_int32_t,
344 jit_int32_t, jit_int32_t);
345# define hrrrit(hc,rs,rt,rd,im,tc) _hrrrit(_jit,hc,rs,rt,rd,im,tc)
4a71579b
PC
346static void
347_hrrrit(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t,
348 jit_int32_t,jit_int32_t);
4a71579b
PC
349# define hrrr_t(hc,rs,rt,rd,tc) hrrrit(hc,rs,rt,rd,0,tc)
350# define rrr_t(rs,rt,rd,tc) hrrr_t(0,rs,rt,rd,tc)
351# define hrri(hc,rs,rt,im) _hrri(_jit,hc,rs,rt,im)
352static void _hrri(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
79bfeef6
PC
353# define hrri9(hc,rs,rt,i9,tc) _hrri9(_jit,hc,rs,rt,i9,tc)
354static void _hrri9(jit_state_t*,jit_int32_t,jit_int32_t,
355 jit_int32_t,jit_int32_t,jit_int32_t);
ba86ff93
PC
356# define hriD(hc,rs,pD,iD) _hriD(_jit,hc,rs,pD,iD)
357static void _hriD(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
358# define hriW(hc,rs,pW,iW) _hriW(_jit,hc,rs,pW,iW)
359static void _hriW(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
4a71579b
PC
360# define hi(hc,im) _hi(_jit,hc,im)
361static void _hi(jit_state_t*,jit_int32_t,jit_int32_t);
79bfeef6 362# define NOP(i0) instr(0)
4a71579b
PC
363# define nop(i0) _nop(_jit,i0)
364static void _nop(jit_state_t*,jit_int32_t);
365# define h_ri(hc,rt,im) _hrri(_jit,hc,0,rt,im)
366# define rrit(rt,rd,im,tc) _hrrrit(_jit,0,0,rt,rd,im,tc)
ba86ff93
PC
367# define AUIPC(rs,im) hrri(MIPS_PCREL,rs,30,im)
368# define ALUIPC(rs,im) hrri(MIPS_PCREL,rs,31,im)
369# define ADDIUPC(rs,im) hriW(MIPS_PCREL,rs,0,im)
4a71579b 370# define LUI(rt,im) h_ri(MIPS_LUI,rt,im)
ba86ff93 371# define AUI(rs,rt) hrri(MIPS_LUI,rs,rt,im) /* mips r6 */
4a71579b
PC
372# define ADDU(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_ADDU)
373# define DADDU(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_DADDU)
374# define ADDIU(rt,rs,im) hrri(MIPS_ADDIU,rs,rt,im)
375# define DADDIU(rt,rs,im) hrri(MIPS_DADDIU,rs,rt,im)
376# define SUBU(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_SUBU)
377# define DSUBU(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_DSUBU)
40a44dcb 378# define MUL(rd,rs,rt) hrrr_t(MIPS_SPECIAL2,rs,rt,rd,MIPS_MUL)
4a71579b 379# define MULT(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_MULT)
79bfeef6
PC
380# define MUL_R6(rd,rs,rt) hrrrit(MIPS_SPECIAL, rs, rt, rd, 2, 24)
381# define MUH_R6(rd,rs,rt) hrrrit(MIPS_SPECIAL, rs, rt, rd, 3, 24)
4a71579b 382# define MULTU(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_MULTU)
79bfeef6
PC
383# define MULU_R6(rd,rs,rt) hrrrit(MIPS_SPECIAL, rs, rt, rd, 2, 25)
384# define MUHU_R6(rd,rs,rt) hrrrit(MIPS_SPECIAL, rs, rt, rd, 3, 25)
4a71579b 385# define DMULT(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_DMULT)
79bfeef6
PC
386# define DMUL_R6(rd,rs,rt) hrrrit(MIPS_SPECIAL, rs, rt, rd, 2, 28)
387# define DMUH_R6(rd,rs,rt) hrrrit(MIPS_SPECIAL, rs, rt, rd, 3, 28)
4a71579b 388# define DMULTU(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_DMULTU)
79bfeef6
PC
389# define DMULU_R6(rd,rs,rt) hrrrit(MIPS_SPECIAL, rs, rt, rd, 2, 29)
390# define DMUHU_R6(rd,rs,rt) hrrrit(MIPS_SPECIAL, rs, rt, rd, 3, 29)
4a71579b 391# define DIV(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_DIV)
79bfeef6
PC
392# define DIV_R6(rd,rs,rt) hrrrit(MIPS_SPECIAL, rs, rt, rd, 2, 26)
393# define MOD_R6(rd,rs,rt) hrrrit(MIPS_SPECIAL, rs, rt, rd, 3, 26)
4a71579b 394# define DIVU(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_DIVU)
79bfeef6
PC
395# define DIVU_R6(rd,rs,rt) hrrrit(MIPS_SPECIAL, rs, rt, rd, 2, 27)
396# define MODU_R6(rd,rs,rt) hrrrit(MIPS_SPECIAL, rs, rt, rd, 3, 27)
4a71579b 397# define DDIV(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_DDIV)
79bfeef6
PC
398# define DDIV_R6(rd,rs,rt) hrrrit(MIPS_SPECIAL, rs, rt, rd, 2, 30)
399# define DMOD_R6(rd,rs,rt) hrrrit(MIPS_SPECIAL, rs, rt, rd, 3, 30)
4a71579b 400# define DDIVU(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_DDIVU)
79bfeef6
PC
401# define DDIVU_R6(rd,rs,rt) hrrrit(MIPS_SPECIAL, rs, rt, rd, 2, 31)
402# define DMODU_R6(rd,rs,rt) hrrrit(MIPS_SPECIAL, rs, rt, rd, 3, 31)
4a71579b
PC
403# define SLLV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_SLLV)
404# define SLL(rd,rt,sa) rrit(rt,rd,sa,MIPS_SLL)
405# define DSLLV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_DSLLV)
406# define DSLL(rd,rt,sa) rrit(rt,rd,sa,MIPS_DSLL)
407# define DSLL32(rd,rt,sa) rrit(rt,rd,sa,MIPS_DSLL32)
408# define SRAV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_SRAV)
409# define SRA(rd,rt,sa) rrit(rt,rd,sa,MIPS_SRA)
410# define SRLV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_SRLV)
411# define SRL(rd,rt,sa) rrit(rt,rd,sa,MIPS_SRL)
412# define DSRAV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_DSRAV)
413# define DSRA(rd,rt,sa) rrit(rt,rd,sa,MIPS_DSRA)
414# define DSRA32(rd,rt,sa) rrit(rt,rd,sa,MIPS_DSRA32)
415# define DSRLV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_DSRLV)
416# define DSRL(rd,rt,sa) rrit(rt,rd,sa,MIPS_DSRL)
417# define DSRL32(rd,rt,sa) rrit(rt,rd,sa,MIPS_DSRL32)
519a9ea1
PC
418# define INS(rt,rs,pos,size) hrrrit(MIPS_SPECIAL3,rs,rt,pos+size-1,pos,MIPS_INS)
419# define DINS(rt,rs,pos,size) hrrrit(MIPS_SPECIAL3,rs,rt,pos+size-1,pos,MIPS_DINS)
40a44dcb
PC
420# define DINSU(rt,rs,pos,size) hrrrit(MIPS_SPECIAL3,rs,rt,pos+size-32-1,pos-32,MIPS_DINSU)
421# define DINSM(rt,rs,pos,size) hrrrit(MIPS_SPECIAL3,rs,rt,pos+size-32-1,pos,MIPS_DINSM)
519a9ea1
PC
422# define EXT(rt,rs,pos,size) hrrrit(MIPS_SPECIAL3,rs,rt,size-1,pos,MIPS_EXT)
423# define DEXT(rt,rs,pos,size) hrrrit(MIPS_SPECIAL3,rs,rt,size-1,pos,MIPS_DEXT)
40a44dcb
PC
424# define DEXTU(rt,rs,pos,size) hrrrit(MIPS_SPECIAL3,rs,rt,size-1,pos-32,MIPS_DEXTU)
425# define DEXTM(rt,rs,pos,size) hrrrit(MIPS_SPECIAL3,rs,rt,size-32-1,pos,MIPS_DEXTM)
4a71579b 426# define ROTR(rd,rt,sa) hrrrit(MIPS_SPECIAL,1,rt,rd,sa,MIPS_SRL)
ba86ff93 427# define ROTRV(rd,rt,rs) hrrrit(MIPS_SPECIAL,rs,rt,rd,1,MIPS_SRLV)
4a71579b 428# define DROTR(rd,rt,sa) hrrrit(MIPS_SPECIAL,1,rt,rd,sa,MIPS_DSRL)
ba86ff93
PC
429# define DROTR32(rd,rt,sa) hrrrit(MIPS_SPECIAL,1,rt,rd,sa,MIPS_DSRL32)
430# define DROTRV(rd,rt,rs) hrrrit(MIPS_SPECIAL,rs,rt,rd,1,MIPS_DSRLV)
c0c16242 431# define SYNC() rrr_t(_ZERO_REGNO,_ZERO_REGNO,_ZERO_REGNO,MIPS_SYNC)
4a71579b
PC
432# define MFHI(rd) rrr_t(_ZERO_REGNO,_ZERO_REGNO,rd,MIPS_MFHI)
433# define MFLO(rd) rrr_t(_ZERO_REGNO,_ZERO_REGNO,rd,MIPS_MFLO)
434# define MTHI(rs) rrr_t(rs,_ZERO_REGNO,_ZERO_REGNO,MIPS_MTHI)
435# define MTLO(rs) rrr_t(rs,_ZERO_REGNO,_ZERO_REGNO,MIPS_MTLO)
436# define AND(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_AND)
437# define ANDI(rt,rs,im) hrri(MIPS_ANDI,rs,rt,im)
438# define OR(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_OR)
439# define ORI(rt,rs,im) hrri(MIPS_ORI,rs,rt,im)
79bfeef6 440# define NOR(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_NOR)
4a71579b
PC
441# define XOR(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_XOR)
442# define XORI(rt,rs,im) hrri(MIPS_XORI,rs,rt,im)
443# define LB(rt,of,rb) hrri(MIPS_LB,rb,rt,of)
444# define LBU(rt,of,rb) hrri(MIPS_LBU,rb,rt,of)
445# define LH(rt,of,rb) hrri(MIPS_LH,rb,rt,of)
446# define LHU(rt,of,rb) hrri(MIPS_LHU,rb,rt,of)
447# define LW(rt,of,rb) hrri(MIPS_LW,rb,rt,of)
ba86ff93 448# define LWPC(rs,im) hriW(MIPS_PCREL,rs,1,im)
4a71579b 449# define LWU(rt,of,rb) hrri(MIPS_LWU,rb,rt,of)
ba86ff93
PC
450# define LWUPC(rs,im) hriW(MIPS_PCREL,rs,2,im)
451# define LWL(rt,of,rb) hrri(MIPS_LWL,rb,rt,of)
452# define LWR(rt,of,rb) hrri(MIPS_LWR,rb,rt,of)
4a71579b 453# define LD(rt,of,rb) hrri(MIPS_LD,rb,rt,of)
ba86ff93 454# define LDPC(rs,im) hriD(MIPS_PCREL,rs,6,im)
c0c16242 455# define LL(rt,of,rb) hrri(MIPS_LL,rb,rt,of)
79bfeef6 456# define LL_R6(rt,of,rb) hrri9(MIPS_SPECIAL3,rb,rt,of,54)
c0c16242 457# define LLD(rt,of,rb) hrri(MIPS_LLD,rb,rt,of)
79bfeef6 458# define LLD_R6(rt,of,rb) hrri9(MIPS_SPECIAL3,rb,rt,of,55)
ba86ff93
PC
459# define LDL(rt,of,rb) hrri(MIPS_LDL,rb,rt,of)
460# define LDR(rt,of,rb) hrri(MIPS_LDR,rb,rt,of)
4a71579b
PC
461# define SB(rt,of,rb) hrri(MIPS_SB,rb,rt,of)
462# define SH(rt,of,rb) hrri(MIPS_SH,rb,rt,of)
463# define SW(rt,of,rb) hrri(MIPS_SW,rb,rt,of)
ba86ff93
PC
464# define SWL(rt,of,rb) hrri(MIPS_SWL,rb,rt,of)
465# define SWR(rt,of,rb) hrri(MIPS_SWR,rb,rt,of)
4a71579b 466# define SD(rt,of,rb) hrri(MIPS_SD,rb,rt,of)
c0c16242 467# define SC(rt,of,rb) hrri(MIPS_SC,rb,rt,of)
79bfeef6 468# define SC_R6(rt,of,rb) hrri9(MIPS_SPECIAL3,rb,rt,of,38)
c0c16242 469# define SCD(rt,of,rb) hrri(MIPS_SCD,rb,rt,of)
79bfeef6 470# define SCD_R6(rt,of,rb) hrri9(MIPS_SPECIAL3,rb,rt,of,39)
ba86ff93
PC
471# define SDL(rt,of,rb) hrri(MIPS_SDL,rb,rt,of)
472# define SDR(rt,of,rb) hrri(MIPS_SDR,rb,rt,of)
4a71579b
PC
473# define WSBH(rd,rt) hrrrit(MIPS_SPECIAL3,0,rt,rd,MIPS_WSBH,MIPS_BSHFL)
474# define SEB(rd,rt) hrrrit(MIPS_SPECIAL3,0,rt,rd,MIPS_SEB,MIPS_BSHFL)
475# define SEH(rd,rt) hrrrit(MIPS_SPECIAL3,0,rt,rd,MIPS_SEH,MIPS_BSHFL)
ba86ff93
PC
476# define DSBH(rd,rt) hrrrit(MIPS_SPECIAL3,0,rt,rd,MIPS_DSBH,MIPS_DBSHFL)
477# define DSHD(rd,rt) hrrrit(MIPS_SPECIAL3,0,rt,rd,MIPS_DSHD,MIPS_DBSHFL)
4a71579b
PC
478# define SLT(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_SLT)
479# define SLTU(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_SLTU)
480# define SLTI(rt,rs,im) hrri(MIPS_SLTI,rs,rt,im)
481# define SLTIU(rt,rs,im) hrri(MIPS_SLTIU,rs,rt,im)
ba86ff93
PC
482# define DAUI(rt,rs,im) hrri(MIPS_DAUI,rs,rt,im)
483# define DAHI(rs,im) hrri(MIPS_REGIMM,rs,6,im)
484# define DATI(rs,im) hrri(MIPS_REGIMM,rs,30,im)
4a71579b
PC
485# define BLTZ(rs,im) hrri(MIPS_REGIMM,rs,MIPS_BLTZ,im)
486# define BLEZ(rs,im) hrri(MIPS_BLEZ,rs,_ZERO_REGNO,im)
487# define BEQ(rs,rt,im) hrri(MIPS_BEQ,rs,rt,im)
488# define BGEZ(rs,im) hrri(MIPS_REGIMM,rs,MIPS_BGEZ,im)
489# define BGTZ(rs,im) hrri(MIPS_BGTZ,rs,_ZERO_REGNO,im)
490# define BNE(rs,rt,im) hrri(MIPS_BNE,rs,rt,im)
79bfeef6 491# define BGEZAL(rs,im) hrri(MIPS_REGIMM,rs,MIPS_BGEZAL,im)
4a71579b 492# define JALR(r0) hrrrit(MIPS_SPECIAL,r0,0,_RA_REGNO,0,MIPS_JALR)
79bfeef6
PC
493# if 1 /* This should work for mips r6 or older */
494# define JR(r0) hrrrit(MIPS_SPECIAL,r0,0,0,0,MIPS_JALR)
495# else /* This should generate an illegal instruction in mips r6 */
496# define JR(r0) hrrrit(MIPS_SPECIAL,r0,0,0,0,MIPS_JR)
4a71579b 497# endif
79bfeef6
PC
498# define CLO_R6(rd,rs) hrrrit(MIPS_SPECIAL,rs,0,rd,1,0x11)
499# define DCLO_R6(rd,rs) hrrrit(MIPS_SPECIAL,rs,0,rd,1,0x13)
500# define CLZ_R6(rd,rs) hrrrit(MIPS_SPECIAL,rs,0,rd,1,0x10)
501# define DCLZ_R6(rd,rs) hrrrit(MIPS_SPECIAL,rs,0,rd,1,0x12)
502# define BITSWAP(rd,rt) hrrrit(MIPS_SPECIAL3,0,rt,rd,0,0x20)
503# define DBITSWAP(rd,rt) hrrrit(MIPS_SPECIAL3,0,rt,rd,0,0x24)
504# define CLO(rd,rs) hrrrit(MIPS_SPECIAL2,rs,rd,rd,0,MIPS_CLO)
505# define DCLO(rd,rs) hrrrit(MIPS_SPECIAL2,rs,rd,rd,0,MIPS_DCLO)
506# define CLZ(rd,rs) hrrrit(MIPS_SPECIAL2,rs,rd,rd,0,MIPS_CLZ)
507# define DCLZ(rd,rs) hrrrit(MIPS_SPECIAL2,rs,rd,rd,0,MIPS_DCLZ)
4a71579b 508# define J(i0) hi(MIPS_J,i0)
c0c16242 509# define JAL(i0) hi(MIPS_JAL,i0)
ba86ff93
PC
510# define BC_R6(i0) hi(MIPS_BC_R6,i0)
511# define BALC(i0) hi(MIPS_BALC,i0)
1f22b268 512# define MOVN(rd,rs,rt) hrrrit(0,rs,rt,rd,0,MIPS_MOVN)
4a71579b 513# define MOVZ(rd,rs,rt) hrrrit(0,rs,rt,rd,0,MIPS_MOVZ)
79bfeef6
PC
514# define SELEQZ(rd,rs,rt) hrrrit(0,rs,rt,rd,0,53)
515# define SELNEZ(rd,rs,rt) hrrrit(0,rs,rt,rd,0,55)
4a71579b
PC
516# define comr(r0,r1) xori(r0,r1,-1)
517# define negr(r0,r1) subr(r0,_ZERO_REGNO,r1)
79bfeef6
PC
518# define clor(r0, r1) _clor(_jit, r0, r1)
519static void _clor(jit_state_t*, jit_int32_t, jit_int32_t);
520# define clzr(r0, r1) _clzr(_jit, r0, r1)
521static void _clzr(jit_state_t*, jit_int32_t, jit_int32_t);
522# define ctor(r0, r1) _ctor(_jit, r0, r1)
523static void _ctor(jit_state_t*, jit_int32_t, jit_int32_t);
524# define ctzr(r0, r1) _ctzr(_jit, r0, r1)
525static void _ctzr(jit_state_t*, jit_int32_t, jit_int32_t);
ba86ff93
PC
526# define rbitr(r0, r1) _rbitr(_jit, r0, r1)
527static void _rbitr(jit_state_t*, jit_int32_t, jit_int32_t);
4a71579b
PC
528# if __WORDSIZE == 32
529# define addr(rd,rs,rt) ADDU(rd,rs,rt)
530# define addiu(r0,r1,i0) ADDIU(r0,r1,i0)
531# define subr(rd,rs,rt) SUBU(rd,rs,rt)
532# define mult(rs,rt) MULT(rs,rt)
79bfeef6
PC
533# define mul_r6(rd,rs,rt) MUL_R6(rd,rs,rt)
534# define muh_r6(rd,rs,rt) MUH_R6(rd,rs,rt)
4a71579b 535# define multu(rs,rt) MULTU(rs,rt)
79bfeef6
PC
536# define mulu_r6(rd,rs,rt) MULU_R6(rd,rs,rt)
537# define muhu_r6(rd,rs,rt) MUHU_R6(rd,rs,rt)
4a71579b
PC
538# define div(rs,rt) DIV(rs,rt)
539# define divu(rs,rt) DIVU(rs,rt)
79bfeef6
PC
540# define div_r6(rd,rs,rt) DIV_R6(rd,rs,rt)
541# define divu_r6(rd,rs,rt) DIVU_R6(rd,rs,rt)
542# define mod_r6(rd,rs,rt) MOD_R6(rd,rs,rt)
543# define modu_r6(rd,rs,rt) MODU_R6(rd,rs,rt)
4a71579b
PC
544# else
545# define addr(rd,rs,rt) DADDU(rd,rs,rt)
546# define addiu(r0,r1,i0) DADDIU(r0,r1,i0)
547# define subr(rd,rs,rt) DSUBU(rd,rs,rt)
548# define mult(rs,rt) DMULT(rs,rt)
79bfeef6
PC
549# define mul_r6(rd,rs,rt) DMUL_R6(rd,rs,rt)
550# define muh_r6(rd,rs,rt) DMUH_R6(rd,rs,rt)
4a71579b 551# define multu(rs,rt) DMULTU(rs,rt)
79bfeef6
PC
552# define mulu_r6(rd,rs,rt) DMULU_R6(rd,rs,rt)
553# define muhu_r6(rd,rs,rt) DMUHU_R6(rd,rs,rt)
4a71579b
PC
554# define div(rs,rt) DDIV(rs,rt)
555# define divu(rs,rt) DDIVU(rs,rt)
79bfeef6
PC
556# define div_r6(rd,rs,rt) DDIV_R6(rd,rs,rt)
557# define divu_r6(rd,rs,rt) DDIVU_R6(rd,rs,rt)
558# define mod_r6(rd,rs,rt) DMOD_R6(rd,rs,rt)
559# define modu_r6(rd,rs,rt) DMODU_R6(rd,rs,rt)
4a71579b 560# endif
ba86ff93
PC
561# define mips_extr(rd,rt,lsb,nb) _mips_extr(_jit,rd,rt,lsb,nb)
562static void _mips_extr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
40a44dcb
PC
563# define insr(rd,rt,lsb,nb) _insr(_jit,rd,rt,lsb,nb)
564static void _insr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
4a71579b
PC
565# define addi(r0,r1,i0) _addi(_jit,r0,r1,i0)
566static void _addi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
567#define addcr(r0,r1,r2) _addcr(_jit,r0,r1,r2)
568static void _addcr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
569#define addci(r0,r1,i0) _addci(_jit,r0,r1,i0)
570static void _addci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
571# define addxr(r0,r1,r2) _addxr(_jit,r0,r1,r2)
572static void _addxr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
573# define addxi(r0,r1,i0) _addxi(_jit,r0,r1,i0)
574static void _addxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
575# define subi(r0,r1,i0) _subi(_jit,r0,r1,i0)
576static void _subi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
577# define subcr(r0,r1,r2) _subcr(_jit,r0,r1,r2)
578static void _subcr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
579# define subci(r0,r1,i0) _subci(_jit,r0,r1,i0)
580static void _subci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
581# define subxr(r0,r1,r2) _subxr(_jit,r0,r1,r2)
582static void _subxr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
583# define subxi(r0,r1,i0) _subxi(_jit,r0,r1,i0)
584static void _subxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
585# define rsbi(r0, r1, i0) _rsbi(_jit, r0, r1, i0)
586static void _rsbi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
587# define mulr(r0,r1,r2) _mulr(_jit,r0,r1,r2)
588static void _mulr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
589# define muli(r0,r1,i0) _muli(_jit,r0,r1,i0)
590static void _muli(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
ba86ff93
PC
591# define hmulr(r0,r1,r2) _hmulr(_jit,r0,r1,r2)
592static void _hmulr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
593# define hmuli(r0,r1,i0) _hmuli(_jit,r0,r1,i0)
594static void _hmuli(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
595# define hmulr_u(r0,r1,r2) _hmulr_u(_jit,r0,r1,r2)
596static void _hmulr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
597# define hmuli_u(r0,r1,i0) _hmuli_u(_jit,r0,r1,i0)
598static void _hmuli_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
4a71579b
PC
599# define qmulr(r0,r1,r2,r3) iqmulr(r0,r1,r2,r3,1)
600# define qmulr_u(r0,r1,r2,r3) iqmulr(r0,r1,r2,r3,0)
601# define iqmulr(r0,r1,r2,r3,cc) _iqmulr(_jit,r0,r1,r2,r3,cc)
602static void _iqmulr(jit_state_t*,jit_int32_t,jit_int32_t,
603 jit_int32_t,jit_int32_t,jit_bool_t);
604# define qmuli(r0,r1,r2,i0) iqmuli(r0,r1,r2,i0,1)
605# define qmuli_u(r0,r1,r2,i0) iqmuli(r0,r1,r2,i0,0)
606# define iqmuli(r0,r1,r2,i0,cc) _iqmuli(_jit,r0,r1,r2,i0,cc)
607static void _iqmuli(jit_state_t*,jit_int32_t,jit_int32_t,
608 jit_int32_t,jit_word_t,jit_bool_t);
609# define divr(r0,r1,r2) _divr(_jit,r0,r1,r2)
610static void _divr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
611# define divi(r0,r1,i0) _divi(_jit,r0,r1,i0)
612static void _divi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
613# define divr_u(r0,r1,r2) _divr_u(_jit,r0,r1,r2)
614static void _divr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
615# define divi_u(r0,r1,i0) _divi_u(_jit,r0,r1,i0)
616static void _divi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
617# define qdivr(r0,r1,r2,r3) iqdivr(r0,r1,r2,r3,1)
618# define qdivr_u(r0,r1,r2,r3) iqdivr(r0,r1,r2,r3,0)
619# define iqdivr(r0,r1,r2,r3,cc) _iqdivr(_jit,r0,r1,r2,r3,cc)
620static void _iqdivr(jit_state_t*,jit_int32_t,jit_int32_t,
621 jit_int32_t,jit_int32_t,jit_bool_t);
622# define qdivi(r0,r1,r2,i0) iqdivi(r0,r1,r2,i0,1)
623# define qdivi_u(r0,r1,r2,i0) iqdivi(r0,r1,r2,i0,0)
624# define iqdivi(r0,r1,r2,i0,cc) _iqdivi(_jit,r0,r1,r2,i0,cc)
625static void _iqdivi(jit_state_t*,jit_int32_t,jit_int32_t,
626 jit_int32_t,jit_word_t,jit_bool_t);
627# define remr(r0,r1,r2) _remr(_jit,r0,r1,r2)
628static void _remr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
629# define remi(r0,r1,i0) _remi(_jit,r0,r1,i0)
630static void _remi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
631# define remr_u(r0,r1,r2) _remr_u(_jit,r0,r1,r2)
632static void _remr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
633# define remi_u(r0,r1,i0) _remi_u(_jit,r0,r1,i0)
634static void _remi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
635# if __WORDSIZE == 32
636# define lshr(r0,r1,r2) SLLV(r0,r1,r2)
637# define lshi(r0,r1,i0) SLL(r0,r1,i0)
638# define rshr(r0,r1,r2) SRAV(r0,r1,r2)
639# define rshi(r0,r1,i0) SRA(r0,r1,i0)
640# define rshr_u(r0,r1,r2) SRLV(r0,r1,r2)
641# define rshi_u(r0,r1,i0) SRL(r0,r1,i0)
642# else
643# define lshr(r0,r1,r2) DSLLV(r0,r1,r2)
644# define lshi(r0,r1,i0) _lshi(_jit,r0,r1,i0)
645static void _lshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
646# define rshr(r0,r1,r2) DSRAV(r0,r1,r2)
647# define rshi(r0,r1,i0) _rshi(_jit,r0,r1,i0)
648static void _rshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
649# define rshr_u(r0,r1,r2) DSRLV(r0,r1,r2)
650# define rshi_u(r0,r1,i0) _rshi_u(_jit,r0,r1,i0)
651static void _rshi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
652# endif
ba86ff93
PC
653# define qlshr(r0,r1,r2,r3) xlshr(1,r0,r1,r2,r3)
654# define qlshr_u(r0, r1, r2, r3) xlshr(0, r0, r1, r2, r3)
655# define xlshr(s,r0,r1,r2,r3) _xlshr(_jit,s,r0,r1,r2,r3)
656static void
657_xlshr(jit_state_t*,jit_bool_t,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
658# define qlshi(r0, r1, r2, i0) xlshi(1, r0, r1, r2, i0)
659# define qlshi_u(r0, r1, r2, i0) xlshi(0, r0, r1, r2, i0)
660# define xlshi(s, r0, r1, r2, i0) _xlshi(_jit, s, r0, r1, r2, i0)
661static void
662_xlshi(jit_state_t*,jit_bool_t,jit_int32_t,jit_int32_t,jit_int32_t,jit_word_t);
663# define qrshr(r0, r1, r2, r3) xrshr(1, r0, r1, r2, r3)
664# define qrshr_u(r0, r1, r2, r3) xrshr(0, r0, r1, r2, r3)
665# define xrshr(s, r0, r1, r2, r3) _xrshr(_jit, s, r0, r1, r2, r3)
666static void
667_xrshr(jit_state_t*,jit_bool_t,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
668# define qrshi(r0, r1, r2, i0) xrshi(1, r0, r1, r2, i0)
669# define qrshi_u(r0, r1, r2, i0) xrshi(0, r0, r1, r2, i0)
670# define xrshi(s, r0, r1, r2, i0) _xrshi(_jit, s, r0, r1, r2, i0)
671static void
672_xrshi(jit_state_t*,jit_bool_t,jit_int32_t,jit_int32_t,jit_int32_t,jit_word_t);
673# define lrotr(r0,r1,r2) _lrotr(_jit,r0,r1,r2)
674static void _lrotr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
675# define lroti(r0,r1,i0) rroti(r0,r1,__WORDSIZE-i0)
676# define rrotr(r0,r1,r2) _rrotr(_jit,r0,r1,r2)
677static void _rrotr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
678# define rroti(r0,r1,i0) _rroti(_jit,r0,r1,i0)
679static void _rroti(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
4a71579b
PC
680# define andr(r0,r1,r2) AND(r0,r1,r2)
681# define andi(r0,r1,i0) _andi(_jit,r0,r1,i0)
682static void _andi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
683# define orr(r0,r1,r2) OR(r0,r1,r2)
684# define ori(r0,r1,i0) _ori(_jit,r0,r1,i0)
685static void _ori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
686# define xorr(r0,r1,r2) XOR(r0,r1,r2)
687# define xori(r0,r1,i0) _xori(_jit,r0,r1,i0)
688static void _xori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
519a9ea1
PC
689# define movr(r0,r1) _movr(_jit,r0,r1)
690static void _movr(jit_state_t*,jit_int32_t,jit_int32_t);
4a71579b
PC
691# define movi(r0,i0) _movi(_jit,r0,i0)
692static void _movi(jit_state_t*,jit_int32_t,jit_word_t);
693# define movi_p(r0,i0) _movi_p(_jit,r0,i0)
694static jit_word_t _movi_p(jit_state_t*,jit_int32_t,jit_word_t);
79bfeef6
PC
695# define movnr(r0, r1, r2) _movnr(_jit, r0, r1, r2)
696static void _movnr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
697# define movzr(r0, r1, r2) _movzr(_jit, r0, r1, r2)
698static void _movzr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
ba3814c1
PC
699# define casx(r0, r1, r2, r3, i0) _casx(_jit, r0, r1, r2, r3, i0)
700static void _casx(jit_state_t *_jit,jit_int32_t,jit_int32_t,
701 jit_int32_t,jit_int32_t,jit_word_t);
702#define casr(r0, r1, r2, r3) casx(r0, r1, r2, r3, 0)
703#define casi(r0, i0, r1, r2) casx(r0, _NOREG, r1, r2, i0)
4a71579b
PC
704# define ldr_c(r0,r1) LB(r0,0,r1)
705# define ldi_c(r0,i0) _ldi_c(_jit,r0,i0)
706static void _ldi_c(jit_state_t*,jit_int32_t,jit_word_t);
707# define ldr_uc(r0,r1) LBU(r0,0,r1)
708# define ldi_uc(r0,i0) _ldi_uc(_jit,r0,i0)
709static void _ldi_uc(jit_state_t*,jit_int32_t,jit_word_t);
710# define ldr_s(r0,r1) LH(r0,0,r1)
711# define ldi_s(r0,i0) _ldi_s(_jit,r0,i0)
712static void _ldi_s(jit_state_t*,jit_int32_t,jit_word_t);
713# define ldr_us(r0,r1) LHU(r0,0,r1)
714# define ldi_us(r0,i0) _ldi_us(_jit,r0,i0)
715static void _ldi_us(jit_state_t*,jit_int32_t,jit_word_t);
716# define ldr_i(r0,r1) LW(r0,0,r1)
717# define ldi_i(r0,i0) _ldi_i(_jit,r0,i0)
718static void _ldi_i(jit_state_t*,jit_int32_t,jit_word_t);
719# if __WORDSIZE == 64
720# define ldr_ui(r0,r1) LWU(r0,0,r1)
721# define ldi_ui(r0,i0) _ldi_ui(_jit,r0,i0)
722static void _ldi_ui(jit_state_t*,jit_int32_t,jit_word_t);
723# define ldr_l(r0,r1) LD(r0,0,r1)
724# define ldi_l(r0,i0) _ldi_l(_jit,r0,i0)
725static void _ldi_l(jit_state_t*,jit_int32_t,jit_word_t);
726# endif
727# define ldxr_c(r0,r1,r2) _ldxr_c(_jit,r0,r1,r2)
728static void _ldxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
729# define ldxi_c(r0,r1,i0) _ldxi_c(_jit,r0,r1,i0)
730static void _ldxi_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
731# define ldxr_uc(r0,r1,r2) _ldxr_uc(_jit,r0,r1,r2)
732static void _ldxr_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
733# define ldxi_uc(r0,r1,i0) _ldxi_uc(_jit,r0,r1,i0)
734static void _ldxi_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
735# define ldxr_s(r0,r1,r2) _ldxr_s(_jit,r0,r1,r2)
736static void _ldxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
737# define ldxi_s(r0,r1,i0) _ldxi_s(_jit,r0,r1,i0)
738static void _ldxi_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
739# define ldxr_us(r0,r1,r2) _ldxr_us(_jit,r0,r1,r2)
740static void _ldxr_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
741# define ldxi_us(r0,r1,i0) _ldxi_us(_jit,r0,r1,i0)
742static void _ldxi_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
743# define ldxr_i(r0,r1,r2) _ldxr_i(_jit,r0,r1,r2)
744static void _ldxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
745# define ldxi_i(r0,r1,i0) _ldxi_i(_jit,r0,r1,i0)
746static void _ldxi_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
747# if __WORDSIZE == 64
748# define ldxr_ui(r0,r1,r2) _ldxr_ui(_jit,r0,r1,r2)
749static void _ldxr_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
750# define ldxi_ui(r0,r1,i0) _ldxi_ui(_jit,r0,r1,i0)
751static void _ldxi_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
752# define ldxr_l(r0,r1,r2) _ldxr_l(_jit,r0,r1,r2)
753static void _ldxr_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
754# define ldxi_l(r0,r1,i0) _ldxi_l(_jit,r0,r1,i0)
755static void _ldxi_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
756# endif
ba86ff93
PC
757# define unldr(r0, r1, i0) _unldr(_jit, r0, r1, i0)
758static void _unldr(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
759# define unldi(r0, i0, i1) _unldi(_jit, r0, i0, i1)
760static void _unldi(jit_state_t*, jit_int32_t, jit_word_t, jit_word_t);
761# define unldr_u(r0, r1, i0) _unldr_u(_jit, r0, r1, i0)
762static void _unldr_u(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
763# define unldi_u(r0, i0, i1) _unldi_u(_jit, r0, i0, i1)
764static void _unldi_u(jit_state_t*, jit_int32_t, jit_word_t, jit_word_t);
4a71579b
PC
765# define str_c(r0,r1) SB(r1,0,r0)
766# define sti_c(i0,r0) _sti_c(_jit,i0,r0)
767static void _sti_c(jit_state_t*,jit_word_t,jit_int32_t);
768# define str_s(r0,r1) SH(r1,0,r0)
769# define sti_s(i0,r0) _sti_s(_jit,i0,r0)
770static void _sti_s(jit_state_t*,jit_word_t,jit_int32_t);
771# define str_i(r0,r1) SW(r1,0,r0)
772# define sti_i(i0,r0) _sti_i(_jit,i0,r0)
773static void _sti_i(jit_state_t*,jit_word_t,jit_int32_t);
774# if __WORDSIZE == 64
775# define str_l(r0,r1) SD(r1,0,r0)
776# define sti_l(i0,r0) _sti_l(_jit,i0,r0)
777static void _sti_l(jit_state_t*,jit_word_t,jit_int32_t);
778# endif
779# define stxr_c(r0,r1,r2) _stxr_c(_jit,r0,r1,r2)
780static void _stxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
781# define stxi_c(i0,r0,r1) _stxi_c(_jit,i0,r0,r1)
782static void _stxi_c(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
783# define stxr_s(r0,r1,r2) _stxr_s(_jit,r0,r1,r2)
784static void _stxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
785# define stxi_s(i0,r0,r1) _stxi_s(_jit,i0,r0,r1)
786static void _stxi_s(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
787# define stxr_i(r0,r1,r2) _stxr_i(_jit,r0,r1,r2)
788static void _stxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
789# define stxi_i(i0,r0,r1) _stxi_i(_jit,i0,r0,r1)
790static void _stxi_i(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
791# if __WORDSIZE == 64
792# define stxr_l(r0,r1,r2) _stxr_l(_jit,r0,r1,r2)
793static void _stxr_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
794# define stxi_l(i0,r0,r1) _stxi_l(_jit,i0,r0,r1)
795static void _stxi_l(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
796# endif
ba86ff93
PC
797# define unstr(r0, r1, i0) _unstr(_jit, r0, r1, i0)
798static void _unstr(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
799# define unsti(i0, r0, i1) _unsti(_jit, i0, r0, i1)
800static void _unsti(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t);
40a44dcb
PC
801# define bswapr_us(r0,r1) _bswapr_us(_jit,r0,r1)
802static void _bswapr_us(jit_state_t*,jit_int32_t,jit_int32_t);
803# define bswapr_ui(r0,r1) _bswapr_ui(_jit,r0,r1)
804static void _bswapr_ui(jit_state_t*,jit_int32_t,jit_int32_t);
805# if __WORDSIZE == 64
ba86ff93
PC
806# define bswapr_ul(r0,r1) _bswapr_ul(_jit,r0,r1)
807static void _bswapr_ul(jit_state_t*,jit_int32_t,jit_int32_t);
4a71579b 808# endif
d481fb64 809#define extr(r0,r1,i0,i1) fallback_ext(r0,r1,i0,i1)
ba86ff93
PC
810#define extr_u(r0,r1,i0,i1) _extr_u(_jit,r0,r1,i0,i1)
811static void _extr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t,jit_word_t);
812#define depr(r0,r1,i0,i1) _depr(_jit,r0,r1,i0,i1)
813static void _depr(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t,jit_word_t);
4a71579b
PC
814# define extr_c(r0,r1) _extr_c(_jit,r0,r1)
815static void _extr_c(jit_state_t*,jit_int32_t,jit_int32_t);
816# define extr_uc(r0,r1) ANDI(r0,r1,0xff)
817# define extr_s(r0,r1) _extr_s(_jit,r0,r1)
818static void _extr_s(jit_state_t*,jit_int32_t,jit_int32_t);
819# define extr_us(r0,r1) ANDI(r0,r1,0xffff)
820# if __WORDSIZE == 64
821# define extr_i(r0,r1) SLL(r0,r1,0)
822# define extr_ui(r0,r1) _extr_ui(_jit,r0,r1)
823static void _extr_ui(jit_state_t*,jit_int32_t,jit_int32_t);
824# endif
825# define ltr(r0,r1,r2) SLT(r0,r1,r2)
826# define lti(r0,r1,i0) _lti(_jit,r0,r1,i0)
827static void _lti(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
828# define ltr_u(r0,r1,r2) SLTU(r0,r1,r2)
829# define lti_u(r0,r1,i0) _lti_u(_jit,r0,r1,i0)
830static void _lti_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
831#define ler(r0,r1,r2) _ler(_jit,r0,r1,r2)
832static void _ler(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
833#define lei(r0,r1,i0) _lei(_jit,r0,r1,i0)
834static void _lei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
835#define ler_u(r0,r1,r2) _ler_u(_jit,r0,r1,r2)
836static void _ler_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
837#define lei_u(r0,r1,i0) _lei_u(_jit,r0,r1,i0)
838static void _lei_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
839#define eqr(r0,r1,r2) _eqr(_jit,r0,r1,r2)
840static void _eqr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
841#define eqi(r0,r1,i0) _eqi(_jit,r0,r1,i0)
842static void _eqi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
843#define ger(r0,r1,r2) _ger(_jit,r0,r1,r2)
844static void _ger(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
845#define gei(r0,r1,i0) _gei(_jit,r0,r1,i0)
846static void _gei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
847#define ger_u(r0,r1,i0) _ger_u(_jit,r0,r1,i0)
848static void _ger_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
849#define gei_u(r0,r1,i0) _gei_u(_jit,r0,r1,i0)
850static void _gei_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
851# define gtr(r0,r1,r2) SLT(r0,r2,r1)
852#define gti(r0,r1,i0) _gti(_jit,r0,r1,i0)
853static void _gti(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
854# define gtr_u(r0,r1,r2) SLTU(r0,r2,r1)
855# define gti_u(r0,r1,i0) _gti_u(_jit,r0,r1,i0)
856static void _gti_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
857#define ner(r0,r1,r2) _ner(_jit,r0,r1,r2)
858static void _ner(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
859#define nei(r0,r1,i0) _nei(_jit,r0,r1,i0)
860static void _nei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
79bfeef6
PC
861#define bltr(i0,r0,r1) bger(i0,r1,r0)
862#define bltr_u(i0,r0,r1) bger_u(i0,r1,r0)
863#define blti(i0,r0,i1) _bgei(_jit,i0,r0,i1,0,1)
864#define blti_u(i0,r0,i1) _bgei(_jit,i0,r0,i1,1,1)
865#define bler(i0,r0,r1) _bgtr(_jit,i0,r1,r0,0,1)
866#define bler_u(i0,r0,r1) _bgtr(_jit,i0,r1,r0,1,1)
867#define blei(i0,r0,i1) _bgti(_jit,i0,r0,i1,0,1)
868#define blei_u(i0,r0,i1) _bgti(_jit,i0,r0,i1,1,1)
4a71579b
PC
869#define beqr(i0,r0,r1) _beqr(_jit,i0,r0,r1)
870static jit_word_t _beqr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
871#define beqi(i0,r0,i1) _beqi(_jit,i0,r0,i1)
872static jit_word_t _beqi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
79bfeef6
PC
873#define bger(i0,r0,r1) _bger(_jit,i0,r0,r1,0)
874#define bger_u(i0,r0,r1) _bger(_jit,i0,r0,r1,1)
875static jit_word_t _bger(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t,
876 jit_bool_t);
877#define bgei(i0,r0,i1) _bgei(_jit,i0,r0,i1,0,0)
878#define bgei_u(i0,r0,i1) _bgei(_jit,i0,r0,i1,1,0)
879static jit_word_t _bgei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t,
880 jit_bool_t,jit_bool_t);
881#define bgtr(i0,r0,r1) _bgtr(_jit,i0,r0,r1,0,0)
882#define bgtr_u(i0,r0,r1) _bgtr(_jit,i0,r0,r1,1,0)
883static jit_word_t _bgtr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t,
884 jit_bool_t,jit_bool_t);
885#define bgti(i0,r0,i1) _bgti(_jit,i0,r0,i1,0,0)
886#define bgti_u(i0,r0,i1) _bgti(_jit,i0,r0,i1,1,0)
887static jit_word_t _bgti(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t,
888 jit_bool_t,jit_bool_t);
4a71579b
PC
889#define bner(i0,r0,r1) _bner(_jit,i0,r0,r1)
890static jit_word_t _bner(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
891#define bnei(i0,r0,i1) _bnei(_jit,i0,r0,i1)
892static jit_word_t _bnei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
893# define jmpr(r0) _jmpr(_jit,r0)
894static void _jmpr(jit_state_t*,jit_int32_t);
79bfeef6
PC
895# define jmpi(i0,patch) _jmpi(_jit,i0,patch)
896static jit_word_t _jmpi(jit_state_t*,jit_word_t,jit_bool_t);
897# define jmpi_p(i0) _jmpi_p(_jit,i0)
898static jit_word_t _jmpi_p(jit_state_t*,jit_word_t);
4a71579b
PC
899# define boaddr(i0,r0,r1) _boaddr(_jit,i0,r0,r1)
900static jit_word_t _boaddr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
901# define boaddi(i0,r0,i1) _boaddi(_jit,i0,r0,i1)
902static jit_word_t _boaddi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
903# define boaddr_u(i0,r0,r1) _boaddr_u(_jit,i0,r0,r1)
904static jit_word_t _boaddr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
905# define boaddi_u(i0,r0,i1) _boaddi_u(_jit,i0,r0,i1)
906static jit_word_t _boaddi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
907# define bxaddr(i0,r0,r1) _bxaddr(_jit,i0,r0,r1)
908static jit_word_t _bxaddr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
909# define bxaddi(i0,r0,i1) _bxaddi(_jit,i0,r0,i1)
910static jit_word_t _bxaddi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
911# define bxaddr_u(i0,r0,r1) _bxaddr_u(_jit,i0,r0,r1)
912static jit_word_t _bxaddr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
913# define bxaddi_u(i0,r0,i1) _bxaddi_u(_jit,i0,r0,i1)
914static jit_word_t _bxaddi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
915# define bosubr(i0,r0,r1) _bosubr(_jit,i0,r0,r1)
916static jit_word_t _bosubr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
917# define bosubi(i0,r0,i1) _bosubi(_jit,i0,r0,i1)
918static jit_word_t _bosubi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
919# define bosubr_u(i0,r0,r1) _bosubr_u(_jit,i0,r0,r1)
920static jit_word_t _bosubr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
921# define bosubi_u(i0,r0,i1) _bosubi_u(_jit,i0,r0,i1)
922static jit_word_t _bosubi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
923# define bxsubr(i0,r0,r1) _bxsubr(_jit,i0,r0,r1)
924static jit_word_t _bxsubr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
925# define bxsubi(i0,r0,i1) _bxsubi(_jit,i0,r0,i1)
926static jit_word_t _bxsubi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
927# define bxsubr_u(i0,r0,r1) _bxsubr_u(_jit,i0,r0,r1)
928static jit_word_t _bxsubr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
929# define bxsubi_u(i0,r0,i1) _bxsubi_u(_jit,i0,r0,i1)
930static jit_word_t _bxsubi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
931# define bmsr(i0,r0,r1) _bmsr(_jit,i0,r0,r1)
932static jit_word_t _bmsr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
933# define bmsi(i0,r0,i1) _bmsi(_jit,i0,r0,i1)
934static jit_word_t _bmsi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
935# define bmcr(i0,r0,r1) _bmcr(_jit,i0,r0,r1)
936static jit_word_t _bmcr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
937# define bmci(i0,r0,i1) _bmci(_jit,i0,r0,i1)
938static jit_word_t _bmci(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
939# define callr(r0) _callr(_jit,r0)
940static void _callr(jit_state_t*,jit_int32_t);
79bfeef6
PC
941# define calli(i0,i1) _calli(_jit,i0,i1)
942static jit_word_t _calli(jit_state_t*,jit_word_t,jit_bool_t);
4a71579b
PC
943# define calli_p(i0) _calli_p(_jit,i0)
944static jit_word_t _calli_p(jit_state_t*,jit_word_t);
945# define prolog(node) _prolog(_jit,node)
946static void _prolog(jit_state_t*,jit_node_t*);
947# define epilog(node) _epilog(_jit,node)
948static void _epilog(jit_state_t*,jit_node_t*);
949# define vastart(r0) _vastart(_jit, r0)
950static void _vastart(jit_state_t*, jit_int32_t);
951# define vaarg(r0, r1) _vaarg(_jit, r0, r1)
952static void _vaarg(jit_state_t*, jit_int32_t, jit_int32_t);
953#define patch_abs(instr,label) _patch_abs(_jit,instr,label)
954static void _patch_abs(jit_state_t*,jit_word_t,jit_word_t);
955#define patch_at(jump,label) _patch_at(_jit,jump,label)
956static void _patch_at(jit_state_t*,jit_word_t,jit_word_t);
79bfeef6
PC
957/* definitions used by jit_get_reg_for_delay_slot() */
958#include "jit_mips-fpu.c"
4a71579b
PC
959#endif
960
961#if CODE
79bfeef6
PC
962static void
963_instr(jit_state_t *_jit, jit_int32_t op)
964{
965 if (_jitc->inst.pend)
966 ii(_jitc->inst.op);
967 else
968 _jitc->inst.pend = 1;
969 _jitc->inst.op = op;
970}
971
972static void
973_flush(jit_state_t *_jit)
974{
975 if (_jitc->inst.pend) {
976 ii(_jitc->inst.op);
977 _jitc->inst.pend = 0;
978 }
979}
980
981static jit_int32_t
982_pending(jit_state_t *_jit)
983{
984 jit_int32_t op;
985 if (_jitc->inst.pend) {
986 op = _jitc->inst.op;
987 _jitc->inst.pend = 0;
988 }
989 else
990 op = 0;
991 return (op);
992}
993
994static void
995_delay(jit_state_t *_jit, jit_int32_t op)
996{
997 assert(_jitc->inst.pend);
998 ii(_jitc->inst.op);
999 _jitc->inst.pend = 0;
1000 ii(op);
1001}
1002
1003static jit_int32_t
1004_jit_get_reg_for_delay_slot(jit_state_t *_jit, jit_int32_t mask,
1005 jit_int32_t reg0, jit_int32_t reg1)
1006{
1007 jit_instr_t i;
ba86ff93 1008 jit_int32_t reg, r0, r1, r2/*, xreg*/, regs[3];
79bfeef6
PC
1009 /* If will emit a pending instruction */
1010 if (_jitc->inst.pend)
1011 i.op = _jitc->inst.op;
1012 /* Else if at least one instruction emited, check it */
1013 else if (_jit->pc.uc > _jit->code.ptr)
1014 i.op = _jit->pc.ui[-1];
1015 /* Else, a nop */
1016 else
1017 i.op = 0;
ba86ff93 1018 regs[0] = regs[1] = regs[2]/* = xreg*/ = -1;
79bfeef6
PC
1019 switch (i.hc.b) {
1020 case MIPS_SPECIAL: /* 00 */
1021 switch (i.tc.b) {
1022 case MIPS_SLLV: /* 04 */
1023 case MIPS_SRLV: /* 06 */
1024 case MIPS_SRAV: /* 07 */
1025 case MIPS_DSLLV: /* 14 */
1026 case MIPS_DSRLV: /* 16 */
1027 case MIPS_DSRAV: /* 17 */
1028 case MIPS_ADDU: /* 21 */
1029 case MIPS_SUBU: /* 23 */
1030 case MIPS_AND: /* 24 */
1031 case MIPS_OR: /* 25 */
1032 case MIPS_XOR: /* 26 */
1033 case MIPS_NOR: /* 27 */
1034 case MIPS_SLT: /* 2a */
1035 case MIPS_SLTU: /* 2b */
1036 case MIPS_DADDU: /* 2d */
1037 case MIPS_DSUBU: /* 2f */
1038 if (mask & jit_class_gpr) {
1039 regs[0] = i.rs.b;
1040 regs[1] = i.rt.b;
1041 regs[2] = i.rd.b;
1042 }
1043 break;
1044 /* MUL MUH */
1045 case MIPS_MULT: /* 18 */
1046 /* MULU MUHU */
1047 case MIPS_MULTU: /* 19 */
1048 /* DIV MOD */
1049 case MIPS_DIV: /* 1a */
1050 /* DIVU MODU */
1051 case MIPS_DIVU: /* 1b */
1052 /* DMUL DMUH */
1053 case MIPS_DMULT: /* 1c */
1054 /* DMULU DMUHU */
1055 case MIPS_DMULTU: /* 1d */
1056 /* DDIV DMOD */
1057 case MIPS_DDIV: /* 1e */
1058 /* DDIVU DMODU */
1059 case MIPS_DDIVU: /* 1f */
1060 if (jit_mips6_p()) {
1061 assert(i.ic.b == 2 || i.ic.b == 3);
1062 if (mask & jit_class_gpr) {
1063 regs[0] = i.rs.b;
1064 regs[1] = i.rt.b;
1065 regs[2] = i.rd.b;
1066 }
1067 }
1068 else {
1069 assert(i.rd.b == 0);
1070 if (mask & jit_class_gpr) {
1071 regs[0] = i.rs.b;
1072 regs[1] = i.rt.b;
1073 regs[2] = 0;
1074 }
1075 }
1076 break;
1077 /* CLZ */
1078 case MIPS_MFHI: /* 10 */
1079 /* CLO */
1080 case MIPS_MTHI: /* 11 */
1081 /* DCLZ */
1082 case MIPS_MFLO: /* 12 */
1083 /* DCLO */
1084 case MIPS_MTLO: /* 13 */
1085 if (mask & jit_class_gpr) {
1086 if (jit_mips6_p()) {
1087 assert(i.ic.b == 1);
1088 regs[1] = i.rd.b;
1089 }
1090 else {
1091 assert(!i.rs.b && !i.rt.b);
1092 regs[1] = 0;
1093 }
1094 regs[0] = i.rd.b;
1095 regs[1] = 0;
1096 }
1097 break;
1098 case MIPS_JR: /* 08 */
1099 assert(!jit_mips6_p());
1100 case MIPS_JALR: /* 09 */
1101 /* check for proper/known encondig */
1102 assert(!i.ic.b);
1103 if (mask & jit_class_gpr) {
1104 regs[0] = i.rs.b;
1105 regs[1] = i.rt.b;
1106 regs[2] = i.rd.b;
1107 }
1108 break;
1109 case MIPS_SLL: /* 00 */
ba86ff93
PC
1110 /* If cannot have a shift in delay slot */
1111 if (!jit_cpu.sll_delay)
1112 flush();
79bfeef6
PC
1113 case MIPS_SRL: /* 02 */
1114 case MIPS_SRA: /* 03 */
1115 case MIPS_DSLL: /* 38 */
1116 case MIPS_DSRL: /* 3a */
1117 case MIPS_DSRA: /* 3b */
1118 case MIPS_DSLL32: /* 3c */
1119 case MIPS_DSRA32: /* 3f */
1120 case MIPS_DSRL32: /* 3e */
1121 /* shift (or rotate if i.rs.b == 1) */
1122 assert(i.rs.b == 0 || i.rs.b == 1);
1123 if (mask & jit_class_gpr) {
1124 regs[0] = i.rt.b;
1125 regs[1] = i.rd.b;
1126 regs[2] = 0;
1127 }
1128 break;
1129 case MIPS_SYNC: /* 0f */
1130 assert(i.rs.b == 0 && i.rt.b == 0 && i.rd.b == 0);
1131 if (mask & jit_class_gpr)
ba86ff93 1132 regs[0] = regs[1] = regs[2] = 0;
79bfeef6
PC
1133 break;
1134 case MIPS_MOVZ: /* 0a */
1135 case MIPS_MOVN: /* 0b */
1136 assert(!jit_mips6_p() && i.ic.b == 0);
1137 if (mask & jit_class_gpr) {
1138 regs[0] = i.rs.b;
1139 regs[1] = i.rt.b;
1140 regs[2] = i.rd.b;
1141 }
1142 break;
1143 /* SELEQZ */
1144 case 53: /* 35 */
1145 /* SELNEZ */
1146 case 55: /* 37 */
1147 assert(jit_mips6_p() && i.ic.b == 0);
1148 if (mask & jit_class_gpr) {
1149 regs[0] = i.rs.b;
1150 regs[1] = i.rt.b;
1151 regs[2] = i.rd.b;
1152 }
1153 break;
1154 default:
1155 abort();
1156 }
1157 break;
1158 case MIPS_REGIMM: /* 01 */
1159 switch (i.rt.b) {
ba86ff93
PC
1160 /* DAHI */
1161 case 6: /* 06 */
1162 /* DATI */
1163 case 15: /* 1e */
1164 assert(jit_mips6_p());
79bfeef6
PC
1165 case MIPS_BLTZ: /* 00 */
1166 case MIPS_BGEZ: /* 01 */
1167 case MIPS_BGEZAL: /* 11 */
1168 break;
1169 default:
1170 abort();
1171 }
1172 if (mask & jit_class_gpr) {
1173 regs[0] = i.rs.b;
1174 regs[1] = regs[2] = 0;
1175 }
1176 break;
ba86ff93
PC
1177 case MIPS_BC_R6: /* 32 */
1178 case MIPS_BALC: /* 3a */
1179 assert(jit_mips6_p());
79bfeef6
PC
1180 case MIPS_J: /* 02 */
1181 case MIPS_JAL: /* 03 */
1182 if (mask & jit_class_gpr)
1183 regs[0] = regs[1] = regs[2] = 0;
1184 break;
1185 case MIPS_LUI: /* 0f */
ba86ff93 1186 assert(jit_mips6_p() || i.rs.b == 0);
79bfeef6
PC
1187 if (mask & jit_class_gpr) {
1188 regs[0] = i.rt.b;
ba86ff93
PC
1189 regs[1] = i.rs.b; /* AUI if non zero */
1190 regs[1] = 0;
79bfeef6
PC
1191 }
1192 break;
1193 case MIPS_SPECIAL2: /* 1c */
1194 switch (i.tc.b) {
1195 case MIPS_CLZ: /* 20 */
1196 case MIPS_CLO: /* 21 */
1197 case MIPS_DCLZ: /* 24 */
1198 case MIPS_DCLO: /* 25 */
1199 assert(!jit_mips6_p() && i.rt.b == i.rd.b && i.ic.b == 0);
1200 if (mask & jit_class_gpr) {
1201 regs[0] = i.rs.b;
1202 regs[1] = i.rd.b;
1203 regs[2] = 0;
1204 }
1205 break;
1206 case MIPS_MUL: /* 02 */
1207 assert(jit_mips2_p() && i.ic.b == 0);
1208 if (mask & jit_class_gpr) {
1209 regs[0] = i.rs.b;
1210 regs[1] = i.rt.b;
1211 regs[2] = i.rd.b;
1212 }
1213 break;
1214 default:
1215 abort();
1216 }
1217 break;
1218 case MIPS_SPECIAL3: /* 1f */
1219 switch (i.tc.b) {
1220 case MIPS_EXT: /* 00 */
1221 case MIPS_DEXTM: /* 01 */
1222 case MIPS_DEXTU: /* 02 */
1223 case MIPS_DEXT: /* 03 */
1224 case MIPS_INS: /* 04 */
1225 case MIPS_DINSM: /* 05 */
1226 case MIPS_DINSU: /* 06 */
1227 case MIPS_DINS: /* 07 */
1228 if (mask & jit_class_gpr) {
1229 regs[0] = i.rs.b;
1230 regs[1] = i.rt.b;
1231 regs[2] = 0;
1232 }
1233 break;
1234 /* BITSWAP */
1235 case MIPS_BSHFL: /* 20 */
1236 /* DBITSWAP */
1237 case MIPS_DBSHFL: /* 24 */
1238 switch (i.ic.b) {
ba86ff93 1239 /* DSBH */
79bfeef6 1240 case MIPS_WSBH: /* 02 */
ba86ff93 1241 case MIPS_DSHD: /* 05 */
79bfeef6
PC
1242 case MIPS_SEB: /* 10 */
1243 case MIPS_SEH: /* 18 */
1244 if (mask & jit_class_gpr) {
1245 regs[0] = i.rt.b;
1246 regs[1] = i.rd.b;
1247 regs[2] = 0;
1248 }
1249 break;
1250 /* BITSWAP DBITSWAP */
1251 case 0:
1252 assert(jit_mips6_p() && i.rt.b == 0);
1253 if (mask & jit_class_gpr) {
1254 regs[0] = i.rs.b;
1255 regs[1] = i.rd.b;
1256 regs[2] = 0;
1257 }
1258 break;
1259 default:
1260 abort();
1261 }
1262 break;
1263 /* SC */
1264 case 38: /* 26 */
1265 /* SCD */
1266 case 39: /* 27 */
1267 /* LD */
1268 case 54: /* 36 */
1269 /* LLD */
1270 case 55: /* 37 */
1271 assert(jit_mips6_p());
1272 if (mask & jit_class_gpr) {
1273 regs[0] = i.rs.b;
1274 regs[1] = i.rt.b;
1275 regs[2] = 0;
1276 }
1277 break;
1278 default:
1279 abort();
1280 }
1281 break;
1282 case MIPS_COP1: /* 11 */
1283 switch (i.tc.b) {
1284 case MIPS_ADD_fmt: /* 00 */
1285 switch (i.rs.b) {
1286 case MIPS_MF: /* 00 */
1287 case MIPS_DMF: /* 01 */
1288 case MIPS_MFH: /* 03 */
1289 case MIPS_MT: /* 04 */
1290 case MIPS_DMT: /* 05 */
1291 case MIPS_MTH: /* 07 */
1292 assert(i.ic.b == 0);
ba86ff93
PC
1293 /* If these cop1 instructions in delay slot
1294 * wont work */
1295 if (!jit_cpu.cop1_delay)
1296 flush();
79bfeef6
PC
1297 if (mask & jit_class_gpr) {
1298 regs[0] = i.rt.b;
1299 regs[1] = regs[2] = 0;
1300 }
1301 else
1302 regs[0] = i.rd.b;
1303 break;
1304 default:
1305 goto three_fprs;
1306 }
1307 break;
ba86ff93
PC
1308 case MIPS_MADDF: /* 18 */
1309 case MIPS_MSUBF: /* 19 */
1310 assert(jit_mips6_p());
79bfeef6
PC
1311 case MIPS_SUB_fmt: /* 01 */
1312 case MIPS_MUL_fmt: /* 02 */
1313 case MIPS_DIV_fmt: /* 03 */
1314 three_fprs:
1315 /* 10 */
1316 assert(i.rs.b == MIPS_fmt_S ||
1317 /* 11 */
1318 i.rs.b == MIPS_fmt_D);
1319 if (mask & jit_class_gpr)
1320 regs[0] = regs[1] = regs[2] = 0;
1321 else {
1322 regs[0] = i.rt.b;
1323 regs[1] = i.rd.b;
1324 regs[2] = i.ic.b;
1325 }
1326 break;
1327 case MIPS_SQRT_fmt: /* 04 */
1328 case MIPS_ABS_fmt: /* 05 */
1329 case MIPS_MOV_fmt: /* 06 */
1330 case MIPS_NEG_fmt: /* 07 */
1331 assert((i.rs.b == MIPS_fmt_S || i.rs.b == MIPS_fmt_D) &&
1332 i.rt.b == 0);
1333 if (mask & jit_class_gpr)
1334 regs[0] = regs[1] = regs[2] = 0;
1335 else {
1336 regs[0] = i.rd.b;
1337 regs[1] = i.ic.b;
1338 }
1339 break;
1340 case MIPS_CVT_fmt_S: /* 20 */
1341 case MIPS_CVT_fmt_D: /* 21 */
1342 case MIPS_CVT_fmt_W: /* 24 */
1343 case MIPS_CVT_fmt_L: /* 25 */
1344 switch (i.rs.b) {
1345 case MIPS_fmt_S:/* 10 */
1346 case MIPS_fmt_D:/* 11 */
1347 case MIPS_fmt_W:/* 14 */
1348 case MIPS_fmt_L:/* 15 */
1349 break;
1350 default:
1351 abort();
1352 }
1353 assert(i.rt.b == 0);
1354 if (mask & jit_class_gpr)
1355 regs[0] = regs[1] = regs[2] = 0;
1356 else {
1357 regs[0] = i.rd.b;
1358 regs[1] = i.ic.b;
1359 }
1360 break;
1361 case MIPS_cond_F: /* 30 */
1362 case MIPS_cond_UN: /* 31 */
1363 case MIPS_cond_EQ: /* 32 */
1364 case MIPS_cond_UEQ: /* 33 */
1365 case MIPS_cond_OLT: /* 34 */
1366 case MIPS_cond_ULT: /* 35 */
1367 case MIPS_cond_OLE: /* 36 */
1368 case MIPS_cond_ULE: /* 37 */
1369 case MIPS_cond_SF: /* 38 */
1370 case MIPS_cond_NGLE: /* 39 */
1371 case MIPS_cond_SEQ: /* 3a */
1372 case MIPS_cond_NGL: /* 3b */
1373 case MIPS_cond_LT: /* 3c */
1374 case MIPS_cond_NGE: /* 3d */
1375 case MIPS_cond_LE: /* 3e */
1376 case MIPS_cond_UGT: /* 3f */
1377 assert(!jit_mips6_p() &&
1378 /* 10 */
1379 (i.fm.b == MIPS_fmt_S ||
1380 /* 11 */
1381 i.fm.b == MIPS_fmt_D));
1382 if (mask & jit_class_gpr)
1383 regs[0] = regs[1] = regs[2] = 0;
1384 else {
1385 regs[0] = i.ft.b;
1386 regs[1] = i.fs.b;
1387 }
1388 break;
1389 default:
1390 switch (i.ic.b) {
1391 case MIPS_cmp_AF: /* 00 */
1392 case MIPS_cmp_UN: /* 01 */
1393 case MIPS_cmp_EQ: /* 02 */
1394 case MIPS_cmp_UEQ: /* 03 */
1395 case MIPS_cmp_LT: /* 04 */
1396 case MIPS_cmp_ULT: /* 05 */
1397 case MIPS_cmp_LE: /* 06 */
1398 case MIPS_cmp_ULE: /* 07 */
1399 case MIPS_cmp_SAF: /* 08 */
1400 case MIPS_cmp_SUN: /* 09 */
1401 case MIPS_cmp_SEQ: /* 0a */
1402 case MIPS_cmp_SUEQ:/* 0b */
1403 case MIPS_cmp_SLT: /* 0c */
1404 case MIPS_cmp_SULT:/* 0d */
1405 case MIPS_cmp_SLE: /* 0e */
1406 case MIPS_cmp_SULE:/* 0f */
1407 assert(jit_mips6_p() &&
1408 /* 14 */
1409 (i.rs.b == MIPS_condn_S ||
1410 /* 15 */
1411 i.rs.b == MIPS_condn_D));
1412 if (mask & jit_class_gpr)
1413 regs[0] = regs[1] = regs[2] = 0;
1414 else {
1415 regs[0] = i.ft.b;
1416 regs[1] = i.fs.b;
1417 regs[2] = i.fd.b;
1418 }
1419 goto done;
1420 default:
1421 break;
1422 }
1423 switch (i.rt.b) {
1424 case MIPS_BC: /* 08 */
1425 assert(!jit_mips6_p() &&
1426 /* 00 */
1427 (i.rs.b == MIPS_BCF ||
1428 /* 01 */
1429 i.rs.b == MIPS_BCT));
1430 if (mask & jit_class_gpr)
1431 regs[0] = regs[1] = regs[2] = 0;
1432 else {
1433 regs[0] = i.rt.b;
1434 regs[1] = i.rd.b;
1435 }
1436 break;
1437 case MIPS_BC1EQZ:/* 09 */
1438 case MIPS_BC1NEZ:/* 0a */
1439 assert(jit_mips6_p());
1440 if (mask & jit_class_gpr)
1441 regs[0] = regs[1] = regs[2] = 0;
1442 else
1443 regs[0] = i.rt.b;
1444 break;
1445 default:
1446 abort();
1447 }
1448 break;
1449 }
1450 break;
ba86ff93
PC
1451 case MIPS_COP1X: /* 13 */
1452 switch (i.tc.b) {
1453 case MIPS_MADD_fmt_S:
1454 case MIPS_MADD_fmt_D:
1455 case MIPS_MSUB_fmt_S:
1456 case MIPS_MSUB_fmt_D:
1457 case MIPS_NMADD_fmt_S:
1458 case MIPS_NMADD_fmt_D:
1459 case MIPS_NMSUB_fmt_S:
1460 case MIPS_NMSUB_fmt_D:
1461 assert(!jit_mips6_p());
1462 if (mask & jit_class_gpr)
1463 regs[0] = regs[1] = regs[2] = 0;
1464 else {
1465 regs[0] = i.ft.b;
1466 regs[1] = i.fs.b;
1467 regs[2] = i.fd.b;
1468 /* FIXME No need to compute and check it.
1469 * If asking for a tmeporary fpr, code will
1470 * be flushed. */
1471 /* xreg = i.fr.b; */
1472 }
1473 break;
1474 default:
1475 abort();
1476 }
1477 break;
1478 case MIPS_DAUI: /* JALX */ /* 1d */
1479 /* Do not generate JALX. No microMIPS64 or MIPS16e support */
1480 assert(jit_mips6_p() && i.rs.b != 0);
79bfeef6
PC
1481 case MIPS_ADDIU: /* 09 */
1482 case MIPS_SLTI: /* 0a */
1483 case MIPS_SLTIU: /* 0b */
1484 case MIPS_ANDI: /* 0c */
1485 case MIPS_ORI: /* 0d */
1486 case MIPS_XORI: /* 0e */
1487 case MIPS_DADDIU: /* 18 */
ba86ff93
PC
1488 case MIPS_LDL: /* 1a */
1489 case MIPS_LDR: /* 1b */
79bfeef6
PC
1490 case MIPS_LB: /* 20 */
1491 case MIPS_LH: /* 21 */
1492 case MIPS_LW: /* 23 */
1493 case MIPS_LBU: /* 24 */
1494 case MIPS_LHU: /* 25 */
1495 case MIPS_LWU: /* 27 */
1496 case MIPS_SB: /* 28 */
1497 case MIPS_SH: // 29 */
1498 case MIPS_SW: /* 2b */
1499 case MIPS_LD: /* 37 */
1500 case MIPS_SD: /* 3f */
1501 if (mask & jit_class_gpr) {
1502 regs[0] = i.rs.b;
1503 regs[1] = i.rt.b;
1504 regs[2] = 0;
1505 }
1506 break;
ba86ff93
PC
1507 case MIPS_LWL: /* 22 */
1508 case MIPS_LWR: /* 26 */
1509 if (!jit_cpu.lwl_lwr_delay)
1510 flush();
1511 case MIPS_SWL: /* 2a */
1512 case MIPS_SWR: /* 2e */
1513 case MIPS_SDL: /* 2c */
1514 case MIPS_SDR: /* 2d */
1515 assert(!(jit_mips6_p()));
1516 if (mask & jit_class_gpr) {
1517 regs[0] = i.rs.b;
1518 regs[1] = i.rt.b;
1519 regs[2] = 0;
1520 }
1521 break;
79bfeef6
PC
1522 case MIPS_LL: /* 30 */
1523 case MIPS_LLD: /* 34 */
1524 case MIPS_SC: /* 38 */
1525 case MIPS_SCD: /* 3c */
1526 assert(!jit_mips6_p() && i.ic.b == 0);
1527 if (mask & jit_class_gpr) {
1528 regs[0] = i.rs.b;
1529 regs[1] = i.rt.b;
1530 regs[2] = 0;
1531 }
1532 break;
1533 case MIPS_BLEZ: /* 06 */
1534 case MIPS_BGTZ: /* 07 */
1535 assert(i.rt.b == 0);
1536 if (mask & jit_class_gpr) {
1537 regs[0] = i.rs.b;
1538 regs[1] = regs[2] = 0;
1539 }
1540 break;
79bfeef6
PC
1541 case MIPS_LWC1: /* 31 */
1542 case MIPS_LDC1: /* 35 */
1543 case MIPS_SWC1: /* 39 */
1544 case MIPS_SDC1: /* 3d */
ba86ff93
PC
1545 /* If these cop1 instructions in delay wont not work */
1546 if (!jit_cpu.cop1_delay)
1547 flush();
79bfeef6
PC
1548 if (mask & jit_class_gpr) {
1549 regs[0] = i.rs.b;
1550 regs[1] = i.rt.b;
1551 regs[2] = 0;
1552 }
1553 else
1554 regs[0] = i.rt.b;
1555 break;
ba86ff93
PC
1556 case MIPS_BEQ: /* 04 */
1557 case MIPS_BNE: /* 05 */
1558 assert(i.rt.b == 0);
1559 if (mask & jit_class_gpr) {
1560 regs[0] = i.rs.b;
1561 regs[1] = i.rt.b;
1562 regs[2] = 0;
1563 }
1564 else
1565 regs[0] = i.rt.b;
1566 break;
1567 case MIPS_PCREL: /* 0x3b */
1568 assert(jit_mips6_p());
1569 switch (i.rt.b) {
1570 case 0x1e: /* AUIPC */
1571 case 0x1f: /* ALUIPC */
1572 break;
1573 default:
1574 assert(i.pD.b == 1 ||/* LDPC */
1575 i.pW.b == 0 ||/* ADDIUPC */
1576 i.pW.b == 1 ||/* LWPC */
1577 i.pW.b == 2); /* LWUPC */
1578 break;
1579 }
1580 if (mask & jit_class_gpr) {
1581 regs[0] = i.rs.b;
1582 regs[1] = regs[2] = 0;
1583 }
1584 break;
79bfeef6
PC
1585 default:
1586 abort();
1587 }
1588done:
1589 /* If cannot move instruction do delay slot */
1590 if (_jitc->inst.pend &&
1591 (((mask & jit_class_fpr) || reg0) &&
1592 (reg0 == regs[0] || reg0 == regs[1] || reg0 == regs[2])) ||
1593 (((mask & jit_class_fpr) || reg1) &&
1594 (reg1 == regs[0] || reg1 == regs[1] || reg1 == regs[2]))) {
1595 flush();
1596 }
1597 /* Get a temporary register */
1598retry:
1599 reg = jit_get_reg(mask|jit_class_nospill);
1600 /* Make sure will not use a register in use by delay slot */
1601 if (_jitc->inst.pend) {
1602 if (rn(reg) == regs[0] ||
1603 rn(reg) == regs[1] || rn(reg) == regs[2]) {
1604 r0 = reg;
1605 reg = jit_get_reg(mask|jit_class_nospill);
1606 if (rn(reg) == regs[0] ||
1607 rn(reg) == regs[1] || rn(reg) == regs[2]) {
1608 r1 = reg;
1609 reg = jit_get_reg(mask|jit_class_nospill);
1610 if (rn(reg) == regs[0] ||
1611 rn(reg) == regs[1] || rn(reg) == regs[2]) {
1612 r2 = reg;
1613 reg = jit_get_reg(mask|jit_class_nospill);
1614 jit_unget_reg(r2);
1615 }
1616 jit_unget_reg(r1);
1617 }
1618 jit_unget_reg(r0);
1619 }
1620 }
1621 if (reg == JIT_NOREG) {
1622 /* Cannot get a register to optimize delay slot */
1623 flush();
1624 /* Must find a free register */
1625 if (!(mask & jit_class_chk))
1626 goto retry;
1627 }
1628 assert(reg != JIT_NOREG || (mask & jit_class_chk));
1629 return (reg);
1630}
1631
4a71579b
PC
1632static void
1633_hrrrit(jit_state_t *_jit,jit_int32_t hc,
1634 jit_int32_t rs, jit_int32_t rt, jit_int32_t rd,
1635 jit_int32_t ic, jit_int32_t tc)
1636{
1637 jit_instr_t i;
1638 i.tc.b = tc;
1639 i.ic.b = ic;
1640 i.rd.b = rd;
1641 i.rt.b = rt;
1642 i.rs.b = rs;
1643 i.hc.b = hc;
79bfeef6 1644 instr(i.op);
4a71579b
PC
1645}
1646
1647static void
1648_hrri(jit_state_t *_jit, jit_int32_t hc,
1649 jit_int32_t rs, jit_int32_t rt, jit_int32_t im)
1650{
1651 jit_instr_t i;
1652 i.op = 0;
1653 i.is.b = im;
1654 i.rt.b = rt;
1655 i.rs.b = rs;
1656 i.hc.b = hc;
79bfeef6
PC
1657 instr(i.op);
1658}
1659
1660static void
1661_hrri9(jit_state_t *_jit, jit_int32_t hc,
1662 jit_int32_t rs, jit_int32_t rt, jit_int32_t i9, jit_int32_t tc)
1663{
1664 jit_instr_t i;
1665 i.op = 0;
1666 i.tc.b = tc;
1667 i.i9.b = i9;
1668 i.rt.b = rt;
1669 i.rs.b = rs;
1670 i.hc.b = hc;
1671 instr(i.op);
4a71579b
PC
1672}
1673
ba86ff93
PC
1674static void
1675_hriD(jit_state_t *_jit, jit_int32_t hc,
1676 jit_int32_t rs, jit_int32_t pD, jit_int32_t iD)
1677{
1678 jit_instr_t i;
1679 i.iD.b = iD;
1680 i.pD.b = pD;
1681 i.rs.b = rs;
1682 i.hc.b = hc;
1683 instr(i.op);
1684}
1685
1686static void
1687_hriW(jit_state_t *_jit, jit_int32_t hc,
1688 jit_int32_t rs, jit_int32_t pW, jit_int32_t iW)
1689{
1690 jit_instr_t i;
1691 i.iW.b = iW;
1692 i.pD.b = pW;
1693 i.rs.b = rs;
1694 i.hc.b = hc;
1695 instr(i.op);
1696}
1697
4a71579b
PC
1698static void
1699_hi(jit_state_t *_jit, jit_int32_t hc, jit_int32_t im)
1700{
1701 jit_instr_t i;
1702 i.ii.b = im;
1703 i.hc.b = hc;
79bfeef6 1704 instr(i.op);
4a71579b
PC
1705}
1706
1707static void
1708_nop(jit_state_t *_jit, jit_int32_t i0)
1709{
1710 for (; i0 > 0; i0 -= 4)
1711 NOP();
1712 assert(i0 == 0);
1713}
1714
40a44dcb 1715static void
ba86ff93 1716_mips_extr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
40a44dcb
PC
1717 jit_int32_t pos, jit_int32_t size)
1718{
1719 assert(size > 0);
1720
1721 if (__WORDSIZE == 32)
1722 EXT(r0, r1, pos, size);
1723 else if (pos >= 32)
1724 DEXTU(r0, r1, pos, size);
1725 else if (size > 32)
1726 DEXTM(r0, r1, pos, size);
1727 else
1728 DEXT(r0, r1, pos, size);
1729}
1730
1731static void
1732_insr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
1733 jit_int32_t pos, jit_int32_t size)
1734{
1735 assert(size > 0);
1736
1737 if (__WORDSIZE == 32)
1738 INS(r0, r1, pos, size);
1739 else if (pos >= 32)
1740 DINSU(r0, r1, pos, size);
1741 else if (size > 32)
1742 DINSM(r0, r1, pos, size);
1743 else
1744 DINS(r0, r1, pos, size);
1745}
1746
79bfeef6
PC
1747static void
1748_clor(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1749{
1750#if __WORDSIZE == 32
1751 if (jit_mips6_p())
1752 CLO_R6(r0, r1);
ba86ff93 1753 else if (jit_mips2_p())
79bfeef6 1754 CLO(r0, r1);
ba86ff93
PC
1755 else
1756 fallback_clo(r0, r1);
79bfeef6 1757#else
ba86ff93 1758 assert(jit_mips2_p());
79bfeef6
PC
1759 if (jit_mips6_p())
1760 DCLO_R6(r0, r1);
1761 else
1762 DCLO(r0, r1);
1763#endif
1764}
1765
1766static void
1767_clzr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1768{
1769#if __WORDSIZE == 32
1770 if (jit_mips6_p())
1771 CLZ_R6(r0, r1);
ba86ff93 1772 else if (jit_mips2_p())
79bfeef6 1773 CLZ(r0, r1);
ba86ff93
PC
1774 else
1775 fallback_clz(r0, r1);
79bfeef6 1776#else
ba86ff93 1777 assert(jit_mips2_p());
79bfeef6
PC
1778 if (jit_mips6_p())
1779 DCLZ_R6(r0, r1);
1780 else
1781 DCLZ(r0, r1);
1782#endif
1783}
1784
1785static void
1786_ctor(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1787{
1788 if (jit_mips6_p()) {
ba86ff93
PC
1789 rbitr(r0, r1);
1790 clor(r0, r0);
79bfeef6
PC
1791 }
1792 else {
ba86ff93
PC
1793 comr(r0, r1);
1794 ctzr(r0, r0);
79bfeef6
PC
1795 }
1796}
1797
1798static void
1799_ctzr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
ba86ff93
PC
1800{
1801 if (jit_mips6_p()) {
1802 rbitr(r0, r1);
1803 clzr(r0, r0);
1804 }
1805 else {
1806 jit_int32_t t0, t1;
1807
1808 t0 = jit_get_reg(jit_class_gpr);
1809 t1 = jit_get_reg(jit_class_gpr);
1810
1811 negr(rn(t0), r1);
1812 andr(rn(t0), rn(t0), r1);
1813 clzr(r0, rn(t0));
1814 xori(rn(t1), r0, __WORDSIZE - 1);
1815 movnr(r0, rn(t1), rn(t0));
1816
1817 jit_unget_reg(t0);
1818 jit_unget_reg(t1);
1819 }
1820}
1821
1822static void
1823_rbitr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
79bfeef6
PC
1824{
1825 if (jit_mips6_p()) {
1826#if __WORDSIZE == 32
1827 BITSWAP(r0, r1);
1828 bswapr_ui(r0, r0);
79bfeef6
PC
1829#else
1830 DBITSWAP(r0, r1);
1831 bswapr_ul(r0, r0);
79bfeef6
PC
1832#endif
1833 }
ba86ff93
PC
1834 else
1835 fallback_rbit(r0, r1);
79bfeef6
PC
1836}
1837
4a71579b
PC
1838static void
1839_addi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1840{
1841 jit_int32_t reg;
1842 if (i0 == 0)
1843 movr(r0, r1);
1844 else if (can_sign_extend_short_p(i0))
1845 addiu(r0, r1, i0);
1846 else {
ba86ff93
PC
1847 if (jit_mips6_p()) {
1848 union {
1849 struct {
1850# if __BYTE_ORDER == __LITTLE_ENDIAN
1851 jit_word_t _ : 16;
1852 jit_word_t aui : 16;
1853# if __WORDSIZE == 64
1854 jit_word_t ahi : 16;
1855 jit_word_t ati : 16;
1856# endif
1857# else
1858# if __WORDSIZE == 64
1859 jit_word_t ati : 16;
1860 jit_word_t ahi : 16;
1861# endif
1862 jit_word_t aui : 16;
1863 jit_word_t _ : 16;
1864# endif
1865 } b;
1866 jit_word_t w;
1867 } bits;
1868 bits.w = i0;
1869 if (r0 == r1 && ((jit_word_t)bits.b.aui << 16) == i0)
1870 /* FIXME It should not be required r0 == r1 per
1871 * documentation, but this is now it works in qemu
1872 * for DAUI. Assume AUI has the same restriction. */
1873 DAUI(r1, r0, bits.b.aui & 0xffff);
1874#if __WORDSIZE == 64
1875 else if (r0 == r1 && ((jit_word_t)bits.b.ahi << 32) == i0)
1876 DAHI(r0, bits.b.ahi & 0xffff);
1877 else if (r0 == r1 && ((jit_word_t)bits.b.ati << 48) == i0)
1878 DATI(r0, bits.b.ati & 0xffff);
1879#endif
1880 else
1881 goto fallback;
1882 goto done;
1883 }
1884 fallback:
4a71579b
PC
1885 reg = jit_get_reg(jit_class_gpr);
1886 movi(rn(reg), i0);
1887 addr(r0, r1, rn(reg));
1888 jit_unget_reg(reg);
1889 }
ba86ff93 1890done:;
4a71579b
PC
1891}
1892
1893static void
1894_addcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1895{
1896 jit_int32_t t0;
1897
1898 if (jit_carry == _NOREG)
1899 jit_carry = jit_get_reg(jit_class_gpr);
1900 if (r0 == r1) {
1901 t0 = jit_get_reg(jit_class_gpr);
1902 addr(rn(t0), r1, r2);
1903 SLTU(rn(jit_carry), rn(t0), r1);
1904 movr(r0, rn(t0));
1905 jit_unget_reg(t0);
1906 }
1907 else {
1908 addr(r0, r1, r2);
1909 SLTU(rn(jit_carry), r0, r1);
1910 }
1911}
1912
1913static void
1914_addci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1915{
1916 jit_int32_t t0;
1917
1918 if (jit_carry == _NOREG)
1919 jit_carry = jit_get_reg(jit_class_gpr);
1920 t0 = jit_get_reg(jit_class_gpr);
1921 if (r0 == r1) {
1922 if (can_sign_extend_short_p(i0))
1923 addiu(rn(t0), r1, i0);
1924 else {
1925 movi(rn(t0), i0);
1926 addr(rn(t0), r1, rn(t0));
1927 }
1928 SLTU(rn(jit_carry), rn(t0), r1);
1929 movr(r0, rn(t0));
1930 }
1931 else {
1932 if (can_sign_extend_short_p(i0))
1933 addiu(r0, r1, i0);
1934 else {
1935 movi(rn(t0), i0);
1936 addr(r0, r1, rn(t0));
1937 }
1938 SLTU(rn(jit_carry), r0, r1);
1939 }
1940 jit_unget_reg(t0);
1941}
1942
1943static void
1944_addxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1945{
1946 jit_int32_t t0;
1947
1948 assert(jit_carry != _NOREG);
1949 t0 = jit_get_reg(jit_class_gpr);
1950 movr(rn(t0), rn(jit_carry));
1951 addcr(r0, r1, r2);
1952 addcr(r0, r0, rn(t0));
1953 jit_unget_reg(t0);
1954}
1955
1956static void
1957_addxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1958{
1959 jit_int32_t t0;
1960
1961 assert(jit_carry != _NOREG);
1962 t0 = jit_get_reg(jit_class_gpr);
1963 movr(rn(t0), rn(jit_carry));
1964 addci(r0, r1, i0);
1965 addcr(r0, r0, rn(t0));
1966 jit_unget_reg(t0);
1967}
1968
1969static void
1970_subi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1971{
1972 jit_int32_t reg;
1973 if (i0 == 0)
1974 movr(r0, r1);
1975 else if (can_sign_extend_short_p(i0) && (i0 & 0xffff) != 0x8000)
1976 addiu(r0, r1, -i0);
1977 else {
1978 reg = jit_get_reg(jit_class_gpr);
1979 movi(rn(reg), i0);
1980 subr(r0, r1, rn(reg));
1981 jit_unget_reg(reg);
1982 }
1983}
1984
1985static void
1986_subcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1987{
1988 jit_int32_t t0;
1989
1990 if (jit_carry == _NOREG)
1991 jit_carry = jit_get_reg(jit_class_gpr);
1992 if (r0 == r1) {
1993 t0 = jit_get_reg(jit_class_gpr);
1994 subr(rn(t0), r1, r2);
1995 SLTU(rn(jit_carry), r1, rn(t0));
1996 movr(r0, rn(t0));
1997 jit_unget_reg(t0);
1998 }
1999 else {
2000 subr(r0, r1, r2);
2001 SLTU(rn(jit_carry), r1, r0);
2002 }
2003}
2004
2005static void
2006_subci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2007{
2008 jit_int32_t t0;
2009
2010 if (jit_carry == _NOREG)
2011 jit_carry = jit_get_reg(jit_class_gpr);
2012 t0 = jit_get_reg(jit_class_gpr);
2013 if (r0 == r1) {
2014 if (can_sign_extend_short_p(i0) && (i0 & 0xffff) != 0x8000)
2015 addiu(rn(t0), r1, -i0);
2016 else {
2017 movi(rn(t0), i0);
2018 subr(rn(t0), r1, rn(t0));
2019 }
2020 SLTU(rn(jit_carry), r1, rn(t0));
2021 movr(r0, rn(t0));
2022 }
2023 else {
2024 if (can_sign_extend_short_p(i0) && (i0 & 0xffff) != 0x8000)
2025 addiu(r0, r1, -i0);
2026 else {
2027 movi(rn(t0), i0);
2028 subr(r0, r1, rn(t0));
2029 }
2030 SLTU(rn(jit_carry), r1, r0);
2031 }
2032 jit_unget_reg(t0);
2033}
2034
2035static void
2036_subxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
2037{
2038 jit_int32_t t0;
2039
2040 assert(jit_carry != _NOREG);
2041 t0 = jit_get_reg(jit_class_gpr);
2042 movr(rn(t0), rn(jit_carry));
2043 subcr(r0, r1, r2);
2044 subcr(r0, r0, rn(t0));
2045 jit_unget_reg(t0);
2046}
2047
2048static void
2049_subxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2050{
2051 jit_int32_t t0;
2052
2053 assert(jit_carry != _NOREG);
2054 t0 = jit_get_reg(jit_class_gpr);
2055 movr(rn(t0), rn(jit_carry));
2056 subci(r0, r1, i0);
2057 subcr(r0, r0, rn(t0));
2058 jit_unget_reg(t0);
2059}
2060
2061static void
2062_rsbi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2063{
2064 subi(r0, r1, i0);
2065 negr(r0, r0);
2066}
2067
2068static void
2069_mulr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
2070{
79bfeef6
PC
2071 if (jit_mips6_p())
2072 mul_r6(r0, r1, r2);
40a44dcb 2073 else {
79bfeef6
PC
2074 if (jit_mips2_p() && __WORDSIZE == 32)
2075 MUL(r0, r1, r2);
2076 else {
2077 multu(r1, r2);
2078 MFLO(r0);
2079 }
40a44dcb 2080 }
4a71579b
PC
2081}
2082
2083static void
2084_muli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2085{
2086 jit_int32_t reg;
2087
2088 reg = jit_get_reg(jit_class_gpr);
2089 movi(rn(reg), i0);
2090 mulr(r0, r1, rn(reg));
2091 jit_unget_reg(reg);
2092}
2093
ba86ff93
PC
2094static void
2095_hmulr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
2096{
2097 if (jit_mips6_p())
2098 muh_r6(r0, r1, r2);
2099 else {
2100 mult(r1, r2);
2101 MFHI(r0);
2102 }
2103}
2104
2105static void
2106_hmuli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2107{
2108 jit_int32_t reg;
2109 reg = jit_get_reg(jit_class_gpr);
2110 movi(rn(reg), i0);
2111 hmulr(r0, r1, rn(reg));
2112 jit_unget_reg(reg);
2113}
2114
2115static void
2116_hmulr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
2117{
2118 if (jit_mips6_p())
2119 muhu_r6(r0, r1, r2);
2120 else {
2121 multu(r1, r2);
2122 MFHI(r0);
2123 }
2124}
2125
2126static void
2127_hmuli_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2128{
2129 jit_int32_t reg;
2130 reg = jit_get_reg(jit_class_gpr);
2131 movi(rn(reg), i0);
2132 hmulr_u(r0, r1, rn(reg));
2133 jit_unget_reg(reg);
2134}
2135
4a71579b
PC
2136static void
2137_iqmulr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
2138 jit_int32_t r2, jit_int32_t r3, jit_bool_t sign)
2139{
79bfeef6
PC
2140 jit_int32_t t0;
2141 if (jit_mips6_p()) {
2142 if (r0 == r2 || r0 == r3) {
2143 t0 = jit_get_reg(jit_class_gpr);
2144 if (sign)
2145 mul_r6(rn(t0), r2, r3);
2146 else
2147 mulu_r6(rn(t0), r2, r3);
2148 }
2149 else {
2150 if (sign)
2151 mul_r6(r0, r2, r3);
2152 else
2153 mulu_r6(r0, r2, r3);
2154 }
2155 if (sign)
2156 muh_r6(r1, r2, r3);
2157 else
2158 muhu_r6(r1, r2, r3);
2159 if (r0 == r2 || r0 == r3) {
2160 movr(r0, rn(t0));
2161 jit_unget_reg(t0);
2162 }
2163 }
2164 else {
2165 if (sign)
2166 mult(r2, r3);
2167 else
2168 multu(r2, r3);
2169 MFLO(r0);
2170 MFHI(r1);
2171 }
4a71579b
PC
2172}
2173
2174static void
2175_iqmuli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
2176 jit_int32_t r2, jit_word_t i0, jit_bool_t sign)
2177{
2178 jit_int32_t reg;
2179 reg = jit_get_reg(jit_class_gpr);
2180 movi(rn(reg), i0);
2181 iqmulr(r0, r1, r2, rn(reg), sign);
2182 jit_unget_reg(reg);
2183}
2184
2185static void
2186_divr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
2187{
79bfeef6
PC
2188 if (jit_mips6_p())
2189 div_r6(r0, r1, r2);
2190 else {
2191 div(r1, r2);
2192 MFLO(r0);
2193 }
4a71579b
PC
2194}
2195
2196static void
2197_divi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2198{
2199 jit_int32_t reg;
2200 reg = jit_get_reg(jit_class_gpr);
2201 movi(rn(reg), i0);
2202 divr(r0, r1, rn(reg));
2203 jit_unget_reg(reg);
2204}
2205
2206static void
2207_divr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
2208{
79bfeef6
PC
2209 if (jit_mips6_p())
2210 divu_r6(r0, r1, r2);
2211 else {
2212 divu(r1, r2);
2213 MFLO(r0);
2214 }
4a71579b
PC
2215}
2216
2217static void
2218_divi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2219{
2220 jit_int32_t reg;
2221 reg = jit_get_reg(jit_class_gpr);
2222 movi(rn(reg), i0);
2223 divr_u(r0, r1, rn(reg));
2224 jit_unget_reg(reg);
2225}
2226
2227static void
2228_iqdivr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
2229 jit_int32_t r2, jit_int32_t r3, jit_bool_t sign)
2230{
79bfeef6
PC
2231 jit_int32_t t0;
2232 if (jit_mips6_p()) {
2233 if (r0 == r2 || r0 == r3)
2234 t0 = jit_get_reg(jit_class_gpr);
2235 else
2236 t0 = _NOREG;
2237 if (sign) {
2238 if (t0 == _NOREG)
2239 div_r6(r0, r2, r3);
2240 else
2241 div_r6(rn(t0), r2, r3);
2242 mod_r6(r1, r2, r3);
2243 }
2244 else {
2245 if (t0 == _NOREG)
2246 divu_r6(r0, r2, r3);
2247 else
2248 divu_r6(rn(t0), r2, r3);
2249 modu_r6(r1, r2, r3);
2250 }
2251 if (t0 != _NOREG) {
2252 movr(r0, rn(t0));
2253 jit_unget_reg(t0);
2254 }
2255 }
2256 else {
2257 if (sign)
2258 div(r2, r3);
2259 else
2260 divu(r2, r3);
2261 MFLO(r0);
2262 MFHI(r1);
2263 }
4a71579b
PC
2264}
2265
2266static void
2267_iqdivi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
2268 jit_int32_t r2, jit_word_t i0, jit_bool_t sign)
2269{
2270 jit_int32_t reg;
2271 reg = jit_get_reg(jit_class_gpr);
2272 movi(rn(reg), i0);
2273 iqdivr(r0, r1, r2, rn(reg), sign);
2274 jit_unget_reg(reg);
2275}
2276
2277static void
2278_remr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
2279{
79bfeef6
PC
2280 if (jit_mips6_p())
2281 mod_r6(r0, r1, r2);
2282 else {
2283 div(r1, r2);
2284 MFHI(r0);
2285 }
4a71579b
PC
2286}
2287
2288static void
2289_remi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2290{
2291 jit_int32_t reg;
2292 reg = jit_get_reg(jit_class_gpr);
2293 movi(rn(reg), i0);
2294 remr(r0, r1, rn(reg));
2295 jit_unget_reg(reg);
2296}
2297
2298static void
2299_remr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
2300{
79bfeef6
PC
2301 if (jit_mips6_p())
2302 modu_r6(r0, r1, r2);
2303 else {
2304 divu(r1, r2);
2305 MFHI(r0);
2306 }
4a71579b
PC
2307}
2308
2309static void
2310_remi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2311{
2312 jit_int32_t reg;
2313 reg = jit_get_reg(jit_class_gpr);
2314 movi(rn(reg), i0);
2315 remr_u(r0, r1, rn(reg));
2316 jit_unget_reg(reg);
2317}
2318
2319#if __WORDSIZE == 64
2320static void
2321_lshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2322{
2323 assert(i0 >= 0 && i0 <= 63);
2324 if (i0 < 32)
2325 DSLL(r0, r1, i0);
2326 else
2327 DSLL32(r0, r1, i0 - 32);
2328}
2329
2330static void
2331_rshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2332{
2333 assert(i0 >= 0 && i0 <= 63);
2334 if (i0 < 32)
2335 DSRA(r0, r1, i0);
2336 else
2337 DSRA32(r0, r1, i0 - 32);
2338}
2339
2340static void
2341_rshi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2342{
2343 assert(i0 >= 0 && i0 <= 63);
2344 if (i0 < 32)
2345 DSRL(r0, r1, i0);
2346 else
2347 DSRL32(r0, r1, i0 - 32);
2348}
2349#endif
2350
ba86ff93
PC
2351static void
2352_xlshr(jit_state_t *_jit, jit_bool_t sign,
2353 jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3)
2354{
d481fb64 2355 jit_int32_t t0, s0, t2, s2, t3, s3;
ba86ff93
PC
2356 s0 = jit_get_reg(jit_class_gpr);
2357 t0 = rn(s0);
2358 if (r0 == r2 || r1 == r2) {
d481fb64
PC
2359 s2 = jit_get_reg(jit_class_gpr);
2360 t2 = rn(s2);
2361 movr(t2, r2);
ba86ff93
PC
2362 }
2363 else
d481fb64 2364 t2 = r2;
ba86ff93 2365 if (r0 == r3 || r1 == r3) {
d481fb64
PC
2366 s3 = jit_get_reg(jit_class_gpr);
2367 t3 = rn(s3);
2368 movr(t3, r3);
ba86ff93
PC
2369 }
2370 else
d481fb64 2371 t3 = r3;
ba86ff93
PC
2372 rsbi(t0, t3, __WORDSIZE);
2373 lshr(r0, t2, t3);
2374 if (sign)
d481fb64 2375 rshr(r1, t2, t0);
ba86ff93 2376 else
d481fb64
PC
2377 rshr_u(r1, t2, t0);
2378 if (sign) {
2379 rshi(t0, t2, __WORDSIZE - 1);
2380 /* zero? */
2381 movzr(r1, t0, t3);
ba86ff93
PC
2382 }
2383 else {
d481fb64
PC
2384 /* zero? */
2385 movzr(r1, t3, t3);
ba86ff93 2386 }
d481fb64
PC
2387 /* overflow? */
2388 nei(t0, t3, __WORDSIZE);
2389 movzr(r0, t0, t0);
2390
ba86ff93
PC
2391 jit_unget_reg(s0);
2392 if (t2 != r2)
2393 jit_unget_reg(s2);
2394 if (t3 != r3)
2395 jit_unget_reg(s3);
2396}
2397
2398static void
2399_xlshi(jit_state_t *_jit, jit_bool_t sign,
2400 jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_word_t i0)
2401{
2402 if (i0 == 0) {
2403 movr(r0, r2);
2404 if (sign)
2405 rshi(r1, r2, __WORDSIZE - 1);
2406 else
2407 movi(r1, 0);
2408 }
2409 else if (i0 == __WORDSIZE) {
2410 movr(r1, r2);
2411 movi(r0, 0);
2412 }
2413 else {
2414 assert((jit_uword_t)i0 <= __WORDSIZE);
2415 if (sign)
2416 rshi(r1, r2, __WORDSIZE - i0);
2417 else
2418 rshi_u(r1, r2, __WORDSIZE - i0);
2419 lshi(r0, r2, i0);
2420 }
2421}
2422
2423static void
2424_xrshr(jit_state_t *_jit, jit_bool_t sign,
2425 jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3)
2426{
d481fb64 2427 jit_int32_t t0, s0, t2, s2, t3, s3;
ba86ff93
PC
2428 s0 = jit_get_reg(jit_class_gpr);
2429 t0 = rn(s0);
2430 if (r0 == r2 || r1 == r2) {
d481fb64
PC
2431 s2 = jit_get_reg(jit_class_gpr);
2432 t2 = rn(s2);
2433 movr(t2, r2);
ba86ff93
PC
2434 }
2435 else
d481fb64 2436 t2 = r2;
ba86ff93 2437 if (r0 == r3 || r1 == r3) {
d481fb64
PC
2438 s3 = jit_get_reg(jit_class_gpr);
2439 t3 = rn(s3);
2440 movr(t3, r3);
ba86ff93
PC
2441 }
2442 else
d481fb64
PC
2443 t3 = r3;
2444
2445 if (sign) {
2446 /* underflow? */
2447 eqi(t0, t3, __WORDSIZE);
2448 subr(t0, t3, t0);
2449 rshr(r0, t2, t0);
2450 } else {
2451 /* underflow? */
2452 nei(t0, t3, __WORDSIZE);
2453 rshr_u(r0, t2, t3);
2454 movzr(r0, t0, t0);
ba86ff93 2455 }
d481fb64 2456
ba86ff93 2457 rsbi(t0, t3, __WORDSIZE);
ba86ff93 2458 lshr(r1, t2, t0);
d481fb64
PC
2459
2460 /* zero? */
2461 movzr(r1, t3, t3);
2462
ba86ff93
PC
2463 jit_unget_reg(s0);
2464 if (t2 != r2)
d481fb64 2465 jit_unget_reg(s2);
ba86ff93 2466 if (t3 != r3)
d481fb64 2467 jit_unget_reg(s3);
ba86ff93
PC
2468}
2469
2470static void
2471_xrshi(jit_state_t *_jit, jit_bool_t sign,
2472 jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_word_t i0)
2473{
2474 if (i0 == 0) {
2475 movr(r0, r2);
d481fb64 2476 movi(r1, 0);
ba86ff93
PC
2477 }
2478 else if (i0 == __WORDSIZE) {
2479 movr(r1, r2);
2480 if (sign)
2481 rshi(r0, r2, __WORDSIZE - 1);
2482 else
2483 movi(r0, 0);
2484 }
2485 else {
2486 assert((jit_uword_t)i0 <= __WORDSIZE);
2487 lshi(r1, r2, __WORDSIZE - i0);
2488 if (sign)
2489 rshi(r0, r2, i0);
2490 else
2491 rshi_u(r0, r2, i0);
2492 }
2493}
2494
2495static void
2496_lrotr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
2497{
2498 jit_int32_t reg;
2499 if (jit_mips2_p()) {
2500 if (r0 != r1 && r0 != r2) {
2501 rsbi(r0, r2, __WORDSIZE);
2502 rrotr(r0, r1, r0);
2503 }
2504 else {
2505 reg = jit_get_reg(jit_class_gpr);
2506 rsbi(rn(reg), r2, __WORDSIZE);
2507 rrotr(r0, r1, rn(reg));
2508 jit_unget_reg(reg);
2509 }
2510 }
2511 else
2512 fallback_lrotr(r0, r1, r2);
2513}
2514
2515static void
2516_rrotr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
2517{
2518 if (jit_mips2_p()) {
2519#if __WORDSIZE == 32
2520 ROTRV(r0, r1, r2);
2521#else
2522 DROTRV(r0, r1, r2);
2523#endif
2524 }
2525 else
2526 fallback_rrotr(r0, r1, r2);
2527}
2528
2529static void
2530_rroti(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2531{
2532 assert(i0 >= 0 && i0 <= __WORDSIZE - 1);
2533 if (jit_mips2_p()) {
2534#if __WORDSIZE == 32
2535 ROTR(r0, r1, i0);
2536#else
2537 if (i0 < 32)
2538 DROTR(r0, r1, i0);
2539 else
2540 DROTR32(r0, r1, i0 - 32);
2541#endif
2542 }
2543 else
2544 fallback_rroti(r0, r1, i0);
2545}
2546
4a71579b
PC
2547static void
2548_andi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2549{
2550 jit_int32_t reg;
2551 if (can_zero_extend_short_p(i0))
40a44dcb 2552 ANDI(r0, r1, i0);
519a9ea1 2553 else if (is_low_mask(i0)) {
40a44dcb 2554 if (jit_mips2_p())
ba86ff93 2555 mips_extr(r0, r1, 0, masked_bits_count(i0));
40a44dcb
PC
2556 else {
2557 lshi(r0, r1, unmasked_bits_count(i0));
2558 rshi_u(r0, r0, unmasked_bits_count(i0));
2559 }
519a9ea1 2560 } else if (is_high_mask(i0)) {
40a44dcb
PC
2561 if (jit_mips2_p() && r0 == r1)
2562 insr(r0, _ZERO_REGNO, 0, unmasked_bits_count(i0));
2563 else {
2564 rshi(r0, r1, unmasked_bits_count(i0));
2565 lshi(r0, r0, unmasked_bits_count(i0));
2566 }
2567 } else if (jit_mips2_p() && is_middle_mask(i0)) {
ba86ff93 2568 mips_extr(r0, r1, __builtin_ctzl(i0), masked_bits_count(i0));
40a44dcb
PC
2569 lshi(r0, r0, __builtin_ctzl(i0));
2570 } else if (jit_mips2_p() && is_middle_mask(~i0)) {
2571 if (r0 != r1)
2572 movr(r0, r1);
2573 insr(r0, _ZERO_REGNO, __builtin_ctzl(~i0), masked_bits_count(~i0));
519a9ea1 2574 } else {
40a44dcb
PC
2575 reg = jit_get_reg(jit_class_gpr);
2576 movi(rn(reg), i0);
2577 AND(r0, r1, rn(reg));
2578 jit_unget_reg(reg);
4a71579b
PC
2579 }
2580}
2581
2582static void
2583_ori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2584{
2585 jit_int32_t reg;
2586 if (can_zero_extend_short_p(i0))
2587 ORI(r0, r1, i0);
2588 else {
2589 reg = jit_get_reg(jit_class_gpr);
2590 movi(rn(reg), i0);
2591 OR(r0, r1, rn(reg));
2592 jit_unget_reg(reg);
2593 }
2594}
2595
2596static void
2597_xori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2598{
2599 jit_int32_t reg;
2600 if (can_zero_extend_short_p(i0))
2601 XORI(r0, r1, i0);
2602 else {
2603 reg = jit_get_reg(jit_class_gpr);
2604 movi(rn(reg), i0);
2605 XOR(r0, r1, rn(reg));
2606 jit_unget_reg(reg);
2607 }
2608}
2609
519a9ea1
PC
2610static void
2611_movr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
2612{
2613 if (r0 != r1)
2614 orr(r0, r1, _ZERO_REGNO);
2615}
2616
4a71579b
PC
2617static void
2618_movi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
2619{
2620 if (i0 == 0)
2621 OR(r0, _ZERO_REGNO, _ZERO_REGNO);
2622 else if (can_sign_extend_short_p(i0))
2623 addiu(r0, _ZERO_REGNO, i0);
2624 else if (can_zero_extend_short_p(i0))
2625 ORI(r0, _ZERO_REGNO, i0);
2626 else {
ba86ff93
PC
2627 /* Check if loading some constant reachable address */
2628 if (jit_mips6_p()) {
2629 jit_word_t w, d;
2630 w = i0 - (_jit->pc.w + (_jitc->inst.pend ? 4 : 0));
2631#if !PCREL_BROKEN
2632 if (!(i0 & 3)) {
2633 d = w >> 2;
2634 if (can_sign_extend_i19_p(d)) {
2635 ADDIUPC(r0, d);
2636 goto done;
2637 }
2638 }
2639#endif
2640 if (can_sign_extend_int_p(w)) {
2641 jit_int32_t lo = (jit_int32_t)w << 16 >> 16;
2642 jit_int32_t hi = w - lo;
2643 AUIPC(r0, hi >> 16);
2644 if (lo)
2645 addiu(r0, r0, lo);
2646 goto done;
2647 }
2648 }
4a71579b
PC
2649 if (can_sign_extend_int_p(i0))
2650 LUI(r0, i0 >> 16);
2651 else if (can_zero_extend_int_p(i0)) {
2652 if (i0 & 0xffff0000) {
2653 ORI(r0, _ZERO_REGNO, i0 >> 16);
2654 lshi(r0, r0, 16);
2655 }
2656 }
2657# if __WORDSIZE == 64
2658 else {
2659 movi(r0, (jit_uword_t)i0 >> 32);
2660 if (i0 & 0xffff0000) {
2661 lshi(r0, r0, 16);
2662 ORI(r0, r0, i0 >> 16);
2663 lshi(r0, r0, 16);
2664 }
2665 else
2666 lshi(r0, r0, 32);
2667 }
2668# endif
2669 if (i0 & 0xffff)
2670 ORI(r0, r0, i0);
2671 }
ba86ff93 2672done:;
4a71579b
PC
2673}
2674
2675static jit_word_t
2676_movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
2677{
2678 jit_word_t w;
79bfeef6 2679 flush();
4a71579b
PC
2680 w = _jit->pc.w;
2681# if __WORDSIZE == 32
2682 LUI(r0, i0 >> 16);
2683 ORI(r0, r0, i0);
2684# else
2685 LUI(r0, i0 >> 48);
2686 ORI(r0, r0, i0 >> 32);
2687 lshi(r0, r0, 16);
2688 ORI(r0, r0, i0 >> 16);
2689 lshi(r0, r0, 16);
2690 ORI(r0, r0, i0);
2691# endif
2692
2693 return (w);
2694}
2695
79bfeef6
PC
2696static void
2697_movnr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
2698{
2699 jit_int32_t reg;
2700 if (jit_mips6_p()) {
2701 reg = jit_get_reg(jit_class_gpr);
2702 SELNEZ(rn(reg), r1, r2);
2703 SELEQZ(r0, r0, r2);
2704 OR(r0, r0, rn(reg));
2705 jit_unget_reg(reg);
2706 }
2707 else
2708 MOVN(r0, r1, r2);
2709}
2710
2711static void
2712_movzr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
2713{
2714 jit_int32_t reg;
2715 if (jit_mips6_p()) {
2716 reg = jit_get_reg(jit_class_gpr);
2717 SELEQZ(rn(reg), r1, r2);
2718 SELNEZ(r0, r0, r2);
2719 OR(r0, r0, rn(reg));
2720 jit_unget_reg(reg);
2721 }
2722 else
2723 MOVZ(r0, r1, r2);
2724}
2725
ba3814c1
PC
2726static void
2727_casx(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
2728 jit_int32_t r2, jit_int32_t r3, jit_word_t i0)
2729{
c0c16242
PC
2730 jit_int32_t r1_reg, iscasi;
2731 jit_word_t retry, done, jump0, jump1;
2732 if ((iscasi = (r1 == _NOREG))) {
2733 r1_reg = jit_get_reg(jit_class_gpr);
2734 r1 = rn(r1_reg);
2735 movi(r1, i0);
2736 }
2737 SYNC();
2738 /* retry: */
79bfeef6 2739 flush();
c0c16242
PC
2740 retry = _jit->pc.w;
2741# if __WORDSIZE == 32
79bfeef6
PC
2742 if (jit_mips6_p()) LL_R6(r0, 0, r1);
2743 else LL(r0, 0, r1);
c0c16242 2744# else
79bfeef6
PC
2745 if (jit_mips6_p()) LLD_R6(r0, 0, r1);
2746 else LLD(r0, 0, r1);
c0c16242 2747# endif
79bfeef6 2748 flush();
c0c16242
PC
2749 jump0 = _jit->pc.w;
2750 BNE(r0, r2, 1); /* bne done r0 r2 */
2751 movi(r0, 0); /* set to 0 in delay slot */
79bfeef6 2752 flush();
c0c16242
PC
2753 movr(r0, r3); /* after jump and delay slot */
2754 /* store new value */
2755# if __WORDSIZE == 32
79bfeef6
PC
2756 if (jit_mips6_p()) SC_R6(r0, 0, r1);
2757 else SC(r0, 0, r1);
c0c16242 2758# else
79bfeef6
PC
2759 if (jit_mips6_p()) SCD_R6(r0, 0, r1);
2760 else SCD(r0, 0, r1);
c0c16242 2761# endif
79bfeef6 2762 flush();
c0c16242
PC
2763 jump1 = _jit->pc.w;
2764 BEQ(r0, _ZERO_REGNO, 0); /* beqi retry r0 0 */
2765 movi(r0, 1); /* set to 1 in delay slot */
79bfeef6 2766 flush();
c0c16242
PC
2767 SYNC();
2768 /* done: */
79bfeef6 2769 flush();
c0c16242
PC
2770 done = _jit->pc.w;
2771 patch_at(jump0, done);
2772 patch_at(jump1, retry);
2773 if (iscasi)
2774 jit_unget_reg(r1_reg);
ba3814c1
PC
2775}
2776
4a71579b
PC
2777static void
2778_ldi_c(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
2779{
2780 jit_int32_t reg;
2781 if (can_sign_extend_short_p(i0))
2782 LB(r0, i0, _ZERO_REGNO);
2783 else {
2784 reg = jit_get_reg(jit_class_gpr);
2785 movi(rn(reg), i0);
2786 ldr_c(r0, rn(reg));
2787 jit_unget_reg(reg);
2788 }
2789}
2790
2791static void
2792_ldi_uc(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
2793{
2794 jit_int32_t reg;
2795 if (can_sign_extend_short_p(i0))
2796 LBU(r0, i0, _ZERO_REGNO);
2797 else {
2798 reg = jit_get_reg(jit_class_gpr);
2799 movi(rn(reg), i0);
2800 ldr_uc(r0, rn(reg));
2801 jit_unget_reg(reg);
2802 }
2803}
2804
2805static void
2806_ldi_s(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
2807{
2808 jit_int32_t reg;
2809 if (can_sign_extend_short_p(i0))
2810 LH(r0, i0, _ZERO_REGNO);
2811 else {
2812 reg = jit_get_reg(jit_class_gpr);
2813 movi(rn(reg), i0);
2814 ldr_s(r0, rn(reg));
2815 jit_unget_reg(reg);
2816 }
2817}
2818
2819static void
2820_ldi_us(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
2821{
2822 jit_int32_t reg;
2823 if (can_sign_extend_short_p(i0))
2824 LHU(r0, i0, _ZERO_REGNO);
2825 else {
2826 reg = jit_get_reg(jit_class_gpr);
2827 movi(rn(reg), i0);
2828 ldr_us(r0, rn(reg));
2829 jit_unget_reg(reg);
2830 }
2831}
2832
2833static void
2834_ldi_i(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
2835{
2836 jit_int32_t reg;
ba86ff93
PC
2837#if !PCREL_BROKEN
2838 if (jit_mips6_p()) {
2839 jit_word_t w;
2840 assert(!(i0 & 3));
2841 w = (i0 - (_jit->pc.w + (_jitc->inst.pend ? 4 : 0))) >> 2;
2842 if (can_sign_extend_i19_p(w)) {
2843 LWPC(r0, w);
2844 goto done;
2845 }
2846 }
2847#endif
4a71579b
PC
2848 if (can_sign_extend_short_p(i0))
2849 LW(r0, i0, _ZERO_REGNO);
2850 else {
2851 reg = jit_get_reg(jit_class_gpr);
2852 movi(rn(reg), i0);
2853 ldr_i(r0, rn(reg));
2854 jit_unget_reg(reg);
2855 }
ba86ff93
PC
2856#if !PCREL_BROKEN
2857done:;
2858#endif
4a71579b
PC
2859}
2860
2861#if __WORDSIZE == 64
2862static void
2863_ldi_ui(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
2864{
2865 jit_int32_t reg;
ba86ff93
PC
2866#if !PCREL_BROKEN
2867 if (jit_mips6_p()) {
2868 jit_word_t w;
2869 assert(!(i0 & 3));
2870 w = (i0 - (_jit->pc.w + (_jitc->inst.pend ? 4 : 0))) >> 2;
2871 if (can_sign_extend_i19_p(w)) {
2872 LWUPC(r0, w);
2873 goto done;
2874 }
2875 }
2876#endif
4a71579b
PC
2877 if (can_sign_extend_short_p(i0))
2878 LWU(r0, i0, _ZERO_REGNO);
2879 else {
2880 reg = jit_get_reg(jit_class_gpr);
2881 movi(rn(reg), i0);
2882 ldr_ui(r0, rn(reg));
2883 jit_unget_reg(reg);
2884 }
ba86ff93
PC
2885#if !PCREL_BROKEN
2886done:;
2887#endif
4a71579b
PC
2888}
2889
2890static void
2891_ldi_l(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
2892{
ba86ff93 2893 jit_word_t w;
4a71579b 2894 jit_int32_t reg;
ba86ff93
PC
2895 if (jit_mips6_p()) {
2896 assert(!(i0 & 7));
2897 w = (i0 - (_jit->pc.w + (_jitc->inst.pend ? 4 : 0))) >> 3;
2898 if (can_sign_extend_i18_p(w)) {
2899 LDPC(r0, w);
2900 goto done;
2901 }
2902 }
4a71579b
PC
2903 if (can_sign_extend_short_p(i0))
2904 LD(r0, i0, _ZERO_REGNO);
2905 else {
2906 reg = jit_get_reg(jit_class_gpr);
2907 movi(rn(reg), i0);
2908 ldr_l(r0, rn(reg));
2909 jit_unget_reg(reg);
2910 }
ba86ff93 2911done:;
4a71579b
PC
2912}
2913#endif
2914
2915static void
2916_ldxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2)
2917{
79bfeef6
PC
2918 addr(r0, r1, r2);
2919 ldr_c(r0, r0);
4a71579b
PC
2920}
2921
2922static void
2923_ldxi_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2924{
4a71579b
PC
2925 if (can_sign_extend_short_p(i0))
2926 LB(r0, i0, r1);
2927 else {
79bfeef6
PC
2928 addi(r0, r1, i0);
2929 ldr_c(r0, r0);
4a71579b
PC
2930 }
2931}
2932
2933static void
2934_ldxr_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2)
2935{
79bfeef6
PC
2936 addr(r0, r1, r2);
2937 ldr_uc(r0, r0);
4a71579b
PC
2938}
2939
2940static void
2941_ldxi_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2942{
4a71579b
PC
2943 if (can_sign_extend_short_p(i0))
2944 LBU(r0, i0, r1);
2945 else {
79bfeef6
PC
2946 addi(r0, r1, i0);
2947 ldr_uc(r0, r0);
4a71579b
PC
2948 }
2949}
2950
2951static void
2952_ldxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2)
2953{
79bfeef6
PC
2954 addr(r0, r1, r2);
2955 ldr_s(r0, r0);
4a71579b
PC
2956}
2957
2958static void
2959_ldxi_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2960{
4a71579b
PC
2961 if (can_sign_extend_short_p(i0))
2962 LH(r0, i0, r1);
2963 else {
79bfeef6
PC
2964 addi(r0, r1, i0);
2965 ldr_s(r0, r0);
4a71579b
PC
2966 }
2967}
2968
2969static void
2970_ldxr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2)
2971{
79bfeef6
PC
2972 addr(r0, r1, r2);
2973 ldr_us(r0, r0);
4a71579b
PC
2974}
2975
2976static void
2977_ldxi_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2978{
4a71579b
PC
2979 if (can_sign_extend_short_p(i0))
2980 LHU(r0, i0, r1);
2981 else {
79bfeef6
PC
2982 addi(r0, r1, i0);
2983 ldr_us(r0, r0);
4a71579b
PC
2984 }
2985}
2986
2987static void
2988_ldxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2)
2989{
79bfeef6
PC
2990 addr(r0, r1, r2);
2991 ldr_i(r0, r0);
4a71579b
PC
2992}
2993
2994static void
2995_ldxi_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2996{
4a71579b
PC
2997 if (can_sign_extend_short_p(i0))
2998 LW(r0, i0, r1);
2999 else {
79bfeef6
PC
3000 addi(r0, r1, i0);
3001 ldr_i(r0, r0);
4a71579b
PC
3002 }
3003}
3004
3005#if __WORDSIZE == 64
3006static void
3007_ldxr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2)
3008{
79bfeef6
PC
3009 addr(r0, r1, r2);
3010 ldr_ui(r0, r0);
4a71579b
PC
3011}
3012
3013static void
3014_ldxi_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
3015{
4a71579b
PC
3016 if (can_sign_extend_short_p(i0))
3017 LWU(r0, i0, r1);
3018 else {
79bfeef6
PC
3019 addi(r0, r1, i0);
3020 ldr_ui(r0, r0);
4a71579b
PC
3021 }
3022}
3023
3024static void
3025_ldxr_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2)
3026{
79bfeef6
PC
3027 addr(r0, r1, r2);
3028 ldr_l(r0, r0);
4a71579b
PC
3029}
3030
3031static void
3032_ldxi_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
3033{
4a71579b
PC
3034 if (can_sign_extend_short_p(i0))
3035 LD(r0, i0, r1);
3036 else {
79bfeef6
PC
3037 addi(r0, r1, i0);
3038 ldr_l(r0, r0);
4a71579b
PC
3039 }
3040}
3041#endif
3042
ba86ff93
PC
3043#if __WORDSIZE == 32
3044# define LOAD_LEFT LWL
3045# define LOAD_RIGHT LWR
3046#else
3047# define LOAD_LEFT LDL
3048# define LOAD_RIGHT LDR
3049#endif
3050static void
3051_unldr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
3052{
3053 jit_int32_t t0, r2;
3054 if (jit_unaligned_p()) {
3055 assert(i0 >= 1 && i0 <= sizeof(jit_word_t));
3056 if (i0 == 1)
3057 ldr_c(r0, r1);
3058 else {
3059 if (r0 == r1) {
3060 t0 = jit_get_reg(jit_class_gpr);
3061 r2 = rn(t0);
3062 movr(r2, r1);
3063 }
3064 else
3065 r2 = r1;
3066#if __BYTE_ORDER == __LITTLE_ENDIAN
3067 LOAD_LEFT(r0, sizeof(jit_word_t) - 1, r2);
3068 LOAD_RIGHT(r0, 0, r2);
3069#else
3070 LOAD_LEFT(r0, 0, r2);
3071 LOAD_RIGHT(r0, sizeof(jit_word_t) - 1, r2);
3072#endif
3073 if (r0 == r1)
3074 jit_unget_reg(t0);
3075 switch (i0) {
3076 case 2:
3077#if __BYTE_ORDER == __LITTLE_ENDIAN
3078 extr_s(r0, r0);
3079#else
3080 rshi(r0, r0, __WORDSIZE - 16);
3081#endif
3082 break;
3083 case 3:
3084#if __BYTE_ORDER == __LITTLE_ENDIAN
3085 lshi(r0, r0, __WORDSIZE - 24);
3086#endif
3087 rshi(r0, r0, __WORDSIZE - 24);
3088 break;
3089#if __WORDSIZE == 32
3090 default:
3091#else
3092 case 4:
3093# if __BYTE_ORDER == __LITTLE_ENDIAN
3094 extr_i(r0, r0);
3095# else
3096 rshi(r0, r0, __WORDSIZE - 32);
3097# endif
3098#endif
3099 break;
3100#if __WORDSIZE == 64
3101 case 5:
3102# if __BYTE_ORDER == __LITTLE_ENDIAN
3103 lshi(r0, r0, __WORDSIZE - 40);
3104# endif
3105 rshi(r0, r0, __WORDSIZE - 40);
3106 break;
3107 case 6:
3108# if __BYTE_ORDER == __LITTLE_ENDIAN
3109 lshi(r0, r0, __WORDSIZE - 48);
3110# endif
3111 rshi(r0, r0, __WORDSIZE - 48);
3112 break;
3113 case 7:
3114# if __BYTE_ORDER == __LITTLE_ENDIAN
3115 lshi(r0, r0, __WORDSIZE - 56);
3116# endif
3117 rshi(r0, r0, __WORDSIZE - 56);
3118 break;
3119 default:
3120 break;
3121#endif
3122 }
3123 }
3124 }
3125 else
3126 generic_unldr(r0, r1, i0);
3127}
3128
3129static void
3130_unldi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0, jit_word_t i1)
3131{
3132 jit_int32_t t0;
3133 if (jit_unaligned_p()) {
3134 t0 = jit_get_reg(jit_class_gpr);
3135 movi(rn(t0), i0);
3136 unldr(r0, rn(t0), i1);
3137 jit_unget_reg(t0);
3138 }
3139 else
3140 generic_unldi(r0, i0, i1);
3141}
3142
3143static void
3144_unldr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
3145{
3146 jit_int32_t t0, r2;
3147 if (jit_unaligned_p()) {
3148 assert(i0 >= 1 && i0 <= sizeof(jit_word_t));
3149 if (i0 == 1)
3150 ldr_uc(r0, r1);
3151 else {
3152 if (r0 == r1) {
3153 t0 = jit_get_reg(jit_class_gpr);
3154 r2 = rn(t0);
3155 movr(r2, r1);
3156 }
3157 else
3158 r2 = r1;
3159#if __BYTE_ORDER == __LITTLE_ENDIAN
3160 LOAD_LEFT(r0, sizeof(jit_word_t) - 1, r2);
3161 LOAD_RIGHT(r0, 0, r2);
3162#else
3163 LOAD_LEFT(r0, 0, r2);
3164 LOAD_RIGHT(r0, sizeof(jit_word_t) - 1, r2);
3165#endif
3166 if (r0 == r1)
3167 jit_unget_reg(t0);
3168 switch (i0) {
3169 case 2:
3170#if __BYTE_ORDER == __LITTLE_ENDIAN
3171 extr_us(r0, r0);
3172#else
3173 rshi_u(r0, r0, __WORDSIZE - 16);
3174#endif
3175 break;
3176 case 3:
3177#if __BYTE_ORDER == __LITTLE_ENDIAN
3178 lshi(r0, r0, __WORDSIZE - 24);
3179#endif
3180 rshi_u(r0, r0, __WORDSIZE - 24);
3181 break;
3182#if __WORDSIZE == 32
3183 default:
3184#else
3185 case 4:
3186# if __BYTE_ORDER == __LITTLE_ENDIAN
3187 extr_ui(r0, r0);
3188# else
3189 rshi_u(r0, r0, __WORDSIZE - 32);
3190# endif
3191#endif
3192 break;
3193#if __WORDSIZE == 64
3194 case 5:
3195# if __BYTE_ORDER == __LITTLE_ENDIAN
3196 lshi(r0, r0, __WORDSIZE - 40);
3197# endif
3198 rshi_u(r0, r0, __WORDSIZE - 40);
3199 break;
3200 case 6:
3201# if __BYTE_ORDER == __LITTLE_ENDIAN
3202 lshi(r0, r0, __WORDSIZE - 48);
3203# endif
3204 rshi_u(r0, r0, __WORDSIZE - 48);
3205 break;
3206 case 7:
3207# if __BYTE_ORDER == __LITTLE_ENDIAN
3208 lshi(r0, r0, __WORDSIZE - 56);
3209# endif
3210 rshi_u(r0, r0, __WORDSIZE - 56);
3211 break;
3212 default:
3213 break;
3214#endif
3215 }
3216 }
3217 }
3218 else
3219 generic_unldr_u(r0, r1, i0);
3220}
3221#undef LOAD_LEFT
3222#undef LOAD_RIGHT
3223
3224static void
3225_unldi_u(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0, jit_word_t i1)
3226{
3227 jit_int32_t t0;
3228 if (jit_unaligned_p()) {
3229 t0 = jit_get_reg(jit_class_gpr);
3230 movi(rn(t0), i0);
3231 unldr_u(r0, rn(t0), i1);
3232 jit_unget_reg(t0);
3233 }
3234 else
3235 generic_unldi_u(r0, i0, i1);
3236}
3237
4a71579b
PC
3238static void
3239_sti_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
3240{
3241 jit_int32_t reg;
3242 if (can_sign_extend_short_p(i0))
3243 SB(r0, i0, _ZERO_REGNO);
3244 else {
3245 reg = jit_get_reg(jit_class_gpr);
3246 movi(rn(reg), i0);
3247 str_c(rn(reg), r0);
3248 jit_unget_reg(reg);
3249 }
3250}
3251
3252static void
3253_sti_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
3254{
3255 jit_int32_t reg;
3256 if (can_sign_extend_short_p(i0))
3257 SH(r0, i0, _ZERO_REGNO);
3258 else {
3259 reg = jit_get_reg(jit_class_gpr);
3260 movi(rn(reg), i0);
3261 str_s(rn(reg), r0);
3262 jit_unget_reg(reg);
3263 }
3264}
3265
3266static void
3267_sti_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
3268{
3269 jit_int32_t reg;
3270 if (can_sign_extend_short_p(i0))
3271 SW(r0, i0, _ZERO_REGNO);
3272 else {
3273 reg = jit_get_reg(jit_class_gpr);
3274 movi(rn(reg), i0);
3275 str_i(rn(reg), r0);
3276 jit_unget_reg(reg);
3277 }
3278}
3279
3280#if __WORDSIZE == 64
3281static void
3282_sti_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
3283{
3284 jit_int32_t reg;
3285 if (can_sign_extend_short_p(i0))
3286 SD(r0, i0, _ZERO_REGNO);
3287 else {
3288 reg = jit_get_reg(jit_class_gpr);
3289 movi(rn(reg), i0);
3290 str_l(rn(reg), r0);
3291 jit_unget_reg(reg);
3292 }
3293}
3294#endif
3295
3296static void
3297_stxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
3298{
3299 jit_int32_t reg;
3300 reg = jit_get_reg(jit_class_gpr);
3301 addr(rn(reg), r0, r1);
3302 str_c(rn(reg), r2);
3303 jit_unget_reg(reg);
3304}
3305
3306static void
3307_stxi_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
3308{
3309 jit_int32_t reg;
3310 if (can_sign_extend_short_p(i0))
3311 SB(r1, i0, r0);
3312 else {
3313 reg = jit_get_reg(jit_class_gpr);
3314 addi(rn(reg), r0, i0);
3315 str_c(rn(reg), r1);
3316 jit_unget_reg(reg);
3317 }
3318}
3319
3320static void
3321_stxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2)
3322{
3323 jit_int32_t reg;
3324 reg = jit_get_reg(jit_class_gpr);
3325 addr(rn(reg), r0, r1);
3326 str_s(rn(reg), r2);
3327 jit_unget_reg(reg);
3328}
3329
3330static void
3331_stxi_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
3332{
3333 jit_int32_t reg;
3334 if (can_sign_extend_short_p(i0))
3335 SH(r1, i0, r0);
3336 else {
3337 reg = jit_get_reg(jit_class_gpr);
3338 addi(rn(reg), r0, i0);
3339 str_s(rn(reg), r1);
3340 jit_unget_reg(reg);
3341 }
3342}
3343
3344static void
3345_stxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2)
3346{
3347 jit_int32_t reg;
3348 reg = jit_get_reg(jit_class_gpr);
3349 addr(rn(reg), r0, r1);
3350 str_i(rn(reg), r2);
3351 jit_unget_reg(reg);
3352}
3353
3354static void
3355_stxi_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
3356{
3357 jit_int32_t reg;
3358 if (can_sign_extend_short_p(i0))
3359 SW(r1, i0, r0);
3360 else {
3361 reg = jit_get_reg(jit_class_gpr);
3362 addi(rn(reg), r0, i0);
3363 str_i(rn(reg), r1);
3364 jit_unget_reg(reg);
3365 }
3366}
3367
3368#if __WORDSIZE == 64
3369static void
3370_stxr_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2)
3371{
3372 jit_int32_t reg;
3373 reg = jit_get_reg(jit_class_gpr);
3374 addr(rn(reg), r0, r1);
3375 str_l(rn(reg), r2);
3376 jit_unget_reg(reg);
3377}
3378
3379static void
3380_stxi_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
3381{
3382 jit_int32_t reg;
3383 if (can_sign_extend_short_p(i0))
3384 SD(r1, i0, r0);
3385 else {
3386 reg = jit_get_reg(jit_class_gpr);
3387 addi(rn(reg), r0, i0);
3388 str_l(rn(reg), r1);
3389 jit_unget_reg(reg);
3390 }
3391}
3392#endif
3393
ba86ff93
PC
3394static void
3395_unstr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
3396{
3397 assert(i0 > 0 && i0 <= sizeof(jit_word_t));
3398 if (jit_unaligned_p()) {
3399 switch (i0) {
3400 case 4:
3401#if __BYTE_ORDER == __LITTLE_ENDIAN
3402 SWL(r1, 3, r0);
3403 SWR(r1, 0, r0);
3404#else
3405 SWL(r1, 0, r0);
3406 SWR(r1, 3, r0);
3407#endif
3408 break;
3409#if __WORDSIZE == 64
3410 case 8:
3411# if __BYTE_ORDER == __LITTLE_ENDIAN
3412 SDL(r1, 7, r0);
3413 SDR(r1, 0, r0);
3414# else
3415 SDL(r1, 0, r0);
3416 SDR(r1, 7, r0);
3417# endif
3418 break;
3419#endif
3420 default:
3421 /* FIXME Cost of loading memory contents, creating masks,
3422 * and'ing, and or'ing values to use SW* or SD* might
3423 * larger than using fallback. */
3424 /* FIXME Probably not, and would be without branches. */
3425 fallback_unstr(r0, r1, i0);
3426 break;
3427 }
3428 }
3429 else
3430 generic_unstr(r0, r1, i0);
3431}
3432
3433static void
3434_unsti(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
3435{
3436 jit_int32_t reg;
3437 if (jit_unaligned_p()) {
3438 if (i1 == 4 || i1 == 8) {
3439 reg = jit_get_reg(jit_class_gpr);
3440 movi(rn(reg), i0);
3441 unstr(rn(reg), r0, i1);
3442 jit_unget_reg(reg);
3443 }
3444 else
3445 fallback_unsti(i0, r0, i1);
3446 }
3447 else
3448 generic_unsti(i0, r0, i1);
3449}
3450
4a71579b 3451static void
40a44dcb 3452_bswapr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
4a71579b 3453{
40a44dcb
PC
3454 if (jit_mips2_p()) {
3455 extr_us(r0, r1);
3456 WSBH(r0, r0);
3457 } else {
3458 generic_bswapr_us(_jit, r0, r1);
3459 }
4a71579b
PC
3460}
3461
3462static void
40a44dcb 3463_bswapr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
4a71579b 3464{
40a44dcb
PC
3465 if (jit_mips2_p()) {
3466 if (__WORDSIZE == 64) {
3467 SLL(r0, r1, 0);
3468 WSBH(r0, r0);
3469 ROTR(r0, r0, 16);
ba86ff93 3470 mips_extr(r0, r0, 0, 32);
40a44dcb
PC
3471 } else {
3472 WSBH(r0, r1);
3473 ROTR(r0, r0, 16);
3474 }
3475 } else {
3476 generic_bswapr_ui(_jit, r0, r1);
3477 }
4a71579b 3478}
4a71579b 3479
ba86ff93
PC
3480#if __WORDSIZE == 64
3481static void
3482_bswapr_ul(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
3483{
3484 if (jit_mips2_p()) {
3485 DSBH(r0, r1);
3486 DSHD(r0, r0);
3487 }
3488 else
3489 generic_bswapr_ul(_jit, r0, r1);
3490}
3491#endif
3492
ba86ff93
PC
3493static void
3494_extr_u(jit_state_t *_jit,
3495 jit_int32_t r0, jit_int32_t r1, jit_word_t i0, jit_word_t i1)
3496{
3497 assert(i0 >= 0 && i1 >= 1 && i0 + i1 <= __WORDSIZE);
3498 if (jit_mips2_p()) {
3499 if (i1 == __WORDSIZE)
3500 movr(r0, r1);
3501 else {
3502# if __BYTE_ORDER == __BIG_ENDIAN
3503 i0 = __WORDSIZE - (i0 + i1);
3504# endif
3505#if __WORDSIZE == 32
3506 EXT(r0, r1, i0, i1);
3507#else
3508 if (i0 < 32 && i1 <= 32)
3509 DEXT(r0, r1, i0, i1);
3510 else if (i0 < 32 && i1 > 32)
3511 DEXTM(r0, r1, i0, i1);
3512 else {
3513 assert(i0 >= 32 && i1 <= 32);
3514 DEXTU(r0, r1, i0, i1);
3515 }
3516#endif
3517 }
3518 }
3519 else
3520 fallback_ext_u(r0, r1, i0, i1);
3521}
3522
3523static void
3524_depr(jit_state_t *_jit,
3525 jit_int32_t r0, jit_int32_t r1, jit_word_t i0, jit_word_t i1)
3526{
3527 assert(i0 >= 0 && i1 >= 1 && i0 + i1 <= __WORDSIZE);
3528 if (jit_mips2_p()) {
3529 if (i1 == __WORDSIZE)
3530 movr(r0, r1);
3531 else {
3532# if __BYTE_ORDER == __BIG_ENDIAN
3533 i0 = __WORDSIZE - (i0 + i1);
3534# endif
3535#if __WORDSIZE == 32
3536 INS(r0, r1, i0, i1);
3537#else
3538 if (i0 < 32 && i1 <= 32 && (i0 + i1) <= 32)
3539 DINS(r0, r1, i0, i1);
3540 else if (i0 < 32 && i1 >= 2 && (i0 + i1) > 32)
3541 DINSM(r0, r1, i0, i1);
3542 else {
3543 assert(i0 >= 32 && i1 >= 1 && i1 <= 32 && (i0 + i1) > 32);
3544 DINSU(r0, r1, i0, i1);
3545 }
3546#endif
3547 }
3548 }
3549 else
3550 fallback_dep(r0, r1, i0, i1);
3551}
3552
4a71579b
PC
3553static void
3554_extr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
3555{
3556 if (jit_mips2_p())
3557 SEB(r0, r1);
3558 else {
3559 lshi(r0, r1, __WORDSIZE - 8);
3560 rshi(r0, r0, __WORDSIZE - 8);
3561 }
3562}
3563
3564static void
3565_extr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
3566{
3567 if (jit_mips2_p())
3568 SEH(r0, r1);
3569 else {
3570 lshi(r0, r1, __WORDSIZE - 16);
3571 rshi(r0, r0, __WORDSIZE - 16);
3572 }
3573}
3574
3575# if __WORDSIZE == 64
3576static void
3577_extr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
3578{
40a44dcb
PC
3579 if (jit_mips2_p())
3580 DEXT(r0, r1, 0, 32);
3581 else {
3582 lshi(r0, r1, 32);
3583 rshi_u(r0, r0, 32);
3584 }
4a71579b
PC
3585}
3586# endif
3587
3588static void
3589_lti(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
3590{
3591 jit_int32_t reg;
3592
3593 if (can_sign_extend_short_p(i0))
3594 SLTI(r0, r1, i0);
3595 else {
3596 reg = jit_get_reg(jit_class_gpr);
3597 movi(rn(reg), i0);
3598 ltr(r0, r1, rn(reg));
3599 jit_unget_reg(reg);
3600 }
3601}
3602
3603static void
3604_lti_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
3605{
3606 jit_int32_t reg;
3607
3608 if (can_sign_extend_short_p(i0))
3609 SLTIU(r0, r1, i0);
3610 else {
3611 reg = jit_get_reg(jit_class_gpr);
3612 movi(rn(reg), i0);
3613 ltr_u(r0, r1, rn(reg));
3614 jit_unget_reg(reg);
3615 }
3616}
3617
3618static void
3619_ler(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
3620{
3621 SLT(r0, r2, r1);
3622 XORI(r0, r0, 1);
3623}
3624
3625static void
3626_lei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
3627{
3628 jit_int32_t reg;
3629
40a44dcb
PC
3630 if (can_sign_extend_short_p(i0 + 1))
3631 SLTI(r0, r1, i0 + 1);
4a71579b
PC
3632 else {
3633 reg = jit_get_reg(jit_class_gpr);
3634 movi(rn(reg), i0);
3635 ler(r0, r1, rn(reg));
3636 jit_unget_reg(reg);
3637 }
3638}
3639
3640static void
3641_ler_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
3642{
3643 SLTU(r0, r2, r1);
3644 XORI(r0, r0, 1);
3645}
3646
3647static void
3648_lei_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
3649{
3650 jit_int32_t reg;
3651
40a44dcb
PC
3652 if (can_sign_extend_short_p(i0 + 1))
3653 SLTIU(r0, r1, i0 + 1);
4a71579b
PC
3654 else {
3655 reg = jit_get_reg(jit_class_gpr);
3656 movi(rn(reg), i0);
3657 ler_u(r0, r1, rn(reg));
3658 jit_unget_reg(reg);
3659 }
3660}
3661
3662static void
3663_eqr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
3664{
3665 subr(r0, r1, r2);
79bfeef6 3666 SLTIU(r0, r0, 1);
4a71579b
PC
3667}
3668
3669static void
3670_eqi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
3671{
3672 if (i0) {
3673 subi(r0, r1, i0);
79bfeef6
PC
3674 SLTIU(r0, r0, 1);
3675 } else {
3676 SLTIU(r0, r1, 1);
4a71579b 3677 }
4a71579b
PC
3678}
3679
3680static void
3681_ger(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
3682{
3683 SLT(r0, r1, r2);
3684 XORI(r0, r0, 1);
3685}
3686
3687static void
3688_gei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
3689{
3690 jit_int32_t reg;
3691
40a44dcb
PC
3692 if (can_sign_extend_short_p(i0)) {
3693 SLTI(r0, r1, i0);
3694 XORI(r0, r0, 1);
3695 } else {
3696 reg = jit_get_reg(jit_class_gpr);
3697 movi(rn(reg), i0);
3698 ger(r0, r1, rn(reg));
3699 jit_unget_reg(reg);
3700 }
4a71579b
PC
3701}
3702
3703static void
3704_ger_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
3705{
3706 SLTU(r0, r1, r2);
3707 XORI(r0, r0, 1);
3708}
3709
3710static void
3711_gei_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
3712{
3713 jit_int32_t reg;
3714
40a44dcb
PC
3715 if (can_sign_extend_short_p(i0)) {
3716 SLTIU(r0, r1, i0);
3717 XORI(r0, r0, 1);
3718 } else {
3719 reg = jit_get_reg(jit_class_gpr);
3720 movi(rn(reg), i0);
3721 ger_u(r0, r1, rn(reg));
3722 jit_unget_reg(reg);
3723 }
4a71579b
PC
3724}
3725
3726static void
3727_gti(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
3728{
3729 jit_int32_t reg;
3730
3731 if (i0 == 0)
3732 SLT(r0, _ZERO_REGNO, r1);
3733 else {
3734 reg = jit_get_reg(jit_class_gpr);
3735 movi(rn(reg), i0);
3736 SLT(r0, rn(reg), r1);
3737 jit_unget_reg(reg);
3738 }
3739}
3740
3741static void
3742_gti_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
3743{
3744 jit_int32_t reg;
3745
3746 if (i0 == 0)
3747 SLTU(r0, _ZERO_REGNO, r1);
3748 else {
3749 reg = jit_get_reg(jit_class_gpr);
3750 movi(rn(reg), i0);
3751 SLTU(r0, rn(reg), r1);
3752 jit_unget_reg(reg);
3753 }
3754}
3755
3756static void
3757_ner(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
3758{
3759 subr(r0, r1, r2);
3760 SLTU(r0, _ZERO_REGNO, r0);
3761}
3762
3763static void
3764_nei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
3765{
3766 if (i0) {
3767 subi(r0, r1, i0);
3768 SLTU(r0, _ZERO_REGNO, r0);
3769 }
3770 else
3771 SLTU(r0, _ZERO_REGNO, r1);
3772}
3773
3774static jit_word_t
79bfeef6 3775_beqr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
4a71579b
PC
3776{
3777 jit_word_t w;
79bfeef6
PC
3778 jit_int32_t op, reg;
3779 /* Just to not move incorrectly instruction to delay slot */
3780 reg = jit_get_reg_for_delay_slot(jit_class_gpr|jit_class_chk, r0, r1);
3781 op = pending();
3782 /* implicit flush() */
4a71579b
PC
3783 w = _jit->pc.w;
3784 BEQ(r0, r1, ((i0 - w) >> 2) - 1);
79bfeef6
PC
3785 delay(op);
3786 if (reg != JIT_NOREG)
3787 jit_unget_reg(reg);
4a71579b
PC
3788 return (w);
3789}
3790
3791static jit_word_t
3792_beqi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
3793{
3794 jit_word_t w;
79bfeef6
PC
3795 jit_int32_t op, reg;
3796 if (i1 == 0)
3797 w = beqr(i0, r0, _ZERO_REGNO);
4a71579b 3798 else {
79bfeef6
PC
3799 reg = jit_get_reg_for_delay_slot(jit_class_gpr, r0, _ZERO_REGNO);
3800 op = pending();
4a71579b 3801 movi(rn(reg), i1);
79bfeef6
PC
3802 flush();
3803 w = _jit->pc.w;
3804 BEQ(r0, rn(reg), ((i0 - w) >> 2) - 1);
3805 delay(op);
4a71579b
PC
3806 jit_unget_reg(reg);
3807 }
4a71579b
PC
3808 return (w);
3809}
3810
3811static jit_word_t
79bfeef6
PC
3812_bger(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1,
3813 jit_bool_t sltu)
4a71579b
PC
3814{
3815 jit_word_t w;
79bfeef6
PC
3816 jit_int32_t op, reg;
3817 reg = jit_get_reg_for_delay_slot(jit_class_gpr, r0, r1);
3818 op = pending();
3819 if (sltu)
3820 SLTU(rn(reg), r0, r1);
3821 else
3822 SLT(rn(reg), r0, r1);
3823 flush();
4a71579b
PC
3824 w = _jit->pc.w;
3825 BEQ(rn(reg), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
79bfeef6 3826 delay(op);
4a71579b 3827 jit_unget_reg(reg);
4a71579b
PC
3828 return (w);
3829}
3830
3831static jit_word_t
79bfeef6
PC
3832_bgei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1,
3833 jit_bool_t sltiu, jit_bool_t bne)
4a71579b
PC
3834{
3835 jit_word_t w;
3836 jit_word_t d;
4a71579b 3837 jit_bool_t zero_p;
79bfeef6
PC
3838 jit_int32_t op, t0, mask;
3839 zero_p = !sltiu && i1 == 0;
3840 /* Even if zero_p allocate one as a mean to avoid incorrect delay slot */
3841 mask = jit_class_gpr;
3842 if (zero_p)
3843 mask |= jit_class_chk;
3844 t0 = jit_get_reg_for_delay_slot(mask, r0, _ZERO_REGNO);
4a71579b 3845 if (can_sign_extend_short_p(i1)) {
79bfeef6
PC
3846 op = pending();
3847 if (!zero_p) {
3848 if (sltiu)
3849 SLTIU(rn(t0), r0, i1);
3850 else
3851 SLTI(rn(t0), r0, i1);
3852 }
3853 flush();
4a71579b
PC
3854 w = _jit->pc.w;
3855 d = ((i0 - w) >> 2) - 1;
79bfeef6
PC
3856 if (bne) {
3857 if (!zero_p)
3858 BNE(rn(t0), _ZERO_REGNO, d);
3859 else
3860 BLTZ(r0, d);
3861 }
3862 else {
3863 if (!zero_p)
3864 BEQ(rn(t0), _ZERO_REGNO, d);
3865 else
3866 BGEZ(r0, d);
3867 }
4a71579b
PC
3868 }
3869 else {
79bfeef6
PC
3870 op = pending();
3871 movi(rn(t0), i1);
3872 if (sltiu)
3873 SLTU(rn(t0), r0, rn(t0));
3874 else
3875 SLT(rn(t0), r0, rn(t0));
3876 flush();
4a71579b 3877 w = _jit->pc.w;
79bfeef6
PC
3878 if (bne)
3879 BNE(rn(t0), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
3880 else
3881 BEQ(rn(t0), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
4a71579b 3882 }
79bfeef6
PC
3883 delay(op);
3884 if (t0 != JIT_NOREG)
3885 jit_unget_reg(t0);
4a71579b
PC
3886 return (w);
3887}
3888
3889static jit_word_t
79bfeef6
PC
3890_bgtr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1,
3891 jit_bool_t sltu, jit_bool_t inv)
4a71579b
PC
3892{
3893 jit_word_t w;
79bfeef6
PC
3894 jit_int32_t op, reg;
3895 reg = jit_get_reg_for_delay_slot(jit_class_gpr, r0, r1);
3896 op = pending();
3897 if (sltu)
3898 SLTU(rn(reg), r1, r0);
3899 else
3900 SLT(rn(reg), r1, r0);
3901 flush();
4a71579b 3902 w = _jit->pc.w;
79bfeef6
PC
3903 if (inv)
3904 BEQ(rn(reg), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
3905 else
3906 BNE(rn(reg), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
3907 delay(op);
4a71579b 3908 jit_unget_reg(reg);
4a71579b
PC
3909 return (w);
3910}
3911
3912static jit_word_t
79bfeef6
PC
3913_bgti(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1,
3914 jit_bool_t sltiu, jit_bool_t inv)
4a71579b
PC
3915{
3916 jit_word_t w;
79bfeef6
PC
3917 jit_int32_t op, t0, mask;
3918 mask = jit_class_gpr;
3919 if (i0 == 0)
3920 mask |= jit_class_chk;
3921 /* Allocate even if i0 == 0 as a way to avoid incorrect delay slot */
3922 t0 = jit_get_reg_for_delay_slot(mask, r0, _ZERO_REGNO);
4a71579b 3923 if (i1 == 0) {
79bfeef6
PC
3924 op = pending();
3925 /* implicit flush() */
4a71579b 3926 w = _jit->pc.w;
79bfeef6
PC
3927 if (inv) {
3928 if (sltiu)
3929 BEQ(r0, _ZERO_REGNO, ((i0 - w) >> 2) - 1);
3930 else
3931 BLEZ(r0, ((i0 - w) >> 2) - 1);
3932 }
3933 else {
3934 if (sltiu)
3935 BNE(r0, _ZERO_REGNO, ((i0 - w) >> 2) - 1);
3936 else
3937 BGTZ(r0, ((i0 - w) >> 2) - 1);
3938 }
4a71579b
PC
3939 }
3940 else {
79bfeef6
PC
3941 op = pending();
3942 movi(rn(t0), i1);
3943 if (sltiu)
3944 SLTU(rn(t0), rn(t0), r0);
3945 else
3946 SLT(rn(t0), rn(t0), r0);
3947 flush();
4a71579b 3948 w = _jit->pc.w;
79bfeef6
PC
3949 if (inv)
3950 BEQ(rn(t0), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
3951 else
3952 BNE(rn(t0), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
4a71579b 3953 }
79bfeef6
PC
3954 delay(op);
3955 if (t0 != JIT_NOREG)
3956 jit_unget_reg(t0);
4a71579b
PC
3957 return (w);
3958}
3959
3960static jit_word_t
3961_bner(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
3962{
3963 jit_word_t w;
79bfeef6
PC
3964 jit_int32_t op, reg;
3965 /* Just to not move incorrectly instruction to delay slot */
3966 reg = jit_get_reg_for_delay_slot(jit_class_gpr|jit_class_chk, r0, r1);
3967 op = pending();
3968 /* implicit flush() */
4a71579b
PC
3969 w = _jit->pc.w;
3970 BNE(r0, r1, ((i0 - w) >> 2) - 1);
79bfeef6
PC
3971 delay(op);
3972 if (reg != JIT_NOREG)
3973 jit_unget_reg(reg);
4a71579b
PC
3974 return (w);
3975}
3976
3977static jit_word_t
3978_bnei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
3979{
3980 jit_word_t w;
79bfeef6
PC
3981 jit_int32_t op, reg;
3982 if (i1 == 0)
3983 w = bner(i0, r0, _ZERO_REGNO);
4a71579b 3984 else {
79bfeef6
PC
3985 reg = jit_get_reg_for_delay_slot(jit_class_gpr, r0, _ZERO_REGNO);
3986 op = pending();
4a71579b 3987 movi(rn(reg), i1);
79bfeef6
PC
3988 flush();
3989 w = _jit->pc.w;
3990 BNE(r0, rn(reg), ((i0 - w) >> 2) - 1);
3991 delay(op);
4a71579b
PC
3992 jit_unget_reg(reg);
3993 }
4a71579b
PC
3994 return (w);
3995}
3996
3997static void
3998_jmpr(jit_state_t *_jit, jit_int32_t r0)
3999{
79bfeef6
PC
4000 jit_int32_t op, t0;
4001 /* make sure delay slot does not use r0 */
4002 t0 = jit_get_reg_for_delay_slot(jit_class_gpr|jit_class_chk,
4003 r0, _ZERO_REGNO);
4004 op = pending();
4a71579b 4005 JR(r0);
79bfeef6
PC
4006 delay(op);
4007 if (t0 != JIT_NOREG)
4008 jit_unget_reg(t0);
4a71579b
PC
4009}
4010
4011static jit_word_t
79bfeef6
PC
4012_jmpi(jit_state_t *_jit, jit_word_t i0, jit_bool_t patch)
4013{
4014 jit_int32_t op, t0;
4015 jit_word_t w, disp;
ba86ff93
PC
4016#if !BALC_BROKEN
4017 if (jit_mips6_p() && !(i0 & 3)) {
4018 disp = ((i0 - (_jit->pc.w + (_jitc->inst.pend ? 4 : 0))) >> 2) - 1;
4019 if (patch || can_sign_extend_i26_p(disp)) {
4020 flush();
4021 w = _jit->pc.w;
4022 /* Compact branch instructions do not have a delay slot */
4023 BC_R6(disp);
4024 goto done_without_delay;
4025 }
4026 }
4027#endif
79bfeef6
PC
4028 /* try to get a pending instruction before the jump */
4029 t0 = jit_get_reg_for_delay_slot(jit_class_gpr, _ZERO_REGNO, _ZERO_REGNO);
4030 op = pending();
4031 /* implicit flush() */
4a71579b 4032 w = _jit->pc.w;
79bfeef6
PC
4033 if (jit_mips2_p()) {
4034 disp = ((i0 - w) >> 2) - 1;
4035 if (patch || can_sign_extend_short_p(disp)) {
4036 BEQ(_ZERO_REGNO, _ZERO_REGNO, disp);
4037 goto done;
4038 }
4a71579b 4039 }
79bfeef6
PC
4040 if (((w + sizeof(jit_int32_t)) & 0xf0000000) == (i0 & 0xf0000000))
4041 J((i0 & ~0xf0000000) >> 2);
4a71579b 4042 else {
79bfeef6
PC
4043 if (patch)
4044 w = movi_p(rn(t0), i0);
4045 else
4046 movi(rn(t0), i0);
4047 JR(rn(t0));
4a71579b 4048 }
79bfeef6
PC
4049done:
4050 delay(op);
4051 jit_unget_reg(t0);
ba86ff93
PC
4052#if !BALC_BROKEN
4053done_without_delay:
4054#endif
79bfeef6
PC
4055 return (w);
4056}
4a71579b 4057
79bfeef6
PC
4058static jit_word_t
4059_jmpi_p(jit_state_t *_jit, jit_word_t i0)
4060{
4061 jit_word_t w;
4062 jit_int32_t op, t0;
ba86ff93
PC
4063 /* Get a register without side effects in delay slot */
4064 t0 = jit_get_reg_for_delay_slot(jit_class_gpr, _ZERO_REGNO, _ZERO_REGNO);
4065 /* Check for a instruction that can be executed in the delay slot */
79bfeef6
PC
4066 op = pending();
4067 /* implicit flush() */
4068 w = _jit->pc.w;
4069 movi_p(rn(t0), i0);
4070 flush(); /* movi_p will be patched */
4071 JR(rn(t0));
4072 delay(op);
ba86ff93 4073 jit_unget_reg(t0);
4a71579b
PC
4074 return (w);
4075}
4076
4077static jit_word_t
4078_boaddr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
4079{
4080 jit_word_t w;
4081 jit_int32_t t0;
4082 jit_int32_t t1;
4083 jit_int32_t t2;
4084
4085 /* t1 = r0 + r1; overflow = r1 < 0 ? r0 < t1 : t1 < r0 */
4086 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4087 t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4088 t2 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4089 SLT(rn(t0), r1, _ZERO_REGNO); /* t0 = r1 < 0 */
4090 addr(rn(t1), r0, r1); /* t1 = r0 + r1 */
4091 SLT(rn(t2), rn(t1), r0); /* t2 = t1 < r0 */
4092 SLT(rn(t1), r0, rn(t1)); /* t1 = r0 < t1 */
79bfeef6
PC
4093 movzr(rn(t1), rn(t2), rn(t0)); /* if (r0 == 0) t1 = t2 */
4094 /* cannot optimize delay slot */
4095 flush();
4a71579b
PC
4096 w = _jit->pc.w;
4097 BNE(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
4098 /* delay slot */
4099 addr(r0, r0, r1);
79bfeef6 4100 flush();
4a71579b
PC
4101 jit_unget_reg(t2);
4102 jit_unget_reg(t1);
4103 jit_unget_reg(t0);
4104
4105 return (w);
4106}
4107
4108static jit_word_t
4109_boaddi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
4110{
4111 jit_word_t w;
4112 jit_int32_t t0;
4113 jit_int32_t t1;
4114 jit_int32_t t2;
4115
4116 if (can_sign_extend_short_p(i1)) {
4117 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4118 t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4119 t2 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4120 SLTI(rn(t0), _ZERO_REGNO, i1);
4121 addiu(rn(t1), r0, i1);
4122 SLT(rn(t2), r0, rn(t1));
4123 SLT(rn(t1), rn(t1), r0);
79bfeef6
PC
4124 movzr(rn(t1), rn(t2), rn(t0));
4125 /* cannot optimize delay slot */
4126 flush();
4a71579b
PC
4127 w = _jit->pc.w;
4128 BNE(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
4129 /* delay slot */
4130 addiu(r0, r0, i1);
79bfeef6 4131 flush();
4a71579b
PC
4132 jit_unget_reg(t2);
4133 jit_unget_reg(t1);
4134 jit_unget_reg(t0);
4135 }
4136 else {
4137 t0 = jit_get_reg(jit_class_gpr);
4138 movi(rn(t0), i1);
4139 w = boaddr(i0, r0, rn(t0));
4140 jit_unget_reg(t0);
4141 }
4142 return (w);
4143}
4144
4145static jit_word_t
4146_boaddr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
4147{
4148 jit_word_t w;
4149 jit_int32_t t0;
4150 jit_int32_t t1;
4151
4152 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4153 t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4154 addr(rn(t0), r0, r1);
4155 SLTU(rn(t1), rn(t0), r0);
79bfeef6
PC
4156 flush();
4157 /* cannot optimize delay slot */
4a71579b
PC
4158 w = _jit->pc.w;
4159 BNE(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1);
4160 /* delay slot */
4161 movr(r0, rn(t0));
79bfeef6 4162 flush();
4a71579b
PC
4163 jit_unget_reg(t1);
4164 jit_unget_reg(t0);
4165 return (w);
4166}
4167
4168static jit_word_t
4169_boaddi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
4170{
4171 jit_word_t w;
4172 jit_int32_t t0;
4173 jit_int32_t t1;
4174
4175 if (can_sign_extend_short_p(i0)) {
4176 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4177 t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4178 addiu(rn(t0), r0, i1);
4179 SLTU(rn(t1), rn(t0), r0);
79bfeef6
PC
4180 flush();
4181 /* cannot optimize delay slot */
4a71579b
PC
4182 w = _jit->pc.w;
4183 BNE(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1);
4184 /* delay slot */
4185 movr(r0, rn(t0));
79bfeef6 4186 flush();
4a71579b
PC
4187 jit_unget_reg(t1);
4188 jit_unget_reg(t0);
4189 }
4190 else {
4191 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4192 movi(rn(t0), i1);
4193 w = boaddr_u(i0, r0, rn(t0));
4194 jit_unget_reg(t0);
4195 }
4196 return (w);
4197}
4198
4199static jit_word_t
4200_bxaddr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
4201{
4202 jit_word_t w;
4203 jit_int32_t t0;
4204 jit_int32_t t1;
4205 jit_int32_t t2;
4206
4207 /* t1 = r0 + r1; overflow = r1 < 0 ? r0 < t1 : t1 < r0 */
4208 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4209 t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4210 t2 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4211 SLT(rn(t0), r1, _ZERO_REGNO); /* t0 = r1 < 0 */
4212 addr(rn(t1), r0, r1); /* t1 = r0 + r1 */
4213 SLT(rn(t2), rn(t1), r0); /* t2 = t1 < r0 */
4214 SLT(rn(t1), r0, rn(t1)); /* t1 = r0 < t1 */
79bfeef6
PC
4215 movzr(rn(t1), rn(t2), rn(t0)); /* if (r0 == 0) t1 = t2 */
4216 /* cannot optimize delay slot */
4217 flush();
4a71579b
PC
4218 w = _jit->pc.w;
4219 BEQ(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
4220 /* delay slot */
4221 addr(r0, r0, r1);
79bfeef6 4222 flush();
4a71579b
PC
4223 jit_unget_reg(t2);
4224 jit_unget_reg(t1);
4225 jit_unget_reg(t0);
4226
4227 return (w);
4228}
4229
4230static jit_word_t
4231_bxaddi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
4232{
4233 jit_word_t w;
4234 jit_int32_t t0;
4235 jit_int32_t t1;
4236 jit_int32_t t2;
4237
4238 if (can_sign_extend_short_p(i1)) {
4239 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4240 t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4241 t2 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4242 SLTI(rn(t0), _ZERO_REGNO, i1);
4243 addiu(rn(t1), r0, i1);
4244 SLT(rn(t2), r0, rn(t1));
4245 SLT(rn(t1), rn(t1), r0);
79bfeef6
PC
4246 movzr(rn(t1), rn(t2), rn(t0));
4247 /* cannot optimize delay slot */
4248 flush();
4a71579b
PC
4249 w = _jit->pc.w;
4250 BEQ(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
4251 /* delay slot */
4252 addiu(r0, r0, i1);
79bfeef6 4253 flush();
4a71579b
PC
4254 jit_unget_reg(t2);
4255 jit_unget_reg(t1);
4256 jit_unget_reg(t0);
4257 }
4258 else {
4259 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4260 movi(rn(t0), i1);
4261 w = bxaddr(i0, r0, rn(t0));
4262 jit_unget_reg(t0);
4263 }
4264 return (w);
4265}
4266
4267static jit_word_t
4268_bxaddr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
4269{
4270 jit_word_t w;
4271 jit_int32_t t0;
4272 jit_int32_t t1;
4273
4274 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4275 t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4276 addr(rn(t0), r0, r1);
4277 SLTU(rn(t1), rn(t0), r0);
79bfeef6
PC
4278 /* cannot optimize delay slot */
4279 flush();
4a71579b
PC
4280 w = _jit->pc.w;
4281 BEQ(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1);
4282 /* delay slot */
4283 movr(r0, rn(t0));
79bfeef6 4284 flush();
4a71579b
PC
4285 jit_unget_reg(t1);
4286 jit_unget_reg(t0);
4287 return (w);
4288}
4289
4290static jit_word_t
4291_bxaddi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
4292{
4293 jit_word_t w;
4294 jit_int32_t t0;
4295 jit_int32_t t1;
4296
4297 if (can_sign_extend_short_p(i0)) {
4298 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4299 t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4300 addiu(rn(t0), r0, i1);
4301 SLTU(rn(t1), rn(t0), r0);
79bfeef6
PC
4302 /* cannot optimize delay slot */
4303 flush();
4a71579b
PC
4304 w = _jit->pc.w;
4305 BEQ(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1);
4306 /* delay slot */
4307 movr(r0, rn(t0));
79bfeef6 4308 flush();
4a71579b
PC
4309 jit_unget_reg(t1);
4310 jit_unget_reg(t0);
4311 }
4312 else {
4313 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4314 movi(rn(t0), i1);
4315 w = bxaddr_u(i0, r0, rn(t0));
4316 jit_unget_reg(t0);
4317 }
4318 return (w);
4319}
4320
4321static jit_word_t
4322_bosubr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
4323{
4324 jit_word_t w;
4325 jit_int32_t t0;
4326 jit_int32_t t1;
4327 jit_int32_t t2;
4328
4329 /* t1 = r0 - r1; overflow = 0 < r1 ? r0 < t1 : t1 < r0 */
4330 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4331 t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4332 t2 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4333 SLT(rn(t0), _ZERO_REGNO, r1); /* t0 = 0 < r1 */
4334 subr(rn(t1), r0, r1); /* t1 = r0 - r1 */
4335 SLT(rn(t2), rn(t1), r0); /* t2 = t1 < r0 */
4336 SLT(rn(t1), r0, rn(t1)); /* t1 = r0 < t1 */
79bfeef6
PC
4337 movzr(rn(t1), rn(t2), rn(t0)); /* if (r0 == 0) t1 = t2 */
4338 flush();
4a71579b
PC
4339 w = _jit->pc.w;
4340 BNE(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
4341 /* delay slot */
4342 subr(r0, r0, r1);
79bfeef6 4343 flush();
4a71579b
PC
4344 jit_unget_reg(t2);
4345 jit_unget_reg(t1);
4346 jit_unget_reg(t0);
4347
4348 return (w);
4349}
4350
4351static jit_word_t
4352_bosubi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
4353{
4354 jit_word_t w;
4355 jit_int32_t t0;
4356 jit_int32_t t1;
4357 jit_int32_t t2;
4358
4359 if (can_sign_extend_short_p(i1) && (i1 & 0xffff) != 0x8000) {
4360 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4361 t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4362 t2 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4363 SLTI(rn(t0), _ZERO_REGNO, i1);
4364 addiu(rn(t1), r0, -i1);
4365 SLT(rn(t2), rn(t1), r0);
4366 SLT(rn(t1), r0, rn(t1));
79bfeef6
PC
4367 movzr(rn(t1), rn(t2), rn(t0));
4368 flush();
4a71579b
PC
4369 w = _jit->pc.w;
4370 BNE(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
4371 /* delay slot */
4372 addiu(r0, r0, -i1);
79bfeef6 4373 flush();
4a71579b
PC
4374 jit_unget_reg(t2);
4375 jit_unget_reg(t1);
4376 jit_unget_reg(t0);
4377 }
4378 else {
4379 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4380 movi(rn(t0), i1);
4381 w = bosubr(i0, r0, rn(t0));
4382 jit_unget_reg(t0);
4383 }
4384 return (w);
4385}
4386
4387static jit_word_t
4388_bosubr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
4389{
4390 jit_word_t w;
4391 jit_int32_t t0;
4392 jit_int32_t t1;
4393
4394 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4395 t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4396 subr(rn(t0), r0, r1);
4397 SLTU(rn(t1), r0, rn(t0));
79bfeef6
PC
4398 /* cannot optimize delay slot */
4399 flush();
4a71579b
PC
4400 w = _jit->pc.w;
4401 BNE(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1);
4402 /* delay slot */
4403 movr(r0, rn(t0));
79bfeef6 4404 flush();
4a71579b
PC
4405 jit_unget_reg(t1);
4406 jit_unget_reg(t0);
4407 return (w);
4408}
4409
4410static jit_word_t
4411_bosubi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
4412{
4413 jit_word_t w;
4414 jit_int32_t t0;
4415 jit_int32_t t1;
4416
4417 if (can_sign_extend_short_p(i0) && (i0 & 0xffff) != 0x8000) {
4418 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4419 t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4420 addiu(rn(t0), r0, -i1);
4421 SLTU(rn(t1), r0, rn(t0));
79bfeef6
PC
4422 /* cannot optimize delay slot */
4423 flush();
4a71579b
PC
4424 w = _jit->pc.w;
4425 BNE(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1);
4426 /* delay slot */
4427 movr(r0, rn(t0));
79bfeef6 4428 flush();
4a71579b
PC
4429 jit_unget_reg(t1);
4430 jit_unget_reg(t0);
4431 }
4432 else {
4433 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4434 movi(rn(t0), i1);
4435 w = bosubr_u(i0, r0, rn(t0));
4436 jit_unget_reg(t0);
4437 }
4438 return (w);
4439}
4440
4441static jit_word_t
4442_bxsubr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
4443{
4444 jit_word_t w;
4445 jit_int32_t t0;
4446 jit_int32_t t1;
4447 jit_int32_t t2;
4448
4449 /* t1 = r0 - r1; overflow = 0 < r1 ? r0 < t1 : t1 < r0 */
4450 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4451 t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4452 t2 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4453 SLT(rn(t0), _ZERO_REGNO, r1); /* t0 = 0 < r1 */
4454 subr(rn(t1), r0, r1); /* t1 = r0 - r1 */
4455 SLT(rn(t2), rn(t1), r0); /* t2 = t1 < r0 */
4456 SLT(rn(t1), r0, rn(t1)); /* t1 = r0 < t1 */
79bfeef6
PC
4457 movzr(rn(t1), rn(t2), rn(t0)); /* if (t0 == 0) t1 = t2 */
4458 /* cannot optimize delay slot */
4459 flush();
4a71579b
PC
4460 w = _jit->pc.w;
4461 BEQ(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
4462 /* delay slot */
4463 subr(r0, r0, r1);
79bfeef6 4464 flush();
4a71579b
PC
4465 jit_unget_reg(t2);
4466 jit_unget_reg(t1);
4467 jit_unget_reg(t0);
4468
4469 return (w);
4470}
4471
4472static jit_word_t
4473_bxsubi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
4474{
4475 jit_word_t w;
4476 jit_int32_t t0;
4477 jit_int32_t t1;
4478 jit_int32_t t2;
4479
4480 if (can_sign_extend_short_p(i1) && (i1 & 0xffff) != 0x8000) {
4481 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4482 t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4483 t2 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4484 SLTI(rn(t0), _ZERO_REGNO, i1);
4485 addiu(rn(t1), r0, -i1);
4486 SLT(rn(t2), rn(t1), r0);
4487 SLT(rn(t1), r0, rn(t1));
79bfeef6
PC
4488 movzr(rn(t1), rn(t2), rn(t0));
4489 /* cannot optimize delay slot */
4490 flush();
4a71579b
PC
4491 w = _jit->pc.w;
4492 BEQ(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
4493 /* delay slot */
4494 addiu(r0, r0, -i1);
79bfeef6 4495 flush();
4a71579b
PC
4496 jit_unget_reg(t2);
4497 jit_unget_reg(t1);
4498 jit_unget_reg(t0);
4499 }
4500 else {
4501 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4502 movi(rn(t0), i1);
4503 w = bxsubr(i0, r0, rn(t0));
4504 jit_unget_reg(t0);
4505 }
4506 return (w);
4507}
4508
4509static jit_word_t
4510_bxsubr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
4511{
4512 jit_word_t w;
4513 jit_int32_t t0;
4514 jit_int32_t t1;
4515
4516 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4517 t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4518 subr(rn(t0), r0, r1);
4519 SLTU(rn(t1), r0, rn(t0));
79bfeef6
PC
4520 /* cannot optimize delay slot */
4521 flush();
4a71579b
PC
4522 w = _jit->pc.w;
4523 BEQ(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1);
4524 /* delay slot */
4525 movr(r0, rn(t0));
79bfeef6 4526 flush();
4a71579b
PC
4527 jit_unget_reg(t1);
4528 jit_unget_reg(t0);
4529 return (w);
4530}
4531
4532static jit_word_t
4533_bxsubi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
4534{
4535 jit_word_t w;
4536 jit_int32_t t0;
4537 jit_int32_t t1;
4538
4539 if (can_sign_extend_short_p(i0) && (i0 & 0xffff) != 0x8000) {
4540 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4541 t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4542 addiu(rn(t0), r0, -i1);
4543 SLTU(rn(t1), r0, rn(t0));
79bfeef6
PC
4544 /* cannot optimize delay slot */
4545 flush();
4a71579b
PC
4546 w = _jit->pc.w;
4547 BEQ(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1);
4548 /* delay slot */
4549 movr(r0, rn(t0));
79bfeef6 4550 flush();
4a71579b
PC
4551 jit_unget_reg(t1);
4552 jit_unget_reg(t0);
4553 }
4554 else {
4555 t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
4556 movi(rn(t0), i1);
4557 w = bxsubr_u(i0, r0, rn(t0));
4558 jit_unget_reg(t0);
4559 }
4560 return (w);
4561}
4562
4563static jit_word_t
4564_bmsr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
4565{
4566 jit_word_t w;
79bfeef6
PC
4567 jit_int32_t op, t0;
4568 t0 = jit_get_reg_for_delay_slot(jit_class_gpr, r0, r1);
4569 op = pending();
4a71579b 4570 AND(rn(t0), r0, r1);
79bfeef6 4571 flush();
4a71579b
PC
4572 w = _jit->pc.w;
4573 BNE(_ZERO_REGNO, rn(t0), ((i0 - w) >> 2) - 1);
79bfeef6 4574 delay(op);
4a71579b
PC
4575 jit_unget_reg(t0);
4576 return (w);
4577}
4578
4579static jit_word_t
4580_bmsi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
4581{
4582 jit_word_t w;
79bfeef6
PC
4583 jit_int32_t op, t0;
4584 t0 = jit_get_reg_for_delay_slot(jit_class_gpr, r0, _ZERO_REGNO);
4585 op = pending();
40a44dcb 4586 andi(rn(t0), r0, i1);
79bfeef6 4587 flush();
40a44dcb
PC
4588 w = _jit->pc.w;
4589 BNE(_ZERO_REGNO, rn(t0), ((i0 - w) >> 2) - 1);
79bfeef6 4590 delay(op);
4a71579b
PC
4591 jit_unget_reg(t0);
4592 return (w);
4593}
4594
4595static jit_word_t
4596_bmcr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
4597{
4598 jit_word_t w;
79bfeef6
PC
4599 jit_int32_t op, t0;
4600 t0 = jit_get_reg_for_delay_slot(jit_class_gpr, r0, r1);
4601 op = pending();
4a71579b 4602 AND(rn(t0), r0, r1);
79bfeef6 4603 flush();
4a71579b
PC
4604 w = _jit->pc.w;
4605 BEQ(_ZERO_REGNO, rn(t0), ((i0 - w) >> 2) - 1);
79bfeef6 4606 delay(op);
4a71579b
PC
4607 jit_unget_reg(t0);
4608 return (w);
4609}
4610
4611static jit_word_t
4612_bmci(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
4613{
4614 jit_word_t w;
79bfeef6
PC
4615 jit_int32_t op, t0;
4616 t0 = jit_get_reg_for_delay_slot(jit_class_gpr, r0, _ZERO_REGNO);
4617 op = pending();
40a44dcb 4618 andi(rn(t0), r0, i1);
79bfeef6 4619 flush();
40a44dcb
PC
4620 w = _jit->pc.w;
4621 BEQ(_ZERO_REGNO, rn(t0), ((i0 - w) >> 2) - 1);
79bfeef6 4622 delay(op);
4a71579b
PC
4623 jit_unget_reg(t0);
4624 return (w);
4625}
4626
4627static void
4628_callr(jit_state_t *_jit, jit_int32_t r0)
4629{
79bfeef6
PC
4630 jit_int32_t op, t0;
4631 if (r0 != _T9_REGNO) {
4632 JALR(r0);
4633 /* delay slot */
4634 movr(_T9_REGNO, r0);
4635 flush();
4636 }
4637 else {
4638 /* make sure delay slot does not use r0 */
4639 t0 = jit_get_reg_for_delay_slot(jit_class_gpr|jit_class_chk,
4640 r0, _ZERO_REGNO);
4641 op = pending();
4642 JALR(r0);
4643 delay(op);
4644 if (t0 != JIT_NOREG)
4645 jit_unget_reg(t0);
4646 }
4a71579b
PC
4647}
4648
79bfeef6
PC
4649static jit_word_t
4650_calli(jit_state_t *_jit, jit_word_t i0, jit_bool_t patch)
4a71579b 4651{
79bfeef6
PC
4652 jit_int32_t op, t0;
4653 jit_word_t w, disp;
4654 w = _jit->pc.w;
ba86ff93
PC
4655#if !BALC_BROKEN
4656 if (jit_mips6_p() && !(i0 & 3)) {
4657 disp = ((i0 - (w + (_jitc->inst.pend ? 4 : 0))) >> 2) - 1;
4658 if (patch || can_sign_extend_i26_p(disp)) {
4659 flush();
4660 w = _jit->pc.w;
4661 /* Compact branch instructions do not have a delay slot */
4662 BALC(disp);
4663 goto done;
4664 }
4665 }
4666#endif
79bfeef6 4667 if (jit_mips2_p()) {
ba86ff93 4668 disp = ((i0 - (w + _jitc->inst.pend ? 4 : 0)) >> 2) - 1;
79bfeef6
PC
4669 if (patch || can_sign_extend_short_p(disp)) {
4670 op = pending();
4671 BGEZAL(_ZERO_REGNO, disp); /* Renamed to BAL in mips release 6 */
4672 delay(op);
4673 goto done;
4674 }
4675 }
4676 assert(!patch);
4677 flush();
4678 if (((w + sizeof(jit_int32_t)) & 0xf0000000) == (i0 & 0xf0000000)) {
4679 if (can_sign_extend_short_p(i0)) {
4680 JAL((i0 & ~0xf0000000) >> 2);
4681 /* delay slot */
4682 addiu(_T9_REGNO, _ZERO_REGNO, i0);
4683 }
4684 else if (can_zero_extend_short_p(i0)) {
4685 JAL((i0 & ~0xf0000000) >> 2);
4686 /* delay slot */
4687 ORI(_T9_REGNO, _ZERO_REGNO, i0);
ba3814c1 4688 }
79bfeef6
PC
4689 else if (can_sign_extend_int_p(i0)) {
4690 if (i0 & 0xffff) {
4691 LUI(_T9_REGNO, i0 >> 16);
4692 JAL((i0 & ~0xf0000000) >> 2);
4693 /* delay slot */
4694 ORI(_T9_REGNO, _T9_REGNO, i0);
ba3814c1 4695 }
79bfeef6
PC
4696 else {
4697 JAL((i0 & ~0xf0000000) >> 2);
4698 /* delay slot */
4699 LUI(_T9_REGNO, i0 >> 16);
4700 }
ba3814c1 4701 }
79bfeef6
PC
4702 else
4703 goto fallback;
ba3814c1 4704 }
79bfeef6
PC
4705 else {
4706 fallback:
4707 /* make sure delay slot does not use _T9_REGNO */
4708 t0 = jit_get_reg_for_delay_slot(jit_class_gpr|jit_class_chk,
4709 _T9_REGNO, _ZERO_REGNO);
4710 /* try to get an instruction before the call */
4711 op = pending();
4712 movi(_T9_REGNO, i0);
4713 JALR(_T9_REGNO);
4714 delay(op);
4715 if (t0 != JIT_NOREG)
4716 jit_unget_reg(t0);
4717 }
4718 done:
4719 return (w);
4a71579b
PC
4720}
4721
4722static jit_word_t
4723_calli_p(jit_state_t *_jit, jit_word_t i0)
4724{
4725 jit_word_t word;
79bfeef6
PC
4726 jit_int32_t op, t0;
4727 /* make sure delay slot does not use _T9_REGNO */
4728 t0 = jit_get_reg_for_delay_slot(jit_class_gpr|jit_class_chk,
4729 _T9_REGNO, _ZERO_REGNO);
4730 op = pending();
4731 /* implicit flush() */
4a71579b
PC
4732 word = _jit->pc.w;
4733 movi_p(_T9_REGNO, i0);
4734 JALR(_T9_REGNO);
79bfeef6
PC
4735 delay(op);
4736 if (t0 != JIT_NOREG)
4737 jit_unget_reg(t0);
4a71579b
PC
4738 return (word);
4739}
4740
4a71579b
PC
4741static void
4742_prolog(jit_state_t *_jit, jit_node_t *node)
4743{
79bfeef6 4744 jit_int32_t reg, offs;
4a71579b
PC
4745 if (_jitc->function->define_frame || _jitc->function->assume_frame) {
4746 jit_int32_t frame = -_jitc->function->frame;
79bfeef6 4747 jit_check_frame();
4a71579b
PC
4748 assert(_jitc->function->self.aoff >= frame);
4749 if (_jitc->function->assume_frame)
4750 return;
4751 _jitc->function->self.aoff = frame;
4752 }
4753 if (_jitc->function->allocar)
4754 _jitc->function->self.aoff &= -8;
4755#if NEW_ABI
4756 _jitc->function->stack = ((_jitc->function->self.alen -
4757 /* align stack at 16 bytes */
4758 _jitc->function->self.aoff) + 15) & -16;
4759#else
4760 _jitc->function->stack = ((/* first 16 bytes must be allocated */
4761 (_jitc->function->self.alen > 16 ?
4762 _jitc->function->self.alen : 16) -
4763 /* align stack at 8 bytes */
4764 _jitc->function->self.aoff) + 7) & -8;
4765#endif
79bfeef6 4766
4a71579b 4767#if NEW_ABI
79bfeef6
PC
4768 if (_jitc->function->stack)
4769 _jitc->function->need_stack = 1;
4770 if (!_jitc->function->need_frame && !_jitc->function->need_stack) {
4771 /* check if any callee save register needs to be saved */
4772 for (reg = 0; reg < _jitc->reglen; ++reg)
4773 if (jit_regset_tstbit(&_jitc->function->regset, reg) &&
4774 (_rvs[reg].spec & jit_class_sav)) {
4775 _jitc->function->need_stack = 1;
4776 break;
4777 }
4778 }
4779#else
4780 /* Need always a frame due to the need to always allocate 16 bytes */
4781 jit_check_frame();
4a71579b 4782#endif
79bfeef6
PC
4783
4784 if (_jitc->function->need_frame || _jitc->function->need_stack)
4785 subi(_SP_REGNO, _SP_REGNO, jit_framesize());
4786 if (_jitc->function->need_frame) {
4787 stxi(0, _SP_REGNO, _RA_REGNO);
4788 stxi(STACK_SLOT, _SP_REGNO, _BP_REGNO);
4789 }
4790 /* callee save registers */
4791 for (reg = 0, offs = STACK_SLOT << 1; reg < jit_size(iregs); reg++) {
4792 if (jit_regset_tstbit(&_jitc->function->regset, iregs[reg])) {
4793 stxi(offs, _SP_REGNO, rn(iregs[reg]));
4794 offs += STACK_SLOT;
4795 }
4796 }
4797 for (reg = 0; reg < jit_size(fregs); reg++) {
4798 if (jit_regset_tstbit(&_jitc->function->regset, fregs[reg])) {
4799 stxi_d(offs, _SP_REGNO, rn(fregs[reg]));
4800 offs += sizeof(jit_float64_t);
4801 }
4802 }
4803
4804 if (_jitc->function->need_frame)
4805 movr(_BP_REGNO, _SP_REGNO);
4a71579b
PC
4806
4807 /* alloca */
4808 if (_jitc->function->stack)
4809 subi(_SP_REGNO, _SP_REGNO, _jitc->function->stack);
4810 if (_jitc->function->allocar) {
79bfeef6
PC
4811 reg = jit_get_reg(jit_class_gpr);
4812 movi(rn(reg), _jitc->function->self.aoff);
4813 stxi_i(_jitc->function->aoffoff, _BP_REGNO, rn(reg));
4814 jit_unget_reg(reg);
4a71579b
PC
4815 }
4816
4817 if (_jitc->function->self.call & jit_call_varargs) {
79bfeef6
PC
4818 for (reg = _jitc->function->vagp; jit_arg_reg_p(reg); ++reg) {
4819 offs = jit_framesize() - ((NUM_WORD_ARGS - reg) * STACK_SLOT);
4a71579b 4820#if NEW_ABI
79bfeef6 4821 SD(rn(_A0 - reg), offs, _BP_REGNO);
4a71579b 4822#else
79bfeef6
PC
4823 offs += 16 + WORD_ADJUST;
4824 stxi(offs, _BP_REGNO, rn(_A0 - reg));
4a71579b
PC
4825#endif
4826 }
4827 }
4828}
4829
4830static void
4831_epilog(jit_state_t *_jit, jit_node_t *node)
4832{
79bfeef6 4833 jit_int32_t reg, offs;
4a71579b
PC
4834 if (_jitc->function->assume_frame)
4835 return;
79bfeef6
PC
4836
4837 if (_jitc->function->need_frame) {
4838 movr(_SP_REGNO, _BP_REGNO);
4839 ldxi(_RA_REGNO, _SP_REGNO, 0);
4840 ldxi(_BP_REGNO, _SP_REGNO, STACK_SLOT);
4841 }
4842
4a71579b 4843 /* callee save registers */
79bfeef6
PC
4844 for (reg = 0, offs = STACK_SLOT << 1; reg < jit_size(iregs); reg++) {
4845 if (jit_regset_tstbit(&_jitc->function->regset, iregs[reg])) {
4846 ldxi(rn(iregs[reg]), _SP_REGNO, offs);
4847 offs += sizeof(jit_word_t);
4848 }
4849 }
4850 for (reg = 0; reg < jit_size(fregs); reg++) {
4851 if (jit_regset_tstbit(&_jitc->function->regset, fregs[reg])) {
4852 ldxi_d(rn(fregs[reg]), _SP_REGNO, offs);
4853 offs += sizeof(jit_float64_t);
4854 }
4855 }
4a71579b
PC
4856 JR(_RA_REGNO);
4857 /* delay slot */
79bfeef6
PC
4858 if (_jitc->function->need_frame || _jitc->function->need_stack)
4859 addi(_SP_REGNO, _SP_REGNO, jit_framesize());
4a71579b 4860 else
79bfeef6
PC
4861 NOP(1);
4862 flush();
4a71579b
PC
4863}
4864
4865static void
4866_vastart(jit_state_t *_jit, jit_int32_t r0)
4867{
4868 assert(_jitc->function->self.call & jit_call_varargs);
4a71579b 4869#if NEW_ABI
79bfeef6 4870 /* Initialize va_list to the first stack argument. */
4a71579b 4871 if (jit_arg_reg_p(_jitc->function->vagp))
79bfeef6
PC
4872 addi(r0, _BP_REGNO,
4873 jit_framesize() -
4874 ((NUM_WORD_ARGS - _jitc->function->vagp) * STACK_SLOT));
4a71579b
PC
4875 else
4876#endif
79bfeef6 4877 addi(r0, _BP_REGNO, jit_selfsize());
4a71579b
PC
4878}
4879
4880static void
4881_vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
4882{
4883 /* Load argument. */
4884#if WORD_ADJUST
4885 ldxi(r0, r1, WORD_ADJUST);
4886#else
4887 ldr(r0, r1);
4888#endif
4889
4890 /* Update va_list. */
4891 addi(r1, r1, STACK_SLOT);
4892}
4893
4894static void
4895_patch_abs(jit_state_t *_jit, jit_word_t instr, jit_word_t label)
4896{
4897 jit_instr_t i;
4898 union {
4899 jit_int32_t *i;
4900 jit_word_t w;
4901 } u;
4902
4903 u.w = instr;
4904#if __WORDSIZE == 32
4905 i.op = u.i[0];
4906 assert(i.hc.b == MIPS_LUI);
4907 i.is.b = label >> 16;
4908 u.i[0] = i.op;
4909 i.op = u.i[1];
4910 assert(i.hc.b == MIPS_ORI);
4911 i.is.b = label;
4912 u.i[1] = i.op;
4913#else
4914 i.op = u.i[0];
4915 assert(i.hc.b == MIPS_LUI);
4916 i.is.b = label >> 48;
4917 u.i[0] = i.op;
4918 i.op = u.i[1];
4919 assert(i.hc.b == MIPS_ORI);
4920 i.is.b = label >> 32;
4921 u.i[1] = i.op;
4922 /* lshi */
4923 i.op = u.i[3];
4924 assert(i.hc.b == MIPS_ORI);
4925 i.is.b = label >> 16;
4926 u.i[3] = i.op;
4927 /* lshi */
4928 i.op = u.i[5];
4929 assert(i.hc.b == MIPS_ORI);
4930 i.is.b = label;
4931 u.i[5] = i.op;
4932#endif
4933}
4934
4935static void
4936_patch_at(jit_state_t *_jit, jit_word_t instr, jit_word_t label)
4937{
4938 jit_instr_t i;
4939 union {
4940 jit_int32_t *i;
4941 jit_word_t w;
4942 } u;
4943
4944 u.w = instr;
4945 i.op = u.i[0];
4946 switch (i.hc.b) {
4947 /* 16 bit immediate opcodes */
4948 case MIPS_REGIMM:
4949 switch (i.rt.b) {
4950 case MIPS_BLTZ: case MIPS_BLTZL:
4951 case MIPS_BLTZAL: case MIPS_BLTZALL:
4952 case MIPS_BGEZ: case MIPS_BGEZAL:
4953 case MIPS_BGEZALL: case MIPS_BGEZL:
4954 case MIPS_TEQI: case MIPS_TGEI:
4955 case MIPS_TGEIU: case MIPS_TLTI:
4956 case MIPS_TLTIU: case MIPS_TNEI:
4957 i.is.b = ((label - instr) >> 2) - 1;
4958 u.i[0] = i.op;
4959 break;
4960 default:
4961 assert(!"unhandled branch opcode");
4962 break;
4963 }
4964 break;
4965
4966 case MIPS_COP1: case MIPS_COP2:
79bfeef6
PC
4967 if (jit_mips6_p()) {
4968 switch (i.rs.b) {
4969 case MIPS_BC1EQZ: case MIPS_BC1NEZ:
4970 assert(jit_mips6_p());
4971 i.is.b = ((label - instr) >> 2) - 1;
4972 u.i[0] = i.op;
4973 break;
4974 default:
4975 assert(!"unhandled branch opcode");
4976 break;
4977 }
4978 }
4979 else {
4980 assert(i.rs.b == MIPS_BC);
4981 switch (i.rt.b) {
4982 case MIPS_BCF: case MIPS_BCFL:
4983 case MIPS_BCT: case MIPS_BCTL:
4984 assert(!jit_mips6_p());
4985 i.is.b = ((label - instr) >> 2) - 1;
4986 u.i[0] = i.op;
4987 break;
4988 default:
4989 assert(!"unhandled branch opcode");
4990 break;
4991 }
4a71579b
PC
4992 }
4993 break;
4994
4995 case MIPS_BLEZ: case MIPS_BLEZL:
4996 case MIPS_BEQ: case MIPS_BEQL:
4997 case MIPS_BGTZ: case MIPS_BGTZL:
4998 case MIPS_BNE: case MIPS_BNEL:
4999 i.is.b = ((label - instr) >> 2) - 1;
5000 u.i[0] = i.op;
5001 break;
5002
5003 case MIPS_LUI:
5004 patch_abs(instr, label);
5005 break;
5006
5007 case MIPS_J: case MIPS_JAL:
5008 case MIPS_JALX:
5009 assert(((instr + sizeof(jit_int32_t)) & 0xf0000000) ==
5010 (label & 0xf0000000));
5011 i.ii.b = (label & ~0xf0000000) >> 2;
5012 u.i[0] = i.op;
5013 break;
5014
ba86ff93
PC
5015 case MIPS_BALC: case MIPS_BC_R6:
5016 assert(jit_mips6_p());
5017 i.ii.b = ((label - instr) >> 2) - 1;
5018 u.i[0] = i.op;
5019 break;
5020
4a71579b
PC
5021 default:
5022 assert(!"unhandled branch opcode");
5023 break;
5024 }
5025}
5026#endif