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