Statistics
| Branch: | Revision:

root / tcg / ppc / tcg-target.c @ c5baaa48

History | View | Annotate | Download (44.3 kB)

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