Statistics
| Branch: | Revision:

root / tcg / ppc64 / tcg-target.c @ 53108fb5

History | View | Annotate | Download (47 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 cea5f9a2 Blue Swirl
    TCG_REG_R27, /* currently used for the global env */
155 810260a8 malc
    TCG_REG_R28,
156 810260a8 malc
    TCG_REG_R29,
157 810260a8 malc
    TCG_REG_R30,
158 810260a8 malc
    TCG_REG_R31
159 810260a8 malc
};
160 810260a8 malc
161 810260a8 malc
static uint32_t reloc_pc24_val (void *pc, tcg_target_long target)
162 810260a8 malc
{
163 810260a8 malc
    tcg_target_long disp;
164 810260a8 malc
165 810260a8 malc
    disp = target - (tcg_target_long) pc;
166 810260a8 malc
    if ((disp << 38) >> 38 != disp)
167 810260a8 malc
        tcg_abort ();
168 810260a8 malc
169 810260a8 malc
    return disp & 0x3fffffc;
170 810260a8 malc
}
171 810260a8 malc
172 810260a8 malc
static void reloc_pc24 (void *pc, tcg_target_long target)
173 810260a8 malc
{
174 810260a8 malc
    *(uint32_t *) pc = (*(uint32_t *) pc & ~0x3fffffc)
175 810260a8 malc
        | reloc_pc24_val (pc, target);
176 810260a8 malc
}
177 810260a8 malc
178 810260a8 malc
static uint16_t reloc_pc14_val (void *pc, tcg_target_long target)
179 810260a8 malc
{
180 810260a8 malc
    tcg_target_long disp;
181 810260a8 malc
182 810260a8 malc
    disp = target - (tcg_target_long) pc;
183 810260a8 malc
    if (disp != (int16_t) disp)
184 810260a8 malc
        tcg_abort ();
185 810260a8 malc
186 810260a8 malc
    return disp & 0xfffc;
187 810260a8 malc
}
188 810260a8 malc
189 810260a8 malc
static void reloc_pc14 (void *pc, tcg_target_long target)
190 810260a8 malc
{
191 810260a8 malc
    *(uint32_t *) pc = (*(uint32_t *) pc & ~0xfffc)
192 810260a8 malc
        | reloc_pc14_val (pc, target);
193 810260a8 malc
}
194 810260a8 malc
195 810260a8 malc
static void patch_reloc (uint8_t *code_ptr, int type,
196 810260a8 malc
                         tcg_target_long value, tcg_target_long addend)
197 810260a8 malc
{
198 810260a8 malc
    value += addend;
199 810260a8 malc
    switch (type) {
200 810260a8 malc
    case R_PPC_REL14:
201 810260a8 malc
        reloc_pc14 (code_ptr, value);
202 810260a8 malc
        break;
203 810260a8 malc
    case R_PPC_REL24:
204 810260a8 malc
        reloc_pc24 (code_ptr, value);
205 810260a8 malc
        break;
206 810260a8 malc
    default:
207 810260a8 malc
        tcg_abort ();
208 810260a8 malc
    }
209 810260a8 malc
}
210 810260a8 malc
211 810260a8 malc
/* maximum number of register used for input function arguments */
212 810260a8 malc
static int tcg_target_get_call_iarg_regs_count (int flags)
213 810260a8 malc
{
214 b1503cda malc
    return ARRAY_SIZE (tcg_target_call_iarg_regs);
215 810260a8 malc
}
216 810260a8 malc
217 810260a8 malc
/* parse target specific constraints */
218 810260a8 malc
static int target_parse_constraint (TCGArgConstraint *ct, const char **pct_str)
219 810260a8 malc
{
220 810260a8 malc
    const char *ct_str;
221 810260a8 malc
222 810260a8 malc
    ct_str = *pct_str;
223 810260a8 malc
    switch (ct_str[0]) {
224 810260a8 malc
    case 'A': case 'B': case 'C': case 'D':
225 810260a8 malc
        ct->ct |= TCG_CT_REG;
226 810260a8 malc
        tcg_regset_set_reg (ct->u.regs, 3 + ct_str[0] - 'A');
227 810260a8 malc
        break;
228 810260a8 malc
    case 'r':
229 810260a8 malc
        ct->ct |= TCG_CT_REG;
230 810260a8 malc
        tcg_regset_set32 (ct->u.regs, 0, 0xffffffff);
231 810260a8 malc
        break;
232 810260a8 malc
    case 'L':                   /* qemu_ld constraint */
233 810260a8 malc
        ct->ct |= TCG_CT_REG;
234 810260a8 malc
        tcg_regset_set32 (ct->u.regs, 0, 0xffffffff);
235 810260a8 malc
        tcg_regset_reset_reg (ct->u.regs, TCG_REG_R3);
236 735ee40d malc
#ifdef CONFIG_SOFTMMU
237 810260a8 malc
        tcg_regset_reset_reg (ct->u.regs, TCG_REG_R4);
238 735ee40d malc
#endif
239 810260a8 malc
        break;
240 c070355d malc
    case 'S':                   /* qemu_st constraint */
241 810260a8 malc
        ct->ct |= TCG_CT_REG;
242 810260a8 malc
        tcg_regset_set32 (ct->u.regs, 0, 0xffffffff);
243 810260a8 malc
        tcg_regset_reset_reg (ct->u.regs, TCG_REG_R3);
244 735ee40d malc
#ifdef CONFIG_SOFTMMU
245 810260a8 malc
        tcg_regset_reset_reg (ct->u.regs, TCG_REG_R4);
246 810260a8 malc
        tcg_regset_reset_reg (ct->u.regs, TCG_REG_R5);
247 735ee40d malc
#endif
248 810260a8 malc
        break;
249 fe6f943f malc
    case 'Z':
250 fe6f943f malc
        ct->ct |= TCG_CT_CONST_U32;
251 fe6f943f malc
        break;
252 810260a8 malc
    default:
253 810260a8 malc
        return -1;
254 810260a8 malc
    }
255 810260a8 malc
    ct_str++;
256 810260a8 malc
    *pct_str = ct_str;
257 810260a8 malc
    return 0;
258 810260a8 malc
}
259 810260a8 malc
260 810260a8 malc
/* test if a constant matches the constraint */
261 810260a8 malc
static int tcg_target_const_match (tcg_target_long val,
262 810260a8 malc
                                   const TCGArgConstraint *arg_ct)
263 810260a8 malc
{
264 810260a8 malc
    int ct;
265 810260a8 malc
266 810260a8 malc
    ct = arg_ct->ct;
267 810260a8 malc
    if (ct & TCG_CT_CONST)
268 810260a8 malc
        return 1;
269 fe6f943f malc
    else if ((ct & TCG_CT_CONST_U32) && (val == (uint32_t) val))
270 fe6f943f malc
        return 1;
271 810260a8 malc
    return 0;
272 810260a8 malc
}
273 810260a8 malc
274 810260a8 malc
#define OPCD(opc) ((opc)<<26)
275 810260a8 malc
#define XO19(opc) (OPCD(19)|((opc)<<1))
276 810260a8 malc
#define XO30(opc) (OPCD(30)|((opc)<<2))
277 810260a8 malc
#define XO31(opc) (OPCD(31)|((opc)<<1))
278 810260a8 malc
#define XO58(opc) (OPCD(58)|(opc))
279 810260a8 malc
#define XO62(opc) (OPCD(62)|(opc))
280 810260a8 malc
281 810260a8 malc
#define B      OPCD( 18)
282 810260a8 malc
#define BC     OPCD( 16)
283 810260a8 malc
#define LBZ    OPCD( 34)
284 810260a8 malc
#define LHZ    OPCD( 40)
285 810260a8 malc
#define LHA    OPCD( 42)
286 810260a8 malc
#define LWZ    OPCD( 32)
287 810260a8 malc
#define STB    OPCD( 38)
288 810260a8 malc
#define STH    OPCD( 44)
289 810260a8 malc
#define STW    OPCD( 36)
290 810260a8 malc
291 810260a8 malc
#define STD    XO62(  0)
292 810260a8 malc
#define STDU   XO62(  1)
293 810260a8 malc
#define STDX   XO31(149)
294 810260a8 malc
295 810260a8 malc
#define LD     XO58(  0)
296 810260a8 malc
#define LDX    XO31( 21)
297 810260a8 malc
#define LDU    XO58(  1)
298 301f6d90 malc
#define LWA    XO58(  2)
299 810260a8 malc
#define LWAX   XO31(341)
300 810260a8 malc
301 1cd62ae9 malc
#define ADDIC  OPCD( 12)
302 810260a8 malc
#define ADDI   OPCD( 14)
303 810260a8 malc
#define ADDIS  OPCD( 15)
304 810260a8 malc
#define ORI    OPCD( 24)
305 810260a8 malc
#define ORIS   OPCD( 25)
306 810260a8 malc
#define XORI   OPCD( 26)
307 810260a8 malc
#define XORIS  OPCD( 27)
308 810260a8 malc
#define ANDI   OPCD( 28)
309 810260a8 malc
#define ANDIS  OPCD( 29)
310 810260a8 malc
#define MULLI  OPCD(  7)
311 810260a8 malc
#define CMPLI  OPCD( 10)
312 810260a8 malc
#define CMPI   OPCD( 11)
313 810260a8 malc
314 810260a8 malc
#define LWZU   OPCD( 33)
315 810260a8 malc
#define STWU   OPCD( 37)
316 810260a8 malc
317 810260a8 malc
#define RLWINM OPCD( 21)
318 810260a8 malc
319 810260a8 malc
#define RLDICL XO30(  0)
320 810260a8 malc
#define RLDICR XO30(  1)
321 3ee1b855 malc
#define RLDIMI XO30(  3)
322 810260a8 malc
323 810260a8 malc
#define BCLR   XO19( 16)
324 810260a8 malc
#define BCCTR  XO19(528)
325 810260a8 malc
#define CRAND  XO19(257)
326 810260a8 malc
#define CRANDC XO19(129)
327 810260a8 malc
#define CRNAND XO19(225)
328 810260a8 malc
#define CROR   XO19(449)
329 1cd62ae9 malc
#define CRNOR  XO19( 33)
330 810260a8 malc
331 810260a8 malc
#define EXTSB  XO31(954)
332 810260a8 malc
#define EXTSH  XO31(922)
333 810260a8 malc
#define EXTSW  XO31(986)
334 810260a8 malc
#define ADD    XO31(266)
335 810260a8 malc
#define ADDE   XO31(138)
336 810260a8 malc
#define ADDC   XO31( 10)
337 810260a8 malc
#define AND    XO31( 28)
338 810260a8 malc
#define SUBF   XO31( 40)
339 810260a8 malc
#define SUBFC  XO31(  8)
340 810260a8 malc
#define SUBFE  XO31(136)
341 810260a8 malc
#define OR     XO31(444)
342 810260a8 malc
#define XOR    XO31(316)
343 810260a8 malc
#define MULLW  XO31(235)
344 810260a8 malc
#define MULHWU XO31( 11)
345 810260a8 malc
#define DIVW   XO31(491)
346 810260a8 malc
#define DIVWU  XO31(459)
347 810260a8 malc
#define CMP    XO31(  0)
348 810260a8 malc
#define CMPL   XO31( 32)
349 810260a8 malc
#define LHBRX  XO31(790)
350 810260a8 malc
#define LWBRX  XO31(534)
351 810260a8 malc
#define STHBRX XO31(918)
352 810260a8 malc
#define STWBRX XO31(662)
353 810260a8 malc
#define MFSPR  XO31(339)
354 810260a8 malc
#define MTSPR  XO31(467)
355 810260a8 malc
#define SRAWI  XO31(824)
356 810260a8 malc
#define NEG    XO31(104)
357 1cd62ae9 malc
#define MFCR   XO31( 19)
358 1cd62ae9 malc
#define CNTLZW XO31( 26)
359 1cd62ae9 malc
#define CNTLZD XO31( 58)
360 810260a8 malc
361 810260a8 malc
#define MULLD  XO31(233)
362 810260a8 malc
#define MULHD  XO31( 73)
363 810260a8 malc
#define MULHDU XO31(  9)
364 810260a8 malc
#define DIVD   XO31(489)
365 810260a8 malc
#define DIVDU  XO31(457)
366 810260a8 malc
367 810260a8 malc
#define LBZX   XO31( 87)
368 4f4a67ae malc
#define LHZX   XO31(279)
369 810260a8 malc
#define LHAX   XO31(343)
370 810260a8 malc
#define LWZX   XO31( 23)
371 810260a8 malc
#define STBX   XO31(215)
372 810260a8 malc
#define STHX   XO31(407)
373 810260a8 malc
#define STWX   XO31(151)
374 810260a8 malc
375 810260a8 malc
#define SPR(a,b) ((((a)<<5)|(b))<<11)
376 810260a8 malc
#define LR     SPR(8, 0)
377 810260a8 malc
#define CTR    SPR(9, 0)
378 810260a8 malc
379 810260a8 malc
#define SLW    XO31( 24)
380 810260a8 malc
#define SRW    XO31(536)
381 810260a8 malc
#define SRAW   XO31(792)
382 810260a8 malc
383 810260a8 malc
#define SLD    XO31( 27)
384 810260a8 malc
#define SRD    XO31(539)
385 810260a8 malc
#define SRAD   XO31(794)
386 fe6f943f malc
#define SRADI  XO31(413<<1)
387 810260a8 malc
388 810260a8 malc
#define TW     XO31( 4)
389 810260a8 malc
#define TRAP   (TW | TO (31))
390 810260a8 malc
391 810260a8 malc
#define RT(r) ((r)<<21)
392 810260a8 malc
#define RS(r) ((r)<<21)
393 810260a8 malc
#define RA(r) ((r)<<16)
394 810260a8 malc
#define RB(r) ((r)<<11)
395 810260a8 malc
#define TO(t) ((t)<<21)
396 810260a8 malc
#define SH(s) ((s)<<11)
397 810260a8 malc
#define MB(b) ((b)<<6)
398 810260a8 malc
#define ME(e) ((e)<<1)
399 810260a8 malc
#define BO(o) ((o)<<21)
400 810260a8 malc
#define MB64(b) ((b)<<5)
401 810260a8 malc
402 810260a8 malc
#define LK    1
403 810260a8 malc
404 810260a8 malc
#define TAB(t,a,b) (RT(t) | RA(a) | RB(b))
405 810260a8 malc
#define SAB(s,a,b) (RS(s) | RA(a) | RB(b))
406 810260a8 malc
407 810260a8 malc
#define BF(n)    ((n)<<23)
408 810260a8 malc
#define BI(n, c) (((c)+((n)*4))<<16)
409 810260a8 malc
#define BT(n, c) (((c)+((n)*4))<<21)
410 810260a8 malc
#define BA(n, c) (((c)+((n)*4))<<16)
411 810260a8 malc
#define BB(n, c) (((c)+((n)*4))<<11)
412 810260a8 malc
413 810260a8 malc
#define BO_COND_TRUE  BO (12)
414 810260a8 malc
#define BO_COND_FALSE BO ( 4)
415 810260a8 malc
#define BO_ALWAYS     BO (20)
416 810260a8 malc
417 810260a8 malc
enum {
418 810260a8 malc
    CR_LT,
419 810260a8 malc
    CR_GT,
420 810260a8 malc
    CR_EQ,
421 810260a8 malc
    CR_SO
422 810260a8 malc
};
423 810260a8 malc
424 810260a8 malc
static const uint32_t tcg_to_bc[10] = {
425 810260a8 malc
    [TCG_COND_EQ]  = BC | BI (7, CR_EQ) | BO_COND_TRUE,
426 810260a8 malc
    [TCG_COND_NE]  = BC | BI (7, CR_EQ) | BO_COND_FALSE,
427 810260a8 malc
    [TCG_COND_LT]  = BC | BI (7, CR_LT) | BO_COND_TRUE,
428 810260a8 malc
    [TCG_COND_GE]  = BC | BI (7, CR_LT) | BO_COND_FALSE,
429 810260a8 malc
    [TCG_COND_LE]  = BC | BI (7, CR_GT) | BO_COND_FALSE,
430 810260a8 malc
    [TCG_COND_GT]  = BC | BI (7, CR_GT) | BO_COND_TRUE,
431 810260a8 malc
    [TCG_COND_LTU] = BC | BI (7, CR_LT) | BO_COND_TRUE,
432 810260a8 malc
    [TCG_COND_GEU] = BC | BI (7, CR_LT) | BO_COND_FALSE,
433 810260a8 malc
    [TCG_COND_LEU] = BC | BI (7, CR_GT) | BO_COND_FALSE,
434 810260a8 malc
    [TCG_COND_GTU] = BC | BI (7, CR_GT) | BO_COND_TRUE,
435 810260a8 malc
};
436 810260a8 malc
437 3b6dac34 Richard Henderson
static void tcg_out_mov (TCGContext *s, TCGType type, int ret, int arg)
438 810260a8 malc
{
439 810260a8 malc
    tcg_out32 (s, OR | SAB (arg, ret, arg));
440 810260a8 malc
}
441 810260a8 malc
442 810260a8 malc
static void tcg_out_rld (TCGContext *s, int op, int ra, int rs, int sh, int mb)
443 810260a8 malc
{
444 810260a8 malc
    sh = SH (sh & 0x1f) | (((sh >> 5) & 1) << 1);
445 810260a8 malc
    mb = MB64 ((mb >> 5) | ((mb << 1) & 0x3f));
446 810260a8 malc
    tcg_out32 (s, op | RA (ra) | RS (rs) | sh | mb);
447 810260a8 malc
}
448 810260a8 malc
449 810260a8 malc
static void tcg_out_movi32 (TCGContext *s, int ret, int32_t arg)
450 810260a8 malc
{
451 810260a8 malc
    if (arg == (int16_t) arg)
452 810260a8 malc
        tcg_out32 (s, ADDI | RT (ret) | RA (0) | (arg & 0xffff));
453 810260a8 malc
    else {
454 810260a8 malc
        tcg_out32 (s, ADDIS | RT (ret) | RA (0) | ((arg >> 16) & 0xffff));
455 810260a8 malc
        if (arg & 0xffff)
456 810260a8 malc
            tcg_out32 (s, ORI | RS (ret) | RA (ret) | (arg & 0xffff));
457 810260a8 malc
    }
458 810260a8 malc
}
459 810260a8 malc
460 810260a8 malc
static void tcg_out_movi (TCGContext *s, TCGType type,
461 810260a8 malc
                          int ret, tcg_target_long arg)
462 810260a8 malc
{
463 810260a8 malc
    int32_t arg32 = arg;
464 591d6f1d malc
    arg = type == TCG_TYPE_I32 ? arg & 0xffffffff : arg;
465 810260a8 malc
466 591d6f1d malc
    if (arg == arg32) {
467 810260a8 malc
        tcg_out_movi32 (s, ret, arg32);
468 810260a8 malc
    }
469 810260a8 malc
    else {
470 810260a8 malc
        if ((uint64_t) arg >> 32) {
471 6fc9dbcc malc
            uint16_t h16 = arg >> 16;
472 6fc9dbcc malc
            uint16_t l16 = arg;
473 6fc9dbcc malc
474 95153fde malc
            tcg_out_movi32 (s, ret, arg >> 32);
475 810260a8 malc
            tcg_out_rld (s, RLDICR, ret, ret, 32, 31);
476 6fc9dbcc malc
            if (h16) tcg_out32 (s, ORIS | RS (ret) | RA (ret) | h16);
477 6fc9dbcc malc
            if (l16) tcg_out32 (s, ORI | RS (ret) | RA (ret) | l16);
478 810260a8 malc
        }
479 810260a8 malc
        else {
480 810260a8 malc
            tcg_out_movi32 (s, ret, arg32);
481 6fc9dbcc malc
            if (arg32 < 0)
482 6fc9dbcc malc
                tcg_out_rld (s, RLDICL, ret, ret, 0, 32);
483 810260a8 malc
        }
484 810260a8 malc
    }
485 810260a8 malc
}
486 810260a8 malc
487 5d7ff5bb Andreas Faerber
static void tcg_out_b (TCGContext *s, int mask, tcg_target_long target)
488 5d7ff5bb Andreas Faerber
{
489 5d7ff5bb Andreas Faerber
    tcg_target_long disp;
490 5d7ff5bb Andreas Faerber
491 5d7ff5bb Andreas Faerber
    disp = target - (tcg_target_long) s->code_ptr;
492 5d7ff5bb Andreas Faerber
    if ((disp << 38) >> 38 == disp)
493 5d7ff5bb Andreas Faerber
        tcg_out32 (s, B | (disp & 0x3fffffc) | mask);
494 5d7ff5bb Andreas Faerber
    else {
495 5d7ff5bb Andreas Faerber
        tcg_out_movi (s, TCG_TYPE_I64, 0, (tcg_target_long) target);
496 5d7ff5bb Andreas Faerber
        tcg_out32 (s, MTSPR | RS (0) | CTR);
497 5d7ff5bb Andreas Faerber
        tcg_out32 (s, BCCTR | BO_ALWAYS | mask);
498 5d7ff5bb Andreas Faerber
    }
499 5d7ff5bb Andreas Faerber
}
500 5d7ff5bb Andreas Faerber
501 810260a8 malc
static void tcg_out_call (TCGContext *s, tcg_target_long arg, int const_arg)
502 810260a8 malc
{
503 5d7ff5bb Andreas Faerber
#ifdef __APPLE__
504 5d7ff5bb Andreas Faerber
    if (const_arg) {
505 5d7ff5bb Andreas Faerber
        tcg_out_b (s, LK, arg);
506 5d7ff5bb Andreas Faerber
    }
507 5d7ff5bb Andreas Faerber
    else {
508 5d7ff5bb Andreas Faerber
        tcg_out32 (s, MTSPR | RS (arg) | LR);
509 5d7ff5bb Andreas Faerber
        tcg_out32 (s, BCLR | BO_ALWAYS | LK);
510 5d7ff5bb Andreas Faerber
    }
511 5d7ff5bb Andreas Faerber
#else
512 810260a8 malc
    int reg;
513 810260a8 malc
514 810260a8 malc
    if (const_arg) {
515 810260a8 malc
        reg = 2;
516 810260a8 malc
        tcg_out_movi (s, TCG_TYPE_I64, reg, arg);
517 810260a8 malc
    }
518 810260a8 malc
    else reg = arg;
519 810260a8 malc
520 810260a8 malc
    tcg_out32 (s, LD | RT (0) | RA (reg));
521 810260a8 malc
    tcg_out32 (s, MTSPR | RA (0) | CTR);
522 810260a8 malc
    tcg_out32 (s, LD | RT (11) | RA (reg) | 16);
523 810260a8 malc
    tcg_out32 (s, LD | RT (2) | RA (reg) | 8);
524 810260a8 malc
    tcg_out32 (s, BCCTR | BO_ALWAYS | LK);
525 5d7ff5bb Andreas Faerber
#endif
526 810260a8 malc
}
527 810260a8 malc
528 810260a8 malc
static void tcg_out_ldst (TCGContext *s, int ret, int addr,
529 810260a8 malc
                          int offset, int op1, int op2)
530 810260a8 malc
{
531 810260a8 malc
    if (offset == (int16_t) offset)
532 810260a8 malc
        tcg_out32 (s, op1 | RT (ret) | RA (addr) | (offset & 0xffff));
533 810260a8 malc
    else {
534 810260a8 malc
        tcg_out_movi (s, TCG_TYPE_I64, 0, offset);
535 810260a8 malc
        tcg_out32 (s, op2 | RT (ret) | RA (addr) | RB (0));
536 810260a8 malc
    }
537 810260a8 malc
}
538 810260a8 malc
539 828808f5 malc
static void tcg_out_ldsta (TCGContext *s, int ret, int addr,
540 828808f5 malc
                           int offset, int op1, int op2)
541 828808f5 malc
{
542 828808f5 malc
    if (offset == (int16_t) (offset & ~3))
543 828808f5 malc
        tcg_out32 (s, op1 | RT (ret) | RA (addr) | (offset & 0xffff));
544 828808f5 malc
    else {
545 828808f5 malc
        tcg_out_movi (s, TCG_TYPE_I64, 0, offset);
546 828808f5 malc
        tcg_out32 (s, op2 | RT (ret) | RA (addr) | RB (0));
547 828808f5 malc
    }
548 828808f5 malc
}
549 828808f5 malc
550 810260a8 malc
#if defined (CONFIG_SOFTMMU)
551 79383c9c blueswir1
552 79383c9c blueswir1
#include "../../softmmu_defs.h"
553 810260a8 malc
554 810260a8 malc
static void *qemu_ld_helpers[4] = {
555 810260a8 malc
    __ldb_mmu,
556 810260a8 malc
    __ldw_mmu,
557 810260a8 malc
    __ldl_mmu,
558 810260a8 malc
    __ldq_mmu,
559 810260a8 malc
};
560 810260a8 malc
561 810260a8 malc
static void *qemu_st_helpers[4] = {
562 810260a8 malc
    __stb_mmu,
563 810260a8 malc
    __stw_mmu,
564 810260a8 malc
    __stl_mmu,
565 810260a8 malc
    __stq_mmu,
566 810260a8 malc
};
567 810260a8 malc
568 810260a8 malc
static void tcg_out_tlb_read (TCGContext *s, int r0, int r1, int r2,
569 810260a8 malc
                              int addr_reg, int s_bits, int offset)
570 810260a8 malc
{
571 880e52b8 malc
#if TARGET_LONG_BITS == 32
572 810260a8 malc
    tcg_out_rld (s, RLDICL, addr_reg, addr_reg, 0, 32);
573 810260a8 malc
574 4a40e231 malc
    tcg_out32 (s, (RLWINM
575 4a40e231 malc
                   | RA (r0)
576 4a40e231 malc
                   | RS (addr_reg)
577 4a40e231 malc
                   | SH (32 - (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS))
578 4a40e231 malc
                   | MB (32 - (CPU_TLB_BITS + CPU_TLB_ENTRY_BITS))
579 4a40e231 malc
                   | ME (31 - CPU_TLB_ENTRY_BITS)
580 4a40e231 malc
                   )
581 4a40e231 malc
        );
582 4a40e231 malc
    tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (TCG_AREG0));
583 4a40e231 malc
    tcg_out32 (s, (LWZU | RT (r1) | RA (r0) | offset));
584 4a40e231 malc
    tcg_out32 (s, (RLWINM
585 4a40e231 malc
                   | RA (r2)
586 4a40e231 malc
                   | RS (addr_reg)
587 4a40e231 malc
                   | SH (0)
588 4a40e231 malc
                   | MB ((32 - s_bits) & 31)
589 4a40e231 malc
                   | ME (31 - TARGET_PAGE_BITS)
590 4a40e231 malc
                   )
591 4a40e231 malc
        );
592 4a40e231 malc
#else
593 810260a8 malc
    tcg_out_rld (s, RLDICL, r0, addr_reg,
594 810260a8 malc
                 64 - TARGET_PAGE_BITS,
595 810260a8 malc
                 64 - CPU_TLB_BITS);
596 810260a8 malc
    tcg_out_rld (s, RLDICR, r0, r0,
597 810260a8 malc
                 CPU_TLB_ENTRY_BITS,
598 810260a8 malc
                 63 - CPU_TLB_ENTRY_BITS);
599 810260a8 malc
600 810260a8 malc
    tcg_out32 (s, ADD | TAB (r0, r0, TCG_AREG0));
601 810260a8 malc
    tcg_out32 (s, LD_ADDR | RT (r1) | RA (r0) | offset);
602 810260a8 malc
603 4a40e231 malc
    if (!s_bits) {
604 4a40e231 malc
        tcg_out_rld (s, RLDICR, r2, addr_reg, 0, 63 - TARGET_PAGE_BITS);
605 4a40e231 malc
    }
606 4a40e231 malc
    else {
607 4a40e231 malc
        tcg_out_rld (s, RLDICL, r2, addr_reg,
608 4a40e231 malc
                     64 - TARGET_PAGE_BITS,
609 4a40e231 malc
                     TARGET_PAGE_BITS - s_bits);
610 4a40e231 malc
        tcg_out_rld (s, RLDICL, r2, r2, TARGET_PAGE_BITS, 0);
611 4a40e231 malc
    }
612 4a40e231 malc
#endif
613 810260a8 malc
}
614 a2a546b3 malc
#endif
615 810260a8 malc
616 810260a8 malc
static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
617 810260a8 malc
{
618 f6548c0a malc
    int addr_reg, data_reg, r0, r1, rbase, mem_index, s_bits, bswap;
619 810260a8 malc
#ifdef CONFIG_SOFTMMU
620 109719ec malc
    int r2;
621 810260a8 malc
    void *label1_ptr, *label2_ptr;
622 810260a8 malc
#endif
623 810260a8 malc
624 810260a8 malc
    data_reg = *args++;
625 810260a8 malc
    addr_reg = *args++;
626 810260a8 malc
    mem_index = *args;
627 810260a8 malc
    s_bits = opc & 3;
628 810260a8 malc
629 810260a8 malc
#ifdef CONFIG_SOFTMMU
630 810260a8 malc
    r0 = 3;
631 810260a8 malc
    r1 = 4;
632 810260a8 malc
    r2 = 0;
633 f6548c0a malc
    rbase = 0;
634 810260a8 malc
635 810260a8 malc
    tcg_out_tlb_read (s, r0, r1, r2, addr_reg, s_bits,
636 810260a8 malc
                      offsetof (CPUState, tlb_table[mem_index][0].addr_read));
637 810260a8 malc
638 e924bbec malc
    tcg_out32 (s, CMP | BF (7) | RA (r2) | RB (r1) | CMP_L);
639 810260a8 malc
640 810260a8 malc
    label1_ptr = s->code_ptr;
641 810260a8 malc
#ifdef FAST_PATH
642 810260a8 malc
    tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE);
643 810260a8 malc
#endif
644 810260a8 malc
645 810260a8 malc
    /* slow path */
646 3b6dac34 Richard Henderson
    tcg_out_mov (s, TCG_TYPE_I64, 3, addr_reg);
647 810260a8 malc
    tcg_out_movi (s, TCG_TYPE_I64, 4, mem_index);
648 810260a8 malc
649 810260a8 malc
    tcg_out_call (s, (tcg_target_long) qemu_ld_helpers[s_bits], 1);
650 810260a8 malc
651 810260a8 malc
    switch (opc) {
652 810260a8 malc
    case 0|4:
653 810260a8 malc
        tcg_out32 (s, EXTSB | RA (data_reg) | RS (3));
654 810260a8 malc
        break;
655 810260a8 malc
    case 1|4:
656 810260a8 malc
        tcg_out32 (s, EXTSH | RA (data_reg) | RS (3));
657 810260a8 malc
        break;
658 810260a8 malc
    case 2|4:
659 810260a8 malc
        tcg_out32 (s, EXTSW | RA (data_reg) | RS (3));
660 810260a8 malc
        break;
661 810260a8 malc
    case 0:
662 810260a8 malc
    case 1:
663 810260a8 malc
    case 2:
664 810260a8 malc
    case 3:
665 810260a8 malc
        if (data_reg != 3)
666 3b6dac34 Richard Henderson
            tcg_out_mov (s, TCG_TYPE_I64, data_reg, 3);
667 810260a8 malc
        break;
668 810260a8 malc
    }
669 810260a8 malc
    label2_ptr = s->code_ptr;
670 810260a8 malc
    tcg_out32 (s, B);
671 810260a8 malc
672 810260a8 malc
    /* label1: fast path */
673 810260a8 malc
#ifdef FAST_PATH
674 810260a8 malc
    reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr);
675 810260a8 malc
#endif
676 810260a8 malc
677 810260a8 malc
    /* r0 now contains &env->tlb_table[mem_index][index].addr_read */
678 355b1943 Paul Brook
    tcg_out32 (s, (LD
679 810260a8 malc
                   | RT (r0)
680 810260a8 malc
                   | RA (r0)
681 810260a8 malc
                   | (offsetof (CPUTLBEntry, addend)
682 810260a8 malc
                      - offsetof (CPUTLBEntry, addr_read))
683 810260a8 malc
                   ));
684 810260a8 malc
    /* r0 = env->tlb_table[mem_index][index].addend */
685 810260a8 malc
    tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (addr_reg));
686 810260a8 malc
    /* r0 = env->tlb_table[mem_index][index].addend + addr */
687 810260a8 malc
688 810260a8 malc
#else  /* !CONFIG_SOFTMMU */
689 0b7c1d89 malc
#if TARGET_LONG_BITS == 32
690 0b7c1d89 malc
    tcg_out_rld (s, RLDICL, addr_reg, addr_reg, 0, 32);
691 0b7c1d89 malc
#endif
692 810260a8 malc
    r0 = addr_reg;
693 735ee40d malc
    r1 = 3;
694 f6548c0a malc
    rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
695 810260a8 malc
#endif
696 810260a8 malc
697 810260a8 malc
#ifdef TARGET_WORDS_BIGENDIAN
698 810260a8 malc
    bswap = 0;
699 810260a8 malc
#else
700 810260a8 malc
    bswap = 1;
701 810260a8 malc
#endif
702 810260a8 malc
    switch (opc) {
703 810260a8 malc
    default:
704 810260a8 malc
    case 0:
705 f6548c0a malc
        tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));
706 810260a8 malc
        break;
707 810260a8 malc
    case 0|4:
708 f6548c0a malc
        tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));
709 810260a8 malc
        tcg_out32 (s, EXTSB | RA (data_reg) | RS (data_reg));
710 810260a8 malc
        break;
711 810260a8 malc
    case 1:
712 f6548c0a malc
        if (bswap)
713 f6548c0a malc
            tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));
714 f6548c0a malc
        else
715 f6548c0a malc
            tcg_out32 (s, LHZX | TAB (data_reg, rbase, r0));
716 810260a8 malc
        break;
717 810260a8 malc
    case 1|4:
718 810260a8 malc
        if (bswap) {
719 f6548c0a malc
            tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));
720 810260a8 malc
            tcg_out32 (s, EXTSH | RA (data_reg) | RS (data_reg));
721 810260a8 malc
        }
722 f6548c0a malc
        else tcg_out32 (s, LHAX | TAB (data_reg, rbase, r0));
723 810260a8 malc
        break;
724 810260a8 malc
    case 2:
725 f6548c0a malc
        if (bswap)
726 f6548c0a malc
            tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
727 f6548c0a malc
        else
728 f6548c0a malc
            tcg_out32 (s, LWZX | TAB (data_reg, rbase, r0));
729 810260a8 malc
        break;
730 810260a8 malc
    case 2|4:
731 810260a8 malc
        if (bswap) {
732 f6548c0a malc
            tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
733 450e62e7 malc
            tcg_out32 (s, EXTSW | RA (data_reg) | RS (data_reg));
734 810260a8 malc
        }
735 f6548c0a malc
        else tcg_out32 (s, LWAX | TAB (data_reg, rbase, r0));
736 810260a8 malc
        break;
737 810260a8 malc
    case 3:
738 f6548c0a malc
#ifdef CONFIG_USE_GUEST_BASE
739 f6548c0a malc
        if (bswap) {
740 f6548c0a malc
            tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
741 f6548c0a malc
            tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
742 f6548c0a malc
            tcg_out32 (s, LWBRX | TAB (      r1, rbase, r1));
743 f6548c0a malc
            tcg_out_rld (s, RLDIMI, data_reg, r1, 32, 0);
744 f6548c0a malc
        }
745 f6548c0a malc
        else tcg_out32 (s, LDX | TAB (data_reg, rbase, r0));
746 f6548c0a malc
#else
747 810260a8 malc
        if (bswap) {
748 b1d6d51d Andreas Fรคrber
            tcg_out_movi32 (s, 0, 4);
749 3ee1b855 malc
            tcg_out32 (s, LWBRX | RT (data_reg) | RB (r0));
750 3ee1b855 malc
            tcg_out32 (s, LWBRX | RT (      r1) | RA (r0));
751 3ee1b855 malc
            tcg_out_rld (s, RLDIMI, data_reg, r1, 32, 0);
752 810260a8 malc
        }
753 810260a8 malc
        else tcg_out32 (s, LD | RT (data_reg) | RA (r0));
754 f6548c0a malc
#endif
755 810260a8 malc
        break;
756 810260a8 malc
    }
757 810260a8 malc
758 810260a8 malc
#ifdef CONFIG_SOFTMMU
759 810260a8 malc
    reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr);
760 810260a8 malc
#endif
761 810260a8 malc
}
762 810260a8 malc
763 810260a8 malc
static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
764 810260a8 malc
{
765 f6548c0a malc
    int addr_reg, r0, r1, rbase, data_reg, mem_index, bswap;
766 810260a8 malc
#ifdef CONFIG_SOFTMMU
767 810260a8 malc
    int r2;
768 810260a8 malc
    void *label1_ptr, *label2_ptr;
769 810260a8 malc
#endif
770 810260a8 malc
771 810260a8 malc
    data_reg = *args++;
772 810260a8 malc
    addr_reg = *args++;
773 810260a8 malc
    mem_index = *args;
774 810260a8 malc
775 810260a8 malc
#ifdef CONFIG_SOFTMMU
776 810260a8 malc
    r0 = 3;
777 810260a8 malc
    r1 = 4;
778 810260a8 malc
    r2 = 0;
779 f6548c0a malc
    rbase = 0;
780 810260a8 malc
781 810260a8 malc
    tcg_out_tlb_read (s, r0, r1, r2, addr_reg, opc,
782 810260a8 malc
                      offsetof (CPUState, tlb_table[mem_index][0].addr_write));
783 810260a8 malc
784 e924bbec malc
    tcg_out32 (s, CMP | BF (7) | RA (r2) | RB (r1) | CMP_L);
785 810260a8 malc
786 810260a8 malc
    label1_ptr = s->code_ptr;
787 810260a8 malc
#ifdef FAST_PATH
788 810260a8 malc
    tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE);
789 810260a8 malc
#endif
790 810260a8 malc
791 810260a8 malc
    /* slow path */
792 3b6dac34 Richard Henderson
    tcg_out_mov (s, TCG_TYPE_I64, 3, addr_reg);
793 810260a8 malc
    tcg_out_rld (s, RLDICL, 4, data_reg, 0, 64 - (1 << (3 + opc)));
794 810260a8 malc
    tcg_out_movi (s, TCG_TYPE_I64, 5, mem_index);
795 810260a8 malc
796 810260a8 malc
    tcg_out_call (s, (tcg_target_long) qemu_st_helpers[opc], 1);
797 810260a8 malc
798 810260a8 malc
    label2_ptr = s->code_ptr;
799 810260a8 malc
    tcg_out32 (s, B);
800 810260a8 malc
801 810260a8 malc
    /* label1: fast path */
802 810260a8 malc
#ifdef FAST_PATH
803 810260a8 malc
    reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr);
804 810260a8 malc
#endif
805 810260a8 malc
806 355b1943 Paul Brook
    tcg_out32 (s, (LD
807 810260a8 malc
                   | RT (r0)
808 810260a8 malc
                   | RA (r0)
809 810260a8 malc
                   | (offsetof (CPUTLBEntry, addend)
810 810260a8 malc
                      - offsetof (CPUTLBEntry, addr_write))
811 810260a8 malc
                   ));
812 810260a8 malc
    /* r0 = env->tlb_table[mem_index][index].addend */
813 810260a8 malc
    tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (addr_reg));
814 810260a8 malc
    /* r0 = env->tlb_table[mem_index][index].addend + addr */
815 810260a8 malc
816 810260a8 malc
#else  /* !CONFIG_SOFTMMU */
817 0b7c1d89 malc
#if TARGET_LONG_BITS == 32
818 0b7c1d89 malc
    tcg_out_rld (s, RLDICL, addr_reg, addr_reg, 0, 32);
819 0b7c1d89 malc
#endif
820 735ee40d malc
    r1 = 3;
821 810260a8 malc
    r0 = addr_reg;
822 f6548c0a malc
    rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
823 810260a8 malc
#endif
824 810260a8 malc
825 810260a8 malc
#ifdef TARGET_WORDS_BIGENDIAN
826 810260a8 malc
    bswap = 0;
827 810260a8 malc
#else
828 810260a8 malc
    bswap = 1;
829 810260a8 malc
#endif
830 810260a8 malc
    switch (opc) {
831 810260a8 malc
    case 0:
832 f6548c0a malc
        tcg_out32 (s, STBX | SAB (data_reg, rbase, r0));
833 810260a8 malc
        break;
834 810260a8 malc
    case 1:
835 f6548c0a malc
        if (bswap)
836 f6548c0a malc
            tcg_out32 (s, STHBRX | SAB (data_reg, rbase, r0));
837 f6548c0a malc
        else
838 f6548c0a malc
            tcg_out32 (s, STHX | SAB (data_reg, rbase, r0));
839 810260a8 malc
        break;
840 810260a8 malc
    case 2:
841 f6548c0a malc
        if (bswap)
842 f6548c0a malc
            tcg_out32 (s, STWBRX | SAB (data_reg, rbase, r0));
843 f6548c0a malc
        else
844 f6548c0a malc
            tcg_out32 (s, STWX | SAB (data_reg, rbase, r0));
845 810260a8 malc
        break;
846 810260a8 malc
    case 3:
847 810260a8 malc
        if (bswap) {
848 f6548c0a malc
            tcg_out32 (s, STWBRX | SAB (data_reg, rbase, r0));
849 109719ec malc
            tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
850 810260a8 malc
            tcg_out_rld (s, RLDICL, 0, data_reg, 32, 0);
851 f6548c0a malc
            tcg_out32 (s, STWBRX | SAB (0, rbase, r1));
852 810260a8 malc
        }
853 f6548c0a malc
        else tcg_out32 (s, STDX | SAB (data_reg, rbase, r0));
854 810260a8 malc
        break;
855 810260a8 malc
    }
856 810260a8 malc
857 810260a8 malc
#ifdef CONFIG_SOFTMMU
858 810260a8 malc
    reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr);
859 810260a8 malc
#endif
860 810260a8 malc
}
861 810260a8 malc
862 e4d58b41 Richard Henderson
static void tcg_target_qemu_prologue (TCGContext *s)
863 810260a8 malc
{
864 810260a8 malc
    int i, frame_size;
865 5d7ff5bb Andreas Faerber
#ifndef __APPLE__
866 a69abbe0 malc
    uint64_t addr;
867 5d7ff5bb Andreas Faerber
#endif
868 810260a8 malc
869 810260a8 malc
    frame_size = 0
870 810260a8 malc
        + 8                     /* back chain */
871 810260a8 malc
        + 8                     /* CR */
872 810260a8 malc
        + 8                     /* LR */
873 810260a8 malc
        + 8                     /* compiler doubleword */
874 810260a8 malc
        + 8                     /* link editor doubleword */
875 810260a8 malc
        + 8                     /* TOC save area */
876 810260a8 malc
        + TCG_STATIC_CALL_ARGS_SIZE
877 810260a8 malc
        + ARRAY_SIZE (tcg_target_callee_save_regs) * 8
878 f74b32de Blue Swirl
        + CPU_TEMP_BUF_NLONGS * sizeof(long)
879 810260a8 malc
        ;
880 810260a8 malc
    frame_size = (frame_size + 15) & ~15;
881 810260a8 malc
882 f74b32de Blue Swirl
    tcg_set_frame(s, TCG_REG_CALL_STACK, frame_size
883 f74b32de Blue Swirl
                  - CPU_TEMP_BUF_NLONGS * sizeof(long),
884 f74b32de Blue Swirl
                  CPU_TEMP_BUF_NLONGS * sizeof(long));
885 f74b32de Blue Swirl
886 5d7ff5bb Andreas Faerber
#ifndef __APPLE__
887 a69abbe0 malc
    /* First emit adhoc function descriptor */
888 a69abbe0 malc
    addr = (uint64_t) s->code_ptr + 24;
889 a69abbe0 malc
    tcg_out32 (s, addr >> 32); tcg_out32 (s, addr); /* entry point */
890 a69abbe0 malc
    s->code_ptr += 16;          /* skip TOC and environment pointer */
891 5d7ff5bb Andreas Faerber
#endif
892 a69abbe0 malc
893 a69abbe0 malc
    /* Prologue */
894 810260a8 malc
    tcg_out32 (s, MFSPR | RT (0) | LR);
895 810260a8 malc
    tcg_out32 (s, STDU | RS (1) | RA (1) | (-frame_size & 0xffff));
896 810260a8 malc
    for (i = 0; i < ARRAY_SIZE (tcg_target_callee_save_regs); ++i)
897 810260a8 malc
        tcg_out32 (s, (STD
898 810260a8 malc
                       | RS (tcg_target_callee_save_regs[i])
899 810260a8 malc
                       | RA (1)
900 810260a8 malc
                       | (i * 8 + 48 + TCG_STATIC_CALL_ARGS_SIZE)
901 810260a8 malc
                       )
902 810260a8 malc
            );
903 e03ae7f9 malc
    tcg_out32 (s, STD | RS (0) | RA (1) | (frame_size + 16));
904 810260a8 malc
905 f6548c0a malc
#ifdef CONFIG_USE_GUEST_BASE
906 b9e946c7 Richard Henderson
    if (GUEST_BASE) {
907 b9e946c7 Richard Henderson
        tcg_out_movi (s, TCG_TYPE_I64, TCG_GUEST_BASE_REG, GUEST_BASE);
908 b9e946c7 Richard Henderson
        tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
909 b9e946c7 Richard Henderson
    }
910 f6548c0a malc
#endif
911 f6548c0a malc
912 cea5f9a2 Blue Swirl
    tcg_out_mov (s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
913 cea5f9a2 Blue Swirl
    tcg_out32 (s, MTSPR | RS (tcg_target_call_iarg_regs[1]) | CTR);
914 810260a8 malc
    tcg_out32 (s, BCCTR | BO_ALWAYS);
915 a69abbe0 malc
916 a69abbe0 malc
    /* Epilogue */
917 810260a8 malc
    tb_ret_addr = s->code_ptr;
918 810260a8 malc
919 810260a8 malc
    for (i = 0; i < ARRAY_SIZE (tcg_target_callee_save_regs); ++i)
920 810260a8 malc
        tcg_out32 (s, (LD
921 810260a8 malc
                       | RT (tcg_target_callee_save_regs[i])
922 810260a8 malc
                       | RA (1)
923 810260a8 malc
                       | (i * 8 + 48 + TCG_STATIC_CALL_ARGS_SIZE)
924 810260a8 malc
                       )
925 810260a8 malc
            );
926 e03ae7f9 malc
    tcg_out32 (s, LD | RT (0) | RA (1) | (frame_size + 16));
927 810260a8 malc
    tcg_out32 (s, MTSPR | RS (0) | LR);
928 810260a8 malc
    tcg_out32 (s, ADDI | RT (1) | RA (1) | frame_size);
929 810260a8 malc
    tcg_out32 (s, BCLR | BO_ALWAYS);
930 810260a8 malc
}
931 810260a8 malc
932 810260a8 malc
static void tcg_out_ld (TCGContext *s, TCGType type, int ret, int arg1,
933 810260a8 malc
                        tcg_target_long arg2)
934 810260a8 malc
{
935 810260a8 malc
    if (type == TCG_TYPE_I32)
936 810260a8 malc
        tcg_out_ldst (s, ret, arg1, arg2, LWZ, LWZX);
937 810260a8 malc
    else
938 828808f5 malc
        tcg_out_ldsta (s, ret, arg1, arg2, LD, LDX);
939 810260a8 malc
}
940 810260a8 malc
941 810260a8 malc
static void tcg_out_st (TCGContext *s, TCGType type, int arg, int arg1,
942 810260a8 malc
                        tcg_target_long arg2)
943 810260a8 malc
{
944 810260a8 malc
    if (type == TCG_TYPE_I32)
945 810260a8 malc
        tcg_out_ldst (s, arg, arg1, arg2, STW, STWX);
946 810260a8 malc
    else
947 828808f5 malc
        tcg_out_ldsta (s, arg, arg1, arg2, STD, STDX);
948 810260a8 malc
}
949 810260a8 malc
950 810260a8 malc
static void ppc_addi32 (TCGContext *s, int rt, int ra, tcg_target_long si)
951 810260a8 malc
{
952 810260a8 malc
    if (!si && rt == ra)
953 810260a8 malc
        return;
954 810260a8 malc
955 810260a8 malc
    if (si == (int16_t) si)
956 810260a8 malc
        tcg_out32 (s, ADDI | RT (rt) | RA (ra) | (si & 0xffff));
957 810260a8 malc
    else {
958 810260a8 malc
        uint16_t h = ((si >> 16) & 0xffff) + ((uint16_t) si >> 15);
959 810260a8 malc
        tcg_out32 (s, ADDIS | RT (rt) | RA (ra) | h);
960 810260a8 malc
        tcg_out32 (s, ADDI | RT (rt) | RA (rt) | (si & 0xffff));
961 810260a8 malc
    }
962 810260a8 malc
}
963 810260a8 malc
964 810260a8 malc
static void ppc_addi64 (TCGContext *s, int rt, int ra, tcg_target_long si)
965 810260a8 malc
{
966 fe6f943f malc
    /* XXX: suboptimal */
967 fe6f943f malc
    if (si == (int16_t) si
968 8421d9e5 malc
        || ((((uint64_t) si >> 31) == 0) && (si & 0x8000) == 0))
969 fe6f943f malc
        ppc_addi32 (s, rt, ra, si);
970 fe6f943f malc
    else {
971 fe6f943f malc
        tcg_out_movi (s, TCG_TYPE_I64, 0, si);
972 fe6f943f malc
        tcg_out32 (s, ADD | RT (rt) | RA (ra));
973 fe6f943f malc
    }
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
}