Statistics
| Branch: | Revision:

root / tcg / ppc64 / tcg-target.c @ 6b64b624

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