Merge pull request #657 from pcercuei/update-lightrec-20220529
[pcsx_rearmed.git] / deps / lightning / lib / jit_ppc-cpu.c
CommitLineData
4a71579b
PC
1/*
2 * Copyright (C) 2012-2019 Free Software Foundation, Inc.
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
21# if __WORDSIZE == 32
22# define gpr_save_area 72 /* r14~r31 = 18 * 4 */
23# if _CALL_SYSV
24# define params_offset (sizeof(jit_word_t) << 1)
25# else
26# define params_offset 24
27# endif
28# define can_sign_extend_int_p(im) 1
29# define can_zero_extend_int_p(im) 1
30# define fits_uint32_p(im) 1
31# else
32# define gpr_save_area 144 /* r14~r31 = 18 * 8 */
33# if _CALL_ELF == 2
34# define params_offset 32
35# else
36# define params_offset 48
37# endif
38# define can_sign_extend_int_p(im) \
39 (((im) >= 0 && (long)(im) <= 0x7fffffffL) || \
40 ((im) < 0 && (long)(im) >= -0x80000000L))
41# define can_zero_extend_int_p(im) \
42 ((im) >= 0 && (im) < 0x80000000L)
43# define fits_uint32_p(im) ((im & 0xffffffff00000000L) == 0)
44# endif
45# define fpr_save_area 64
46# define alloca_offset -(gpr_save_area + fpr_save_area)
47# define ii(i) *_jit->pc.ui++ = i
48# if __WORDSIZE == 32
49# define iw(i) *_jit->pc.ui++ = i
50# else
51# define iw(i) *_jit->pc.ul++ = i
52# endif
53# define can_sign_extend_short_p(im) ((im) >= -32768 && (im) <= 32767)
54# define can_zero_extend_short_p(im) ((im) >= 0 && (im) <= 65535)
55# define can_sign_extend_jump_p(im) ((im) >= -33554432 && (im) <= 33554431)
56# define _R0_REGNO 0
57# define _SP_REGNO 1
58# define _R2_REGNO 2
59# define _R11_REGNO 11
60# define _R12_REGNO 12
61# define _FP_REGNO 31
62# if __WORDSIZE == 32
63# define ldr(r0,r1) ldr_i(r0,r1)
64# define ldxi(r0,r1,i0) ldxi_i(r0,r1,i0)
65# define ldxr(r0,r1,r2) ldxr_i(r0,r1,r2)
66# define stxi(i0,r0,r1) stxi_i(i0,r0,r1)
67# define stxr(r0,r1,r2) stxr_i(r0,r1,r2)
68# else
69# define ldr(r0,r1) ldr_l(r0,r1)
70# define ldxi(r0,r1,i0) ldxi_l(r0,r1,i0)
71# define ldxr(r0,r1,r2) ldxr_l(r0,r1,r2)
72# define stxi(i0,r0,r1) stxi_l(i0,r0,r1)
73# define stxr(r0,r1,r2) stxr_l(r0,r1,r2)
74# endif
75# define FXO(o,d,a,b,e,x) _FXO(_jit,o,d,a,b,e,x,0)
76# define FXO_(o,d,a,b,e,x) _FXO(_jit,o,d,a,b,e,x,1)
77static void _FXO(jit_state_t*,int,int,int,int,int,int,int);
78# define FDs(o,d,a,s) _FDs(_jit,o,d,a,s)
79static void _FDs(jit_state_t*,int,int,int,int);
80# define FDu(o,d,a,s) _FDu(_jit,o,d,a,s)
81static void _FDu(jit_state_t*,int,int,int,int);
82# define FX(o,d,a,b,x) _FX(_jit,o,d,a,b,x,0)
83# define FX_(o,d,a,b,x) _FX(_jit,o,d,a,b,x,1)
84static void _FX(jit_state_t*,int,int,int,int,int,int);
85# define FI(o,t,a,k) _FI(_jit,o,t,a,k)
86static void _FI(jit_state_t*,int,int,int,int);
87# define FB(o,bo,bi,t,a,k) _FB(_jit,o,bo,bi,t,a,k)
88static void _FB(jit_state_t*,int,int,int,int,int,int);
89# define FXL(o,bo,bi,x) _FXL(_jit,o,bo,bi,x,0)
90# define FXL_(o,bo,bi,x) _FXL(_jit,o,bo,bi,x,1)
91static void _FXL(jit_state_t*,int,int,int,int,int);
92# define FC(o,d,l,a,b,x) _FC(_jit,o,d,l,a,b,x)
93static void _FC(jit_state_t*,int,int,int,int,int,int);
94# define FCI(o,d,l,a,s) _FCI(_jit,o,d,l,a,s)
95static void _FCI(jit_state_t*,int,int,int,int,int);
96# define FXFX(o,s,x,f) _FXFX(_jit,o,s,x,f)
97static void _FXFX(jit_state_t*,int,int,int,int);
98# define FM(o,s,a,h,b,e,r) _FM(_jit,o,s,a,h,b,e,r)
99static void _FM(jit_state_t*,int,int,int,int,int,int,int);
100# if __WORDSIZE == 64
101# define FMDS(o,s,a,b,e,x) _FMDS(_jit,o,s,a,b,e,x,0)
102# define FMDS_(o,s,a,b,e,x) _FMDS(_jit,o,s,a,b,e,x,1)
103static void _FMDS(jit_state_t*,int,int,int,int,int,int,int);
104# define FMD(o,s,a,h,b,x,i) _FMD(_jit,o,s,a,h,b,x,i,0)
105# define FMD_(o,s,a,h,b,x,i) _FMD(_jit,o,s,a,h,b,x,i,1)
106static void _FMD(jit_state_t*,int,int,int,int,int,int,int,int);
107# define FXS(o,d,a,h,x,i) _FXS(_jit,o,d,a,h,x,i,0)
108# define FXS_(o,d,a,h,x,i) _FXS(_jit,o,d,a,h,x,i,1)
109static void _FXS(jit_state_t*,int,int,int,int,int,int,int);
110# endif
111# define CR_0 0
112# define CR_1 1
113# define CR_2 2
114# define CR_3 3
115# define CR_4 4
116# define CR_5 5
117# define CR_6 6
118# define CR_7 7
119# define CR_LT 0
120# define CR_GT 1
121# define CR_EQ 2
122# define CR_SO 3
123# define CR_UN 3
124# define BCC_F 4
125# define BCC_T 12
126# define ADD(d,a,b) FXO(31,d,a,b,0,266)
127# define ADD_(d,a,b) FXO_(31,d,a,b,0,266)
128# define ADDO(d,a,b) FXO(31,d,a,b,1,266)
129# define ADDO_(d,a,b) FXO_(31,d,a,b,1,266)
130# define ADDC(d,a,b) FXO_(31,d,a,b,0,10)
131# define ADDC_(d,a,b) FXO_(31,d,a,b,0,10)
132# define ADDCO(d,a,b) FXO(31,d,a,b,1,10)
133# define ADDCO_(d,a,b) FXO_(31,d,a,b,1,10)
134# define ADDE(d,a,b) FXO(31,d,a,b,0,138)
135# define ADDE_(d,a,b) FXO_(31,d,a,b,0,138)
136# define ADDEO(d,a,b) FXO(31,d,a,b,1,138)
137# define ADDEO_(d,a,b) FXO_(31,d,a,b,1,138)
138# define ADDI(d,a,s) FDs(14,d,a,s)
139# define ADDIC(d,a,s) FDs(12,d,a,s)
140# define ADDIC_(d,a,s) FDs(13,d,a,s)
141# define ADDIS(d,a,s) FDs(15,d,a,s)
142# define LIS(d,s) ADDIS(d,0,s)
143# define ADDME(d,a) FXO(31,d,a,0,0,234)
144# define ADDME_(d,a) FXO_(31,d,a,0,0,234)
145# define ADDMEO(d,a) FXO(31,d,a,0,1,234)
146# define ADDMEO_(d,a) FXO_(31,d,a,0,1,234)
147# define ADDZE(d,a) FXO(31,d,a,0,0,202)
148# define ADDZE_(d,a) FXO_(31,d,a,0,0,202)
149# define ADDZEO(d,a) FXO(31,d,a,0,1,202)
150# define ADDZEO_(d,a) FXO_(31,d,a,0,1,202)
151# define AND(d,a,b) FX(31,a,d,b,28)
152# define ANDC(d,a,b) FXO(31,a,d,b,0,60)
153# define ANDC_(d,a,b) FXO_(31,a,d,b,0,60)
154# define AND_(d,a,b) FX_(31,a,b,d,28)
155# define ANDI_(d,a,u) FDu(28,a,d,u)
156# define ANDIS_(d,a,u) FDu(29,a,d,u)
157# define B(t) FI(18,t,0,0)
158# define BA(t) FI(18,t,1,0)
159# define BL(t) FI(18,t,0,1)
160# define BLA(t) FI(18,t,1,1)
161# define BC(o,i,t) FB(16,o,i,t,0,0)
162# define BCA(o,i,t) FB(16,o,i,t,1,0)
163# define BCL(o,i,t) FB(16,o,i,t,0,1)
164# define BCLA(o,i,t) FB(16,o,i,t,1,1)
165# define BLT(t) BC(BCC_T,CR_LT,t)
166# define BLE(t) BC(BCC_F,CR_GT,t)
167# define BEQ(t) BC(BCC_T,CR_EQ,t)
168# define BGE(t) BC(BCC_F,CR_LT,t)
169# define BGT(t) BC(BCC_T,CR_GT,t)
170# define BNE(t) BC(BCC_F,CR_EQ,t)
171# define BUN(t) BC(BCC_T,CR_UN,t)
172# define BNU(t) BC(BCC_F,CR_UN,t)
173# define BCCTR(o,i) FXL(19,o,i,528)
174# define BCCTRL(o,i) FXL_(19,o,i,528)
175# define BLTCTR() BCCTR(BCC_T,CR_LT)
176# define BLECTR() BCCTR(BCC_F,CR_GT)
177# define BEQCTR() BCCTR(BCC_T,CR_EQ)
178# define BGECTR() BCCTR(BCC_F,CR_LT)
179# define BGTCTR() BCCTR(BCC_T,CR_GT)
180# define BNECTR() BCCTR(BCC_F,CR_EQ)
181# define BCTR() BCCTR(20,0)
182# define BCTRL() BCCTRL(20,0)
183# define BCLR(o,i) FXL(19,o,i,16)
184# define BCLRL(o,i) FXL_(19,o,i,16)
185# define BLTLR() BCLR(BCC_T,CR_LT)
186# define BLELR() BCLR(BCC_F,CR_GT)
187# define BEQLR() BCLR(BCC_T,CR_EQ)
188# define BGELR() BCLR(BCC_F,CR_LT)
189# define BGTLR() BCLR(BCC_T,CR_GT)
190# define BNELR() BCLR(BCC_F,CR_EQ)
191# define BLR() BCLR(20,0)
192# define BLRL() BCLRL(20,0)
193# define XCMP(cr,l,a,b) FC(31,cr,l,a,b,0)
194# define CMPD(a,b) XCMP(0,1,a,b)
195# define CMPW(a,b) XCMP(0,0,a,b)
196# define XCMPI(cr,l,a,s) FCI(11,cr,l,a,s)
197# define CMPDI(a,s) XCMPI(0,1,a,s)
198# define CMPWI(a,s) XCMPI(0,0,a,s)
199# define XCMPL(cr,l,a,b) FC(31,cr,l,a,b,32)
200# define CMPLD(a,b) XCMPL(0,1,a,b)
201# define CMPLW(a,b) XCMPL(0,0,a,b)
202# define XCMPLI(cr,l,a,u) FCI(10,cr,l,a,u)
203# define CMPLDI(a,s) XCMPLI(0,1,a,s)
204# define CMPLWI(a,s) XCMPLI(0,0,a,s)
205# define CNTLZW(a,s) FX(31,s,a,0,26)
206# define CNTLZW_(a,s) FX_(31,s,a,0,26)
207# define CRAND(d,a,b) FX(19,d,a,b,257)
208# define CRANDC(d,a,b) FX(19,d,a,b,129)
209# define CREQV(d,a,b) FX(19,d,a,b,289)
210# define CRSET(d) CREQV(d,d,d)
211# define CRNAND(d,a,b) FX(19,d,a,b,225)
212# define CRNOR(d,a,b) FX(19,d,a,b,33)
213# define CRNOT(d,a) CRNOR(d,a,a)
214# define CROR(d,a,b) FX(19,d,a,b,449)
215# define CRMOVE(d,a) CROR(d,a,a)
216# define CRORC(d,a,b) FX(19,d,a,b,417)
217# define CRXOR(d,a,b) FX(19,d,a,b,193)
218# define CRCLR(d) CRXOR(d,d,d)
219# define DCBA(a,b) FX(31,0,a,b,758)
220# define DCBF(a,b) FX(31,0,a,b,86)
221# define DCBI(a,b) FX(31,0,a,b,470)
222# define DCBST(a,b) FX(31,0,a,b,54)
223# define DCBT(a,b) FX(31,0,a,b,278)
224# define DCBTST(a,b) FX(31,0,a,b,246)
225# define DCBZ(a,b) FX(31,0,a,b,1014)
226# define DIVW(d,a,b) FXO(31,d,a,b,0,491)
227# define DIVW_(d,a,b) FXO_(31,d,a,b,0,491)
228# define DIVWO(d,a,b) FXO(31,d,a,b,1,491)
229# define DIVWO_(d,a,b) FXO_(31,d,a,b,1,491)
230# define DIVWU(d,a,b) FXO(31,d,a,b,0,459)
231# define DIVWU_(d,a,b) FXO_(31,d,a,b,0,459)
232# define DIVWUO(d,a,b) FXO(31,d,a,b,1,459)
233# define DIVWUO_(d,a,b) FXO_(31,d,a,b,1,459)
234# define DIVD(d,a,b) FXO(31,d,a,b,0,489)
235# define DIVD_(d,a,b) FXO_(31,d,a,b,0,489)
236# define DIVDO(d,a,b) FXO(31,d,a,b,1,489)
237# define DIVDO_(d,a,b) FXO_(31,d,a,b,1,489)
238# define DIVDU(d,a,b) FXO(31,d,a,b,0,457)
239# define DIVDU_(d,a,b) FXO_(31,d,a,b,0,457)
240# define DIVDUO(d,a,b) FXO(31,d,a,b,1,457)
241# define DIVDUO_(d,a,b) FXO_(31,d,a,b,1,457)
242# define ECIWX(d,a,b) FX(31,d,a,b,310)
243# define ECOWX(s,a,b) FX(31,s,a,b,438)
244# define EIEIO() FX(31,0,0,0,854)
245# define EQV(d,a,b) FX(31,a,d,b,284)
246# define EQV_(d,a,b) FX_(31,a,d,b,284)
247# define EXTSB(d,a) FX(31,a,d,0,954)
248# define EXTSB_(d,a) FX_(31,a,d,0,954)
249# define EXTSH(d,a) FX(31,a,d,0,922)
250# define EXTSH_(d,a) FX_(31,a,d,0,922)
251# define EXTSW(d,a) FX(31,a,d,0,986)
252# define EXTSW_(d,a) FX_(31,a,d,0,986)
253# define ICIB(a,b) FX(31,0,a,b,982)
254# define ISYNC() FXL(19,0,0,150)
255# define LBZ(d,a,s) FDs(34,d,a,s)
256# define LBZU(d,a,s) FDs(35,d,a,s)
257# define LBZUX(d,a,b) FX(31,d,a,b,119)
258# define LBZX(d,a,b) FX(31,d,a,b,87)
259# define LHA(d,a,s) FDs(42,d,a,s)
260# define LHAU(d,a,s) FDs(43,d,a,s)
261# define LHAUX(d,a,b) FX(31,d,a,b,375)
262# define LHAX(d,a,b) FX(31,d,a,b,343)
263# define LHRBX(d,a,b) FX(31,d,a,b,790)
264# define LHZ(d,a,s) FDs(40,d,a,s)
265# define LHZU(d,a,s) FDs(41,d,a,s)
266# define LHZUX(d,a,b) FX(31,d,a,b,311)
267# define LHZX(d,a,b) FX(31,d,a,b,279)
268# define LA(d,a,s) ADDI(d,a,s)
269# define LI(d,s) ADDI(d,0,s)
270# define LMW(d,a,s) FDs(46,d,a,s)
271# define LSWI(d,a,n) FX(31,d,a,n,597)
272# define LSWX(d,a,b) FX(31,d,a,b,533)
273# define LWARX(d,a,b) FX(31,d,a,b,20)
274# define LWBRX(d,a,b) FX(31,d,a,b,534)
275# define LWA(d,a,s) FDs(58,d,a,s|2)
276# define LWAUX(d,a,b) FX(31,d,a,b,373)
277# define LWAX(d,a,b) FX(31,d,a,b,341)
278# define LWZ(d,a,s) FDs(32,d,a,s)
279# define LWZU(d,a,s) FDs(33,d,a,s)
280# define LWZUX(d,a,b) FX(31,d,a,b,55)
281# define LWZX(d,a,b) FX(31,d,a,b,23)
282# define LD(d,a,s) FDs(58,d,a,s)
283# define LDX(d,a,b) FX(31,d,a,b,21)
284# define MCRF(d,s) FXL(19,d<<2,(s)<<2,0)
285# if DEBUG
286/* In case instruction is emulated, check the kernel can handle it.
287 Will only generate it if DEBUG is enabled.
288"""
289Chapter 6. Optional Facilities and Instructions that are being
290Phased Out of the Architecture
291...
2926.1 Move To Condition Register from XER
293The mcrxr instruction is being phased out of the archi-
294tecture. Its description is included here as an aid to
295constructing operating system code to emulate it.
296
297Move to Condition Register from XER
298X-form
299mcrxr BF
30031 BF // /// /// 512 /
3010 6 9 11 16 21 31
302CR(4xBF:4xBF+3) <- XER(32:35)
303XER(32:35) <- 0b0000
304The contents of XER(32:35) are copied to Condition Reg-
305ister field BF. XER(32:35) are set to zero.
306Special Registers Altered:
307CR field BF XER(32:35)
308
309Programming Note
310Warning: This instruction has been phased out of
311the architecture. Attempting to execute this
312instruction will cause the system illegal instruction
313error handler to be invoked
314"""
315 */
316# define MCRXR(d) FX(31,d<<2,0,0,512)
317# else
318# define MCRXR(cr) _MCRXR(_jit,cr);
319static void _MCRXR(jit_state_t*, jit_int32_t);
320# endif
321# define MFCR(d) FX(31,d,0,0,19)
322# define MFMSR(d) FX(31,d,0,0,83)
323# define MFSPR(d,s) FXFX(31,d,s<<5,339)
324# define MFXER(d) MFSPR(d,1)
325# define MFLR(d) MFSPR(d,8)
326# define MFCTR(d) MFSPR(d,9)
327# define MFSR(d,s) FX(31,d,s,0,595)
328# define MFSRIN(d,b) FX(31,d,0,b,659)
329# define MFTB(d,x,y) FXFX(31,d,(x)|((y)<<5),371)
330# define MFTBL(d) MFTB(d,8,12)
331# define MFTBU(d) MFTB(d,8,13)
332# define MTCRF(c,s) FXFX(31,s,c<<1,144)
333# define MTCR(s) MTCRF(0xff,s)
334# define MTMSR(s) FX(31,s,0,0,146)
335# define MTSPR(d,s) FXFX(31,d,s<<5,467)
336# define MTXER(d) MTSPR(d,1)
337# define MTLR(d) MTSPR(d,8)
338# define MTCTR(d) MTSPR(d,9)
339# define MTSR(r,s) FX(31,s<<1,r,0,210)
340# define MTSRIN(r,b) FX(31,r<<1,0,b,242)
341# define MULLI(d,a,s) FDs(07,d,a,s)
342# define MULHW(d,a,b) FXO(31,d,a,b,0,75)
343# define MULHW_(d,a,b) FXO_(31,d,a,b,0,75)
344# define MULHWU(d,a,b) FXO(31,d,a,b,0,11)
345# define MULHWU_(d,a,b) FXO_(31,d,a,b,0,11)
346# define MULLW(d,a,b) FXO(31,d,a,b,0,235)
347# define MULLW_(d,a,b) FXO_(31,d,a,b,0,235)
348# define MULLWO(d,a,b) FXO(31,d,a,b,1,235)
349# define MULLWO_(d,a,b) FXO_(31,d,a,b,1,235)
350# define MULHD(d,a,b) FXO(31,d,a,b,0,73)
351# define MULHD_(d,a,b) FXO_(31,d,a,b,0,73)
352# define MULHDU(d,a,b) FXO(31,d,a,b,0,9)
353# define MULHDU_(d,a,b) FXO_(31,d,a,b,0,9)
354# define MULLD(d,a,b) FXO(31,d,a,b,0,233)
355# define MULLD_(d,a,b) FXO_(31,d,a,b,0,233)
356# define MULLDO(d,a,b) FXO(31,d,a,b,1,233)
357# define MULLDO_(d,a,b) FXO_(31,d,a,b,1,233)
358# define NAND(d,a,b) FX(31,a,d,b,476)
359# define NAND_(d,a,b) FX_(31,a,d,b,476)
360# define NEG(d,a) FXO(31,d,a,0,0,104)
361# define NEG_(d,a) FXO_(31,d,a,0,0,104)
362# define NEGO(d,a) FXO(31,d,a,0,1,104)
363# define NEGO_(d,a) FXO_(31,d,a,0,1,104)
364# define NOR(d,a,b) FX(31,a,d,b,124)
365# define NOR_(d,a,b) FX_(31,a,d,b,124)
366# define NOT(d,s) NOR(d,s,s)
367# define OR(d,a,b) FX(31,a,d,b,444)
368# define OR_(d,a,b) FX_(31,a,d,b,444)
369# define MR(d,a) OR(d,a,a)
370# define ORC(d,a,b) FX(31,a,d,b,412)
371# define ORC_(d,a,b) FX_(31,a,d,b,412)
372# define ORI(d,a,u) FDu(24,a,d,u)
373# define NOP() ORI(0,0,0)
374# define ORIS(d,a,u) FDu(25,a,d,u)
375# define RFI() FXL(19,0,0,50)
376# define RLWIMI(d,s,h,b,e) FM(20,s,d,h,b,e,0)
377# define RLWIMI_(d,s,h,b,e) FM(20,s,d,h,b,e,1)
378# define INSLWI(a,s,n,b) RLWIMI(a,s,32-b,b,b+n-1)
379# define INSRWI(a,s,n,b) RLWIMI(a,s,32-(b+n),b,(b+n)-1)
380# define RLWINM(a,s,h,b,e) FM(21,s,a,h,b,e,0)
381# define RLWINM_(a,s,h,b,e) FM(21,s,a,h,b,e,1)
382# define EXTLWI(a,s,n,b) RLWINM(a,s,b,0,n-1)
383# define EXTRWI(a,s,n,b) RLWINM(a,s,b+n,32-n,31)
384# define ROTLWI(a,s,n) RLWINM(a,s,n,0,31)
385# define ROTRWI(a,s,n) RLWINM(a,s,32-n,0,31)
386# define SLWI(a,s,n) RLWINM(a,s,n,0,31-n)
387# define SRWI(a,s,n) RLWINM(a,s,32-n,n,31)
388# define CLRLWI(a,s,n) RLWINM(a,s,0,n,31)
389# define CLRRWI(a,s,n) RLWINM(a,s,0,0,31-n)
390# define CLRLSWI(a,s,b,n) RLWINM(a,s,n,b-n,31-n)
391# define RLWNM(a,s,b,m,e) FM(23,s,a,b,m,e,0)
392# define RLWNM_(a,s,b,m,e) FM(23,s,a,b,m,e,1)
393# define ROTLW(a,s,b) RLWNM(a,s,b,0,31)
394# define SC() FDu(17,0,0,2)
395# define SLW(a,s,b) FX(31,s,a,b,24)
396# define SLW_(a,s,b) FX_(31,s,a,b,24)
397# define SRAW(a,s,b) FX(31,s,a,b,792)
398# define SRAW_(a,s,b) FX_(31,s,a,b,792)
399# define SRAWI(a,s,h) FX(31,s,a,h,824)
400# define SRAWI_(a,s,h) FX_(31,s,a,h,824)
401# define SRW(a,s,b) FX(31,s,a,b,536)
402# define SRW_(a,s,b) FX_(31,s,a,b,536)
403# if __WORDSIZE == 64
404# define RLDICL(a,s,h,b) FMD(30,s,a,h&~32,b,0,h>>5)
405# define RLDICL_(a,s,h,b) FMD_(30,s,a,h&~32,b,0,h>>5)
406# define EXTRDI(x,y,n,b) RLDICL(x,y,(b+n),(64-n))
407# define SRDI(x,y,n) RLDICL(x,y,(64-n),n)
408# define CLRLDI(x,y,n) RLDICL(x,y,0,n)
409# define RLDICR(a,s,h,e) FMD(30,s,a,h&~32,e,1,h>>5)
410# define RLDICR_(a,s,h,e) FMD_(30,s,a,h&~32,e,1,h>>5)
411# define EXTRLI(x,y,n,b) RLDICR(x,y,b,(n-1))
412# define SLDI(x,y,n) RLDICR(x,y,n,(63-n))
413# define CLRRDI(x,y,n) RLDICR(x,y,0,(63-n))
414# define RLDIC(a,s,h,b) FMD(30,s,a,h&~32,b,2,h>>5)
415# define RLDIC_(a,s,h,b) FMD_(30,s,a,h&~32,b,2,h>>5)
416# define CLRLSLDI(x,y,b,n) RLDIC(x,y,n,(b-n))
417# define RLDCL(a,s,h,b) FMDS(30,s,a,h,b,8)
418# define RLDCL_(a,s,h,b) FMDS_(30,s,a,h,b,8)
419# define ROTLD(x,y,z) RLDCL(x,y,z,0)
420# define RLDCR(a,s,b,e) FMDS(30,s,a,b,e,0)
421# define RLDCR_(a,s,b,e) FMDS_(30,s,a,b,e,0)
422# define RLDIMI(a,s,h,b) FMD(30,s,a,h&~32,b,3,h>>5)
423# define RLDIMI_(a,s,h,b) FMD_(30,s,a,h&~32,b,3,h>>5)
424# define INSRDI(x,y,n,b) RLDIMI(x,y,(64-(b+n)),b)
425# define SLD(a,s,b) FX(31,s,a,b,27)
426# define SLD_(a,s,b) FX_(31,s,a,b,27)
427# define SRD(a,s,b) FX(31,s,a,b,539)
428# define SRD_(a,s,b) FX_(31,s,a,b,539)
429# define SRADI(a,s,h) FXS(31,s,a,h&~32,413,h>>5)
430# define SRADI_(a,s,h) FXS_(31,s,a,h&~32,413,h>>5)
431# define SRAD(a,s,b) FX(31,s,a,b,794)
432# define SRAD_(a,s,b) FX_(31,s,a,b,794)
433# endif
434# define STB(s,a,d) FDs(38,s,a,d)
435# define STBU(s,a,d) FDs(39,s,a,d)
436# define STBUX(s,a,b) FX(31,s,a,b,247)
437# define STBX(s,a,b) FX(31,s,a,b,215)
438# define STH(s,a,d) FDs(44,s,a,d)
439# define STHBRX(s,a,b) FX(31,s,a,b,918)
440# define STHU(s,a,d) FDs(45,s,a,d)
441# define STHUX(s,a,b) FX(31,s,a,b,439)
442# define STHX(s,a,b) FX(31,s,a,b,407)
443# define STMW(s,a,d) FDs(47,s,a,d)
444# define STWSI(s,a,nb) FX(31,s,a,nb,725)
445# define STSWX(s,a,b) FX(31,s,a,b,661)
446# define STW(s,a,d) FDs(36,s,a,d)
447# define STWBRX(s,a,b) FX(31,s,a,b,662)
448# define STWCX_(s,a,b) FX_(31,s,a,b,150)
449# define STWU(s,a,d) FDs(37,s,a,d)
450# define STWUX(s,a,b) FX(31,s,a,b,183)
451# define STWX(s,a,b) FX(31,s,a,b,151)
452# define STD(s,a,d) FDs(62,s,a,d)
453# define STDX(s,a,b) FX(31,s,a,b,149)
454# define STDU(s,a,d) FDs(62,s,a,d|1)
455# define STDUX(s,a,b) FX(31,s,a,b,181)
456# define SUBF(d,a,b) FXO(31,d,a,b,0,40)
457# define SUBF_(d,a,b) FXO_(31,d,a,b,0,40)
458# define SUBFO(d,a,b) FXO(31,d,a,b,1,40)
459# define SUBFO_(d,a,b) FXO_(31,d,a,b,1,40)
460# define SUB(d,a,b) SUBF(d,b,a)
461# define SUB_(d,a,b) SUBF_(d,b,a)
462# define SUBO(d,a,b) SUBFO(d,b,a)
463# define SUBO_(d,a,b) SUBFO_(d,b,a)
464# define SUBI(d,a,s) ADDI(d,a,-s)
465# define SUBIS(d,a,s) ADDIS(d,a,-s)
466# define SUBFC(d,a,b) FXO(31,d,a,b,0,8)
467# define SUBFC_(d,a,b) FXO_(31,d,a,b,0,8)
468# define SUBFCO(d,a,b) FXO(31,d,a,b,1,8)
469# define SUBFCO_(d,a,b) FXO_(31,d,a,b,1,8)
470# define SUBC(d,a,b) SUBFC(d,b,a)
471# define SUBIC(d,a,s) ADDIC(d,a,-s)
472# define SUBIC_(d,a,s) ADDIC_(d,a,-s)
473# define SUBFE(d,a,b) FXO(31,d,a,b,0,136)
474# define SUBFE_(d,a,b) FXO_(31,d,a,b,0,136)
475# define SUBFEO(d,a,b) FXO(31,d,a,b,1,136)
476# define SUBFEO_(d,a,b) FXO_(31,d,a,b,1,136)
477# define SUBE(d,a,b) SUBFE(d,b,a)
478# define SUBFIC(d,a,s) FDs(8,d,a,s)
479# define SUBFME(d,a) FXO(31,d,a,0,0,232)
480# define SUBFME_(d,a) FXO_(31,d,a,0,0,232)
481# define SUBFMEO(d,a) FXO(31,d,a,0,1,232)
482# define SUBFMEO_(d,a) FXO_(31,d,a,0,1,232)
483# define SUBFZE(d,a) FXO(31,d,a,0,0,200)
484# define SUBFZE_(d,a) FXO_(31,d,a,0,0,200)
485# define SUBFZEO(d,a) FXO(31,d,a,0,1,200)
486# define SUBFZEO_(d,a) FXO_(31,d,a,0,1,200)
487# define SYNC() FX(31,0,0,0,598)
488# define TLBIA() FX(31,0,0,0,370)
489# define TLBIE(b) FX(31,0,0,b,306)
490# define TLBSYNC() FX(31,0,0,0,566)
491# define TW(t,a,b) FX(31,t,a,b,4)
492# define TWEQ(a,b) FX(31,4,a,b,4)
493# define TWLGE(a,b) FX(31,5,a,b,4)
494# define TRAP() FX(31,31,0,0,4)
495# define TWI(t,a,s) FDs(3,t,a,s)
496# define TWGTI(a,s) TWI(8,a,s)
497# define TWLLEI(a,s) TWI(6,a,s)
498# define XOR(d,a,b) FX(31,a,d,b,316)
499# define XOR_(d,a,b) FX_(31,a,d,b,316)
500# define XORI(s,a,u) FDu(26,a,s,u)
501# define XORIS(s,a,u) FDu(27,a,s,u)
502# define nop(c) _nop(_jit,c)
503static void _nop(jit_state_t*,jit_int32_t);
504# define movr(r0,r1) _movr(_jit,r0,r1)
505static void _movr(jit_state_t*,jit_int32_t,jit_int32_t);
506# define movi(r0,i0) _movi(_jit,r0,i0)
507static void _movi(jit_state_t*,jit_int32_t,jit_word_t);
e0659411
PC
508# define movnr(r0,r1,r2) _movnr(_jit,r0,r1,r2)
509static void _movnr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
510# define movzr(r0,r1,r2) _movzr(_jit,r0,r1,r2)
511static void _movzr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
4a71579b
PC
512# define movi_p(r0,i0) _movi_p(_jit,r0,i0)
513static jit_word_t _movi_p(jit_state_t*,jit_int32_t,jit_word_t);
514# define negr(r0,r1) NEG(r0,r1)
515# define comr(r0,r1) NOT(r0,r1)
516# define extr_c(r0,r1) EXTSB(r0,r1)
517# define extr_uc(r0,r1) ANDI_(r0,r1,0xff)
518# define extr_s(r0,r1) EXTSH(r0,r1)
519# define extr_us(r0,r1) ANDI_(r0,r1,0xffff)
520# if __WORDSIZE == 64
521# define extr_i(r0,r1) EXTSW(r0,r1)
522# define extr_ui(r0,r1) CLRLDI(r0,r1,32)
523# endif
40a44dcb
PC
524# define bswapr_us(r0,r1) _bswapr_us(_jit,r0,r1)
525static void _bswapr_us(jit_state_t*,jit_int32_t,jit_int32_t);
526# define bswapr_ui(r0,r1) _bswapr_ui(_jit,r0,r1)
527static void _bswapr_ui(jit_state_t*,jit_int32_t,jit_int32_t);
528# if __WORDSIZE == 64
529# define bswapr_ul(r0,r1) generic_bswapr_ul(_jit,r0,r1)
4a71579b
PC
530# endif
531# define addr(r0,r1,r2) ADD(r0,r1,r2)
532# define addi(r0,r1,i0) _addi(_jit,r0,r1,i0)
533static void _addi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
534# define addcr(r0,r1,r2) ADDC(r0,r1,r2)
535# define addci(r0,r1,i0) _addci(_jit,r0,r1,i0)
536static void _addci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
537# define addxr(r0,r1,r2) ADDE(r0,r1,r2)
538# define addxi(r0,r1,i0) _addxi(_jit,r0,r1,i0)
539static void _addxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
540# define subr(r0,r1,r2) SUB(r0,r1,r2)
541# define subi(r0,r1,i0) _subi(_jit,r0,r1,i0)
542static void _subi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
543# define subcr(r0,r1,r2) SUBC(r0,r1,r2)
544# define subci(r0,r1,i0) _subci(_jit,r0,r1,i0)
545static void _subci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
546# define subxr(r0,r1,r2) SUBFE(r0,r2,r1)
547# define subxi(r0,r1,i0) _subxi(_jit,r0,r1,i0)
548static void _subxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
549# define rsbi(r0, r1, i0) _rsbi(_jit, r0, r1, i0)
550static void _rsbi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
551# if __WORDSIZE == 32
552# define mulr(r0,r1,r2) MULLW(r0,r1,r2)
553# define mullr(r0,r1,r2) MULLW(r0,r1,r2)
554# define mulhr(r0,r1,r2) MULHW(r0,r1,r2)
555# define mulhr_u(r0,r1,r2) MULHWU(r0,r1,r2)
556# else
557# define mulr(r0,r1,r2) MULLD(r0,r1,r2)
558# define mullr(r0,r1,r2) MULLD(r0,r1,r2)
559# define mulhr(r0,r1,r2) MULHD(r0,r1,r2)
560# define mulhr_u(r0,r1,r2) MULHDU(r0,r1,r2)
561# endif
562# define muli(r0,r1,i0) _muli(_jit,r0,r1,i0)
563static void _muli(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
564# define qmulr(r0,r1,r2,r3) iqmulr(r0,r1,r2,r3,1)
565# define qmulr_u(r0,r1,r2,r3) iqmulr(r0,r1,r2,r3,0)
566# define iqmulr(r0,r1,r2,r3,cc) _iqmulr(_jit,r0,r1,r2,r3,cc)
567static void _iqmulr(jit_state_t*,jit_int32_t,jit_int32_t,
568 jit_int32_t,jit_int32_t,jit_bool_t);
569# define qmuli(r0,r1,r2,i0) iqmuli(r0,r1,r2,i0,1)
570# define qmuli_u(r0,r1,r2,i0) iqmuli(r0,r1,r2,i0,0)
571# define iqmuli(r0,r1,r2,i0,cc) _iqmuli(_jit,r0,r1,r2,i0,cc)
572static void _iqmuli(jit_state_t*,jit_int32_t,jit_int32_t,
573 jit_int32_t,jit_word_t,jit_bool_t);
574# if __WORDSIZE == 32
575# define divr(r0,r1,r2) DIVW(r0,r1,r2)
576# else
577# define divr(r0,r1,r2) DIVD(r0,r1,r2)
578# endif
579# define divi(r0,r1,i0) _divi(_jit,r0,r1,i0)
580static void _divi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
581# if __WORDSIZE == 32
582# define divr_u(r0,r1,r2) DIVWU(r0,r1,r2)
583# else
584# define divr_u(r0,r1,r2) DIVDU(r0,r1,r2)
585# endif
586# define divi_u(r0,r1,i0) _divi_u(_jit,r0,r1,i0)
587static void _divi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
588# define qdivr(r0,r1,r2,r3) iqdivr(r0,r1,r2,r3,1)
589# define qdivr_u(r0,r1,r2,r3) iqdivr(r0,r1,r2,r3,0)
590# define iqdivr(r0,r1,r2,r3,cc) _iqdivr(_jit,r0,r1,r2,r3,cc)
591static void _iqdivr(jit_state_t*,jit_int32_t,jit_int32_t,
592 jit_int32_t,jit_int32_t,jit_bool_t);
593# define qdivi(r0,r1,r2,i0) iqdivi(r0,r1,r2,i0,1)
594# define qdivi_u(r0,r1,r2,i0) iqdivi(r0,r1,r2,i0,0)
595# define iqdivi(r0,r1,r2,i0,cc) _iqdivi(_jit,r0,r1,r2,i0,cc)
596static void _iqdivi(jit_state_t*,jit_int32_t,jit_int32_t,
597 jit_int32_t,jit_word_t,jit_bool_t);
598# define remr(r0,r1,r2) _remr(_jit,r0,r1,r2)
599static void _remr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
600# define remi(r0,r1,i0) _remi(_jit,r0,r1,i0)
601static void _remi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
602# define remr_u(r0,r1,r2) _remr_u(_jit,r0,r1,r2)
603static void _remr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
604# define remi_u(r0,r1,i0) _remi_u(_jit,r0,r1,i0)
605static void _remi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
606# define andr(r0,r1,r2) AND(r0,r1,r2)
607# define andi(r0,r1,i0) _andi(_jit,r0,r1,i0)
608static void _andi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
609# define orr(r0,r1,r2) OR(r0,r1,r2)
610# define ori(r0,r1,i0) _ori(_jit,r0,r1,i0)
611static void _ori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
612# define xorr(r0,r1,r2) XOR(r0,r1,r2)
613# define xori(r0,r1,i0) _xori(_jit,r0,r1,i0)
614static void _xori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
615# if __WORDSIZE == 32
616# define lshr(r0,r1,r2) SLW(r0,r1,r2)
617# else
618# define lshr(r0,r1,r2) SLD(r0,r1,r2)
619# endif
620# define lshi(r0,r1,i0) _lshi(_jit,r0,r1,i0)
621static void _lshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
622# if __WORDSIZE == 32
623# define rshr(r0,r1,r2) SRAW(r0,r1,r2)
624# else
625# define rshr(r0,r1,r2) SRAD(r0,r1,r2)
626# endif
627# define rshi(r0,r1,i0) _rshi(_jit,r0,r1,i0)
628static void _rshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
629# if __WORDSIZE == 32
630# define rshr_u(r0,r1,r2) SRW(r0,r1,r2)
631# else
632# define rshr_u(r0,r1,r2) SRD(r0,r1,r2)
633# endif
634# define rshi_u(r0,r1,i0) _rshi_u(_jit,r0,r1,i0)
635static void _rshi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
636# define ltr(r0,r1,r2) _ltr(_jit,r0,r1,r2)
637static void _ltr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
638# define lti(r0,r1,i0) _lti(_jit,r0,r1,i0)
639static void _lti(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
640# define ltr_u(r0,r1,r2) _ltr_u(_jit,r0,r1,r2)
641static void _ltr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
642# define lti_u(r0,r1,i0) _lti_u(_jit,r0,r1,i0)
643static void _lti_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
644# define ler(r0,r1,r2) _ler(_jit,r0,r1,r2)
645static void _ler(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
646# define lei(r0,r1,i0) _lei(_jit,r0,r1,i0)
647static void _lei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
648# define ler_u(r0,r1,r2) _ler_u(_jit,r0,r1,r2)
649static void _ler_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
650# define lei_u(r0,r1,i0) _lei_u(_jit,r0,r1,i0)
651static void _lei_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
652# define eqr(r0,r1,r2) _eqr(_jit,r0,r1,r2)
653static void _eqr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
654# define eqi(r0,r1,i0) _eqi(_jit,r0,r1,i0)
655static void _eqi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
656# define ger(r0,r1,r2) _ger(_jit,r0,r1,r2)
657static void _ger(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
658# define gei(r0,r1,i0) _gei(_jit,r0,r1,i0)
659static void _gei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
660# define ger_u(r0,r1,r2) _ger_u(_jit,r0,r1,r2)
661static void _ger_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
662# define gei_u(r0,r1,i0) _gei_u(_jit,r0,r1,i0)
663static void _gei_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
664# define gtr(r0,r1,r2) _gtr(_jit,r0,r1,r2)
665static void _gtr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
666# define gti(r0,r1,i0) _gti(_jit,r0,r1,i0)
667static void _gti(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
668# define gtr_u(r0,r1,r2) _gtr_u(_jit,r0,r1,r2)
669static void _gtr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
670# define gti_u(r0,r1,i0) _gti_u(_jit,r0,r1,i0)
671static void _gti_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
672# define ner(r0,r1,r2) _ner(_jit,r0,r1,r2)
673static void _ner(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
674# define nei(r0,r1,i0) _nei(_jit,r0,r1,i0)
675static void _nei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
676#define bltr(i0,r0,r1) _bltr(_jit,i0,r0,r1)
677static jit_word_t _bltr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
678#define blti(i0,r0,i1) _blti(_jit,i0,r0,i1)
679static jit_word_t _blti(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
680#define bltr_u(i0,r0,r1) _bltr_u(_jit,i0,r0,r1)
681static jit_word_t _bltr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
682#define blti_u(i0,r0,i1) _blti_u(_jit,i0,r0,i1)
683static jit_word_t _blti_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
684#define bler(i0,r0,r1) _bler(_jit,i0,r0,r1)
685static jit_word_t _bler(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
686#define blei(i0,r0,i1) _blei(_jit,i0,r0,i1)
687static jit_word_t _blei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
688#define bler_u(i0,r0,r1) _bler_u(_jit,i0,r0,r1)
689static jit_word_t _bler_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
690#define blei_u(i0,r0,i1) _blei_u(_jit,i0,r0,i1)
691static jit_word_t _blei_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
692#define beqr(i0,r0,r1) _beqr(_jit,i0,r0,r1)
693static jit_word_t _beqr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
694#define beqi(i0,r0,i1) _beqi(_jit,i0,r0,i1)
695static jit_word_t _beqi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
696#define bger(i0,r0,r1) _bger(_jit,i0,r0,r1)
697static jit_word_t _bger(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
698#define bgei(i0,r0,i1) _bgei(_jit,i0,r0,i1)
699static jit_word_t _bgei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
700#define bger_u(i0,r0,r1) _bger_u(_jit,i0,r0,r1)
701static jit_word_t _bger_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
702#define bgei_u(i0,r0,i1) _bgei_u(_jit,i0,r0,i1)
703static jit_word_t _bgei_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
704#define bgtr(i0,r0,r1) _bgtr(_jit,i0,r0,r1)
705static jit_word_t _bgtr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
706#define bgti(i0,r0,i1) _bgti(_jit,i0,r0,i1)
707static jit_word_t _bgti(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
708#define bgtr_u(i0,r0,r1) _bgtr_u(_jit,i0,r0,r1)
709static jit_word_t _bgtr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
710#define bgti_u(i0,r0,i1) _bgti_u(_jit,i0,r0,i1)
711static jit_word_t _bgti_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
712#define bner(i0,r0,r1) _bner(_jit,i0,r0,r1)
713static jit_word_t _bner(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
714#define bnei(i0,r0,i1) _bnei(_jit,i0,r0,i1)
715static jit_word_t _bnei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
716#define bmsr(i0,r0,r1) _bmsr(_jit,i0,r0,r1)
717static jit_word_t _bmsr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
718#define bmsi(i0,r0,i1) _bmsi(_jit,i0,r0,i1)
719static jit_word_t _bmsi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
720#define bmcr(i0,r0,r1) _bmcr(_jit,i0,r0,r1)
721static jit_word_t _bmcr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
722#define bmci(i0,r0,i1) _bmci(_jit,i0,r0,i1)
723static jit_word_t _bmci(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
724#define boaddr(i0,r0,r1) _boaddr(_jit,i0,r0,r1)
725static jit_word_t _boaddr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
726#define boaddi(i0,r0,i1) _boaddi(_jit,i0,r0,i1)
727static jit_word_t _boaddi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
728#define bxaddr(i0,r0,r1) _bxaddr(_jit,i0,r0,r1)
729static jit_word_t _bxaddr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
730#define bxaddi(i0,r0,i1) _bxaddi(_jit,i0,r0,i1)
731static jit_word_t _bxaddi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
732#define bosubr(i0,r0,r1) _bosubr(_jit,i0,r0,r1)
733static jit_word_t _bosubr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
734#define bosubi(i0,r0,i1) _bosubi(_jit,i0,r0,i1)
735static jit_word_t _bosubi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
736#define bxsubr(i0,r0,r1) _bxsubr(_jit,i0,r0,r1)
737static jit_word_t _bxsubr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
738#define bxsubi(i0,r0,i1) _bxsubi(_jit,i0,r0,i1)
739static jit_word_t _bxsubi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
740#define boaddr_u(i0,r0,r1) _boaddr_u(_jit,i0,r0,r1)
741static jit_word_t _boaddr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
742#define boaddi_u(i0,r0,i1) _boaddi_u(_jit,i0,r0,i1)
743static jit_word_t _boaddi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
744#define bxaddr_u(i0,r0,r1) _bxaddr_u(_jit,i0,r0,r1)
745static jit_word_t _bxaddr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
746#define bxaddi_u(i0,r0,i1) _bxaddi_u(_jit,i0,r0,i1)
747static jit_word_t _bxaddi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
748#define bosubr_u(i0,r0,r1) _bosubr_u(_jit,i0,r0,r1)
749static jit_word_t _bosubr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
750#define bosubi_u(i0,r0,i1) _bosubi_u(_jit,i0,r0,i1)
751static jit_word_t _bosubi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
752#define bxsubr_u(i0,r0,r1) _bxsubr_u(_jit,i0,r0,r1)
753static jit_word_t _bxsubr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
754#define bxsubi_u(i0,r0,i1) _bxsubi_u(_jit,i0,r0,i1)
755static jit_word_t _bxsubi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
756# define ldr_c(r0,r1) _ldr_c(_jit,r0,r1)
757static void _ldr_c(jit_state_t*,jit_int32_t,jit_int32_t);
758# define ldi_c(r0,i0) _ldi_c(_jit,r0,i0)
759static void _ldi_c(jit_state_t*,jit_int32_t,jit_word_t);
760# define ldxr_c(r0,r1,i0) _ldxr_c(_jit,r0,r1,i0)
761static void _ldxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
762# define ldxi_c(r0,r1,i0) _ldxi_c(_jit,r0,r1,i0)
763static void _ldxi_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
764# define ldr_uc(r0,r1) LBZX(r0, _R0_REGNO, r1)
765# define ldi_uc(r0,i0) _ldi_uc(_jit,r0,i0)
766static void _ldi_uc(jit_state_t*,jit_int32_t,jit_word_t);
767# define ldxr_uc(r0,r1,r2) _ldxr_uc(_jit,r0,r1,r2)
768static void _ldxr_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
769# define ldxi_uc(r0,r1,i0) _ldxi_uc(_jit,r0,r1,i0)
770static void _ldxi_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
771# define ldr_s(r0,r1) LHAX(r0, _R0_REGNO, r1)
772# define ldi_s(r0,i0) _ldi_s(_jit,r0,i0)
773static void _ldi_s(jit_state_t*,jit_int32_t,jit_word_t);
774# define ldxr_s(r0,r1,i0) _ldxr_s(_jit,r0,r1,i0)
775static void _ldxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
776# define ldxi_s(r0,r1,i0) _ldxi_s(_jit,r0,r1,i0)
777static void _ldxi_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
778# define ldr_us(r0,r1) LHZX(r0, _R0_REGNO, r1)
779# define ldi_us(r0,i0) _ldi_us(_jit,r0,i0)
780static void _ldi_us(jit_state_t*,jit_int32_t,jit_word_t);
781# define ldxr_us(r0,r1,i0) _ldxr_us(_jit,r0,r1,i0)
782static void _ldxr_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
783# define ldxi_us(r0,r1,i0) _ldxi_us(_jit,r0,r1,i0)
784static void _ldxi_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
785# if __WORDSIZE == 32
786# define ldr_i(r0,r1) LWZX(r0, _R0_REGNO, r1)
787# else
788# define ldr_i(r0,r1) LWAX(r0, _R0_REGNO, r1)
789# endif
790# define ldi_i(r0,i0) _ldi_i(_jit,r0,i0)
791static void _ldi_i(jit_state_t*,jit_int32_t,jit_word_t);
792# define ldxr_i(r0,r1,i0) _ldxr_i(_jit,r0,r1,i0)
793static void _ldxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
794# define ldxi_i(r0,r1,i0) _ldxi_i(_jit,r0,r1,i0)
795static void _ldxi_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
796# if __WORDSIZE == 64
797# define ldr_ui(r0,r1) LWZX(r0, _R0_REGNO, r1)
798# define ldi_ui(r0,i0) _ldi_ui(_jit,r0,i0)
799static void _ldi_ui(jit_state_t*,jit_int32_t,jit_word_t);
800# define ldxr_ui(r0,r1,i0) _ldxr_ui(_jit,r0,r1,i0)
801static void _ldxr_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
802# define ldxi_ui(r0,r1,i0) _ldxi_ui(_jit,r0,r1,i0)
803static void _ldxi_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
804# define ldr_l(r0,r1) LDX(r0, _R0_REGNO, r1)
805# define ldi_l(r0,i0) _ldi_l(_jit,r0,i0)
806static void _ldi_l(jit_state_t*,jit_int32_t,jit_word_t);
807# define ldxr_l(r0,r1,i0) _ldxr_l(_jit,r0,r1,i0)
808static void _ldxr_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
809# define ldxi_l(r0,r1,i0) _ldxi_l(_jit,r0,r1,i0)
810static void _ldxi_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
811# endif
812# define str_c(r0,r1) STBX(r1, _R0_REGNO, r0)
813# define sti_c(i0,r0) _sti_c(_jit,i0,r0)
814static void _sti_c(jit_state_t*,jit_word_t,jit_int32_t);
815# define stxr_c(r0,r1,r2) _stxr_c(_jit,r0,r1,r2)
816static void _stxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
817# define stxi_c(i0,r0,r1) _stxi_c(_jit,i0,r0,r1)
818static void _stxi_c(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
819# define str_s(r0,r1) STHX(r1, _R0_REGNO, r0)
820# define sti_s(i0,r0) _sti_s(_jit,i0,r0)
821static void _sti_s(jit_state_t*,jit_word_t,jit_int32_t);
822# define stxr_s(r0,r1,r2) _stxr_s(_jit,r0,r1,r2)
823static void _stxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
824# define stxi_s(i0,r0,r1) _stxi_s(_jit,i0,r0,r1)
825static void _stxi_s(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
826# define str_i(r0,r1) STWX(r1, _R0_REGNO, r0)
827# define sti_i(i0,r0) _sti_i(_jit,i0,r0)
828static void _sti_i(jit_state_t*,jit_word_t,jit_int32_t);
829# define stxr_i(r0,r1,r2) _stxr_i(_jit,r0,r1,r2)
830static void _stxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
831# define stxi_i(i0,r0,r1) _stxi_i(_jit,i0,r0,r1)
832static void _stxi_i(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
833# if __WORDSIZE == 64
834# define str_l(r0,r1) STDX(r1, _R0_REGNO, r0)
835# define sti_l(i0,r0) _sti_l(_jit,i0,r0)
836static void _sti_l(jit_state_t*,jit_word_t,jit_int32_t);
837# define stxr_l(r0,r1,r2) _stxr_l(_jit,r0,r1,r2)
838static void _stxr_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
839# define stxi_l(i0,r0,r1) _stxi_l(_jit,i0,r0,r1)
840static void _stxi_l(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
841# endif
842# define jmpr(r0) _jmpr(_jit,r0)
843static void _jmpr(jit_state_t*,jit_int32_t);
844# define jmpi(i0) _jmpi(_jit,i0)
845static jit_word_t _jmpi(jit_state_t*,jit_word_t);
846# define jmpi_p(i0) _jmpi_p(_jit,i0)
847static jit_word_t _jmpi_p(jit_state_t*,jit_word_t) maybe_unused;
848# if _CALL_SYSV
849# define callr(r0,i0) _callr(_jit,r0,i0)
850static void _callr(jit_state_t*,jit_int32_t,jit_int32_t);
851# define calli(i0,i1) _calli(_jit,i0,i1)
852static void _calli(jit_state_t*,jit_word_t,jit_int32_t);
853# define calli_p(i0,i1) _calli_p(_jit,i0,i1)
854static jit_word_t _calli_p(jit_state_t*,jit_word_t,jit_int32_t);
855# else
856# define callr(r0) _callr(_jit,r0)
857static void _callr(jit_state_t*,jit_int32_t);
858# define calli(i0) _calli(_jit,i0)
859static void _calli(jit_state_t*,jit_word_t);
860# define calli_p(i0) _calli_p(_jit,i0)
861static jit_word_t _calli_p(jit_state_t*,jit_word_t);
862#endif
863# define prolog(node) _prolog(_jit, node)
864static void _prolog(jit_state_t*, jit_node_t*);
865# define epilog(node) _epilog(_jit, node)
866static void _epilog(jit_state_t*, jit_node_t*);
867# define vastart(r0) _vastart(_jit, r0)
868static void _vastart(jit_state_t*, jit_int32_t);
869# define vaarg(r0, r1) _vaarg(_jit, r0, r1)
870static void _vaarg(jit_state_t*, jit_int32_t, jit_int32_t);
871# define vaarg_d(r0, r1) _vaarg_d(_jit, r0, r1)
872static void _vaarg_d(jit_state_t*, jit_int32_t, jit_int32_t);
873# define patch_at(i,l) _patch_at(_jit,i,l)
874static void _patch_at(jit_state_t*,jit_word_t,jit_word_t);
875#endif
876
877#if CODE
878# define _u16(v) ((v) & 0xffff)
879# define _u26(v) ((v) & 0x3ffffff)
880static void
881_FXO(jit_state_t *_jit, int o, int d, int a, int b, int e, int x, int r)
882{
883 assert(!(o & ~((1 << 6) - 1)));
884 assert(!(d & ~((1 << 5) - 1)));
885 assert(!(a & ~((1 << 5) - 1)));
886 assert(!(b & ~((1 << 5) - 1)));
887 assert(!(e & ~((1 << 1) - 1)));
888 assert(!(x & ~((1 << 9) - 1)));
889 assert(!(r & ~((1 << 1) - 1)));
890 ii((o<<26)|(d<<21)|(a<<16)|(b<<11)|(e<<10)|(x<<1)|r);
891}
892
893static void
894_FDs(jit_state_t *_jit, int o, int d, int a, int s)
895{
896 assert(!(o & ~((1 << 6) - 1)));
897 assert(!(d & ~((1 << 5) - 1)));
898 assert(!(a & ~((1 << 5) - 1)));
899 assert(can_sign_extend_short_p(s));
900 ii((o<<26)|(d<<21)|(a<<16)|_u16(s));
901}
902
903static void
904_FDu(jit_state_t *_jit, int o, int d, int a, int s)
905{
906 assert(!(o & ~((1 << 6) - 1)));
907 assert(!(d & ~((1 << 5) - 1)));
908 assert(!(a & ~((1 << 5) - 1)));
909 assert(can_zero_extend_short_p(s));
910 ii((o<<26)|(d<<21)|(a<<16)|_u16(s));
911}
912
913static void
914_FX(jit_state_t *_jit, int o, int s, int a, int b, int x, int r)
915{
916 assert(!(o & ~((1 << 6) - 1)));
917 assert(!(s & ~((1 << 5) - 1)));
918 assert(!(a & ~((1 << 5) - 1)));
919 assert(!(b & ~((1 << 5) - 1)));
920 assert(!(x & ~((1 << 10) - 1)));
921 assert(!(r & ~((1 << 1) - 1)));
922 ii((o<<26)|(s<<21)|(a<<16)|(b<<11)|(x<<1)|r);
923}
924
925static void
926_FI(jit_state_t *_jit, int o, int t, int a, int k)
927{
928 assert(!(o & ~(( 1 << 6) - 1)));
929 assert(!(t & 3) && can_sign_extend_jump_p(t));
930 assert(!(a & ~(( 1 << 1) - 1)));
931 assert(!(k & ~(( 1 << 1) - 1)));
932 ii((o<<26)|_u26(t)|(a<<1)|k);
933}
934
935static void
936_FB(jit_state_t *_jit, int o, int bo, int bi, int t, int a, int k)
937{
938 assert(!( o & ~((1 << 6) - 1)));
939 assert(!(bo & ~((1 << 5) - 1)));
940 assert(!(bi & ~((1 << 5) - 1)));
941 assert(!(t & 3) && can_sign_extend_short_p(t));
942 assert(!(a & ~(( 1 << 1) - 1)));
943 assert(!(k & ~(( 1 << 1) - 1)));
944 ii((o<<26)|(bo<<21)|(bi<<16)|_u16(t)|(a<<1)|k);
945}
946
947static void
948_FXL(jit_state_t *_jit, int o, int bo, int bi, int x, int k)
949{
950 assert(!( o & ~((1 << 6) - 1)));
951 assert(!(bo & ~((1 << 5) - 1)));
952 assert(!(bi & ~((1 << 5) - 1)));
953 assert(!(x & ~(( 1 << 10) - 1)));
954 assert(!(k & ~(( 1 << 1) - 1)));
955 ii((o<<26)|(bo<<21)|(bi<<16)|(x<<1)|k);
956}
957
958static void
959_FC(jit_state_t *_jit, int o, int d, int l, int a, int b, int x)
960{
961 assert(!(o & ~((1 << 6) - 1)));
962 assert(!(d & ~((1 << 3) - 1)));
963 assert(!(l & ~((1 << 1) - 1)));
964 assert(!(a & ~((1 << 5) - 1)));
965 assert(!(b & ~((1 << 5) - 1)));
966 assert(!(x & ~((1 << 10) - 1)));
967 ii((o<<26)|(d<<23)|(l<<21)|(a<<16)|(b<<11)|(x<<1));
968}
969
970static void
971_FCI(jit_state_t *_jit, int o, int d, int l, int a, int s)
972{
973 assert(!(o & ~((1 << 6) - 1)));
974 assert(!(d & ~((1 << 3) - 1)));
975 assert(!(l & ~((1 << 1) - 1)));
976 assert(!(a & ~((1 << 5) - 1)));
977 if (o == 11) assert(can_sign_extend_short_p(s));
978 else if (o == 10) assert(can_zero_extend_short_p(s));
979#if DEBUG
980 else abort();
981#endif
982 ii((o<<26)|(d<<23)|(l<<21)|(a<<16)|_u16(s));
983}
984
985static void
986_FXFX(jit_state_t *_jit, int o, int d, int x, int f)
987{
988 assert(!(o & ~((1 << 6) - 1)));
989 assert(!(d & ~((1 << 5) - 1)));
990 assert(!(x & ~((1 << 10) - 1)));
991 assert(!(f & ~((1 << 10) - 1)));
992 ii((o<<26)|(d<<21)|(x<<11)|(f<<1));
993}
994
995static void
996_FM(jit_state_t *_jit, int o, int s, int a, int h, int b, int e, int r)
997{
998 assert(!(o & ~((1 << 6) - 1)));
999 assert(!(s & ~((1 << 5) - 1)));
1000 assert(!(a & ~((1 << 5) - 1)));
1001 assert(!(h & ~((1 << 5) - 1)));
1002 assert(!(b & ~((1 << 5) - 1)));
1003 assert(!(e & ~((1 << 5) - 1)));
1004 assert(!(r & ~((1 << 1) - 1)));
1005 ii((o<<26)|(s<<21)|(a<<16)|(h<<11)|(b<<6)|(e<<1)|r);
1006}
1007
1008# if __WORDSIZE == 64
1009static void
1010_FMDS(jit_state_t *_jit, int o, int s, int a, int b, int e, int x, int r)
1011{
1012 assert(!(o & ~((1 << 6) - 1)));
1013 assert(!(s & ~((1 << 5) - 1)));
1014 assert(!(a & ~((1 << 5) - 1)));
1015 assert(!(b & ~((1 << 5) - 1)));
1016 assert(!(e & ~((1 << 6) - 1)));
1017 assert(!(x & ~((1 << 4) - 1)));
1018 assert(!(r & ~((1 << 1) - 1)));
1019 e = (e >> 5) | ((e << 1) & 63);
1020 ii((o<<26)|(s<<21)|(a<<16)|(b<<11)|(e<<5)|(x<<1)|r);
1021}
1022
1023static void
1024_FMD(jit_state_t *_jit, int o, int s, int a, int h, int e, int x, int i, int r)
1025{
1026 assert(!(o & ~((1 << 6) - 1)));
1027 assert(!(s & ~((1 << 5) - 1)));
1028 assert(!(a & ~((1 << 5) - 1)));
1029 assert(!(h & ~((1 << 5) - 1)));
1030 assert(!(e & ~((1 << 6) - 1)));
1031 assert(!(x & ~((1 << 3) - 1)));
1032 assert(!(i & ~((1 << 1) - 1)));
1033 assert(!(r & ~((1 << 1) - 1)));
1034 e = (e >> 5) | ((e << 1) & 63);
1035 ii((o<<26)|(s<<21)|(a<<16)|(h<<11)|(e<<5)|(x<<2)|(i<<1)|r);
1036}
1037
1038static void
1039_FXS(jit_state_t *_jit, int o, int s, int a, int h, int x, int i, int r)
1040{
1041 assert(!(o & ~((1 << 6) - 1)));
1042 assert(!(s & ~((1 << 5) - 1)));
1043 assert(!(a & ~((1 << 5) - 1)));
1044 assert(!(h & ~((1 << 5) - 1)));
1045 assert(!(x & ~((1 << 9) - 1)));
1046 assert(!(i & ~((1 << 1) - 1)));
1047 assert(!(r & ~((1 << 1) - 1)));
1048 ii((o<<26)|(s<<21)|(a<<16)|(h<<11)|(x<<2)|(i<<1)|r);
1049}
1050#endif
1051
1052#if !DEBUG
1053/*
1054 * Use the sequence commented at
1055 * http://tenfourfox.blogspot.com/2011/04/attention-g5-owners-your-javascript-no.html
1056 */
1057static void
1058_MCRXR(jit_state_t *_jit, jit_int32_t cr)
1059{
1060 jit_int32_t reg;
1061 reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
1062 MFXER(rn(reg));
1063 MTCRF(128, rn(reg));
1064 RLWINM(rn(reg), rn(reg), 0, 0, 28);
1065 MTXER(rn(reg));
1066 jit_unget_reg(reg);
1067}
1068#endif
1069
1070static void
1071_nop(jit_state_t *_jit, jit_int32_t i0)
1072{
1073 for (; i0 > 0; i0 -= 4)
1074 NOP();
1075 assert(i0 == 0);
1076}
1077
1078static void
1079_movr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1080{
1081 if (r0 != r1)
1082 MR(r0, r1);
1083}
1084
1085static void
1086_movi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
1087{
1088 if (can_sign_extend_short_p(i0))
1089 LI(r0, i0);
1090 else {
1091 if (can_sign_extend_int_p(i0))
1092 LIS(r0, (jit_int16_t)(i0 >> 16));
1093 else if (can_zero_extend_int_p(i0)) {
1094 if (i0 & 0xffff0000) {
1095 ORI(r0, r0, (jit_uint16_t)(i0 >> 16));
1096 SLWI(r0, r0, 16);
1097 }
1098 }
1099# if __WORDSIZE == 64
1100 else {
1101 movi(r0, (jit_uint32_t)(i0 >> 32));
1102 if (i0 & 0xffff0000) {
1103 SLDI(r0, r0, 16);
1104 ORI(r0, r0, (jit_uint16_t)(i0 >> 16));
1105 SLDI(r0, r0, 16);
1106 }
1107 else
1108 SLDI(r0, r0, 32);
1109 }
1110# endif
1111 if (i0 & 0xffff)
1112 ORI(r0, r0, (jit_uint16_t)i0);
1113 }
1114}
1115
e0659411
PC
1116static void
1117_movnr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1118{
1119 CMPWI(r2, 0);
1120 BEQ(8);
1121 MR(r0, r1);
1122}
1123
1124static void
1125_movzr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1126{
1127 CMPWI(r2, 0);
1128 BNE(8);
1129 MR(r0, r1);
1130}
1131
4a71579b
PC
1132static jit_word_t
1133_movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
1134{
1135 jit_word_t word = _jit->pc.w;
1136# if __WORDSIZE == 32
1137 LIS(r0, (jit_int16_t)(i0 >> 16));
1138 ORI(r0, r0, (jit_uint16_t)i0);
1139# else
1140 LIS(r0, (jit_int16_t)(i0 >> 48));
1141 ORI(r0, r0, (jit_uint16_t)(i0 >> 32));
1142 SLDI(r0, r0, 16);
1143 ORI(r0, r0, (jit_uint16_t)(i0 >> 16));
1144 SLDI(r0, r0, 16);
1145 ORI(r0, r0, (jit_uint16_t)i0);
1146# endif
1147 return (word);
1148}
1149
4a71579b 1150static void
40a44dcb 1151_bswapr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
4a71579b 1152{
40a44dcb
PC
1153 if (r0 == r1) {
1154 RLWIMI(r0, r0, 16, 8, 15);
1155 RLWINM(r0, r0, 24, 16, 31);
1156 } else {
1157 RLWINM(r0, r1, 8, 16, 23);
1158 RLWIMI(r0, r1, 24, 24, 31);
1159 }
4a71579b
PC
1160}
1161
1162static void
40a44dcb 1163_bswapr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
4a71579b
PC
1164{
1165 jit_int32_t reg;
1166 reg = jit_get_reg(jit_class_gpr);
1167 ROTLWI(rn(reg), r1, 8);
1168 RLWIMI(rn(reg), r1, 24, 0, 7);
1169 RLWIMI(rn(reg), r1, 24, 16, 23);
519a9ea1 1170# if __WORDSIZE == 64
4a71579b 1171 CLRLDI(r0, rn(reg), 32);
519a9ea1
PC
1172# else
1173 MR(r0,rn(reg));
1174# endif
4a71579b
PC
1175 jit_unget_reg(reg);
1176}
1177
4a71579b
PC
1178static void
1179_addi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1180{
1181 jit_int32_t reg;
1182 if (can_sign_extend_short_p(i0))
1183 ADDI(r0, r1, i0);
1184 else if (can_zero_extend_int_p(i0) && !(i0 & 0x0000ffff))
1185 ADDIS(r0, r1, i0 >> 16);
1186 else {
1187 reg = jit_get_reg(jit_class_gpr);
1188 movi(rn(reg), i0);
1189 ADD(r0, r1, rn(reg));
1190 jit_unget_reg(reg);
1191 }
1192}
1193
1194static void
1195_addci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1196{
1197 jit_int32_t reg;
1198 if (can_sign_extend_short_p(i0))
1199 ADDIC(r0, r1, i0);
1200 else {
1201 reg = jit_get_reg(jit_class_gpr);
1202 movi(rn(reg), i0);
1203 ADDC(r0, r1, rn(reg));
1204 jit_unget_reg(reg);
1205 }
1206}
1207
1208static void
1209_addxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1210{
1211 jit_int32_t reg;
1212 reg = jit_get_reg(jit_class_gpr);
1213 movi(rn(reg), i0);
1214 ADDE(r0, r1, rn(reg));
1215 jit_unget_reg(reg);
1216}
1217
1218static void
1219_subi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1220{
1221 jit_int32_t reg;
1222 jit_word_t ni0 = -i0;
1223 if (can_sign_extend_short_p(ni0))
1224 ADDI(r0, r1, ni0);
1225 else if (can_zero_extend_int_p(ni0) && !(ni0 & 0x0000ffff))
1226 ADDIS(r0, r1, ni0 >> 16);
1227 else {
1228 reg = jit_get_reg(jit_class_gpr);
1229 movi(rn(reg), i0);
1230 SUB(r0, r1, rn(reg));
1231 jit_unget_reg(reg);
1232 }
1233}
1234
1235static void
1236_subci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1237{
1238 jit_int32_t reg;
1239 reg = jit_get_reg(jit_class_gpr);
1240 movi(rn(reg), i0);
1241 SUBC(r0, r1, rn(reg));
1242 jit_unget_reg(reg);
1243}
1244
1245static void
1246_subxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1247{
1248 jit_int32_t reg;
1249 reg = jit_get_reg(jit_class_gpr);
1250 movi(rn(reg), i0);
1251 SUBE(r0, r1, rn(reg));
1252 jit_unget_reg(reg);
1253}
1254
1255static void
1256_rsbi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1257{
1258 subi(r0, r1, i0);
1259 negr(r0, r0);
1260}
1261
1262static void
1263_muli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1264{
1265 jit_int32_t reg;
1266 if (can_sign_extend_short_p(i0))
1267 MULLI(r0, r1, i0);
1268 else {
1269 reg = jit_get_reg(jit_class_gpr);
1270 movi(rn(reg), i0);
1271 mulr(r0, r1, rn(reg));
1272 jit_unget_reg(reg);
1273 }
1274}
1275
1276static void
1277_iqmulr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
1278 jit_int32_t r2, jit_int32_t r3, jit_bool_t sign)
1279{
1280 jit_int32_t reg;
1281 if (r0 == r2 || r0 == r3) {
1282 reg = jit_get_reg(jit_class_gpr);
1283 mullr(rn(reg), r2, r3);
1284 }
1285 else
1286 mullr(r0, r2, r3);
1287 if (sign)
1288 mulhr(r1, r2, r3);
1289 else
1290 mulhr_u(r1, r2, r3);
1291 if (r0 == r2 || r0 == r3) {
1292 movr(r0, rn(reg));
1293 jit_unget_reg(reg);
1294 }
1295}
1296
1297static void
1298_iqmuli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
1299 jit_int32_t r2, jit_word_t i0, jit_bool_t sign)
1300{
1301 jit_int32_t reg;
1302 reg = jit_get_reg(jit_class_gpr);
1303 movi(rn(reg), i0);
1304 iqmulr(r0, r1, r2, rn(reg), sign);
1305 jit_unget_reg(reg);
1306}
1307
1308static void
1309_divi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1310{
1311 jit_int32_t reg;
1312 reg = jit_get_reg(jit_class_gpr);
1313 movi(rn(reg), i0);
1314 divr(r0, r1, rn(reg));
1315 jit_unget_reg(reg);
1316}
1317
1318static void
1319_divi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1320{
1321 jit_int32_t reg;
1322 reg = jit_get_reg(jit_class_gpr);
1323 movi(rn(reg), i0);
1324 divr_u(r0, r1, rn(reg));
1325 jit_unget_reg(reg);
1326}
1327
1328static void
1329_iqdivr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
1330 jit_int32_t r2, jit_int32_t r3, jit_bool_t sign)
1331{
1332 jit_int32_t sv0, rg0;
1333 jit_int32_t sv1, rg1;
1334
1335 if (r0 == r2 || r0 == r3) {
1336 sv0 = jit_get_reg(jit_class_gpr);
1337 rg0 = rn(sv0);
1338 }
1339 else
1340 rg0 = r0;
1341 if (r1 == r2 || r1 == r3) {
1342 sv1 = jit_get_reg(jit_class_gpr);
1343 rg1 = rn(sv1);
1344 }
1345 else
1346 rg1 = r1;
1347
1348 if (sign)
1349 divr(rg0, r2, r3);
1350 else
1351 divr_u(rg0, r2, r3);
1352 mulr(rg1, r3, rg0);
1353 subr(rg1, r2, rg1);
1354 if (rg0 != r0) {
1355 movr(r0, rg0);
1356 jit_unget_reg(sv0);
1357 }
1358 if (rg1 != r1) {
1359 movr(r1, rg1);
1360 jit_unget_reg(sv1);
1361 }
1362}
1363
1364static void
1365_iqdivi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
1366 jit_int32_t r2, jit_word_t i0, jit_bool_t sign)
1367{
1368 jit_int32_t reg;
1369 reg = jit_get_reg(jit_class_gpr);
1370 movi(rn(reg), i0);
1371 iqdivr(r0, r1, r2, rn(reg), sign);
1372 jit_unget_reg(reg);
1373}
1374
1375static void
1376_remr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1377{
1378 jit_int32_t reg;
1379 if (r0 == r1 || r0 == r2) {
1380 reg = jit_get_reg(jit_class_gpr);
1381 divr(rn(reg), r1, r2);
1382 mulr(rn(reg), r2, rn(reg));
1383 subr(r0, r1, rn(reg));
1384 jit_unget_reg(reg);
1385 }
1386 else {
1387 divr(r0, r1, r2);
1388 mulr(r0, r2, r0);
1389 subr(r0, r1, r0);
1390 }
1391}
1392
1393static void
1394_remi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1395{
1396 jit_int32_t reg;
1397 reg = jit_get_reg(jit_class_gpr);
1398 movi(rn(reg), i0);
1399 remr(r0, r1, rn(reg));
1400 jit_unget_reg(reg);
1401}
1402
1403static void
1404_remr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1405{
1406 jit_int32_t reg;
1407 if (r0 == r1 || r0 == r2) {
1408 reg = jit_get_reg(jit_class_gpr);
1409 divr_u(rn(reg), r1, r2);
1410 mulr(rn(reg), r2, rn(reg));
1411 subr(r0, r1, rn(reg));
1412 jit_unget_reg(reg);
1413 }
1414 else {
1415 divr_u(r0, r1, r2);
1416 mulr(r0, r2, r0);
1417 subr(r0, r1, r0);
1418 }
1419}
1420
1421static void
1422_remi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1423{
1424 jit_int32_t reg;
1425 reg = jit_get_reg(jit_class_gpr);
1426 movi(rn(reg), i0);
1427 remr_u(r0, r1, rn(reg));
1428 jit_unget_reg(reg);
1429}
1430
1431static void
1432_andi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1433{
1434 jit_int32_t reg;
1435 if (can_zero_extend_short_p(i0))
1436 ANDI_(r0, r1, i0);
1437 else if (can_zero_extend_int_p(i0) && !(i0 & 0x0000ffff))
1438 ANDIS_(r0, r1, (jit_uword_t)i0 >> 16);
1439 else {
1440 reg = jit_get_reg(jit_class_gpr);
1441 movi(rn(reg), i0);
1442 AND(r0, r1, rn(reg));
1443 jit_unget_reg(reg);
1444 }
1445}
1446
1447static void
1448_ori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1449{
1450 jit_int32_t reg;
1451 if (can_zero_extend_short_p(i0))
1452 ORI(r0, r1, i0);
1453 else if (can_zero_extend_int_p(i0) && !(i0 & 0x0000ffff))
1454 ORIS(r0, r1, (jit_uword_t)i0 >> 16);
1455 else {
1456 reg = jit_get_reg(jit_class_gpr);
1457 movi(rn(reg), i0);
1458 OR(r0, r1, rn(reg));
1459 jit_unget_reg(reg);
1460 }
1461}
1462
1463static void
1464_xori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1465{
1466 jit_int32_t reg;
1467 if (can_zero_extend_short_p(i0))
1468 XORI(r0, r1, i0);
1469 else if (can_zero_extend_int_p(i0) && !(i0 & 0x0000ffff))
1470 XORIS(r0, r1, (jit_uword_t)i0 >> 16);
1471 else {
1472 reg = jit_get_reg(jit_class_gpr);
1473 movi(rn(reg), i0);
1474 XOR(r0, r1, rn(reg));
1475 jit_unget_reg(reg);
1476 }
1477}
1478
1479static void
1480_lshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1481{
1482 if (i0 == 0)
1483 movr(r0, r1);
1484 else {
1485# if __WORDSIZE == 32
1486 SLWI(r0, r1, i0);
1487# else
1488 SLDI(r0, r1, i0);
1489# endif
1490 }
1491}
1492
1493static void
1494_rshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1495{
1496 if (i0 == 0)
1497 movr(r0, r1);
1498 else {
1499# if __WORDSIZE == 32
1500 SRAWI(r0, r1, i0);
1501# else
1502 SRADI(r0, r1, i0);
1503# endif
1504 }
1505}
1506
1507static void
1508_rshi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1509{
1510 if (i0 == 0)
1511 movr(r0, r1);
1512 else {
1513# if __WORDSIZE == 32
1514 SRWI(r0, r1, i0);
1515# else
1516 SRDI(r0, r1, i0);
1517# endif
1518 }
1519}
1520
1521static void
1522_ltr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1523{
1524 CMPW(r1, r2);
1525 MFCR(r0);
1526 EXTRWI(r0, r0, 1, CR_LT);
1527}
1528
1529static void
1530_lti(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1531{
1532 jit_int32_t reg;
1533 if (can_sign_extend_short_p(i0))
1534 CMPWI(r1, i0);
1535 else {
1536 reg = jit_get_reg(jit_class_gpr);
1537 movi(rn(reg), i0);
1538 CMPW(r1, rn(reg));
1539 jit_unget_reg(reg);
1540 }
1541 MFCR(r0);
1542 EXTRWI(r0, r0, 1, CR_LT);
1543}
1544
1545static void
1546_ltr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1547{
1548 CMPLW(r1, r2);
1549 MFCR(r0);
1550 EXTRWI(r0, r0, 1, CR_LT);
1551}
1552
1553static void
1554_lti_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1555{
1556 jit_int32_t reg;
1557 if (can_zero_extend_short_p(i0))
1558 CMPLWI(r1, i0);
1559 else {
1560 reg = jit_get_reg(jit_class_gpr);
1561 movi(rn(reg), i0);
1562 CMPLW(r1, rn(reg));
1563 jit_unget_reg(reg);
1564 }
1565 MFCR(r0);
1566 EXTRWI(r0, r0, 1, CR_LT);
1567}
1568
1569static void
1570_ler(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1571{
1572 CMPW(r1, r2);
1573 CRNOT(CR_GT, CR_GT);
1574 MFCR(r0);
1575 EXTRWI(r0, r0, 1, CR_GT);
1576}
1577
1578static void
1579_lei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1580{
1581 jit_int32_t reg;
1582 if (can_sign_extend_short_p(i0))
1583 CMPWI(r1, i0);
1584 else {
1585 reg = jit_get_reg(jit_class_gpr);
1586 movi(rn(reg), i0);
1587 CMPW(r1, rn(reg));
1588 jit_unget_reg(reg);
1589 }
1590 CRNOT(CR_GT, CR_GT);
1591 MFCR(r0);
1592 EXTRWI(r0, r0, 1, CR_GT);
1593}
1594
1595static void
1596_ler_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1597{
1598 CMPLW(r1, r2);
1599 CRNOT(CR_GT, CR_GT);
1600 MFCR(r0);
1601 EXTRWI(r0, r0, 1, CR_GT);
1602}
1603
1604static void
1605_lei_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1606{
1607 jit_int32_t reg;
1608 if (can_zero_extend_short_p(i0))
1609 CMPLWI(r1, i0);
1610 else {
1611 reg = jit_get_reg(jit_class_gpr);
1612 movi(rn(reg), i0);
1613 CMPLW(r1, rn(reg));
1614 jit_unget_reg(reg);
1615 }
1616 CRNOT(CR_GT, CR_GT);
1617 MFCR(r0);
1618 EXTRWI(r0, r0, 1, CR_GT);
1619}
1620
1621static void
1622_eqr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1623{
1624 CMPW(r1, r2);
1625 MFCR(r0);
1626 EXTRWI(r0, r0, 1, CR_EQ);
1627}
1628
1629static void
1630_eqi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1631{
1632 jit_int32_t reg;
1633 if (can_sign_extend_short_p(i0))
1634 CMPWI(r1, i0);
1635 else if (can_zero_extend_short_p(i0))
1636 CMPLWI(r1, i0);
1637 else {
1638 reg = jit_get_reg(jit_class_gpr);
1639 movi(rn(reg), i0);
1640 CMPW(r1, rn(reg));
1641 jit_unget_reg(reg);
1642 }
1643 MFCR(r0);
1644 EXTRWI(r0, r0, 1, CR_EQ);
1645}
1646
1647static void
1648_ger(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1649{
1650 CMPW(r1, r2);
1651 CRNOT(CR_LT, CR_LT);
1652 MFCR(r0);
1653 EXTRWI(r0, r0, 1, CR_LT);
1654}
1655
1656static void
1657_gei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1658{
1659 jit_int32_t reg;
1660 if (can_sign_extend_short_p(i0))
1661 CMPWI(r1, i0);
1662 else {
1663 reg = jit_get_reg(jit_class_gpr);
1664 movi(rn(reg), i0);
1665 CMPW(r1, rn(reg));
1666 jit_unget_reg(reg);
1667 }
1668 CRNOT(CR_LT, CR_LT);
1669 MFCR(r0);
1670 EXTRWI(r0, r0, 1, CR_LT);
1671}
1672
1673static void
1674_ger_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1675{
1676 CMPLW(r1, r2);
1677 CRNOT(CR_LT, CR_LT);
1678 MFCR(r0);
1679 EXTRWI(r0, r0, 1, CR_LT);
1680}
1681
1682static void
1683_gei_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1684{
1685 jit_int32_t reg;
1686 if (can_zero_extend_short_p(i0))
1687 CMPLWI(r1, i0);
1688 else {
1689 reg = jit_get_reg(jit_class_gpr);
1690 movi(rn(reg), i0);
1691 CMPLW(r1, rn(reg));
1692 jit_unget_reg(reg);
1693 }
1694 CRNOT(CR_LT, CR_LT);
1695 MFCR(r0);
1696 EXTRWI(r0, r0, 1, CR_LT);
1697}
1698
1699static void
1700_gtr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1701{
1702 CMPW(r1, r2);
1703 MFCR(r0);
1704 EXTRWI(r0, r0, 1, CR_GT);
1705}
1706
1707static void
1708_gti(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1709{
1710 jit_int32_t reg;
1711 if (can_sign_extend_short_p(i0))
1712 CMPWI(r1, i0);
1713 else {
1714 reg = jit_get_reg(jit_class_gpr);
1715 movi(rn(reg), i0);
1716 CMPW(r1, rn(reg));
1717 jit_unget_reg(reg);
1718 }
1719 MFCR(r0);
1720 EXTRWI(r0, r0, 1, CR_GT);
1721}
1722
1723static void
1724_gtr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1725{
1726 CMPLW(r1, r2);
1727 MFCR(r0);
1728 EXTRWI(r0, r0, 1, CR_GT);
1729}
1730
1731static void
1732_gti_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1733{
1734 jit_int32_t reg;
1735 if (can_zero_extend_short_p(i0))
1736 CMPLWI(r1, i0);
1737 else {
1738 reg = jit_get_reg(jit_class_gpr);
1739 movi(rn(reg), i0);
1740 CMPLW(r1, rn(reg));
1741 jit_unget_reg(reg);
1742 }
1743 MFCR(r0);
1744 EXTRWI(r0, r0, 1, CR_GT);
1745}
1746
1747static void
1748_ner(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1749{
1750 CMPW(r1, r2);
1751 CRNOT(CR_EQ, CR_EQ);
1752 MFCR(r0);
1753 EXTRWI(r0, r0, 1, CR_EQ);
1754}
1755
1756static void
1757_nei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1758{
1759 jit_int32_t reg;
1760 if (can_sign_extend_short_p(i0))
1761 CMPWI(r1, i0);
1762 else if (can_zero_extend_short_p(i0))
1763 CMPLWI(r1, i0);
1764 else {
1765 reg = jit_get_reg(jit_class_gpr);
1766 movi(rn(reg), i0);
1767 CMPW(r1, rn(reg));
1768 jit_unget_reg(reg);
1769 }
1770 CRNOT(CR_EQ, CR_EQ);
1771 MFCR(r0);
1772 EXTRWI(r0, r0, 1, CR_EQ);
1773}
1774
1775static jit_word_t
1776_bltr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1777{
1778 jit_word_t d, w;
1779 CMPW(r0, r1);
1780 w = _jit->pc.w;
1781 d = (i0 - w) & ~3;
1782 BLT(d);
1783 return (w);
1784}
1785
1786static jit_word_t
1787_blti(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
1788{
1789 jit_int32_t reg;
1790 jit_word_t d, w;
1791 if (can_sign_extend_short_p(i1))
1792 CMPWI(r0, i1);
1793 else {
1794 reg = jit_get_reg(jit_class_gpr);
1795 movi(rn(reg), i1);
1796 CMPW(r0, rn(reg));
1797 jit_unget_reg(reg);
1798 }
1799 w = _jit->pc.w;
1800 d = (i0 - w) & ~3;
1801 BLT(d);
1802 return (w);
1803}
1804
1805static jit_word_t
1806_bltr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1807{
1808 jit_word_t d, w;
1809 CMPLW(r0, r1);
1810 w = _jit->pc.w;
1811 d = (i0 - w) & ~3;
1812 BLT(d);
1813 return (w);
1814}
1815
1816static jit_word_t
1817_blti_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
1818{
1819 jit_int32_t reg;
1820 jit_word_t d, w;
1821 if (can_zero_extend_short_p(i1))
1822 CMPLWI(r0, i1);
1823 else {
1824 reg = jit_get_reg(jit_class_gpr);
1825 movi(rn(reg), i1);
1826 CMPLW(r0, rn(reg));
1827 jit_unget_reg(reg);
1828 }
1829 w = _jit->pc.w;
1830 d = (i0 - w) & ~3;
1831 BLT(d);
1832 return (w);
1833}
1834
1835static jit_word_t
1836_bler(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1837{
1838 jit_word_t d, w;
1839 CMPW(r0, r1);
1840 w = _jit->pc.w;
1841 d = (i0 - w) & ~3;
1842 BLE(d);
1843 return (w);
1844}
1845
1846static jit_word_t
1847_blei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
1848{
1849 jit_int32_t reg;
1850 jit_word_t d, w;
1851 if (can_sign_extend_short_p(i1))
1852 CMPWI(r0, i1);
1853 else {
1854 reg = jit_get_reg(jit_class_gpr);
1855 movi(rn(reg), i1);
1856 CMPW(r0, rn(reg));
1857 jit_unget_reg(reg);
1858 }
1859 w = _jit->pc.w;
1860 d = (i0 - w) & ~3;
1861 BLE(d);
1862 return (w);
1863}
1864
1865static jit_word_t
1866_bler_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1867{
1868 jit_word_t d, w;
1869 CMPLW(r0, r1);
1870 w = _jit->pc.w;
1871 d = (i0 - w) & ~3;
1872 BLE(d);
1873 return (w);
1874}
1875
1876static jit_word_t
1877_blei_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
1878{
1879 jit_int32_t reg;
1880 jit_word_t d, w;
1881 if (can_zero_extend_short_p(i1))
1882 CMPLWI(r0, i1);
1883 else {
1884 reg = jit_get_reg(jit_class_gpr);
1885 movi(rn(reg), i1);
1886 CMPLW(r0, rn(reg));
1887 jit_unget_reg(reg);
1888 }
1889 w = _jit->pc.w;
1890 d = (i0 - w) & ~3;
1891 BLE(d);
1892 return (w);
1893}
1894
1895static jit_word_t
1896_beqr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1897{
1898 jit_word_t d, w;
1899 CMPW(r0, r1);
1900 w = _jit->pc.w;
1901 d = (i0 - w) & ~3;
1902 BEQ(d);
1903 return (w);
1904}
1905
1906static jit_word_t
1907_beqi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
1908{
1909 jit_int32_t reg;
1910 jit_word_t d, w;
1911 if (can_sign_extend_short_p(i1))
1912 CMPWI(r0, i1);
1913 else if (can_zero_extend_short_p(i1))
1914 CMPLWI(r0, i1);
1915 else {
1916 reg = jit_get_reg(jit_class_gpr);
1917 movi(rn(reg), i1);
1918 CMPW(r0, rn(reg));
1919 jit_unget_reg(reg);
1920 }
1921 w = _jit->pc.w;
1922 d = (i0 - w) & ~3;
1923 BEQ(d);
1924 return (w);
1925}
1926
1927static jit_word_t
1928_bger(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1929{
1930 jit_word_t d, w;
1931 CMPW(r0, r1);
1932 w = _jit->pc.w;
1933 d = (i0 - w) & ~3;
1934 BGE(d);
1935 return (w);
1936}
1937
1938static jit_word_t
1939_bgei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
1940{
1941 jit_int32_t reg;
1942 jit_word_t d, w;
1943 if (can_sign_extend_short_p(i1))
1944 CMPWI(r0, i1);
1945 else {
1946 reg = jit_get_reg(jit_class_gpr);
1947 movi(rn(reg), i1);
1948 CMPW(r0, rn(reg));
1949 jit_unget_reg(reg);
1950 }
1951 w = _jit->pc.w;
1952 d = (i0 - w) & ~3;
1953 BGE(d);
1954 return (w);
1955}
1956
1957static jit_word_t
1958_bger_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1959{
1960 jit_word_t d, w;
1961 CMPLW(r0, r1);
1962 w = _jit->pc.w;
1963 d = (i0 - w) & ~3;
1964 BGE(d);
1965 return (w);
1966}
1967
1968static jit_word_t
1969_bgei_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
1970{
1971 jit_int32_t reg;
1972 jit_word_t d, w;
1973 if (can_zero_extend_short_p(i1))
1974 CMPLWI(r0, i1);
1975 else {
1976 reg = jit_get_reg(jit_class_gpr);
1977 movi(rn(reg), i1);
1978 CMPLW(r0, rn(reg));
1979 jit_unget_reg(reg);
1980 }
1981 w = _jit->pc.w;
1982 d = (i0 - w) & ~3;
1983 BGE(d);
1984 return (w);
1985}
1986
1987static jit_word_t
1988_bgtr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1989{
1990 jit_word_t d, w;
1991 CMPW(r0, r1);
1992 w = _jit->pc.w;
1993 d = (i0 - w) & ~3;
1994 BGT(d);
1995 return (w);
1996}
1997
1998static jit_word_t
1999_bgti(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
2000{
2001 jit_int32_t reg;
2002 jit_word_t d, w;
2003 if (can_sign_extend_short_p(i1))
2004 CMPWI(r0, i1);
2005 else {
2006 reg = jit_get_reg(jit_class_gpr);
2007 movi(rn(reg), i1);
2008 CMPW(r0, rn(reg));
2009 jit_unget_reg(reg);
2010 }
2011 w = _jit->pc.w;
2012 d = (i0 - w) & ~3;
2013 BGT(d);
2014 return (w);
2015}
2016
2017static jit_word_t
2018_bgtr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2019{
2020 jit_word_t d, w;
2021 CMPLW(r0, r1);
2022 w = _jit->pc.w;
2023 d = (i0 - w) & ~3;
2024 BGT(d);
2025 return (w);
2026}
2027
2028static jit_word_t
2029_bgti_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
2030{
2031 jit_int32_t reg;
2032 jit_word_t d, w;
2033 if (can_zero_extend_short_p(i1))
2034 CMPLWI(r0, i1);
2035 else {
2036 reg = jit_get_reg(jit_class_gpr);
2037 movi(rn(reg), i1);
2038 CMPLW(r0, rn(reg));
2039 jit_unget_reg(reg);
2040 }
2041 w = _jit->pc.w;
2042 d = (i0 - w) & ~3;
2043 BGT(d);
2044 return (w);
2045}
2046
2047static jit_word_t
2048_bner(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2049{
2050 jit_word_t d, w;
2051 CMPW(r0, r1);
2052 w = _jit->pc.w;
2053 d = (i0 - w) & ~3;
2054 BNE(d);
2055 return (w);
2056}
2057
2058static jit_word_t
2059_bnei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
2060{
2061 jit_int32_t reg;
2062 jit_word_t d, w;
2063 if (can_sign_extend_short_p(i1))
2064 CMPWI(r0, i1);
2065 else if (can_zero_extend_short_p(i1))
2066 CMPLWI(r0, i1);
2067 else {
2068 reg = jit_get_reg(jit_class_gpr);
2069 movi(rn(reg), i1);
2070 CMPW(r0, rn(reg));
2071 jit_unget_reg(reg);
2072 }
2073 w = _jit->pc.w;
2074 d = (i0 - w) & ~3;
2075 BNE(d);
2076 return (w);
2077}
2078
2079static jit_word_t
2080_bmsr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2081{
2082 jit_word_t w;
2083 jit_int32_t reg;
2084 reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
2085 andr(rn(reg), r0, r1);
2086 w = bnei(i0, rn(reg), 0);
2087 jit_unget_reg(reg);
2088 return (w);
2089}
2090
2091static jit_word_t
2092_bmsi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
2093{
2094 jit_word_t w;
2095 jit_int32_t reg;
2096 reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
2097 andi(rn(reg), r0, i1);
2098 w = bnei(i0, rn(reg), 0);
2099 jit_unget_reg(reg);
2100 return (w);
2101}
2102
2103static jit_word_t
2104_bmcr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2105{
2106 jit_word_t w;
2107 jit_int32_t reg;
2108 reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
2109 andr(rn(reg), r0, r1);
2110 w = beqi(i0, rn(reg), 0);
2111 jit_unget_reg(reg);
2112 return (w);
2113}
2114
2115static jit_word_t
2116_bmci(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
2117{
2118 jit_word_t w;
2119 jit_int32_t reg;
2120 reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
2121 andi(rn(reg), r0, i1);
2122 w = beqi(i0, rn(reg), 0);
2123 jit_unget_reg(reg);
2124 return (w);
2125}
2126
2127static jit_word_t
2128_boaddr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2129{
2130 jit_word_t d, w;
2131 ADDO(r0, r0, r1);
2132 MCRXR(CR_0);
2133 w = _jit->pc.w;
2134 d = (i0 - w) & ~3;
2135 BGT(d); /* GT = bit 1 of XER = OV */
2136 return (w);
2137}
2138
2139static jit_word_t
2140_boaddi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
2141{
2142 jit_word_t w;
2143 jit_int32_t reg;
2144 reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
2145 movi(rn(reg), i1);
2146 w = boaddr(i0, r0, rn(reg));
2147 jit_unget_reg(reg);
2148 return (w);
2149}
2150
2151static jit_word_t
2152_bxaddr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2153{
2154 jit_word_t d, w;
2155 ADDO(r0, r0, r1);
2156 MCRXR(CR_0);
2157 w = _jit->pc.w;
2158 d = (i0 - w) & ~3;
2159 BLE(d);
2160 return (w);
2161}
2162
2163static jit_word_t
2164_bxaddi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
2165{
2166 jit_word_t w;
2167 jit_int32_t reg;
2168 reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
2169 movi(rn(reg), i1);
2170 w = bxaddr(i0, r0, rn(reg));
2171 jit_unget_reg(reg);
2172 return (w);
2173}
2174
2175static jit_word_t
2176_bosubr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2177{
2178 jit_word_t d, w;
2179 SUBO(r0, r0, r1);
2180 MCRXR(CR_0);
2181 w = _jit->pc.w;
2182 d = (i0 - w) & ~3;
2183 BGT(d);
2184 return (w);
2185}
2186
2187static jit_word_t
2188_bosubi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
2189{
2190 jit_word_t w;
2191 jit_int32_t reg;
2192 reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
2193 movi(rn(reg), i1);
2194 w = bosubr(i0, r0, rn(reg));
2195 jit_unget_reg(reg);
2196 return (w);
2197}
2198
2199static jit_word_t
2200_bxsubr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2201{
2202 jit_word_t d, w;
2203 SUBO(r0, r0, r1);
2204 MCRXR(CR_0);
2205 w = _jit->pc.w;
2206 d = (i0 - w) & ~3;
2207 BLE(d);
2208 return (w);
2209}
2210
2211static jit_word_t
2212_bxsubi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
2213{
2214 jit_word_t w;
2215 jit_int32_t reg;
2216 reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
2217 movi(rn(reg), i1);
2218 w = bxsubr(i0, r0, rn(reg));
2219 jit_unget_reg(reg);
2220 return (w);
2221}
2222
2223static jit_word_t
2224_boaddr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2225{
2226 jit_word_t d, w;
2227 ADDC(r0, r0, r1);
2228 MCRXR(CR_0);
2229 w = _jit->pc.w;
2230 d = (i0 - w) & ~3;
2231 BEQ(d); /* EQ = bit 2 of XER = CA */
2232 return (w);
2233}
2234
2235static jit_word_t
2236_boaddi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
2237{
2238 jit_int32_t reg;
2239 jit_word_t d, w;
2240 if (can_sign_extend_short_p(i1)) {
2241 ADDIC(r0, r0, i1);
2242 MCRXR(CR_0);
2243 w = _jit->pc.w;
2244 d = (i0 - w) & ~3;
2245 BEQ(d);
2246 return (w);
2247 }
2248 reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
2249 movi(rn(reg), i1);
2250 w = boaddr_u(i0, r0, rn(reg));
2251 jit_unget_reg(reg);
2252 return (w);
2253}
2254
2255static jit_word_t
2256_bxaddr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2257{
2258 jit_word_t d, w;
2259 ADDC(r0, r0, r1);
2260 MCRXR(CR_0);
2261 w = _jit->pc.w;
2262 d = (i0 - w) & ~3;
2263 BNE(d);
2264 return (w);
2265}
2266
2267static jit_word_t
2268_bxaddi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
2269{
2270 jit_int32_t reg;
2271 jit_word_t d, w;
2272 if (can_sign_extend_short_p(i1)) {
2273 ADDIC(r0, r0, i1);
2274 MCRXR(CR_0);
2275 w = _jit->pc.w;
2276 d = (i0 - w) & ~3;
2277 BNE(d);
2278 return (w);
2279 }
2280 reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
2281 movi(rn(reg), i1);
2282 w = bxaddr_u(i0, r0, rn(reg));
2283 jit_unget_reg(reg);
2284 return (w);
2285}
2286
2287static jit_word_t
2288_bosubr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2289{
2290 jit_word_t d, w;
2291 SUBC(r0, r0, r1);
2292 MCRXR(CR_0);
2293 w = _jit->pc.w;
2294 d = (i0 - w) & ~3;
2295 BNE(d); /* PPC uses "carry" not "borrow" */
2296 return (w);
2297}
2298
2299static jit_word_t
2300_bosubi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
2301{
2302 jit_word_t w;
2303 jit_int32_t reg;
2304 reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
2305 movi(rn(reg), i1);
2306 w = bosubr_u(i0, r0, rn(reg));
2307 jit_unget_reg(reg);
2308 return (w);
2309}
2310
2311static jit_word_t
2312_bxsubr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2313{
2314 jit_word_t d, w;
2315 SUBC(r0, r0, r1);
2316 MCRXR(CR_0);
2317 w = _jit->pc.w;
2318 d = (i0 - w) & ~3;
2319 BEQ(d);
2320 return (w);
2321}
2322
2323static jit_word_t
2324_bxsubi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
2325{
2326 jit_word_t w;
2327 jit_int32_t reg;
2328 reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
2329 movi(rn(reg), i1);
2330 w = bxsubr_u(i0, r0, rn(reg));
2331 jit_unget_reg(reg);
2332 return (w);
2333}
2334
2335static void
2336_ldr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
2337{
2338 ldr_uc(r0, r1);
2339 extr_c(r0, r0);
2340}
2341
2342static void
2343_ldi_c(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
2344{
2345 ldi_uc(r0, i0);
2346 extr_c(r0, r0);
2347}
2348
2349static void
2350_ldxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
2351{
2352 ldxr_uc(r0, r1, r2);
2353 extr_c(r0, r0);
2354}
2355
2356static void
2357_ldxi_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2358{
2359 ldxi_uc(r0, r1, i0);
2360 extr_c(r0, r0);
2361}
2362
2363static void
2364_ldi_uc(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
2365{
2366 jit_bool_t inv;
2367 jit_int32_t reg;
2368 jit_word_t lo, hi;
2369 if (can_sign_extend_short_p(i0))
2370 LBZ(r0, _R0_REGNO, i0);
2371 else if (can_sign_extend_int_p(i0)) {
2372 hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15));
2373 lo = (jit_int16_t)(i0 - (hi << 16));
2374 reg = jit_get_reg(jit_class_gpr);
2375 if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr);
2376 LIS(rn(reg), hi);
2377 LBZ(r0, rn(reg), lo);
2378 jit_unget_reg(reg);
2379 if (inv) jit_unget_reg(_R0);
2380 }
2381 else {
2382 reg = jit_get_reg(jit_class_gpr);
2383 movi(rn(reg), i0);
2384 ldr_uc(r0, rn(reg));
2385 jit_unget_reg(reg);
2386 }
2387}
2388
2389static void
2390_ldxr_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
2391{
2392 jit_int32_t reg;
2393 if (r1 == _R0_REGNO) {
2394 if (r2 != _R0_REGNO)
2395 LBZX(r0, r2, r1);
2396 else {
2397 reg = jit_get_reg(jit_class_gpr);
2398 movr(rn(reg), r1);
2399 LBZX(r0, rn(reg), r2);
2400 jit_unget_reg(reg);
2401 }
2402 }
2403 else
2404 LBZX(r0, r1, r2);
2405}
2406
2407static void
2408_ldxi_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2409{
2410 jit_int32_t reg;
2411 if (i0 == 0)
2412 ldr_uc(r0, r1);
2413 else if (can_sign_extend_short_p(i0)) {
2414 if (r1 == _R0_REGNO) {
2415 reg = jit_get_reg(jit_class_gpr);
2416 movr(rn(reg), r1);
2417 LBZ(r0, rn(reg), i0);
2418 jit_unget_reg(reg);
2419 }
2420 else
2421 LBZ(r0, r1, i0);
2422 }
2423 else {
2424 reg = jit_get_reg(jit_class_gpr);
2425 movi(rn(reg), i0);
2426 ldxr_uc(r0, r1, rn(reg));
2427 jit_unget_reg(reg);
2428 }
2429}
2430
2431static void
2432_ldi_s(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
2433{
2434 jit_bool_t inv;
2435 jit_int32_t reg;
2436 jit_word_t lo, hi;
2437 if (can_sign_extend_short_p(i0))
2438 LHA(r0, _R0_REGNO, i0);
2439 else if (can_sign_extend_int_p(i0)) {
2440 hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15));
2441 lo = (jit_int16_t)(i0 - (hi << 16));
2442 reg = jit_get_reg(jit_class_gpr);
2443 if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr);
2444 LIS(rn(reg), hi);
2445 LHA(r0, rn(reg), lo);
2446 jit_unget_reg(reg);
2447 if (inv) jit_unget_reg(_R0);
2448 }
2449 else {
2450 reg = jit_get_reg(jit_class_gpr);
2451 movi(rn(reg), i0);
2452 ldr_s(r0, rn(reg));
2453 jit_unget_reg(reg);
2454 }
2455}
2456
2457static void
2458_ldxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
2459{
2460 jit_int32_t reg;
2461 if (r1 == _R0_REGNO) {
2462 if (r2 != _R0_REGNO)
2463 LHAX(r0, r2, r1);
2464 else {
2465 reg = jit_get_reg(jit_class_gpr);
2466 movr(rn(reg), r1);
2467 LHAX(r0, rn(reg), r2);
2468 jit_unget_reg(reg);
2469 }
2470 }
2471 else
2472 LHAX(r0, r1, r2);
2473}
2474
2475static void
2476_ldxi_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2477{
2478 jit_int32_t reg;
2479 if (i0 == 0)
2480 ldr_s(r0, r1);
2481 else if (can_sign_extend_short_p(i0)) {
2482 if (r1 == _R0_REGNO) {
2483 reg = jit_get_reg(jit_class_gpr);
2484 movr(rn(reg), r1);
2485 LHA(r0, rn(reg), i0);
2486 jit_unget_reg(reg);
2487 }
2488 else
2489 LHA(r0, r1, i0);
2490 }
2491 else {
2492 reg = jit_get_reg(jit_class_gpr);
2493 movi(rn(reg), i0);
2494 ldxr_s(r0, r1, rn(reg));
2495 jit_unget_reg(reg);
2496 }
2497}
2498
2499static void
2500_ldi_us(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
2501{
2502 jit_bool_t inv;
2503 jit_int32_t reg;
2504 jit_word_t lo, hi;
2505 if (can_sign_extend_short_p(i0))
2506 LHZ(r0, _R0_REGNO, i0);
2507 else if (can_sign_extend_int_p(i0)) {
2508 hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15));
2509 lo = (jit_int16_t)(i0 - (hi << 16));
2510 reg = jit_get_reg(jit_class_gpr);
2511 if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr);
2512 LIS(rn(reg), hi);
2513 LHZ(r0, rn(reg), lo);
2514 jit_unget_reg(reg);
2515 if (inv) jit_unget_reg(_R0);
2516 }
2517 else {
2518 reg = jit_get_reg(jit_class_gpr);
2519 movi(rn(reg), i0);
2520 ldr_us(r0, rn(reg));
2521 jit_unget_reg(reg);
2522 }
2523}
2524
2525static void
2526_ldxr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
2527{
2528 jit_int32_t reg;
2529 if (r1 == _R0_REGNO) {
2530 if (r2 != _R0_REGNO)
2531 LHZX(r0, r2, r1);
2532 else {
2533 reg = jit_get_reg(jit_class_gpr);
2534 movr(rn(reg), r1);
2535 LHZX(r0, rn(reg), r2);
2536 jit_unget_reg(reg);
2537 }
2538 }
2539 else
2540 LHZX(r0, r1, r2);
2541}
2542
2543static void
2544_ldxi_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2545{
2546 jit_int32_t reg;
2547 if (i0 == 0)
2548 ldr_us(r0, r1);
2549 else if (can_sign_extend_short_p(i0)) {
2550 if (r1 == _R0_REGNO) {
2551 reg = jit_get_reg(jit_class_gpr);
2552 movr(rn(reg), r1);
2553 LHZ(r0, rn(reg), i0);
2554 jit_unget_reg(reg);
2555 }
2556 else
2557 LHZ(r0, r1, i0);
2558 }
2559 else {
2560 reg = jit_get_reg(jit_class_gpr);
2561 movi(rn(reg), i0);
2562 ldxr_us(r0, r1, rn(reg));
2563 jit_unget_reg(reg);
2564 }
2565}
2566
2567# if __WORDSIZE == 32
2568static void
2569_ldi_i(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
2570{
2571 jit_bool_t inv;
2572 jit_int32_t reg;
2573 jit_word_t lo, hi;
2574 if (can_sign_extend_short_p(i0))
2575 LWZ(r0, _R0_REGNO, i0);
2576 else if (can_sign_extend_int_p(i0)) {
2577 hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15));
2578 lo = (jit_int16_t)(i0 - (hi << 16));
2579 reg = jit_get_reg(jit_class_gpr);
2580 if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr);
2581 LIS(rn(reg), hi);
2582 LWZ(r0, rn(reg), lo);
2583 jit_unget_reg(reg);
2584 if (inv) jit_unget_reg(_R0);
2585 }
2586 else {
2587 reg = jit_get_reg(jit_class_gpr);
2588 movi(rn(reg), i0);
2589 ldr_i(r0, rn(reg));
2590 jit_unget_reg(reg);
2591 }
2592}
2593
2594static void
2595_ldxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
2596{
2597 jit_int32_t reg;
2598 if (r1 == _R0_REGNO) {
2599 if (r2 != _R0_REGNO)
2600 LWZX(r0, r2, r1);
2601 else {
2602 reg = jit_get_reg(jit_class_gpr);
2603 movr(rn(reg), r1);
2604 LWZX(r0, rn(reg), r2);
2605 jit_unget_reg(reg);
2606 }
2607 }
2608 else
2609 LWZX(r0, r1, r2);
2610}
2611
2612static void
2613_ldxi_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2614{
2615 jit_int32_t reg;
2616 if (i0 == 0)
2617 ldr_i(r0, r1);
2618 else if (can_sign_extend_short_p(i0)) {
2619 if (r1 == _R0_REGNO) {
2620 reg = jit_get_reg(jit_class_gpr);
2621 movr(rn(reg), r1);
2622 LWZ(r0, rn(reg), i0);
2623 jit_unget_reg(reg);
2624 }
2625 else
2626 LWZ(r0, r1, i0);
2627 }
2628 else {
2629 reg = jit_get_reg(jit_class_gpr);
2630 movi(rn(reg), i0);
2631 ldxr_i(r0, r1, rn(reg));
2632 jit_unget_reg(reg);
2633 }
2634}
2635
2636# else
2637static void
2638_ldi_i(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
2639{
2640 jit_bool_t inv;
2641 jit_int32_t reg;
2642 jit_word_t lo, hi;
2643 if (can_sign_extend_short_p(i0))
2644 LWA(r0, _R0_REGNO, i0);
2645 else if (can_sign_extend_int_p(i0)) {
2646 hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15));
2647 lo = (jit_int16_t)(i0 - (hi << 16));
2648 reg = jit_get_reg(jit_class_gpr);
2649 if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr);
2650 LIS(rn(reg), hi);
2651 LWA(r0, rn(reg), lo);
2652 jit_unget_reg(reg);
2653 if (inv) jit_unget_reg(_R0);
2654 }
2655 else {
2656 reg = jit_get_reg(jit_class_gpr);
2657 movi(rn(reg), i0);
2658 ldr_i(r0, rn(reg));
2659 jit_unget_reg(reg);
2660 }
2661}
2662
2663static void
2664_ldxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
2665{
2666 jit_int32_t reg;
2667 if (r1 == _R0_REGNO) {
2668 if (r2 != _R0_REGNO)
2669 LWZX(r0, r2, r1);
2670 else {
2671 reg = jit_get_reg(jit_class_gpr);
2672 movr(rn(reg), r1);
2673 LWAX(r0, rn(reg), r2);
2674 jit_unget_reg(reg);
2675 }
2676 }
2677 else
2678 LWZX(r0, r1, r2);
2679}
2680
2681static void
2682_ldxi_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2683{
2684 jit_int32_t reg;
2685 if (i0 == 0)
2686 ldr_i(r0, r1);
2687 else if (can_sign_extend_short_p(i0)) {
2688 if (r1 == _R0_REGNO) {
2689 reg = jit_get_reg(jit_class_gpr);
2690 movr(rn(reg), r1);
2691 LWA(r0, rn(reg), i0);
2692 jit_unget_reg(reg);
2693 }
2694 else
2695 LWA(r0, r1, i0);
2696 }
2697 else {
2698 reg = jit_get_reg(jit_class_gpr);
2699 movi(rn(reg), i0);
2700 ldxr_i(r0, r1, rn(reg));
2701 jit_unget_reg(reg);
2702 }
2703}
2704
2705static void
2706_ldi_ui(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
2707{
2708 jit_bool_t inv;
2709 jit_int32_t reg;
2710 jit_word_t lo, hi;
2711 if (can_sign_extend_short_p(i0))
2712 LWZ(r0, _R0_REGNO, i0);
2713 else if (can_sign_extend_int_p(i0)) {
2714 hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15));
2715 lo = (jit_int16_t)(i0 - (hi << 16));
2716 reg = jit_get_reg(jit_class_gpr);
2717 if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr);
2718 LIS(rn(reg), hi);
2719 LWZ(r0, rn(reg), lo);
2720 jit_unget_reg(reg);
2721 if (inv) jit_unget_reg(_R0);
2722 }
2723 else {
2724 reg = jit_get_reg(jit_class_gpr);
2725 movi(rn(reg), i0);
2726 ldr_ui(r0, rn(reg));
2727 jit_unget_reg(reg);
2728 }
2729}
2730
2731static void
2732_ldxr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
2733{
2734 jit_int32_t reg;
2735 if (r1 == _R0_REGNO) {
2736 if (r2 != _R0_REGNO)
2737 LWZX(r0, r2, r1);
2738 else {
2739 reg = jit_get_reg(jit_class_gpr);
2740 movr(rn(reg), r1);
2741 LWZX(r0, rn(reg), r2);
2742 jit_unget_reg(reg);
2743 }
2744 }
2745 else
2746 LWZX(r0, r1, r2);
2747}
2748
2749static void
2750_ldxi_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2751{
2752 jit_int32_t reg;
2753 if (i0 == 0)
2754 ldr_i(r0, r1);
2755 else if (can_sign_extend_short_p(i0)) {
2756 if (r1 == _R0_REGNO) {
2757 reg = jit_get_reg(jit_class_gpr);
2758 movr(rn(reg), r1);
2759 LWZ(r0, rn(reg), i0);
2760 jit_unget_reg(reg);
2761 }
2762 else
2763 LWZ(r0, r1, i0);
2764 }
2765 else {
2766 reg = jit_get_reg(jit_class_gpr);
2767 movi(rn(reg), i0);
2768 ldxr_ui(r0, r1, rn(reg));
2769 jit_unget_reg(reg);
2770 }
2771}
2772
2773static void
2774_ldi_l(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
2775{
2776 jit_bool_t inv;
2777 jit_int32_t reg;
2778 jit_word_t lo, hi;
2779 if (can_sign_extend_short_p(i0))
2780 LD(r0, _R0_REGNO, i0);
2781 else if (can_sign_extend_int_p(i0)) {
2782 hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15));
2783 lo = (jit_int16_t)(i0 - (hi << 16));
2784 reg = jit_get_reg(jit_class_gpr);
2785 if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr);
2786 LIS(rn(reg), hi);
2787 LD(r0, rn(reg), lo);
2788 jit_unget_reg(reg);
2789 if (inv) jit_unget_reg(_R0);
2790 }
2791 else {
2792 reg = jit_get_reg(jit_class_gpr);
2793 movi(rn(reg), i0);
2794 ldr_l(r0, rn(reg));
2795 jit_unget_reg(reg);
2796 }
2797}
2798
2799static void
2800_ldxr_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
2801{
2802 jit_int32_t reg;
2803 if (r1 == _R0_REGNO) {
2804 if (r2 != _R0_REGNO)
2805 LDX(r0, r2, r1);
2806 else {
2807 reg = jit_get_reg(jit_class_gpr);
2808 movr(rn(reg), r1);
2809 LDX(r0, rn(reg), r2);
2810 jit_unget_reg(reg);
2811 }
2812 }
2813 else
2814 LDX(r0, r1, r2);
2815}
2816
2817static void
2818_ldxi_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2819{
2820 jit_int32_t reg;
2821 if (i0 == 0)
2822 ldr_l(r0, r1);
2823 else if (can_sign_extend_short_p(i0)) {
2824 if (r1 == _R0_REGNO) {
2825 reg = jit_get_reg(jit_class_gpr);
2826 movr(rn(reg), r1);
2827 LD(r0, rn(reg), i0);
2828 jit_unget_reg(reg);
2829 }
2830 else
2831 LD(r0, r1, i0);
2832 }
2833 else {
2834 reg = jit_get_reg(jit_class_gpr);
2835 movi(rn(reg), i0);
2836 ldxr_l(r0, r1, rn(reg));
2837 jit_unget_reg(reg);
2838 }
2839}
2840# endif
2841
2842static void
2843_sti_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
2844{
2845 jit_bool_t inv;
2846 jit_int32_t reg;
2847 jit_word_t lo, hi;
2848 if (can_sign_extend_short_p(i0))
2849 STB(r0, _R0_REGNO, i0);
2850 else if (can_sign_extend_int_p(i0)) {
2851 hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15));
2852 lo = (jit_int16_t)(i0 - (hi << 16));
2853 reg = jit_get_reg(jit_class_gpr);
2854 if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr);
2855 LIS(rn(reg), hi);
2856 STB(r0, rn(reg), lo);
2857 jit_unget_reg(reg);
2858 if (inv) jit_unget_reg(_R0);
2859 }
2860 else {
2861 reg = jit_get_reg(jit_class_gpr);
2862 movi(rn(reg), i0);
2863 str_c(rn(reg), r0);
2864 jit_unget_reg(reg);
2865 }
2866}
2867
2868static void
2869_stxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
2870{
2871 jit_int32_t reg;
2872 if (r0 == _R0_REGNO) {
2873 if (r1 != _R0_REGNO)
2874 STBX(r2, r1, r0);
2875 else {
2876 reg = jit_get_reg(jit_class_gpr);
2877 movr(rn(reg), r0);
2878 STBX(r2, rn(reg), r1);
2879 jit_unget_reg(reg);
2880 }
2881 }
2882 else
2883 STBX(r2, r0, r1);
2884}
2885
2886static void
2887_stxi_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2888{
2889 jit_int32_t reg;
2890 if (i0 == 0)
2891 str_c(r0, r1);
2892 else if (can_sign_extend_short_p(i0)) {
2893 if (r0 == _R0_REGNO) {
2894 reg = jit_get_reg(jit_class_gpr);
2895 movr(rn(reg), i0);
2896 STB(r1, rn(reg), i0);
2897 jit_unget_reg(reg);
2898 }
2899 else
2900 STB(r1, r0, i0);
2901 }
2902 else {
2903 reg = jit_get_reg(jit_class_gpr);
2904 movi(rn(reg), i0);
2905 stxr_c(rn(reg), r0, r1);
2906 jit_unget_reg(reg);
2907 }
2908}
2909
2910static void
2911_sti_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
2912{
2913 jit_bool_t inv;
2914 jit_int32_t reg;
2915 jit_word_t lo, hi;
2916 if (can_sign_extend_short_p(i0))
2917 STH(r0, _R0_REGNO, i0);
2918 else if (can_sign_extend_int_p(i0)) {
2919 hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15));
2920 lo = (jit_int16_t)(i0 - (hi << 16));
2921 reg = jit_get_reg(jit_class_gpr);
2922 if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr);
2923 LIS(rn(reg), hi);
2924 STH(r0, rn(reg), lo);
2925 jit_unget_reg(reg);
2926 if (inv) jit_unget_reg(_R0);
2927 }
2928 else {
2929 reg = jit_get_reg(jit_class_gpr);
2930 movi(rn(reg), i0);
2931 str_s(rn(reg), r0);
2932 jit_unget_reg(reg);
2933 }
2934}
2935
2936static void
2937_stxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
2938{
2939 jit_int32_t reg;
2940 if (r0 == _R0_REGNO) {
2941 if (r1 != _R0_REGNO)
2942 STHX(r2, r1, r0);
2943 else {
2944 reg = jit_get_reg(jit_class_gpr);
2945 movr(rn(reg), r0);
2946 STHX(r2, rn(reg), r1);
2947 jit_unget_reg(reg);
2948 }
2949 }
2950 else
2951 STHX(r2, r0, r1);
2952}
2953
2954static void
2955_stxi_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2956{
2957 jit_int32_t reg;
2958 if (i0 == 0)
2959 str_s(r0, r1);
2960 else if (can_sign_extend_short_p(i0)) {
2961 if (r0 == _R0_REGNO) {
2962 reg = jit_get_reg(jit_class_gpr);
2963 movr(rn(reg), i0);
2964 STH(r1, rn(reg), i0);
2965 jit_unget_reg(reg);
2966 }
2967 else
2968 STH(r1, r0, i0);
2969 }
2970 else {
2971 reg = jit_get_reg(jit_class_gpr);
2972 movi(rn(reg), i0);
2973 stxr_s(rn(reg), r0, r1);
2974 jit_unget_reg(reg);
2975 }
2976}
2977
2978static void
2979_sti_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
2980{
2981 jit_bool_t inv;
2982 jit_int32_t reg;
2983 jit_word_t lo, hi;
2984 if (can_sign_extend_short_p(i0))
2985 STW(r0, _R0_REGNO, i0);
2986 else if (can_sign_extend_int_p(i0)) {
2987 hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15));
2988 lo = (jit_int16_t)(i0 - (hi << 16));
2989 reg = jit_get_reg(jit_class_gpr);
2990 if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr);
2991 LIS(rn(reg), hi);
2992 STW(r0, rn(reg), lo);
2993 jit_unget_reg(reg);
2994 if (inv) jit_unget_reg(_R0);
2995 }
2996 else {
2997 reg = jit_get_reg(jit_class_gpr);
2998 movi(rn(reg), i0);
2999 str_i(rn(reg), r0);
3000 jit_unget_reg(reg);
3001 }
3002}
3003
3004static void
3005_stxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
3006{
3007 jit_int32_t reg;
3008 if (r0 == _R0_REGNO) {
3009 if (r1 != _R0_REGNO)
3010 STWX(r2, r1, r0);
3011 else {
3012 reg = jit_get_reg(jit_class_gpr);
3013 movr(rn(reg), r0);
3014 STWX(r2, rn(reg), r1);
3015 jit_unget_reg(reg);
3016 }
3017 }
3018 else
3019 STWX(r2, r0, r1);
3020}
3021
3022static void
3023_stxi_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
3024{
3025 jit_int32_t reg;
3026 if (i0 == 0)
3027 str_i(r0, r1);
3028 else if (can_sign_extend_short_p(i0)) {
3029 if (r0 == _R0_REGNO) {
3030 reg = jit_get_reg(jit_class_gpr);
3031 movr(rn(reg), i0);
3032 STW(r1, rn(reg), i0);
3033 jit_unget_reg(reg);
3034 }
3035 else
3036 STW(r1, r0, i0);
3037 }
3038 else {
3039 reg = jit_get_reg(jit_class_gpr);
3040 movi(rn(reg), i0);
3041 stxr_i(rn(reg), r0, r1);
3042 jit_unget_reg(reg);
3043 }
3044}
3045
3046# if __WORDSIZE == 64
3047static void
3048_sti_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
3049{
3050 jit_bool_t inv;
3051 jit_int32_t reg;
3052 jit_word_t lo, hi;
3053 if (can_sign_extend_short_p(i0))
3054 STD(r0, _R0_REGNO, i0);
3055 else if (can_sign_extend_int_p(i0)) {
3056 hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15));
3057 lo = (jit_int16_t)(i0 - (hi << 16));
3058 reg = jit_get_reg(jit_class_gpr);
3059 if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr);
3060 LIS(rn(reg), hi);
3061 STD(r0, rn(reg), lo);
3062 jit_unget_reg(reg);
3063 if (inv) jit_unget_reg(_R0);
3064 }
3065 else {
3066 reg = jit_get_reg(jit_class_gpr);
3067 movi(rn(reg), i0);
3068 str_l(rn(reg), r0);
3069 jit_unget_reg(reg);
3070 }
3071}
3072
3073static void
3074_stxr_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
3075{
3076 jit_int32_t reg;
3077 if (r0 == _R0_REGNO) {
3078 if (r1 != _R0_REGNO)
3079 STDX(r2, r1, r0);
3080 else {
3081 reg = jit_get_reg(jit_class_gpr);
3082 movr(rn(reg), r0);
3083 STDX(r2, rn(reg), r1);
3084 jit_unget_reg(reg);
3085 }
3086 }
3087 else
3088 STDX(r2, r0, r1);
3089}
3090
3091static void
3092_stxi_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
3093{
3094 jit_int32_t reg;
3095 if (i0 == 0)
3096 str_l(r0, r1);
3097 else if (can_sign_extend_short_p(i0)) {
3098 if (r0 == _R0_REGNO) {
3099 reg = jit_get_reg(jit_class_gpr);
3100 movr(rn(reg), i0);
3101 STD(r1, rn(reg), i0);
3102 jit_unget_reg(reg);
3103 }
3104 else
3105 STD(r1, r0, i0);
3106 }
3107 else {
3108 reg = jit_get_reg(jit_class_gpr);
3109 movi(rn(reg), i0);
3110 stxr_l(rn(reg), r0, r1);
3111 jit_unget_reg(reg);
3112 }
3113}
3114# endif
3115
3116static void
3117_jmpr(jit_state_t *_jit, jit_int32_t r0)
3118{
3119#if 0
3120 MTLR(r0);
3121 BLR();
3122#else
3123 MTCTR(r0);
3124 BCTR();
3125#endif
3126}
3127
3128/* pc relative jump */
3129static jit_word_t
3130_jmpi(jit_state_t *_jit, jit_word_t i0)
3131{
3132 jit_int32_t reg;
3133 jit_word_t w, d;
3134 w = _jit->pc.w;
3135 d = (i0 - w) & ~3;
3136 if (can_sign_extend_jump_p(d))
3137 B(d);
3138 else {
3139 reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
3140 w = movi_p(rn(reg), i0);
3141 jmpr(rn(reg));
3142 jit_unget_reg(reg);
3143 }
3144 return (w);
3145}
3146
3147/* absolute jump */
3148static jit_word_t
3149_jmpi_p(jit_state_t *_jit, jit_word_t i0)
3150{
3151 jit_word_t w;
3152 jit_int32_t reg;
3153 reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
3154 w = movi_p(rn(reg), i0);
3155 jmpr(rn(reg));
3156 jit_unget_reg(reg);
3157 return (w);
3158}
3159
3160static void
3161_callr(jit_state_t *_jit, jit_int32_t r0
3162# if _CALL_SYSV
3163 , jit_int32_t varargs
3164# endif
3165 )
3166{
3167# if _CALL_AIXDESC
3168 stxi(sizeof(void*) * 5, _SP_REGNO, _R2_REGNO);
3169 /* FIXME Pretend to not know about r11? */
3170 if (r0 == _R0_REGNO) {
3171 movr(_R11_REGNO, _R0_REGNO);
3172 ldxi(_R2_REGNO, _R11_REGNO, sizeof(void*));
3173 ldxi(_R11_REGNO, _R11_REGNO, sizeof(void*) * 2);
3174 }
3175 else {
3176 ldxi(_R2_REGNO, r0, sizeof(void*));
3177 ldxi(_R11_REGNO, r0, sizeof(void*) * 2);
3178 }
3179 ldr(r0, r0);
3180# else
3181# if _CALL_SYSV
3182 /* Tell double arguments were passed in registers. */
3183 if (varargs)
3184 CREQV(6, 6, 6);
3185# endif
3186 movr(_R12_REGNO, r0);
3187# endif
3188
3189 MTCTR(r0);
3190 BCTRL();
3191
3192# if _CALL_AIXDESC
3193 ldxi(_R2_REGNO, _SP_REGNO, sizeof(void*) * 5);
3194# endif
3195}
3196
3197/* assume fixed address or reachable address */
3198static void
3199_calli(jit_state_t *_jit, jit_word_t i0
3200# if _CALL_SYSV
3201 , jit_int32_t varargs
3202# endif
3203 )
3204{
3205# if _CALL_SYSV
3206 jit_word_t d;
3207 d = (i0 - _jit->pc.w) & ~3;
3208 if (can_sign_extend_jump_p(d))
3209 BL(d);
3210 else
3211# endif
3212 {
3213 movi(_R12_REGNO, i0);
3214 callr(_R12_REGNO
3215# if _CALL_SYSV
3216 , varargs
3217# endif
3218 );
3219 }
3220}
3221
3222/* absolute jump */
3223static jit_word_t
3224_calli_p(jit_state_t *_jit, jit_word_t i0
3225# if _CALL_SYSV
3226 , jit_int32_t varargs
3227# endif
3228 )
3229{
3230 jit_word_t w;
3231 w = movi_p(_R12_REGNO, i0);
3232 callr(_R12_REGNO
3233# if _CALL_SYSV
3234 , varargs
3235# endif
3236 );
3237 return (w);
3238}
3239
3240/* order is not guaranteed to be sequential */
3241static jit_int32_t save[] = {
3242 _R14, _R15, _R16, _R17, _R18, _R19, _R20, _R21, _R22,
3243 _R23, _R24, _R25, _R26, _R27, _R28, _R29, _R30, _R31,
3244};
3245
3246static void
3247_prolog(jit_state_t *_jit, jit_node_t *node)
3248{
3249 unsigned long regno;
3250 jit_word_t offset;
3251
3252 if (_jitc->function->define_frame || _jitc->function->assume_frame) {
3253 jit_int32_t frame = -_jitc->function->frame;
3254 assert(_jitc->function->self.aoff >= frame);
3255 if (_jitc->function->assume_frame)
3256 return;
3257 _jitc->function->self.aoff = frame;
3258 }
3259 if (_jitc->function->allocar) {
3260 _jitc->function->self.aoff -= 2 * sizeof(jit_word_t);
3261 _jitc->function->self.aoff &= -16;
3262 }
3263 _jitc->function->stack = ((_jitc->function->self.alen +
3264 _jitc->function->self.size -
3265 _jitc->function->self.aoff) + 15) & -16;
3266
3267 /* return address */
3268 MFLR(_R0_REGNO);
3269
3270 /* params >= %r31+params_offset+(8*sizeof(jit_word_t))
3271 * alloca < %r31-80 */
3272
3273#if _CALL_SYSV
3274 stxi(sizeof(jit_word_t), _SP_REGNO, _R0_REGNO);
3275#else
3276 stxi(sizeof(void*) * 2, _SP_REGNO, _R0_REGNO);
3277#endif
3278 offset = -gpr_save_area;
3279 for (regno = 0; regno < jit_size(save); regno++, offset += sizeof(void*)) {
3280 if (jit_regset_tstbit(&_jitc->function->regset, save[regno]))
3281 stxi(offset, _SP_REGNO, rn(save[regno]));
3282 }
3283 for (offset = 0; offset < 8; offset++) {
3284 if (jit_regset_tstbit(&_jitc->function->regset, _F14 + offset))
3285 stxi_d(-(gpr_save_area + 8 + offset * 8),
3286 _SP_REGNO, rn(_F14 + offset));
3287 }
3288
3289 stxi(-(sizeof(void*)), _SP_REGNO, _FP_REGNO);
3290
3291 movr(_FP_REGNO, _SP_REGNO);
3292#if __WORDSIZE == 32
3293 STWU(_SP_REGNO, _SP_REGNO, -_jitc->function->stack);
3294#else
3295 STDU(_SP_REGNO, _SP_REGNO, -_jitc->function->stack);
3296#endif
3297
3298 if (_jitc->function->allocar) {
3299 regno = jit_get_reg(jit_class_gpr);
3300 movi(rn(regno), _jitc->function->self.aoff);
3301 stxi_i(_jitc->function->aoffoff, _FP_REGNO, rn(regno));
3302 jit_unget_reg(regno);
3303 }
3304
3305#if !_CALL_SYSV
3306 if (_jitc->function->self.call & jit_call_varargs) {
3307 for (regno = _jitc->function->vagp; jit_arg_reg_p(regno); ++regno)
3308 stxi(params_offset + regno * sizeof(jit_word_t),
3309 _FP_REGNO, rn(JIT_RA0 - regno));
3310 }
3311#else
3312 if (_jitc->function->self.call & jit_call_varargs) {
3313 for (regno = _jitc->function->vagp; jit_arg_reg_p(regno); ++regno)
3314 stxi(_jitc->function->vaoff + first_gp_offset +
3315 regno * sizeof(jit_word_t), _FP_REGNO, rn(JIT_RA0 - regno));
3316 for (regno = _jitc->function->vafp; jit_arg_f_reg_p(regno); ++regno)
3317 stxi_d(_jitc->function->vaoff + first_fp_offset +
3318 regno * va_fp_increment, _FP_REGNO,
3319 rn(JIT_FA0 - regno));
3320 }
3321#endif
3322}
3323
3324static void
3325_epilog(jit_state_t *_jit, jit_node_t *node)
3326{
3327 unsigned long regno;
3328 jit_word_t offset;
3329
3330 if (_jitc->function->assume_frame)
3331 return;
3332 if (_jitc->function->allocar)
3333 ldr(_SP_REGNO, _SP_REGNO);
3334 else
3335 addi(_SP_REGNO, _SP_REGNO, _jitc->function->stack);
3336#if _CALL_SYSV
3337 ldxi(_R0_REGNO, _SP_REGNO, sizeof(jit_word_t));
3338#else
3339 ldxi(_R0_REGNO, _SP_REGNO, sizeof(void*) * 2);
3340#endif
3341 offset = -gpr_save_area;
3342 for (regno = 0; regno < jit_size(save); regno++, offset += sizeof(void*)) {
3343 if (jit_regset_tstbit(&_jitc->function->regset, save[regno]))
3344 ldxi(rn(save[regno]), _SP_REGNO, offset);
3345 }
3346 for (offset = 0; offset < 8; offset++) {
3347 if (jit_regset_tstbit(&_jitc->function->regset, _F14 + offset))
3348 ldxi_d(rn(_F14 + offset), _SP_REGNO,
3349 -(gpr_save_area + 8 + offset * 8));
3350 }
3351
3352 MTLR(_R0_REGNO);
3353 ldxi(_FP_REGNO, _SP_REGNO, -(sizeof(void*)));
3354
3355 BLR();
3356}
3357
3358static void
3359_vastart(jit_state_t *_jit, jit_int32_t r0)
3360{
3361#if !_CALL_SYSV
3362 assert(_jitc->function->self.call & jit_call_varargs);
3363 /* Initialize stack pointer to the first stack argument. */
3364 addi(r0, _FP_REGNO, _jitc->function->self.size);
3365#else
3366 jit_int32_t reg;
3367 assert(_jitc->function->self.call & jit_call_varargs);
3368
3369 /* Return jit_va_list_t in the register argument */
3370 addi(r0, _FP_REGNO, _jitc->function->vaoff);
3371 reg = jit_get_reg(jit_class_gpr);
3372
3373 /* Initialize the gp counter. */
3374 movi(rn(reg), _jitc->function->vagp);
3375 stxi_c(offsetof(jit_va_list_t, ngpr), r0, rn(reg));
3376
3377 /* Initialize the fp counter. */
3378 movi(rn(reg), _jitc->function->vafp);
3379 stxi_c(offsetof(jit_va_list_t, nfpr), r0, rn(reg));
3380
3381 /* Initialize overflow pointer to the first stack argument. */
3382 addi(rn(reg), _FP_REGNO, _jitc->function->self.size);
3383 stxi(offsetof(jit_va_list_t, over), r0, rn(reg));
3384
3385 /* Initialize register save area pointer. */
3386 addi(rn(reg), r0, first_gp_offset);
3387 stxi(offsetof(jit_va_list_t, save), r0, rn(reg));
3388
3389 jit_unget_reg(reg);
3390#endif
3391}
3392
3393static void
3394_vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
3395{
3396#if !_CALL_SYSV
3397 assert(_jitc->function->self.call & jit_call_varargs);
3398 /* Load argument. */
3399 ldr(r0, r1);
3400 /* Update va_list. */
3401 addi(r1, r1, sizeof(jit_word_t));
3402#else
3403 jit_int32_t rg0;
3404 jit_int32_t rg1;
3405 jit_word_t ge_code;
3406 jit_word_t lt_code;
3407
3408 assert(_jitc->function->self.call & jit_call_varargs);
3409
3410 rg0 = jit_get_reg(jit_class_gpr);
3411 rg1 = jit_get_reg(jit_class_gpr);
3412
3413 /* Load the gp offset in save area in the first temporary. */
3414 ldxi_uc(rn(rg0), r1, offsetof(jit_va_list_t, ngpr));
3415
3416 /* Jump over if there are no remaining arguments in the save area. */
3417 ge_code = bgei(_jit->pc.w, rn(rg0), 8);
3418
3419 /* Update the gp counter. */
3420 addi(rn(rg1), rn(rg0), 1);
3421 stxi_c(offsetof(jit_va_list_t, ngpr), r1, rn(rg1));
3422
3423 /* Load the save area pointer in the second temporary. */
3424 ldxi(rn(rg1), r1, offsetof(jit_va_list_t, save));
3425
3426 /* Load the vararg argument in the first argument. */
3427 lshi(rn(rg0), rn(rg0), va_gp_shift);
3428 ldxr(r0, rn(rg1), rn(rg0));
3429
3430 /* Will only need one temporary register below. */
3431 jit_unget_reg(rg1);
3432
3433 /* Jump over overflow code. */
3434 lt_code = _jit->pc.w;
3435 B(0);
3436
3437 /* Where to land if argument is in overflow area. */
3438 patch_at(ge_code, _jit->pc.w);
3439
3440 /* Load overflow pointer. */
3441 ldxi(rn(rg0), r1, offsetof(jit_va_list_t, over));
3442
3443 /* Load argument. */
3444 ldr(r0, rn(rg0));
3445
3446 /* Update overflow pointer. */
3447 addi(rn(rg0), rn(rg0), va_gp_increment);
3448 stxi(offsetof(jit_va_list_t, over), r1, rn(rg0));
3449
3450 /* Where to land if argument is in save area. */
3451 patch_at(lt_code, _jit->pc.w);
3452
3453 jit_unget_reg(rg0);
3454#endif
3455}
3456
3457static void
3458_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
3459{
3460#if !_CALL_SYSV
3461 assert(_jitc->function->self.call & jit_call_varargs);
3462 /* Load argument. */
3463 ldr_d(r0, r1);
3464 /* Update va_list. */
3465 addi(r1, r1, sizeof(jit_float64_t));
3466#else
3467 jit_int32_t rg0;
3468 jit_int32_t rg1;
3469 jit_word_t ge_code;
3470 jit_word_t lt_code;
3471
3472 assert(_jitc->function->self.call & jit_call_varargs);
3473
3474 rg0 = jit_get_reg(jit_class_gpr);
3475 rg1 = jit_get_reg(jit_class_gpr);
3476
3477 /* Load the fp offset in save area in the first temporary. */
3478 ldxi_uc(rn(rg0), r1, offsetof(jit_va_list_t, nfpr));
3479
3480 /* Jump over if there are no remaining arguments in the save area. */
3481 ge_code = bgei(_jit->pc.w, rn(rg0), 8);
3482
3483 /* Update the fp counter. */
3484 addi(rn(rg1), rn(rg0), 1);
3485 stxi_c(offsetof(jit_va_list_t, nfpr), r1, rn(rg1));
3486
3487 /* Load the save area pointer in the second temporary. */
3488 ldxi(rn(rg1), r1, offsetof(jit_va_list_t, save));
3489
3490 /* Load the vararg argument in the first argument. */
3491 lshi(rn(rg0), rn(rg0), 3);
3492 addi(rn(rg0), rn(rg0), offsetof(jit_va_list_t, first_fp_argument) -
3493 offsetof(jit_va_list_t, first_gp_argument));
3494 ldxr_d(r0, rn(rg1), rn(rg0));
3495
3496 /* Jump over overflow code. */
3497 lt_code = _jit->pc.w;
3498 B(0);
3499
3500 /* Where to land if argument is in overflow area. */
3501 patch_at(ge_code, _jit->pc.w);
3502
3503 /* Load overflow pointer. */
3504 ldxi(rn(rg0), r1, offsetof(jit_va_list_t, over));
3505
3506# if __WORDSIZE == 32
3507 /* Align if required. */
3508 andi(rn(rg1), rn(rg0), 7);
3509 addr(rn(rg0), rn(rg0), rn(rg1));
3510# endif
3511
3512 /* Load argument. */
3513 ldr_d(r0, rn(rg0));
3514
3515 /* Update overflow pointer. */
3516 addi(rn(rg0), rn(rg0), va_fp_increment);
3517 stxi(offsetof(jit_va_list_t, over), r1, rn(rg0));
3518
3519 /* Where to land if argument is in save area. */
3520 patch_at(lt_code, _jit->pc.w);
3521
3522 jit_unget_reg(rg0);
3523 jit_unget_reg(rg1);
3524#endif
3525}
3526
3527static void
3528_patch_at(jit_state_t *_jit, jit_word_t instr, jit_word_t label)
3529{
3530 jit_word_t d;
3531 union {
3532 jit_int32_t *i;
3533 jit_word_t w;
3534 } u;
3535 u.w = instr;
3536 switch ((u.i[0] & 0xfc000000) >> 26) {
3537 case 16: /* BCx */
3538 d = label - instr;
3539 assert(!(d & 3));
3540 if (!can_sign_extend_short_p(d)) {
3541 /* use absolute address */
3542 assert(can_sign_extend_short_p(label));
3543 d |= 2;
3544 }
3545 u.i[0] = (u.i[0] & ~0xfffd) | (d & 0xfffe);
3546 break;
3547 case 18: /* Bx */
3548#if _CALL_AIXDESC
3549 if (_jitc->jump && (!(u.i[0] & 1))) { /* jmpi label */
3550 /* zero is used for toc and env, so, quick check
3551 * if this is a "jmpi main" like initial jit
3552 * instruction */
3553 if (((long *)label)[1] == 0 && ((long *)label)[2] == 0) {
3554 for (d = 0; d < _jitc->prolog.offset; d++) {
3555 /* not so pretty, but hides powerpc
3556 * specific abi intrinsics and/or
3557 * implementation from user */
3558 if (_jitc->prolog.ptr[d] == label) {
3559 label += sizeof(void*) * 3;
3560 break;
3561 }
3562 }
3563 }
3564 }
3565#endif
3566 d = label - instr;
3567 assert(!(d & 3));
3568 if (!can_sign_extend_jump_p(d)) {
3569 /* use absolute address */
3570 assert(can_sign_extend_jump_p(label));
3571 d |= 2;
3572 }
3573 u.i[0] = (u.i[0] & ~0x3fffffd) | (d & 0x3fffffe);
3574 break;
3575 case 15: /* LI */
3576#if __WORDSIZE == 32
3577# define MTCTR_OFF 2
3578# define BCTR_OFF 3
3579#else
3580# define MTCTR_OFF 6
3581# define BCTR_OFF 7
3582#endif
3583#if _CALL_AIXDESC
3584 /* movi reg label; jmpr reg */
3585 if (_jitc->jump &&
3586#if 0
3587 /* check for MLTR(reg) */
3588 (u.i[MTCTR_OFF] >> 26) == 31 &&
3589 ((u.i[MTCTR_OFF] >> 16) & 0x3ff) == 8 &&
3590 ((u.i[MTCTR_OFF] >> 1) & 0x3ff) == 467 &&
3591 /* check for BLR */
3592 u.i[BCTR_OFF] == 0x4e800020) {
3593#else
3594 /* check for MTCTR(reg) */
3595 (u.i[MTCTR_OFF] >> 26) == 31 &&
3596 ((u.i[MTCTR_OFF] >> 16) & 0x3ff) == 9 &&
3597 ((u.i[MTCTR_OFF] >> 1) & 0x3ff) == 467 &&
3598 /* check for BCTR */
3599 u.i[BCTR_OFF] == 0x4e800420) {
3600#endif
3601 /* zero is used for toc and env, so, quick check
3602 * if this is a "jmpi main" like initial jit
3603 * instruction */
3604 if (((long *)label)[1] == 0 && ((long *)label)[2] == 0) {
3605 for (d = 0; d < _jitc->prolog.offset; d++) {
3606 /* not so pretty, but hides powerpc
3607 * specific abi intrinsics and/or
3608 * implementation from user */
3609 if (_jitc->prolog.ptr[d] == label) {
3610 label += sizeof(void*) * 3;
3611 break;
3612 }
3613 }
3614 }
3615 }
3616#endif
3617#undef BCTR_OFF
3618#undef MTCTR_OFF
3619#if __WORDSIZE == 32
3620 assert(!(u.i[0] & 0x1f0000));
3621 u.i[0] = (u.i[0] & ~0xffff) | ((label >> 16) & 0xffff);
3622 assert((u.i[1] & 0xfc000000) >> 26 == 24); /* ORI */
3623 assert(((u.i[1] >> 16) & 0x1f) == ((u.i[1] >> 21) & 0x1f));
3624 u.i[1] = (u.i[1] & ~0xffff) | (label & 0xffff);
3625#else
3626 assert(!(u.i[0] & 0x1f0000));
3627 u.i[0] = (u.i[0] & ~0xffff) | ((label >> 48) & 0xffff);
3628 assert((u.i[1] & 0xfc000000) >> 26 == 24); /* ORI */
3629 assert(((u.i[1] >> 16) & 0x1f) == ((u.i[1] >> 21) & 0x1f));
3630 u.i[1] = (u.i[1] & ~0xffff) | ((label >> 32) & 0xffff);
3631 /* not fully validating SLDI */
3632 assert((u.i[2] & 0xfc000000) >> 26 == 30); /* SLDI */
3633 assert(((u.i[2] >> 16) & 0x1f) == ((u.i[2] >> 21) & 0x1f));
3634 assert((u.i[3] & 0xfc000000) >> 26 == 24); /* ORI */
3635 assert(((u.i[3] >> 16) & 0x1f) == ((u.i[3] >> 21) & 0x1f));
3636 u.i[3] = (u.i[3] & ~0xffff) | ((label >> 16) & 0xffff);
3637 /* not fully validating SLDI */
3638 assert((u.i[4] & 0xfc000000) >> 26 == 30); /* SLDI */
3639 assert(((u.i[4] >> 16) & 0x1f) == ((u.i[4] >> 21) & 0x1f));
3640 assert((u.i[5] & 0xfc000000) >> 26 == 24); /* ORI */
3641 assert(((u.i[5] >> 16) & 0x1f) == ((u.i[5] >> 21) & 0x1f));
3642 u.i[5] = (u.i[5] & ~0xffff) | (label & 0xffff);
3643#endif
3644 break;
3645 default:
3646 assert(!"unhandled branch opcode");
3647 }
3648}
3649#endif