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