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