Statistics
| Branch: | Revision:

root / tcg / ppc64 / tcg-target.c @ 79383c9c

History | View | Annotate | Download (41.4 kB)

1 810260a8 malc
/*
2 810260a8 malc
 * Tiny Code Generator for QEMU
3 810260a8 malc
 *
4 810260a8 malc
 * Copyright (c) 2008 Fabrice Bellard
5 810260a8 malc
 *
6 810260a8 malc
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 810260a8 malc
 * of this software and associated documentation files (the "Software"), to deal
8 810260a8 malc
 * in the Software without restriction, including without limitation the rights
9 810260a8 malc
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 810260a8 malc
 * copies of the Software, and to permit persons to whom the Software is
11 810260a8 malc
 * furnished to do so, subject to the following conditions:
12 810260a8 malc
 *
13 810260a8 malc
 * The above copyright notice and this permission notice shall be included in
14 810260a8 malc
 * all copies or substantial portions of the Software.
15 810260a8 malc
 *
16 810260a8 malc
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 810260a8 malc
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 810260a8 malc
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 810260a8 malc
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 810260a8 malc
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 810260a8 malc
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 810260a8 malc
 * THE SOFTWARE.
23 810260a8 malc
 */
24 810260a8 malc
25 fe6f943f malc
#define TCG_CT_CONST_U32 0x100
26 fe6f943f malc
27 810260a8 malc
static uint8_t *tb_ret_addr;
28 810260a8 malc
29 810260a8 malc
#define FAST_PATH
30 810260a8 malc
31 810260a8 malc
#if TARGET_PHYS_ADDR_BITS == 32
32 810260a8 malc
#define LD_ADDEND LWZ
33 810260a8 malc
#else
34 810260a8 malc
#define LD_ADDEND LD
35 810260a8 malc
#endif
36 810260a8 malc
37 810260a8 malc
#if TARGET_LONG_BITS == 32
38 810260a8 malc
#define LD_ADDR LWZU
39 e924bbec malc
#define CMP_L 0
40 810260a8 malc
#else
41 810260a8 malc
#define LD_ADDR LDU
42 e924bbec malc
#define CMP_L (1<<21)
43 810260a8 malc
#endif
44 810260a8 malc
45 810260a8 malc
static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
46 810260a8 malc
    "r0",
47 810260a8 malc
    "r1",
48 810260a8 malc
    "rp",
49 810260a8 malc
    "r3",
50 810260a8 malc
    "r4",
51 810260a8 malc
    "r5",
52 810260a8 malc
    "r6",
53 810260a8 malc
    "r7",
54 810260a8 malc
    "r8",
55 810260a8 malc
    "r9",
56 810260a8 malc
    "r10",
57 810260a8 malc
    "r11",
58 810260a8 malc
    "r12",
59 810260a8 malc
    "r13",
60 810260a8 malc
    "r14",
61 810260a8 malc
    "r15",
62 810260a8 malc
    "r16",
63 810260a8 malc
    "r17",
64 810260a8 malc
    "r18",
65 810260a8 malc
    "r19",
66 810260a8 malc
    "r20",
67 810260a8 malc
    "r21",
68 810260a8 malc
    "r22",
69 810260a8 malc
    "r23",
70 810260a8 malc
    "r24",
71 810260a8 malc
    "r25",
72 810260a8 malc
    "r26",
73 810260a8 malc
    "r27",
74 810260a8 malc
    "r28",
75 810260a8 malc
    "r29",
76 810260a8 malc
    "r30",
77 810260a8 malc
    "r31"
78 810260a8 malc
};
79 810260a8 malc
80 810260a8 malc
static const int tcg_target_reg_alloc_order[] = {
81 810260a8 malc
    TCG_REG_R14,
82 810260a8 malc
    TCG_REG_R15,
83 810260a8 malc
    TCG_REG_R16,
84 810260a8 malc
    TCG_REG_R17,
85 810260a8 malc
    TCG_REG_R18,
86 810260a8 malc
    TCG_REG_R19,
87 810260a8 malc
    TCG_REG_R20,
88 810260a8 malc
    TCG_REG_R21,
89 810260a8 malc
    TCG_REG_R22,
90 810260a8 malc
    TCG_REG_R23,
91 810260a8 malc
    TCG_REG_R28,
92 810260a8 malc
    TCG_REG_R29,
93 810260a8 malc
    TCG_REG_R30,
94 810260a8 malc
    TCG_REG_R31,
95 810260a8 malc
    TCG_REG_R3,
96 810260a8 malc
    TCG_REG_R4,
97 810260a8 malc
    TCG_REG_R5,
98 810260a8 malc
    TCG_REG_R6,
99 810260a8 malc
    TCG_REG_R7,
100 810260a8 malc
    TCG_REG_R8,
101 810260a8 malc
    TCG_REG_R9,
102 810260a8 malc
    TCG_REG_R10,
103 810260a8 malc
    TCG_REG_R11,
104 810260a8 malc
    TCG_REG_R12,
105 810260a8 malc
    TCG_REG_R13,
106 810260a8 malc
    TCG_REG_R0,
107 810260a8 malc
    TCG_REG_R1,
108 810260a8 malc
    TCG_REG_R2,
109 810260a8 malc
    TCG_REG_R24,
110 810260a8 malc
    TCG_REG_R25,
111 810260a8 malc
    TCG_REG_R26,
112 810260a8 malc
    TCG_REG_R27
113 810260a8 malc
};
114 810260a8 malc
115 810260a8 malc
static const int tcg_target_call_iarg_regs[] = {
116 810260a8 malc
    TCG_REG_R3,
117 810260a8 malc
    TCG_REG_R4,
118 810260a8 malc
    TCG_REG_R5,
119 810260a8 malc
    TCG_REG_R6,
120 810260a8 malc
    TCG_REG_R7,
121 810260a8 malc
    TCG_REG_R8,
122 810260a8 malc
    TCG_REG_R9,
123 810260a8 malc
    TCG_REG_R10
124 810260a8 malc
};
125 810260a8 malc
126 810260a8 malc
static const int tcg_target_call_oarg_regs[2] = {
127 810260a8 malc
    TCG_REG_R3
128 810260a8 malc
};
129 810260a8 malc
130 810260a8 malc
static const int tcg_target_callee_save_regs[] = {
131 810260a8 malc
    TCG_REG_R14,
132 810260a8 malc
    TCG_REG_R15,
133 810260a8 malc
    TCG_REG_R16,
134 810260a8 malc
    TCG_REG_R17,
135 810260a8 malc
    TCG_REG_R18,
136 810260a8 malc
    TCG_REG_R19,
137 810260a8 malc
    TCG_REG_R20,
138 810260a8 malc
    TCG_REG_R21,
139 810260a8 malc
    TCG_REG_R22,
140 810260a8 malc
    TCG_REG_R23,
141 810260a8 malc
    TCG_REG_R28,
142 810260a8 malc
    TCG_REG_R29,
143 810260a8 malc
    TCG_REG_R30,
144 810260a8 malc
    TCG_REG_R31
145 810260a8 malc
};
146 810260a8 malc
147 810260a8 malc
static uint32_t reloc_pc24_val (void *pc, tcg_target_long target)
148 810260a8 malc
{
149 810260a8 malc
    tcg_target_long disp;
150 810260a8 malc
151 810260a8 malc
    disp = target - (tcg_target_long) pc;
152 810260a8 malc
    if ((disp << 38) >> 38 != disp)
153 810260a8 malc
        tcg_abort ();
154 810260a8 malc
155 810260a8 malc
    return disp & 0x3fffffc;
156 810260a8 malc
}
157 810260a8 malc
158 810260a8 malc
static void reloc_pc24 (void *pc, tcg_target_long target)
159 810260a8 malc
{
160 810260a8 malc
    *(uint32_t *) pc = (*(uint32_t *) pc & ~0x3fffffc)
161 810260a8 malc
        | reloc_pc24_val (pc, target);
162 810260a8 malc
}
163 810260a8 malc
164 810260a8 malc
static uint16_t reloc_pc14_val (void *pc, tcg_target_long target)
165 810260a8 malc
{
166 810260a8 malc
    tcg_target_long disp;
167 810260a8 malc
168 810260a8 malc
    disp = target - (tcg_target_long) pc;
169 810260a8 malc
    if (disp != (int16_t) disp)
170 810260a8 malc
        tcg_abort ();
171 810260a8 malc
172 810260a8 malc
    return disp & 0xfffc;
173 810260a8 malc
}
174 810260a8 malc
175 810260a8 malc
static void reloc_pc14 (void *pc, tcg_target_long target)
176 810260a8 malc
{
177 810260a8 malc
    *(uint32_t *) pc = (*(uint32_t *) pc & ~0xfffc)
178 810260a8 malc
        | reloc_pc14_val (pc, target);
179 810260a8 malc
}
180 810260a8 malc
181 810260a8 malc
static void patch_reloc (uint8_t *code_ptr, int type,
182 810260a8 malc
                         tcg_target_long value, tcg_target_long addend)
183 810260a8 malc
{
184 810260a8 malc
    value += addend;
185 810260a8 malc
    switch (type) {
186 810260a8 malc
    case R_PPC_REL14:
187 810260a8 malc
        reloc_pc14 (code_ptr, value);
188 810260a8 malc
        break;
189 810260a8 malc
    case R_PPC_REL24:
190 810260a8 malc
        reloc_pc24 (code_ptr, value);
191 810260a8 malc
        break;
192 810260a8 malc
    default:
193 810260a8 malc
        tcg_abort ();
194 810260a8 malc
    }
195 810260a8 malc
}
196 810260a8 malc
197 810260a8 malc
/* maximum number of register used for input function arguments */
198 810260a8 malc
static int tcg_target_get_call_iarg_regs_count (int flags)
199 810260a8 malc
{
200 810260a8 malc
    return sizeof (tcg_target_call_iarg_regs) / sizeof (tcg_target_call_iarg_regs[0]);
201 810260a8 malc
}
202 810260a8 malc
203 810260a8 malc
/* parse target specific constraints */
204 810260a8 malc
static int target_parse_constraint (TCGArgConstraint *ct, const char **pct_str)
205 810260a8 malc
{
206 810260a8 malc
    const char *ct_str;
207 810260a8 malc
208 810260a8 malc
    ct_str = *pct_str;
209 810260a8 malc
    switch (ct_str[0]) {
210 810260a8 malc
    case 'A': case 'B': case 'C': case 'D':
211 810260a8 malc
        ct->ct |= TCG_CT_REG;
212 810260a8 malc
        tcg_regset_set_reg (ct->u.regs, 3 + ct_str[0] - 'A');
213 810260a8 malc
        break;
214 810260a8 malc
    case 'r':
215 810260a8 malc
        ct->ct |= TCG_CT_REG;
216 810260a8 malc
        tcg_regset_set32 (ct->u.regs, 0, 0xffffffff);
217 810260a8 malc
        break;
218 810260a8 malc
    case 'L':                   /* qemu_ld constraint */
219 810260a8 malc
        ct->ct |= TCG_CT_REG;
220 810260a8 malc
        tcg_regset_set32 (ct->u.regs, 0, 0xffffffff);
221 810260a8 malc
        tcg_regset_reset_reg (ct->u.regs, TCG_REG_R3);
222 735ee40d malc
#ifdef CONFIG_SOFTMMU
223 810260a8 malc
        tcg_regset_reset_reg (ct->u.regs, TCG_REG_R4);
224 735ee40d malc
#endif
225 810260a8 malc
        break;
226 c070355d malc
    case 'S':                   /* qemu_st constraint */
227 810260a8 malc
        ct->ct |= TCG_CT_REG;
228 810260a8 malc
        tcg_regset_set32 (ct->u.regs, 0, 0xffffffff);
229 810260a8 malc
        tcg_regset_reset_reg (ct->u.regs, TCG_REG_R3);
230 735ee40d malc
#ifdef CONFIG_SOFTMMU
231 810260a8 malc
        tcg_regset_reset_reg (ct->u.regs, TCG_REG_R4);
232 810260a8 malc
        tcg_regset_reset_reg (ct->u.regs, TCG_REG_R5);
233 735ee40d malc
#endif
234 810260a8 malc
        break;
235 fe6f943f malc
    case 'Z':
236 fe6f943f malc
        ct->ct |= TCG_CT_CONST_U32;
237 fe6f943f malc
        break;
238 810260a8 malc
    default:
239 810260a8 malc
        return -1;
240 810260a8 malc
    }
241 810260a8 malc
    ct_str++;
242 810260a8 malc
    *pct_str = ct_str;
243 810260a8 malc
    return 0;
244 810260a8 malc
}
245 810260a8 malc
246 810260a8 malc
/* test if a constant matches the constraint */
247 810260a8 malc
static int tcg_target_const_match (tcg_target_long val,
248 810260a8 malc
                                   const TCGArgConstraint *arg_ct)
249 810260a8 malc
{
250 810260a8 malc
    int ct;
251 810260a8 malc
252 810260a8 malc
    ct = arg_ct->ct;
253 810260a8 malc
    if (ct & TCG_CT_CONST)
254 810260a8 malc
        return 1;
255 fe6f943f malc
    else if ((ct & TCG_CT_CONST_U32) && (val == (uint32_t) val))
256 fe6f943f malc
        return 1;
257 810260a8 malc
    return 0;
258 810260a8 malc
}
259 810260a8 malc
260 810260a8 malc
#define OPCD(opc) ((opc)<<26)
261 810260a8 malc
#define XO19(opc) (OPCD(19)|((opc)<<1))
262 810260a8 malc
#define XO30(opc) (OPCD(30)|((opc)<<2))
263 810260a8 malc
#define XO31(opc) (OPCD(31)|((opc)<<1))
264 810260a8 malc
#define XO58(opc) (OPCD(58)|(opc))
265 810260a8 malc
#define XO62(opc) (OPCD(62)|(opc))
266 810260a8 malc
267 810260a8 malc
#define B      OPCD( 18)
268 810260a8 malc
#define BC     OPCD( 16)
269 810260a8 malc
#define LBZ    OPCD( 34)
270 810260a8 malc
#define LHZ    OPCD( 40)
271 810260a8 malc
#define LHA    OPCD( 42)
272 810260a8 malc
#define LWZ    OPCD( 32)
273 810260a8 malc
#define STB    OPCD( 38)
274 810260a8 malc
#define STH    OPCD( 44)
275 810260a8 malc
#define STW    OPCD( 36)
276 810260a8 malc
277 810260a8 malc
#define STD    XO62(  0)
278 810260a8 malc
#define STDU   XO62(  1)
279 810260a8 malc
#define STDX   XO31(149)
280 810260a8 malc
281 810260a8 malc
#define LD     XO58(  0)
282 810260a8 malc
#define LDX    XO31( 21)
283 810260a8 malc
#define LDU    XO58(  1)
284 301f6d90 malc
#define LWA    XO58(  2)
285 810260a8 malc
#define LWAX   XO31(341)
286 810260a8 malc
287 810260a8 malc
#define ADDI   OPCD( 14)
288 810260a8 malc
#define ADDIS  OPCD( 15)
289 810260a8 malc
#define ORI    OPCD( 24)
290 810260a8 malc
#define ORIS   OPCD( 25)
291 810260a8 malc
#define XORI   OPCD( 26)
292 810260a8 malc
#define XORIS  OPCD( 27)
293 810260a8 malc
#define ANDI   OPCD( 28)
294 810260a8 malc
#define ANDIS  OPCD( 29)
295 810260a8 malc
#define MULLI  OPCD(  7)
296 810260a8 malc
#define CMPLI  OPCD( 10)
297 810260a8 malc
#define CMPI   OPCD( 11)
298 810260a8 malc
299 810260a8 malc
#define LWZU   OPCD( 33)
300 810260a8 malc
#define STWU   OPCD( 37)
301 810260a8 malc
302 810260a8 malc
#define RLWINM OPCD( 21)
303 810260a8 malc
304 810260a8 malc
#define RLDICL XO30(  0)
305 810260a8 malc
#define RLDICR XO30(  1)
306 810260a8 malc
307 810260a8 malc
#define BCLR   XO19( 16)
308 810260a8 malc
#define BCCTR  XO19(528)
309 810260a8 malc
#define CRAND  XO19(257)
310 810260a8 malc
#define CRANDC XO19(129)
311 810260a8 malc
#define CRNAND XO19(225)
312 810260a8 malc
#define CROR   XO19(449)
313 810260a8 malc
314 810260a8 malc
#define EXTSB  XO31(954)
315 810260a8 malc
#define EXTSH  XO31(922)
316 810260a8 malc
#define EXTSW  XO31(986)
317 810260a8 malc
#define ADD    XO31(266)
318 810260a8 malc
#define ADDE   XO31(138)
319 810260a8 malc
#define ADDC   XO31( 10)
320 810260a8 malc
#define AND    XO31( 28)
321 810260a8 malc
#define SUBF   XO31( 40)
322 810260a8 malc
#define SUBFC  XO31(  8)
323 810260a8 malc
#define SUBFE  XO31(136)
324 810260a8 malc
#define OR     XO31(444)
325 810260a8 malc
#define XOR    XO31(316)
326 810260a8 malc
#define MULLW  XO31(235)
327 810260a8 malc
#define MULHWU XO31( 11)
328 810260a8 malc
#define DIVW   XO31(491)
329 810260a8 malc
#define DIVWU  XO31(459)
330 810260a8 malc
#define CMP    XO31(  0)
331 810260a8 malc
#define CMPL   XO31( 32)
332 810260a8 malc
#define LHBRX  XO31(790)
333 810260a8 malc
#define LWBRX  XO31(534)
334 810260a8 malc
#define STHBRX XO31(918)
335 810260a8 malc
#define STWBRX XO31(662)
336 810260a8 malc
#define MFSPR  XO31(339)
337 810260a8 malc
#define MTSPR  XO31(467)
338 810260a8 malc
#define SRAWI  XO31(824)
339 810260a8 malc
#define NEG    XO31(104)
340 810260a8 malc
341 810260a8 malc
#define MULLD  XO31(233)
342 810260a8 malc
#define MULHD  XO31( 73)
343 810260a8 malc
#define MULHDU XO31(  9)
344 810260a8 malc
#define DIVD   XO31(489)
345 810260a8 malc
#define DIVDU  XO31(457)
346 810260a8 malc
347 810260a8 malc
#define LBZX   XO31( 87)
348 810260a8 malc
#define LHZX   XO31(276)
349 810260a8 malc
#define LHAX   XO31(343)
350 810260a8 malc
#define LWZX   XO31( 23)
351 810260a8 malc
#define STBX   XO31(215)
352 810260a8 malc
#define STHX   XO31(407)
353 810260a8 malc
#define STWX   XO31(151)
354 810260a8 malc
355 810260a8 malc
#define SPR(a,b) ((((a)<<5)|(b))<<11)
356 810260a8 malc
#define LR     SPR(8, 0)
357 810260a8 malc
#define CTR    SPR(9, 0)
358 810260a8 malc
359 810260a8 malc
#define SLW    XO31( 24)
360 810260a8 malc
#define SRW    XO31(536)
361 810260a8 malc
#define SRAW   XO31(792)
362 810260a8 malc
363 810260a8 malc
#define SLD    XO31( 27)
364 810260a8 malc
#define SRD    XO31(539)
365 810260a8 malc
#define SRAD   XO31(794)
366 fe6f943f malc
#define SRADI  XO31(413<<1)
367 810260a8 malc
368 810260a8 malc
#define LMW    OPCD( 46)
369 810260a8 malc
#define STMW   OPCD( 47)
370 810260a8 malc
371 810260a8 malc
#define TW     XO31( 4)
372 810260a8 malc
#define TRAP   (TW | TO (31))
373 810260a8 malc
374 810260a8 malc
#define RT(r) ((r)<<21)
375 810260a8 malc
#define RS(r) ((r)<<21)
376 810260a8 malc
#define RA(r) ((r)<<16)
377 810260a8 malc
#define RB(r) ((r)<<11)
378 810260a8 malc
#define TO(t) ((t)<<21)
379 810260a8 malc
#define SH(s) ((s)<<11)
380 810260a8 malc
#define MB(b) ((b)<<6)
381 810260a8 malc
#define ME(e) ((e)<<1)
382 810260a8 malc
#define BO(o) ((o)<<21)
383 810260a8 malc
#define MB64(b) ((b)<<5)
384 810260a8 malc
385 810260a8 malc
#define LK    1
386 810260a8 malc
387 810260a8 malc
#define TAB(t,a,b) (RT(t) | RA(a) | RB(b))
388 810260a8 malc
#define SAB(s,a,b) (RS(s) | RA(a) | RB(b))
389 810260a8 malc
390 810260a8 malc
#define BF(n)    ((n)<<23)
391 810260a8 malc
#define BI(n, c) (((c)+((n)*4))<<16)
392 810260a8 malc
#define BT(n, c) (((c)+((n)*4))<<21)
393 810260a8 malc
#define BA(n, c) (((c)+((n)*4))<<16)
394 810260a8 malc
#define BB(n, c) (((c)+((n)*4))<<11)
395 810260a8 malc
396 810260a8 malc
#define BO_COND_TRUE  BO (12)
397 810260a8 malc
#define BO_COND_FALSE BO ( 4)
398 810260a8 malc
#define BO_ALWAYS     BO (20)
399 810260a8 malc
400 810260a8 malc
enum {
401 810260a8 malc
    CR_LT,
402 810260a8 malc
    CR_GT,
403 810260a8 malc
    CR_EQ,
404 810260a8 malc
    CR_SO
405 810260a8 malc
};
406 810260a8 malc
407 810260a8 malc
static const uint32_t tcg_to_bc[10] = {
408 810260a8 malc
    [TCG_COND_EQ]  = BC | BI (7, CR_EQ) | BO_COND_TRUE,
409 810260a8 malc
    [TCG_COND_NE]  = BC | BI (7, CR_EQ) | BO_COND_FALSE,
410 810260a8 malc
    [TCG_COND_LT]  = BC | BI (7, CR_LT) | BO_COND_TRUE,
411 810260a8 malc
    [TCG_COND_GE]  = BC | BI (7, CR_LT) | BO_COND_FALSE,
412 810260a8 malc
    [TCG_COND_LE]  = BC | BI (7, CR_GT) | BO_COND_FALSE,
413 810260a8 malc
    [TCG_COND_GT]  = BC | BI (7, CR_GT) | BO_COND_TRUE,
414 810260a8 malc
    [TCG_COND_LTU] = BC | BI (7, CR_LT) | BO_COND_TRUE,
415 810260a8 malc
    [TCG_COND_GEU] = BC | BI (7, CR_LT) | BO_COND_FALSE,
416 810260a8 malc
    [TCG_COND_LEU] = BC | BI (7, CR_GT) | BO_COND_FALSE,
417 810260a8 malc
    [TCG_COND_GTU] = BC | BI (7, CR_GT) | BO_COND_TRUE,
418 810260a8 malc
};
419 810260a8 malc
420 810260a8 malc
static void tcg_out_mov (TCGContext *s, int ret, int arg)
421 810260a8 malc
{
422 810260a8 malc
    tcg_out32 (s, OR | SAB (arg, ret, arg));
423 810260a8 malc
}
424 810260a8 malc
425 810260a8 malc
static void tcg_out_rld (TCGContext *s, int op, int ra, int rs, int sh, int mb)
426 810260a8 malc
{
427 810260a8 malc
    sh = SH (sh & 0x1f) | (((sh >> 5) & 1) << 1);
428 810260a8 malc
    mb = MB64 ((mb >> 5) | ((mb << 1) & 0x3f));
429 810260a8 malc
    tcg_out32 (s, op | RA (ra) | RS (rs) | sh | mb);
430 810260a8 malc
}
431 810260a8 malc
432 810260a8 malc
static void tcg_out_movi32 (TCGContext *s, int ret, int32_t arg)
433 810260a8 malc
{
434 810260a8 malc
    if (arg == (int16_t) arg)
435 810260a8 malc
        tcg_out32 (s, ADDI | RT (ret) | RA (0) | (arg & 0xffff));
436 810260a8 malc
    else {
437 810260a8 malc
        tcg_out32 (s, ADDIS | RT (ret) | RA (0) | ((arg >> 16) & 0xffff));
438 810260a8 malc
        if (arg & 0xffff)
439 810260a8 malc
            tcg_out32 (s, ORI | RS (ret) | RA (ret) | (arg & 0xffff));
440 810260a8 malc
    }
441 810260a8 malc
}
442 810260a8 malc
443 810260a8 malc
static void tcg_out_movi (TCGContext *s, TCGType type,
444 810260a8 malc
                          int ret, tcg_target_long arg)
445 810260a8 malc
{
446 810260a8 malc
    int32_t arg32 = arg;
447 810260a8 malc
448 810260a8 malc
    if (type == TCG_TYPE_I32 || arg == arg32) {
449 810260a8 malc
        tcg_out_movi32 (s, ret, arg32);
450 810260a8 malc
    }
451 810260a8 malc
    else {
452 810260a8 malc
        if ((uint64_t) arg >> 32) {
453 6fc9dbcc malc
            uint16_t h16 = arg >> 16;
454 6fc9dbcc malc
            uint16_t l16 = arg;
455 6fc9dbcc malc
456 95153fde malc
            tcg_out_movi32 (s, ret, arg >> 32);
457 810260a8 malc
            tcg_out_rld (s, RLDICR, ret, ret, 32, 31);
458 6fc9dbcc malc
            if (h16) tcg_out32 (s, ORIS | RS (ret) | RA (ret) | h16);
459 6fc9dbcc malc
            if (l16) tcg_out32 (s, ORI | RS (ret) | RA (ret) | l16);
460 810260a8 malc
        }
461 810260a8 malc
        else {
462 810260a8 malc
            tcg_out_movi32 (s, ret, arg32);
463 6fc9dbcc malc
            if (arg32 < 0)
464 6fc9dbcc malc
                tcg_out_rld (s, RLDICL, ret, ret, 0, 32);
465 810260a8 malc
        }
466 810260a8 malc
    }
467 810260a8 malc
}
468 810260a8 malc
469 810260a8 malc
static void tcg_out_call (TCGContext *s, tcg_target_long arg, int const_arg)
470 810260a8 malc
{
471 810260a8 malc
    int reg;
472 810260a8 malc
473 810260a8 malc
    if (const_arg) {
474 810260a8 malc
        reg = 2;
475 810260a8 malc
        tcg_out_movi (s, TCG_TYPE_I64, reg, arg);
476 810260a8 malc
    }
477 810260a8 malc
    else reg = arg;
478 810260a8 malc
479 810260a8 malc
    tcg_out32 (s, LD | RT (0) | RA (reg));
480 810260a8 malc
    tcg_out32 (s, MTSPR | RA (0) | CTR);
481 810260a8 malc
    tcg_out32 (s, LD | RT (11) | RA (reg) | 16);
482 810260a8 malc
    tcg_out32 (s, LD | RT (2) | RA (reg) | 8);
483 810260a8 malc
    tcg_out32 (s, BCCTR | BO_ALWAYS | LK);
484 810260a8 malc
}
485 810260a8 malc
486 810260a8 malc
static void tcg_out_ldst (TCGContext *s, int ret, int addr,
487 810260a8 malc
                          int offset, int op1, int op2)
488 810260a8 malc
{
489 810260a8 malc
    if (offset == (int16_t) offset)
490 810260a8 malc
        tcg_out32 (s, op1 | RT (ret) | RA (addr) | (offset & 0xffff));
491 810260a8 malc
    else {
492 810260a8 malc
        tcg_out_movi (s, TCG_TYPE_I64, 0, offset);
493 810260a8 malc
        tcg_out32 (s, op2 | RT (ret) | RA (addr) | RB (0));
494 810260a8 malc
    }
495 810260a8 malc
}
496 810260a8 malc
497 810260a8 malc
static void tcg_out_b (TCGContext *s, int mask, tcg_target_long target)
498 810260a8 malc
{
499 810260a8 malc
    tcg_target_long disp;
500 810260a8 malc
501 810260a8 malc
    disp = target - (tcg_target_long) s->code_ptr;
502 810260a8 malc
    if ((disp << 38) >> 38 == disp)
503 810260a8 malc
        tcg_out32 (s, B | (disp & 0x3fffffc) | mask);
504 810260a8 malc
    else {
505 810260a8 malc
        tcg_out_movi (s, TCG_TYPE_I64, 0, (tcg_target_long) target);
506 810260a8 malc
        tcg_out32 (s, MTSPR | RS (0) | CTR);
507 810260a8 malc
        tcg_out32 (s, BCCTR | BO_ALWAYS | mask);
508 810260a8 malc
    }
509 810260a8 malc
}
510 810260a8 malc
511 810260a8 malc
#if defined (CONFIG_SOFTMMU)
512 79383c9c blueswir1
513 79383c9c blueswir1
#include "../../softmmu_defs.h"
514 810260a8 malc
515 810260a8 malc
static void *qemu_ld_helpers[4] = {
516 810260a8 malc
    __ldb_mmu,
517 810260a8 malc
    __ldw_mmu,
518 810260a8 malc
    __ldl_mmu,
519 810260a8 malc
    __ldq_mmu,
520 810260a8 malc
};
521 810260a8 malc
522 810260a8 malc
static void *qemu_st_helpers[4] = {
523 810260a8 malc
    __stb_mmu,
524 810260a8 malc
    __stw_mmu,
525 810260a8 malc
    __stl_mmu,
526 810260a8 malc
    __stq_mmu,
527 810260a8 malc
};
528 810260a8 malc
529 810260a8 malc
static void tcg_out_tlb_read (TCGContext *s, int r0, int r1, int r2,
530 810260a8 malc
                              int addr_reg, int s_bits, int offset)
531 810260a8 malc
{
532 880e52b8 malc
#if TARGET_LONG_BITS == 32
533 810260a8 malc
    tcg_out_rld (s, RLDICL, addr_reg, addr_reg, 0, 32);
534 810260a8 malc
535 4a40e231 malc
    tcg_out32 (s, (RLWINM
536 4a40e231 malc
                   | RA (r0)
537 4a40e231 malc
                   | RS (addr_reg)
538 4a40e231 malc
                   | SH (32 - (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS))
539 4a40e231 malc
                   | MB (32 - (CPU_TLB_BITS + CPU_TLB_ENTRY_BITS))
540 4a40e231 malc
                   | ME (31 - CPU_TLB_ENTRY_BITS)
541 4a40e231 malc
                   )
542 4a40e231 malc
        );
543 4a40e231 malc
    tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (TCG_AREG0));
544 4a40e231 malc
    tcg_out32 (s, (LWZU | RT (r1) | RA (r0) | offset));
545 4a40e231 malc
    tcg_out32 (s, (RLWINM
546 4a40e231 malc
                   | RA (r2)
547 4a40e231 malc
                   | RS (addr_reg)
548 4a40e231 malc
                   | SH (0)
549 4a40e231 malc
                   | MB ((32 - s_bits) & 31)
550 4a40e231 malc
                   | ME (31 - TARGET_PAGE_BITS)
551 4a40e231 malc
                   )
552 4a40e231 malc
        );
553 4a40e231 malc
#else
554 810260a8 malc
    tcg_out_rld (s, RLDICL, r0, addr_reg,
555 810260a8 malc
                 64 - TARGET_PAGE_BITS,
556 810260a8 malc
                 64 - CPU_TLB_BITS);
557 810260a8 malc
    tcg_out_rld (s, RLDICR, r0, r0,
558 810260a8 malc
                 CPU_TLB_ENTRY_BITS,
559 810260a8 malc
                 63 - CPU_TLB_ENTRY_BITS);
560 810260a8 malc
561 810260a8 malc
    tcg_out32 (s, ADD | TAB (r0, r0, TCG_AREG0));
562 810260a8 malc
    tcg_out32 (s, LD_ADDR | RT (r1) | RA (r0) | offset);
563 810260a8 malc
564 4a40e231 malc
    if (!s_bits) {
565 4a40e231 malc
        tcg_out_rld (s, RLDICR, r2, addr_reg, 0, 63 - TARGET_PAGE_BITS);
566 4a40e231 malc
    }
567 4a40e231 malc
    else {
568 4a40e231 malc
        tcg_out_rld (s, RLDICL, r2, addr_reg,
569 4a40e231 malc
                     64 - TARGET_PAGE_BITS,
570 4a40e231 malc
                     TARGET_PAGE_BITS - s_bits);
571 4a40e231 malc
        tcg_out_rld (s, RLDICL, r2, r2, TARGET_PAGE_BITS, 0);
572 4a40e231 malc
    }
573 4a40e231 malc
#endif
574 810260a8 malc
}
575 a2a546b3 malc
#endif
576 810260a8 malc
577 810260a8 malc
static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
578 810260a8 malc
{
579 109719ec malc
    int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap;
580 810260a8 malc
#ifdef CONFIG_SOFTMMU
581 109719ec malc
    int r2;
582 810260a8 malc
    void *label1_ptr, *label2_ptr;
583 810260a8 malc
#endif
584 810260a8 malc
585 810260a8 malc
    data_reg = *args++;
586 810260a8 malc
    addr_reg = *args++;
587 810260a8 malc
    mem_index = *args;
588 810260a8 malc
    s_bits = opc & 3;
589 810260a8 malc
590 810260a8 malc
#ifdef CONFIG_SOFTMMU
591 810260a8 malc
    r0 = 3;
592 810260a8 malc
    r1 = 4;
593 810260a8 malc
    r2 = 0;
594 810260a8 malc
595 810260a8 malc
    tcg_out_tlb_read (s, r0, r1, r2, addr_reg, s_bits,
596 810260a8 malc
                      offsetof (CPUState, tlb_table[mem_index][0].addr_read));
597 810260a8 malc
598 e924bbec malc
    tcg_out32 (s, CMP | BF (7) | RA (r2) | RB (r1) | CMP_L);
599 810260a8 malc
600 810260a8 malc
    label1_ptr = s->code_ptr;
601 810260a8 malc
#ifdef FAST_PATH
602 810260a8 malc
    tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE);
603 810260a8 malc
#endif
604 810260a8 malc
605 810260a8 malc
    /* slow path */
606 810260a8 malc
    tcg_out_mov (s, 3, addr_reg);
607 810260a8 malc
    tcg_out_movi (s, TCG_TYPE_I64, 4, mem_index);
608 810260a8 malc
609 810260a8 malc
    tcg_out_call (s, (tcg_target_long) qemu_ld_helpers[s_bits], 1);
610 810260a8 malc
611 810260a8 malc
    switch (opc) {
612 810260a8 malc
    case 0|4:
613 810260a8 malc
        tcg_out32 (s, EXTSB | RA (data_reg) | RS (3));
614 810260a8 malc
        break;
615 810260a8 malc
    case 1|4:
616 810260a8 malc
        tcg_out32 (s, EXTSH | RA (data_reg) | RS (3));
617 810260a8 malc
        break;
618 810260a8 malc
    case 2|4:
619 810260a8 malc
        tcg_out32 (s, EXTSW | RA (data_reg) | RS (3));
620 810260a8 malc
        break;
621 810260a8 malc
    case 0:
622 810260a8 malc
    case 1:
623 810260a8 malc
    case 2:
624 810260a8 malc
    case 3:
625 810260a8 malc
        if (data_reg != 3)
626 810260a8 malc
            tcg_out_mov (s, data_reg, 3);
627 810260a8 malc
        break;
628 810260a8 malc
    }
629 810260a8 malc
    label2_ptr = s->code_ptr;
630 810260a8 malc
    tcg_out32 (s, B);
631 810260a8 malc
632 810260a8 malc
    /* label1: fast path */
633 810260a8 malc
#ifdef FAST_PATH
634 810260a8 malc
    reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr);
635 810260a8 malc
#endif
636 810260a8 malc
637 810260a8 malc
    /* r0 now contains &env->tlb_table[mem_index][index].addr_read */
638 810260a8 malc
    tcg_out32 (s, (LD_ADDEND
639 810260a8 malc
                   | RT (r0)
640 810260a8 malc
                   | RA (r0)
641 810260a8 malc
                   | (offsetof (CPUTLBEntry, addend)
642 810260a8 malc
                      - offsetof (CPUTLBEntry, addr_read))
643 810260a8 malc
                   ));
644 810260a8 malc
    /* r0 = env->tlb_table[mem_index][index].addend */
645 810260a8 malc
    tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (addr_reg));
646 810260a8 malc
    /* r0 = env->tlb_table[mem_index][index].addend + addr */
647 810260a8 malc
648 810260a8 malc
#else  /* !CONFIG_SOFTMMU */
649 0b7c1d89 malc
#if TARGET_LONG_BITS == 32
650 0b7c1d89 malc
    tcg_out_rld (s, RLDICL, addr_reg, addr_reg, 0, 32);
651 0b7c1d89 malc
#endif
652 810260a8 malc
    r0 = addr_reg;
653 735ee40d malc
    r1 = 3;
654 810260a8 malc
#endif
655 810260a8 malc
656 810260a8 malc
#ifdef TARGET_WORDS_BIGENDIAN
657 810260a8 malc
    bswap = 0;
658 810260a8 malc
#else
659 810260a8 malc
    bswap = 1;
660 810260a8 malc
#endif
661 810260a8 malc
    switch (opc) {
662 810260a8 malc
    default:
663 810260a8 malc
    case 0:
664 810260a8 malc
        tcg_out32 (s, LBZ | RT (data_reg) | RA (r0));
665 810260a8 malc
        break;
666 810260a8 malc
    case 0|4:
667 810260a8 malc
        tcg_out32 (s, LBZ | RT (data_reg) | RA (r0));
668 810260a8 malc
        tcg_out32 (s, EXTSB | RA (data_reg) | RS (data_reg));
669 810260a8 malc
        break;
670 810260a8 malc
    case 1:
671 810260a8 malc
        if (bswap) tcg_out32 (s, LHBRX | RT (data_reg) | RB (r0));
672 810260a8 malc
        else tcg_out32 (s, LHZ | RT (data_reg) | RA (r0));
673 810260a8 malc
        break;
674 810260a8 malc
    case 1|4:
675 810260a8 malc
        if (bswap) {
676 810260a8 malc
            tcg_out32 (s, LHBRX | RT (data_reg) | RB (r0));
677 810260a8 malc
            tcg_out32 (s, EXTSH | RA (data_reg) | RS (data_reg));
678 810260a8 malc
        }
679 810260a8 malc
        else tcg_out32 (s, LHA | RT (data_reg) | RA (r0));
680 810260a8 malc
        break;
681 810260a8 malc
    case 2:
682 810260a8 malc
        if (bswap) tcg_out32 (s, LWBRX | RT (data_reg) | RB (r0));
683 810260a8 malc
        else tcg_out32 (s, LWZ | RT (data_reg)| RA (r0));
684 810260a8 malc
        break;
685 810260a8 malc
    case 2|4:
686 810260a8 malc
        if (bswap) {
687 810260a8 malc
            tcg_out32 (s, LWBRX | RT (data_reg) | RB (r0));
688 450e62e7 malc
            tcg_out32 (s, EXTSW | RA (data_reg) | RS (data_reg));
689 810260a8 malc
        }
690 810260a8 malc
        else tcg_out32 (s, LWA | RT (data_reg)| RA (r0));
691 810260a8 malc
        break;
692 810260a8 malc
    case 3:
693 810260a8 malc
        if (bswap) {
694 109719ec malc
            tcg_out32 (s, LWBRX | RT (0) | RB (r0));
695 109719ec malc
            tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
696 109719ec malc
            tcg_out32 (s, LWBRX | RT (data_reg) | RB (r1));
697 109719ec malc
            tcg_out_rld (s, RLDICR, data_reg, data_reg, 32, 31);
698 109719ec malc
            tcg_out32 (s, OR | SAB (0, data_reg, data_reg));
699 810260a8 malc
        }
700 810260a8 malc
        else tcg_out32 (s, LD | RT (data_reg) | RA (r0));
701 810260a8 malc
        break;
702 810260a8 malc
    }
703 810260a8 malc
704 810260a8 malc
#ifdef CONFIG_SOFTMMU
705 810260a8 malc
    reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr);
706 810260a8 malc
#endif
707 810260a8 malc
}
708 810260a8 malc
709 810260a8 malc
static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
710 810260a8 malc
{
711 810260a8 malc
    int addr_reg, r0, r1, data_reg, mem_index, bswap;
712 810260a8 malc
#ifdef CONFIG_SOFTMMU
713 810260a8 malc
    int r2;
714 810260a8 malc
    void *label1_ptr, *label2_ptr;
715 810260a8 malc
#endif
716 810260a8 malc
717 810260a8 malc
    data_reg = *args++;
718 810260a8 malc
    addr_reg = *args++;
719 810260a8 malc
    mem_index = *args;
720 810260a8 malc
721 810260a8 malc
#ifdef CONFIG_SOFTMMU
722 810260a8 malc
    r0 = 3;
723 810260a8 malc
    r1 = 4;
724 810260a8 malc
    r2 = 0;
725 810260a8 malc
726 810260a8 malc
    tcg_out_tlb_read (s, r0, r1, r2, addr_reg, opc,
727 810260a8 malc
                      offsetof (CPUState, tlb_table[mem_index][0].addr_write));
728 810260a8 malc
729 e924bbec malc
    tcg_out32 (s, CMP | BF (7) | RA (r2) | RB (r1) | CMP_L);
730 810260a8 malc
731 810260a8 malc
    label1_ptr = s->code_ptr;
732 810260a8 malc
#ifdef FAST_PATH
733 810260a8 malc
    tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE);
734 810260a8 malc
#endif
735 810260a8 malc
736 810260a8 malc
    /* slow path */
737 810260a8 malc
    tcg_out_mov (s, 3, addr_reg);
738 810260a8 malc
    tcg_out_rld (s, RLDICL, 4, data_reg, 0, 64 - (1 << (3 + opc)));
739 810260a8 malc
    tcg_out_movi (s, TCG_TYPE_I64, 5, mem_index);
740 810260a8 malc
741 810260a8 malc
    tcg_out_call (s, (tcg_target_long) qemu_st_helpers[opc], 1);
742 810260a8 malc
743 810260a8 malc
    label2_ptr = s->code_ptr;
744 810260a8 malc
    tcg_out32 (s, B);
745 810260a8 malc
746 810260a8 malc
    /* label1: fast path */
747 810260a8 malc
#ifdef FAST_PATH
748 810260a8 malc
    reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr);
749 810260a8 malc
#endif
750 810260a8 malc
751 810260a8 malc
    tcg_out32 (s, (LD_ADDEND
752 810260a8 malc
                   | RT (r0)
753 810260a8 malc
                   | RA (r0)
754 810260a8 malc
                   | (offsetof (CPUTLBEntry, addend)
755 810260a8 malc
                      - offsetof (CPUTLBEntry, addr_write))
756 810260a8 malc
                   ));
757 810260a8 malc
    /* r0 = env->tlb_table[mem_index][index].addend */
758 810260a8 malc
    tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (addr_reg));
759 810260a8 malc
    /* r0 = env->tlb_table[mem_index][index].addend + addr */
760 810260a8 malc
761 810260a8 malc
#else  /* !CONFIG_SOFTMMU */
762 0b7c1d89 malc
#if TARGET_LONG_BITS == 32
763 0b7c1d89 malc
    tcg_out_rld (s, RLDICL, addr_reg, addr_reg, 0, 32);
764 0b7c1d89 malc
#endif
765 735ee40d malc
    r1 = 3;
766 810260a8 malc
    r0 = addr_reg;
767 810260a8 malc
#endif
768 810260a8 malc
769 810260a8 malc
#ifdef TARGET_WORDS_BIGENDIAN
770 810260a8 malc
    bswap = 0;
771 810260a8 malc
#else
772 810260a8 malc
    bswap = 1;
773 810260a8 malc
#endif
774 810260a8 malc
    switch (opc) {
775 810260a8 malc
    case 0:
776 810260a8 malc
        tcg_out32 (s, STB | RS (data_reg) | RA (r0));
777 810260a8 malc
        break;
778 810260a8 malc
    case 1:
779 810260a8 malc
        if (bswap) tcg_out32 (s, STHBRX | RS (data_reg) | RA (0) | RB (r0));
780 810260a8 malc
        else tcg_out32 (s, STH | RS (data_reg) | RA (r0));
781 810260a8 malc
        break;
782 810260a8 malc
    case 2:
783 810260a8 malc
        if (bswap) tcg_out32 (s, STWBRX | RS (data_reg) | RA (0) | RB (r0));
784 810260a8 malc
        else tcg_out32 (s, STW | RS (data_reg) | RA (r0));
785 810260a8 malc
        break;
786 810260a8 malc
    case 3:
787 810260a8 malc
        if (bswap) {
788 810260a8 malc
            tcg_out32 (s, STWBRX | RS (data_reg) | RA (0) | RB (r0));
789 109719ec malc
            tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
790 810260a8 malc
            tcg_out_rld (s, RLDICL, 0, data_reg, 32, 0);
791 109719ec malc
            tcg_out32 (s, STWBRX | RS (0) | RA (0) | RB (r1));
792 810260a8 malc
        }
793 810260a8 malc
        else tcg_out32 (s, STD | RS (data_reg) | RA (r0));
794 810260a8 malc
        break;
795 810260a8 malc
    }
796 810260a8 malc
797 810260a8 malc
#ifdef CONFIG_SOFTMMU
798 810260a8 malc
    reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr);
799 810260a8 malc
#endif
800 810260a8 malc
}
801 810260a8 malc
802 810260a8 malc
void tcg_target_qemu_prologue (TCGContext *s)
803 810260a8 malc
{
804 810260a8 malc
    int i, frame_size;
805 a69abbe0 malc
    uint64_t addr;
806 810260a8 malc
807 810260a8 malc
    frame_size = 0
808 810260a8 malc
        + 8                     /* back chain */
809 810260a8 malc
        + 8                     /* CR */
810 810260a8 malc
        + 8                     /* LR */
811 810260a8 malc
        + 8                     /* compiler doubleword */
812 810260a8 malc
        + 8                     /* link editor doubleword */
813 810260a8 malc
        + 8                     /* TOC save area */
814 810260a8 malc
        + TCG_STATIC_CALL_ARGS_SIZE
815 810260a8 malc
        + ARRAY_SIZE (tcg_target_callee_save_regs) * 8
816 810260a8 malc
        ;
817 810260a8 malc
    frame_size = (frame_size + 15) & ~15;
818 810260a8 malc
819 a69abbe0 malc
    /* First emit adhoc function descriptor */
820 a69abbe0 malc
    addr = (uint64_t) s->code_ptr + 24;
821 a69abbe0 malc
    tcg_out32 (s, addr >> 32); tcg_out32 (s, addr); /* entry point */
822 a69abbe0 malc
    s->code_ptr += 16;          /* skip TOC and environment pointer */
823 a69abbe0 malc
824 a69abbe0 malc
    /* Prologue */
825 810260a8 malc
    tcg_out32 (s, MFSPR | RT (0) | LR);
826 810260a8 malc
    tcg_out32 (s, STDU | RS (1) | RA (1) | (-frame_size & 0xffff));
827 810260a8 malc
    for (i = 0; i < ARRAY_SIZE (tcg_target_callee_save_regs); ++i)
828 810260a8 malc
        tcg_out32 (s, (STD
829 810260a8 malc
                       | RS (tcg_target_callee_save_regs[i])
830 810260a8 malc
                       | RA (1)
831 810260a8 malc
                       | (i * 8 + 48 + TCG_STATIC_CALL_ARGS_SIZE)
832 810260a8 malc
                       )
833 810260a8 malc
            );
834 e03ae7f9 malc
    tcg_out32 (s, STD | RS (0) | RA (1) | (frame_size + 16));
835 810260a8 malc
836 810260a8 malc
    tcg_out32 (s, MTSPR | RS (3) | CTR);
837 810260a8 malc
    tcg_out32 (s, BCCTR | BO_ALWAYS);
838 a69abbe0 malc
839 a69abbe0 malc
    /* Epilogue */
840 810260a8 malc
    tb_ret_addr = s->code_ptr;
841 810260a8 malc
842 810260a8 malc
    for (i = 0; i < ARRAY_SIZE (tcg_target_callee_save_regs); ++i)
843 810260a8 malc
        tcg_out32 (s, (LD
844 810260a8 malc
                       | RT (tcg_target_callee_save_regs[i])
845 810260a8 malc
                       | RA (1)
846 810260a8 malc
                       | (i * 8 + 48 + TCG_STATIC_CALL_ARGS_SIZE)
847 810260a8 malc
                       )
848 810260a8 malc
            );
849 e03ae7f9 malc
    tcg_out32 (s, LD | RT (0) | RA (1) | (frame_size + 16));
850 810260a8 malc
    tcg_out32 (s, MTSPR | RS (0) | LR);
851 810260a8 malc
    tcg_out32 (s, ADDI | RT (1) | RA (1) | frame_size);
852 810260a8 malc
    tcg_out32 (s, BCLR | BO_ALWAYS);
853 810260a8 malc
}
854 810260a8 malc
855 810260a8 malc
static void tcg_out_ld (TCGContext *s, TCGType type, int ret, int arg1,
856 810260a8 malc
                        tcg_target_long arg2)
857 810260a8 malc
{
858 810260a8 malc
    if (type == TCG_TYPE_I32)
859 810260a8 malc
        tcg_out_ldst (s, ret, arg1, arg2, LWZ, LWZX);
860 810260a8 malc
    else
861 810260a8 malc
        tcg_out_ldst (s, ret, arg1, arg2, LD, LDX);
862 810260a8 malc
}
863 810260a8 malc
864 810260a8 malc
static void tcg_out_st (TCGContext *s, TCGType type, int arg, int arg1,
865 810260a8 malc
                        tcg_target_long arg2)
866 810260a8 malc
{
867 810260a8 malc
    if (type == TCG_TYPE_I32)
868 810260a8 malc
        tcg_out_ldst (s, arg, arg1, arg2, STW, STWX);
869 810260a8 malc
    else
870 810260a8 malc
        tcg_out_ldst (s, arg, arg1, arg2, STD, STDX);
871 810260a8 malc
}
872 810260a8 malc
873 810260a8 malc
static void ppc_addi32 (TCGContext *s, int rt, int ra, tcg_target_long si)
874 810260a8 malc
{
875 810260a8 malc
    if (!si && rt == ra)
876 810260a8 malc
        return;
877 810260a8 malc
878 810260a8 malc
    if (si == (int16_t) si)
879 810260a8 malc
        tcg_out32 (s, ADDI | RT (rt) | RA (ra) | (si & 0xffff));
880 810260a8 malc
    else {
881 810260a8 malc
        uint16_t h = ((si >> 16) & 0xffff) + ((uint16_t) si >> 15);
882 810260a8 malc
        tcg_out32 (s, ADDIS | RT (rt) | RA (ra) | h);
883 810260a8 malc
        tcg_out32 (s, ADDI | RT (rt) | RA (rt) | (si & 0xffff));
884 810260a8 malc
    }
885 810260a8 malc
}
886 810260a8 malc
887 810260a8 malc
static void ppc_addi64 (TCGContext *s, int rt, int ra, tcg_target_long si)
888 810260a8 malc
{
889 fe6f943f malc
    /* XXX: suboptimal */
890 fe6f943f malc
    if (si == (int16_t) si
891 fe6f943f malc
        || (((uint64_t) si >> 31) == 0) && (si & 0x8000) == 0)
892 fe6f943f malc
        ppc_addi32 (s, rt, ra, si);
893 fe6f943f malc
    else {
894 fe6f943f malc
        tcg_out_movi (s, TCG_TYPE_I64, 0, si);
895 fe6f943f malc
        tcg_out32 (s, ADD | RT (rt) | RA (ra));
896 fe6f943f malc
    }
897 810260a8 malc
}
898 810260a8 malc
899 810260a8 malc
static void tcg_out_addi (TCGContext *s, int reg, tcg_target_long val)
900 810260a8 malc
{
901 810260a8 malc
    ppc_addi64 (s, reg, reg, val);
902 810260a8 malc
}
903 810260a8 malc
904 810260a8 malc
static void tcg_out_cmp (TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
905 e924bbec malc
                         int const_arg2, int cr, int arch64)
906 810260a8 malc
{
907 810260a8 malc
    int imm;
908 810260a8 malc
    uint32_t op;
909 810260a8 malc
910 810260a8 malc
    switch (cond) {
911 810260a8 malc
    case TCG_COND_EQ:
912 810260a8 malc
    case TCG_COND_NE:
913 810260a8 malc
        if (const_arg2) {
914 810260a8 malc
            if ((int16_t) arg2 == arg2) {
915 810260a8 malc
                op = CMPI;
916 810260a8 malc
                imm = 1;
917 810260a8 malc
                break;
918 810260a8 malc
            }
919 810260a8 malc
            else if ((uint16_t) arg2 == arg2) {
920 810260a8 malc
                op = CMPLI;
921 810260a8 malc
                imm = 1;
922 810260a8 malc
                break;
923 810260a8 malc
            }
924 810260a8 malc
        }
925 810260a8 malc
        op = CMPL;
926 810260a8 malc
        imm = 0;
927 810260a8 malc
        break;
928 810260a8 malc
929 810260a8 malc
    case TCG_COND_LT:
930 810260a8 malc
    case TCG_COND_GE:
931 810260a8 malc
    case TCG_COND_LE:
932 810260a8 malc
    case TCG_COND_GT:
933 810260a8 malc
        if (const_arg2) {
934 810260a8 malc
            if ((int16_t) arg2 == arg2) {
935 810260a8 malc
                op = CMPI;
936 810260a8 malc
                imm = 1;
937 810260a8 malc
                break;
938 810260a8 malc
            }
939 810260a8 malc
        }
940 810260a8 malc
        op = CMP;
941 810260a8 malc
        imm = 0;
942 810260a8 malc
        break;
943 810260a8 malc
944 810260a8 malc
    case TCG_COND_LTU:
945 810260a8 malc
    case TCG_COND_GEU:
946 810260a8 malc
    case TCG_COND_LEU:
947 810260a8 malc
    case TCG_COND_GTU:
948 810260a8 malc
        if (const_arg2) {
949 810260a8 malc
            if ((uint16_t) arg2 == arg2) {
950 810260a8 malc
                op = CMPLI;
951 810260a8 malc
                imm = 1;
952 810260a8 malc
                break;
953 810260a8 malc
            }
954 810260a8 malc
        }
955 810260a8 malc
        op = CMPL;
956 810260a8 malc
        imm = 0;
957 810260a8 malc
        break;
958 810260a8 malc
959 810260a8 malc
    default:
960 810260a8 malc
        tcg_abort ();
961 810260a8 malc
    }
962 e924bbec malc
    op |= BF (cr) | (arch64 << 21);
963 810260a8 malc
964 810260a8 malc
    if (imm)
965 810260a8 malc
        tcg_out32 (s, op | RA (arg1) | (arg2 & 0xffff));
966 810260a8 malc
    else {
967 810260a8 malc
        if (const_arg2) {
968 810260a8 malc
            tcg_out_movi (s, TCG_TYPE_I64, 0, arg2);
969 810260a8 malc
            tcg_out32 (s, op | RA (arg1) | RB (0));
970 810260a8 malc
        }
971 810260a8 malc
        else
972 810260a8 malc
            tcg_out32 (s, op | RA (arg1) | RB (arg2));
973 810260a8 malc
    }
974 810260a8 malc
975 810260a8 malc
}
976 810260a8 malc
977 810260a8 malc
static void tcg_out_bc (TCGContext *s, int bc, int label_index)
978 810260a8 malc
{
979 810260a8 malc
    TCGLabel *l = &s->labels[label_index];
980 810260a8 malc
981 810260a8 malc
    if (l->has_value)
982 810260a8 malc
        tcg_out32 (s, bc | reloc_pc14_val (s->code_ptr, l->u.value));
983 810260a8 malc
    else {
984 810260a8 malc
        uint16_t val = *(uint16_t *) &s->code_ptr[2];
985 810260a8 malc
986 810260a8 malc
        /* Thanks to Andrzej Zaborowski */
987 810260a8 malc
        tcg_out32 (s, bc | (val & 0xfffc));
988 810260a8 malc
        tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL14, label_index, 0);
989 810260a8 malc
    }
990 810260a8 malc
}
991 810260a8 malc
992 810260a8 malc
static void tcg_out_brcond (TCGContext *s, int cond,
993 810260a8 malc
                            TCGArg arg1, TCGArg arg2, int const_arg2,
994 e924bbec malc
                            int label_index, int arch64)
995 810260a8 malc
{
996 e924bbec malc
    tcg_out_cmp (s, cond, arg1, arg2, const_arg2, 7, arch64);
997 810260a8 malc
    tcg_out_bc (s, tcg_to_bc[cond], label_index);
998 810260a8 malc
}
999 810260a8 malc
1000 810260a8 malc
void ppc_tb_set_jmp_target (unsigned long jmp_addr, unsigned long addr)
1001 810260a8 malc
{
1002 810260a8 malc
    TCGContext s;
1003 810260a8 malc
    unsigned long patch_size;
1004 810260a8 malc
1005 810260a8 malc
    s.code_ptr = (uint8_t *) jmp_addr;
1006 810260a8 malc
    tcg_out_b (&s, 0, addr);
1007 810260a8 malc
    patch_size = s.code_ptr - (uint8_t *) jmp_addr;
1008 810260a8 malc
    flush_icache_range (jmp_addr, jmp_addr + patch_size);
1009 810260a8 malc
}
1010 810260a8 malc
1011 810260a8 malc
static void tcg_out_op (TCGContext *s, int opc, const TCGArg *args,
1012 810260a8 malc
                        const int *const_args)
1013 810260a8 malc
{
1014 e46b9681 malc
    int c;
1015 e46b9681 malc
1016 810260a8 malc
    switch (opc) {
1017 810260a8 malc
    case INDEX_op_exit_tb:
1018 810260a8 malc
        tcg_out_movi (s, TCG_TYPE_I64, TCG_REG_R3, args[0]);
1019 810260a8 malc
        tcg_out_b (s, 0, (tcg_target_long) tb_ret_addr);
1020 810260a8 malc
        break;
1021 810260a8 malc
    case INDEX_op_goto_tb:
1022 810260a8 malc
        if (s->tb_jmp_offset) {
1023 810260a8 malc
            /* direct jump method */
1024 810260a8 malc
1025 810260a8 malc
            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
1026 5424fd10 malc
            s->code_ptr += 28;
1027 810260a8 malc
        }
1028 810260a8 malc
        else {
1029 810260a8 malc
            tcg_abort ();
1030 810260a8 malc
        }
1031 810260a8 malc
        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1032 810260a8 malc
        break;
1033 810260a8 malc
    case INDEX_op_br:
1034 810260a8 malc
        {
1035 810260a8 malc
            TCGLabel *l = &s->labels[args[0]];
1036 810260a8 malc
1037 810260a8 malc
            if (l->has_value) {
1038 810260a8 malc
                tcg_out_b (s, 0, l->u.value);
1039 810260a8 malc
            }
1040 810260a8 malc
            else {
1041 810260a8 malc
                uint32_t val = *(uint32_t *) s->code_ptr;
1042 810260a8 malc
1043 810260a8 malc
                /* Thanks to Andrzej Zaborowski */
1044 810260a8 malc
                tcg_out32 (s, B | (val & 0x3fffffc));
1045 810260a8 malc
                tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL24, args[0], 0);
1046 810260a8 malc
            }
1047 810260a8 malc
        }
1048 810260a8 malc
        break;
1049 810260a8 malc
    case INDEX_op_call:
1050 810260a8 malc
        tcg_out_call (s, args[0], const_args[0]);
1051 810260a8 malc
        break;
1052 810260a8 malc
    case INDEX_op_jmp:
1053 810260a8 malc
        if (const_args[0]) {
1054 810260a8 malc
            tcg_out_b (s, 0, args[0]);
1055 810260a8 malc
        }
1056 810260a8 malc
        else {
1057 810260a8 malc
            tcg_out32 (s, MTSPR | RS (args[0]) | CTR);
1058 810260a8 malc
            tcg_out32 (s, BCCTR | BO_ALWAYS);
1059 810260a8 malc
        }
1060 810260a8 malc
        break;
1061 810260a8 malc
    case INDEX_op_movi_i32:
1062 810260a8 malc
        tcg_out_movi (s, TCG_TYPE_I32, args[0], args[1]);
1063 810260a8 malc
        break;
1064 810260a8 malc
    case INDEX_op_movi_i64:
1065 810260a8 malc
        tcg_out_movi (s, TCG_TYPE_I64, args[0], args[1]);
1066 810260a8 malc
        break;
1067 810260a8 malc
    case INDEX_op_ld8u_i32:
1068 810260a8 malc
    case INDEX_op_ld8u_i64:
1069 810260a8 malc
        tcg_out_ldst (s, args[0], args[1], args[2], LBZ, LBZX);
1070 810260a8 malc
        break;
1071 810260a8 malc
    case INDEX_op_ld8s_i32:
1072 810260a8 malc
    case INDEX_op_ld8s_i64:
1073 810260a8 malc
        tcg_out_ldst (s, args[0], args[1], args[2], LBZ, LBZX);
1074 810260a8 malc
        tcg_out32 (s, EXTSB | RS (args[0]) | RA (args[0]));
1075 810260a8 malc
        break;
1076 810260a8 malc
    case INDEX_op_ld16u_i32:
1077 810260a8 malc
    case INDEX_op_ld16u_i64:
1078 810260a8 malc
        tcg_out_ldst (s, args[0], args[1], args[2], LHZ, LHZX);
1079 810260a8 malc
        break;
1080 810260a8 malc
    case INDEX_op_ld16s_i32:
1081 810260a8 malc
    case INDEX_op_ld16s_i64:
1082 810260a8 malc
        tcg_out_ldst (s, args[0], args[1], args[2], LHA, LHAX);
1083 810260a8 malc
        break;
1084 810260a8 malc
    case INDEX_op_ld_i32:
1085 810260a8 malc
    case INDEX_op_ld32u_i64:
1086 810260a8 malc
        tcg_out_ldst (s, args[0], args[1], args[2], LWZ, LWZX);
1087 810260a8 malc
        break;
1088 810260a8 malc
    case INDEX_op_ld32s_i64:
1089 810260a8 malc
        tcg_out_ldst (s, args[0], args[1], args[2], LWA, LWAX);
1090 810260a8 malc
        break;
1091 810260a8 malc
    case INDEX_op_ld_i64:
1092 810260a8 malc
        tcg_out_ldst (s, args[0], args[1], args[2], LD, LDX);
1093 810260a8 malc
        break;
1094 810260a8 malc
    case INDEX_op_st8_i32:
1095 810260a8 malc
    case INDEX_op_st8_i64:
1096 810260a8 malc
        tcg_out_ldst (s, args[0], args[1], args[2], STB, STBX);
1097 810260a8 malc
        break;
1098 810260a8 malc
    case INDEX_op_st16_i32:
1099 810260a8 malc
    case INDEX_op_st16_i64:
1100 810260a8 malc
        tcg_out_ldst (s, args[0], args[1], args[2], STH, STHX);
1101 810260a8 malc
        break;
1102 810260a8 malc
    case INDEX_op_st_i32:
1103 810260a8 malc
    case INDEX_op_st32_i64:
1104 810260a8 malc
        tcg_out_ldst (s, args[0], args[1], args[2], STW, STWX);
1105 810260a8 malc
        break;
1106 810260a8 malc
    case INDEX_op_st_i64:
1107 810260a8 malc
        tcg_out_ldst (s, args[0], args[1], args[2], STD, STDX);
1108 810260a8 malc
        break;
1109 810260a8 malc
1110 810260a8 malc
    case INDEX_op_add_i32:
1111 810260a8 malc
        if (const_args[2])
1112 810260a8 malc
            ppc_addi32 (s, args[0], args[1], args[2]);
1113 810260a8 malc
        else
1114 810260a8 malc
            tcg_out32 (s, ADD | TAB (args[0], args[1], args[2]));
1115 810260a8 malc
        break;
1116 810260a8 malc
    case INDEX_op_sub_i32:
1117 810260a8 malc
        if (const_args[2])
1118 810260a8 malc
            ppc_addi32 (s, args[0], args[1], -args[2]);
1119 810260a8 malc
        else
1120 810260a8 malc
            tcg_out32 (s, SUBF | TAB (args[0], args[2], args[1]));
1121 810260a8 malc
        break;
1122 810260a8 malc
1123 fe6f943f malc
    case INDEX_op_and_i64:
1124 810260a8 malc
    case INDEX_op_and_i32:
1125 810260a8 malc
        if (const_args[2]) {
1126 000a2d86 malc
            if ((args[2] & 0xffff) == args[2])
1127 000a2d86 malc
                tcg_out32 (s, ANDI | RS (args[1]) | RA (args[0]) | args[2]);
1128 000a2d86 malc
            else if ((args[2] & 0xffff0000) == args[2])
1129 000a2d86 malc
                tcg_out32 (s, ANDIS | RS (args[1]) | RA (args[0])
1130 000a2d86 malc
                           | ((args[2] >> 16) & 0xffff));
1131 810260a8 malc
            else {
1132 fe6f943f malc
                tcg_out_movi (s, (opc == INDEX_op_and_i32
1133 fe6f943f malc
                                  ? TCG_TYPE_I32
1134 fe6f943f malc
                                  : TCG_TYPE_I64),
1135 fe6f943f malc
                              0, args[2]);
1136 000a2d86 malc
                tcg_out32 (s, AND | SAB (args[1], args[0], 0));
1137 810260a8 malc
            }
1138 810260a8 malc
        }
1139 810260a8 malc
        else
1140 810260a8 malc
            tcg_out32 (s, AND | SAB (args[1], args[0], args[2]));
1141 810260a8 malc
        break;
1142 fe6f943f malc
    case INDEX_op_or_i64:
1143 810260a8 malc
    case INDEX_op_or_i32:
1144 810260a8 malc
        if (const_args[2]) {
1145 000a2d86 malc
            if (args[2] & 0xffff) {
1146 000a2d86 malc
                tcg_out32 (s, ORI | RS (args[1]) | RA (args[0])
1147 000a2d86 malc
                           | (args[2] & 0xffff));
1148 000a2d86 malc
                if (args[2] >> 16)
1149 000a2d86 malc
                    tcg_out32 (s, ORIS | RS (args[0])  | RA (args[0])
1150 810260a8 malc
                               | ((args[2] >> 16) & 0xffff));
1151 810260a8 malc
            }
1152 810260a8 malc
            else {
1153 000a2d86 malc
                tcg_out32 (s, ORIS | RS (args[1])  | RA (args[0])
1154 000a2d86 malc
                           | ((args[2] >> 16) & 0xffff));
1155 810260a8 malc
            }
1156 810260a8 malc
        }
1157 810260a8 malc
        else
1158 810260a8 malc
            tcg_out32 (s, OR | SAB (args[1], args[0], args[2]));
1159 810260a8 malc
        break;
1160 fe6f943f malc
    case INDEX_op_xor_i64:
1161 810260a8 malc
    case INDEX_op_xor_i32:
1162 810260a8 malc
        if (const_args[2]) {
1163 000a2d86 malc
            if ((args[2] & 0xffff) == args[2])
1164 000a2d86 malc
                tcg_out32 (s, XORI | RS (args[1])  | RA (args[0])
1165 000a2d86 malc
                           | (args[2] & 0xffff));
1166 000a2d86 malc
            else if ((args[2] & 0xffff0000) == args[2])
1167 000a2d86 malc
                tcg_out32 (s, XORIS | RS (args[1])  | RA (args[0])
1168 000a2d86 malc
                           | ((args[2] >> 16) & 0xffff));
1169 810260a8 malc
            else {
1170 fe6f943f malc
                tcg_out_movi (s, (opc == INDEX_op_and_i32
1171 fe6f943f malc
                                  ? TCG_TYPE_I32
1172 fe6f943f malc
                                  : TCG_TYPE_I64),
1173 fe6f943f malc
                              0, args[2]);
1174 000a2d86 malc
                tcg_out32 (s, XOR | SAB (args[1], args[0], 0));
1175 810260a8 malc
            }
1176 810260a8 malc
        }
1177 810260a8 malc
        else
1178 810260a8 malc
            tcg_out32 (s, XOR | SAB (args[1], args[0], args[2]));
1179 810260a8 malc
        break;
1180 810260a8 malc
1181 810260a8 malc
    case INDEX_op_mul_i32:
1182 810260a8 malc
        if (const_args[2]) {
1183 810260a8 malc
            if (args[2] == (int16_t) args[2])
1184 810260a8 malc
                tcg_out32 (s, MULLI | RT (args[0]) | RA (args[1])
1185 810260a8 malc
                           | (args[2] & 0xffff));
1186 810260a8 malc
            else {
1187 810260a8 malc
                tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]);
1188 810260a8 malc
                tcg_out32 (s, MULLW | TAB (args[0], args[1], 0));
1189 810260a8 malc
            }
1190 810260a8 malc
        }
1191 810260a8 malc
        else
1192 810260a8 malc
            tcg_out32 (s, MULLW | TAB (args[0], args[1], args[2]));
1193 810260a8 malc
        break;
1194 810260a8 malc
1195 810260a8 malc
    case INDEX_op_div_i32:
1196 810260a8 malc
        tcg_out32 (s, DIVW | TAB (args[0], args[1], args[2]));
1197 810260a8 malc
        break;
1198 810260a8 malc
1199 810260a8 malc
    case INDEX_op_divu_i32:
1200 810260a8 malc
        tcg_out32 (s, DIVWU | TAB (args[0], args[1], args[2]));
1201 810260a8 malc
        break;
1202 810260a8 malc
1203 810260a8 malc
    case INDEX_op_rem_i32:
1204 810260a8 malc
        tcg_out32 (s, DIVW | TAB (0, args[1], args[2]));
1205 810260a8 malc
        tcg_out32 (s, MULLW | TAB (0, 0, args[2]));
1206 810260a8 malc
        tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
1207 810260a8 malc
        break;
1208 810260a8 malc
1209 810260a8 malc
    case INDEX_op_remu_i32:
1210 810260a8 malc
        tcg_out32 (s, DIVWU | TAB (0, args[1], args[2]));
1211 810260a8 malc
        tcg_out32 (s, MULLW | TAB (0, 0, args[2]));
1212 810260a8 malc
        tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
1213 810260a8 malc
        break;
1214 810260a8 malc
1215 810260a8 malc
    case INDEX_op_shl_i32:
1216 810260a8 malc
        if (const_args[2]) {
1217 000a2d86 malc
            tcg_out32 (s, (RLWINM
1218 000a2d86 malc
                           | RA (args[0])
1219 000a2d86 malc
                           | RS (args[1])
1220 000a2d86 malc
                           | SH (args[2])
1221 000a2d86 malc
                           | MB (0)
1222 000a2d86 malc
                           | ME (31 - args[2])
1223 000a2d86 malc
                           )
1224 000a2d86 malc
                );
1225 810260a8 malc
        }
1226 810260a8 malc
        else
1227 810260a8 malc
            tcg_out32 (s, SLW | SAB (args[1], args[0], args[2]));
1228 810260a8 malc
        break;
1229 810260a8 malc
    case INDEX_op_shr_i32:
1230 810260a8 malc
        if (const_args[2]) {
1231 000a2d86 malc
            tcg_out32 (s, (RLWINM
1232 000a2d86 malc
                           | RA (args[0])
1233 000a2d86 malc
                           | RS (args[1])
1234 000a2d86 malc
                           | SH (32 - args[2])
1235 000a2d86 malc
                           | MB (args[2])
1236 000a2d86 malc
                           | ME (31)
1237 000a2d86 malc
                           )
1238 000a2d86 malc
                );
1239 810260a8 malc
        }
1240 810260a8 malc
        else
1241 810260a8 malc
            tcg_out32 (s, SRW | SAB (args[1], args[0], args[2]));
1242 810260a8 malc
        break;
1243 810260a8 malc
    case INDEX_op_sar_i32:
1244 810260a8 malc
        if (const_args[2])
1245 810260a8 malc
            tcg_out32 (s, SRAWI | RS (args[1]) | RA (args[0]) | SH (args[2]));
1246 810260a8 malc
        else
1247 810260a8 malc
            tcg_out32 (s, SRAW | SAB (args[1], args[0], args[2]));
1248 810260a8 malc
        break;
1249 810260a8 malc
1250 810260a8 malc
    case INDEX_op_brcond_i32:
1251 e924bbec malc
        tcg_out_brcond (s, args[2], args[0], args[1], const_args[1], args[3], 0);
1252 e924bbec malc
        break;
1253 e924bbec malc
1254 810260a8 malc
    case INDEX_op_brcond_i64:
1255 e924bbec malc
        tcg_out_brcond (s, args[2], args[0], args[1], const_args[1], args[3], 1);
1256 810260a8 malc
        break;
1257 810260a8 malc
1258 810260a8 malc
    case INDEX_op_neg_i32:
1259 810260a8 malc
    case INDEX_op_neg_i64:
1260 810260a8 malc
        tcg_out32 (s, NEG | RT (args[0]) | RA (args[1]));
1261 810260a8 malc
        break;
1262 810260a8 malc
1263 810260a8 malc
    case INDEX_op_add_i64:
1264 fe6f943f malc
        if (const_args[2])
1265 fe6f943f malc
            ppc_addi64 (s, args[0], args[1], args[2]);
1266 fe6f943f malc
        else
1267 fe6f943f malc
            tcg_out32 (s, ADD | TAB (args[0], args[1], args[2]));
1268 810260a8 malc
        break;
1269 810260a8 malc
    case INDEX_op_sub_i64:
1270 fe6f943f malc
        if (const_args[2])
1271 fe6f943f malc
            ppc_addi64 (s, args[0], args[1], -args[2]);
1272 fe6f943f malc
        else
1273 fe6f943f malc
            tcg_out32 (s, SUBF | TAB (args[0], args[2], args[1]));
1274 810260a8 malc
        break;
1275 810260a8 malc
1276 810260a8 malc
    case INDEX_op_shl_i64:
1277 fe6f943f malc
        if (const_args[2])
1278 fe6f943f malc
            tcg_out_rld (s, RLDICR, args[0], args[1], args[2], 63 - args[2]);
1279 fe6f943f malc
        else
1280 fe6f943f malc
            tcg_out32 (s, SLD | SAB (args[1], args[0], args[2]));
1281 810260a8 malc
        break;
1282 810260a8 malc
    case INDEX_op_shr_i64:
1283 fe6f943f malc
        if (const_args[2])
1284 fe6f943f malc
            tcg_out_rld (s, RLDICL, args[0], args[1], 64 - args[2], args[2]);
1285 fe6f943f malc
        else
1286 fe6f943f malc
            tcg_out32 (s, SRD | SAB (args[1], args[0], args[2]));
1287 810260a8 malc
        break;
1288 810260a8 malc
    case INDEX_op_sar_i64:
1289 fe6f943f malc
        if (const_args[2]) {
1290 fe6f943f malc
            int sh = SH (args[2] & 0x1f) | (((args[2] >> 5) & 1) << 1);
1291 fe6f943f malc
            tcg_out32 (s, SRADI | RA (args[0]) | RS (args[1]) | sh);
1292 fe6f943f malc
        }
1293 fe6f943f malc
        else
1294 fe6f943f malc
            tcg_out32 (s, SRAD | SAB (args[1], args[0], args[2]));
1295 810260a8 malc
        break;
1296 810260a8 malc
1297 810260a8 malc
    case INDEX_op_mul_i64:
1298 810260a8 malc
        tcg_out32 (s, MULLD | TAB (args[0], args[1], args[2]));
1299 810260a8 malc
        break;
1300 810260a8 malc
    case INDEX_op_div_i64:
1301 810260a8 malc
        tcg_out32 (s, DIVD | TAB (args[0], args[1], args[2]));
1302 810260a8 malc
        break;
1303 810260a8 malc
    case INDEX_op_divu_i64:
1304 810260a8 malc
        tcg_out32 (s, DIVDU | TAB (args[0], args[1], args[2]));
1305 810260a8 malc
        break;
1306 810260a8 malc
    case INDEX_op_rem_i64:
1307 810260a8 malc
        tcg_out32 (s, DIVD | TAB (0, args[1], args[2]));
1308 810260a8 malc
        tcg_out32 (s, MULLD | TAB (0, 0, args[2]));
1309 810260a8 malc
        tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
1310 810260a8 malc
        break;
1311 810260a8 malc
    case INDEX_op_remu_i64:
1312 810260a8 malc
        tcg_out32 (s, DIVDU | TAB (0, args[1], args[2]));
1313 810260a8 malc
        tcg_out32 (s, MULLD | TAB (0, 0, args[2]));
1314 810260a8 malc
        tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
1315 810260a8 malc
        break;
1316 810260a8 malc
1317 810260a8 malc
    case INDEX_op_qemu_ld8u:
1318 810260a8 malc
        tcg_out_qemu_ld (s, args, 0);
1319 810260a8 malc
        break;
1320 810260a8 malc
    case INDEX_op_qemu_ld8s:
1321 810260a8 malc
        tcg_out_qemu_ld (s, args, 0 | 4);
1322 810260a8 malc
        break;
1323 810260a8 malc
    case INDEX_op_qemu_ld16u:
1324 810260a8 malc
        tcg_out_qemu_ld (s, args, 1);
1325 810260a8 malc
        break;
1326 810260a8 malc
    case INDEX_op_qemu_ld16s:
1327 810260a8 malc
        tcg_out_qemu_ld (s, args, 1 | 4);
1328 810260a8 malc
        break;
1329 810260a8 malc
    case INDEX_op_qemu_ld32u:
1330 810260a8 malc
        tcg_out_qemu_ld (s, args, 2);
1331 810260a8 malc
        break;
1332 810260a8 malc
    case INDEX_op_qemu_ld32s:
1333 810260a8 malc
        tcg_out_qemu_ld (s, args, 2 | 4);
1334 810260a8 malc
        break;
1335 810260a8 malc
    case INDEX_op_qemu_ld64:
1336 810260a8 malc
        tcg_out_qemu_ld (s, args, 3);
1337 810260a8 malc
        break;
1338 810260a8 malc
    case INDEX_op_qemu_st8:
1339 810260a8 malc
        tcg_out_qemu_st (s, args, 0);
1340 810260a8 malc
        break;
1341 810260a8 malc
    case INDEX_op_qemu_st16:
1342 810260a8 malc
        tcg_out_qemu_st (s, args, 1);
1343 810260a8 malc
        break;
1344 810260a8 malc
    case INDEX_op_qemu_st32:
1345 810260a8 malc
        tcg_out_qemu_st (s, args, 2);
1346 810260a8 malc
        break;
1347 810260a8 malc
    case INDEX_op_qemu_st64:
1348 810260a8 malc
        tcg_out_qemu_st (s, args, 3);
1349 810260a8 malc
        break;
1350 810260a8 malc
1351 e46b9681 malc
    case INDEX_op_ext8s_i32:
1352 e46b9681 malc
    case INDEX_op_ext8s_i64:
1353 e46b9681 malc
        c = EXTSB;
1354 e46b9681 malc
        goto gen_ext;
1355 e46b9681 malc
    case INDEX_op_ext16s_i32:
1356 e46b9681 malc
    case INDEX_op_ext16s_i64:
1357 e46b9681 malc
        c = EXTSH;
1358 e46b9681 malc
        goto gen_ext;
1359 e46b9681 malc
    case INDEX_op_ext32s_i64:
1360 e46b9681 malc
        c = EXTSW;
1361 e46b9681 malc
        goto gen_ext;
1362 e46b9681 malc
    gen_ext:
1363 e46b9681 malc
        tcg_out32 (s, c | RS (args[1]) | RA (args[0]));
1364 e46b9681 malc
        break;
1365 e46b9681 malc
1366 810260a8 malc
    default:
1367 810260a8 malc
        tcg_dump_ops (s, stderr);
1368 810260a8 malc
        tcg_abort ();
1369 810260a8 malc
    }
1370 810260a8 malc
}
1371 810260a8 malc
1372 810260a8 malc
static const TCGTargetOpDef ppc_op_defs[] = {
1373 810260a8 malc
    { INDEX_op_exit_tb, { } },
1374 810260a8 malc
    { INDEX_op_goto_tb, { } },
1375 810260a8 malc
    { INDEX_op_call, { "ri" } },
1376 810260a8 malc
    { INDEX_op_jmp, { "ri" } },
1377 810260a8 malc
    { INDEX_op_br, { } },
1378 810260a8 malc
1379 810260a8 malc
    { INDEX_op_mov_i32, { "r", "r" } },
1380 810260a8 malc
    { INDEX_op_mov_i64, { "r", "r" } },
1381 810260a8 malc
    { INDEX_op_movi_i32, { "r" } },
1382 810260a8 malc
    { INDEX_op_movi_i64, { "r" } },
1383 810260a8 malc
1384 810260a8 malc
    { INDEX_op_ld8u_i32, { "r", "r" } },
1385 810260a8 malc
    { INDEX_op_ld8s_i32, { "r", "r" } },
1386 810260a8 malc
    { INDEX_op_ld16u_i32, { "r", "r" } },
1387 810260a8 malc
    { INDEX_op_ld16s_i32, { "r", "r" } },
1388 810260a8 malc
    { INDEX_op_ld_i32, { "r", "r" } },
1389 810260a8 malc
    { INDEX_op_ld_i64, { "r", "r" } },
1390 810260a8 malc
    { INDEX_op_st8_i32, { "r", "r" } },
1391 810260a8 malc
    { INDEX_op_st8_i64, { "r", "r" } },
1392 810260a8 malc
    { INDEX_op_st16_i32, { "r", "r" } },
1393 810260a8 malc
    { INDEX_op_st16_i64, { "r", "r" } },
1394 810260a8 malc
    { INDEX_op_st_i32, { "r", "r" } },
1395 810260a8 malc
    { INDEX_op_st_i64, { "r", "r" } },
1396 810260a8 malc
    { INDEX_op_st32_i64, { "r", "r" } },
1397 810260a8 malc
1398 810260a8 malc
    { INDEX_op_ld8u_i64, { "r", "r" } },
1399 810260a8 malc
    { INDEX_op_ld8s_i64, { "r", "r" } },
1400 810260a8 malc
    { INDEX_op_ld16u_i64, { "r", "r" } },
1401 810260a8 malc
    { INDEX_op_ld16s_i64, { "r", "r" } },
1402 810260a8 malc
    { INDEX_op_ld32u_i64, { "r", "r" } },
1403 810260a8 malc
    { INDEX_op_ld32s_i64, { "r", "r" } },
1404 810260a8 malc
    { INDEX_op_ld_i64, { "r", "r" } },
1405 810260a8 malc
1406 810260a8 malc
    { INDEX_op_add_i32, { "r", "r", "ri" } },
1407 810260a8 malc
    { INDEX_op_mul_i32, { "r", "r", "ri" } },
1408 810260a8 malc
    { INDEX_op_div_i32, { "r", "r", "r" } },
1409 810260a8 malc
    { INDEX_op_divu_i32, { "r", "r", "r" } },
1410 810260a8 malc
    { INDEX_op_rem_i32, { "r", "r", "r" } },
1411 810260a8 malc
    { INDEX_op_remu_i32, { "r", "r", "r" } },
1412 810260a8 malc
    { INDEX_op_sub_i32, { "r", "r", "ri" } },
1413 810260a8 malc
    { INDEX_op_and_i32, { "r", "r", "ri" } },
1414 810260a8 malc
    { INDEX_op_or_i32, { "r", "r", "ri" } },
1415 810260a8 malc
    { INDEX_op_xor_i32, { "r", "r", "ri" } },
1416 810260a8 malc
1417 810260a8 malc
    { INDEX_op_shl_i32, { "r", "r", "ri" } },
1418 810260a8 malc
    { INDEX_op_shr_i32, { "r", "r", "ri" } },
1419 810260a8 malc
    { INDEX_op_sar_i32, { "r", "r", "ri" } },
1420 810260a8 malc
1421 810260a8 malc
    { INDEX_op_brcond_i32, { "r", "ri" } },
1422 810260a8 malc
    { INDEX_op_brcond_i64, { "r", "ri" } },
1423 810260a8 malc
1424 810260a8 malc
    { INDEX_op_neg_i32, { "r", "r" } },
1425 810260a8 malc
1426 fe6f943f malc
    { INDEX_op_add_i64, { "r", "r", "ri" } },
1427 fe6f943f malc
    { INDEX_op_sub_i64, { "r", "r", "ri" } },
1428 fe6f943f malc
    { INDEX_op_and_i64, { "r", "r", "rZ" } },
1429 fe6f943f malc
    { INDEX_op_or_i64, { "r", "r", "rZ" } },
1430 fe6f943f malc
    { INDEX_op_xor_i64, { "r", "r", "rZ" } },
1431 810260a8 malc
1432 fe6f943f malc
    { INDEX_op_shl_i64, { "r", "r", "ri" } },
1433 fe6f943f malc
    { INDEX_op_shr_i64, { "r", "r", "ri" } },
1434 fe6f943f malc
    { INDEX_op_sar_i64, { "r", "r", "ri" } },
1435 810260a8 malc
1436 1d58ee9f malc
    { INDEX_op_mul_i64, { "r", "r", "r" } },
1437 810260a8 malc
    { INDEX_op_div_i64, { "r", "r", "r" } },
1438 810260a8 malc
    { INDEX_op_divu_i64, { "r", "r", "r" } },
1439 810260a8 malc
    { INDEX_op_rem_i64, { "r", "r", "r" } },
1440 810260a8 malc
    { INDEX_op_remu_i64, { "r", "r", "r" } },
1441 810260a8 malc
1442 810260a8 malc
    { INDEX_op_neg_i64, { "r", "r" } },
1443 810260a8 malc
1444 810260a8 malc
    { INDEX_op_qemu_ld8u, { "r", "L" } },
1445 810260a8 malc
    { INDEX_op_qemu_ld8s, { "r", "L" } },
1446 810260a8 malc
    { INDEX_op_qemu_ld16u, { "r", "L" } },
1447 810260a8 malc
    { INDEX_op_qemu_ld16s, { "r", "L" } },
1448 810260a8 malc
    { INDEX_op_qemu_ld32u, { "r", "L" } },
1449 810260a8 malc
    { INDEX_op_qemu_ld32s, { "r", "L" } },
1450 b01d9fea malc
    { INDEX_op_qemu_ld64, { "r", "L" } },
1451 810260a8 malc
1452 c070355d malc
    { INDEX_op_qemu_st8, { "S", "S" } },
1453 c070355d malc
    { INDEX_op_qemu_st16, { "S", "S" } },
1454 c070355d malc
    { INDEX_op_qemu_st32, { "S", "S" } },
1455 c070355d malc
    { INDEX_op_qemu_st64, { "S", "S", "S" } },
1456 810260a8 malc
1457 e46b9681 malc
    { INDEX_op_ext8s_i32, { "r", "r" } },
1458 e46b9681 malc
    { INDEX_op_ext16s_i32, { "r", "r" } },
1459 e46b9681 malc
    { INDEX_op_ext8s_i64, { "r", "r" } },
1460 e46b9681 malc
    { INDEX_op_ext16s_i64, { "r", "r" } },
1461 e46b9681 malc
    { INDEX_op_ext32s_i64, { "r", "r" } },
1462 e46b9681 malc
1463 810260a8 malc
    { -1 },
1464 810260a8 malc
};
1465 810260a8 malc
1466 810260a8 malc
void tcg_target_init (TCGContext *s)
1467 810260a8 malc
{
1468 810260a8 malc
    tcg_regset_set32 (tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
1469 810260a8 malc
    tcg_regset_set32 (tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff);
1470 810260a8 malc
    tcg_regset_set32 (tcg_target_call_clobber_regs, 0,
1471 810260a8 malc
                     (1 << TCG_REG_R0) |
1472 810260a8 malc
                     (1 << TCG_REG_R3) |
1473 810260a8 malc
                     (1 << TCG_REG_R4) |
1474 810260a8 malc
                     (1 << TCG_REG_R5) |
1475 810260a8 malc
                     (1 << TCG_REG_R6) |
1476 810260a8 malc
                     (1 << TCG_REG_R7) |
1477 810260a8 malc
                     (1 << TCG_REG_R8) |
1478 810260a8 malc
                     (1 << TCG_REG_R9) |
1479 810260a8 malc
                     (1 << TCG_REG_R10) |
1480 810260a8 malc
                     (1 << TCG_REG_R11) |
1481 810260a8 malc
                     (1 << TCG_REG_R12)
1482 810260a8 malc
        );
1483 810260a8 malc
1484 810260a8 malc
    tcg_regset_clear (s->reserved_regs);
1485 810260a8 malc
    tcg_regset_set_reg (s->reserved_regs, TCG_REG_R0);
1486 810260a8 malc
    tcg_regset_set_reg (s->reserved_regs, TCG_REG_R1);
1487 810260a8 malc
    tcg_regset_set_reg (s->reserved_regs, TCG_REG_R2);
1488 810260a8 malc
    tcg_regset_set_reg (s->reserved_regs, TCG_REG_R13);
1489 810260a8 malc
1490 810260a8 malc
    tcg_add_target_add_op_defs (ppc_op_defs);
1491 810260a8 malc
}