Statistics
| Branch: | Revision:

root / tcg / ppc64 / tcg-target.c @ 0a9564b9

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