Statistics
| Branch: | Revision:

root / tcg / ppc / tcg-target.c @ 6ec85236

History | View | Annotate | Download (48.1 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 6ec85236 malc
#ifdef _CALL_DARWIN
28 bf6bca52 malc
#define LINKAGE_AREA_SIZE 24
29 2946898b malc
#define LR_OFFSET 8
30 6ec85236 malc
#elif defined _CALL_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 6ec85236 malc
#ifdef _CALL_DARWIN
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 6ec85236 malc
#ifndef _CALL_DARWIN
119 2662e13f bellard
    TCG_REG_R11,
120 f9bf2987 malc
#endif
121 2662e13f bellard
    TCG_REG_R12,
122 6ec85236 malc
#ifndef _CALL_SYSV
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 6ec85236 malc
#ifdef _CALL_DARWIN
149 f9bf2987 malc
    TCG_REG_R11,
150 f9bf2987 malc
    TCG_REG_R13,
151 f9bf2987 malc
#endif
152 6ec85236 malc
#ifdef _CALL_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 b0809bf7 malc
#define ADDIC  OPCD(12)
320 2662e13f bellard
#define ADDI   OPCD(14)
321 2662e13f bellard
#define ADDIS  OPCD(15)
322 2662e13f bellard
#define ORI    OPCD(24)
323 2662e13f bellard
#define ORIS   OPCD(25)
324 2662e13f bellard
#define XORI   OPCD(26)
325 2662e13f bellard
#define XORIS  OPCD(27)
326 2662e13f bellard
#define ANDI   OPCD(28)
327 2662e13f bellard
#define ANDIS  OPCD(29)
328 2662e13f bellard
#define MULLI  OPCD( 7)
329 2662e13f bellard
#define CMPLI  OPCD(10)
330 2662e13f bellard
#define CMPI   OPCD(11)
331 2662e13f bellard
332 2662e13f bellard
#define LWZU   OPCD(33)
333 2662e13f bellard
#define STWU   OPCD(37)
334 2662e13f bellard
335 2662e13f bellard
#define RLWINM OPCD(21)
336 2662e13f bellard
337 c596defd malc
#define BCLR   XO19( 16)
338 2662e13f bellard
#define BCCTR  XO19(528)
339 2662e13f bellard
#define CRAND  XO19(257)
340 c596defd malc
#define CRANDC XO19(129)
341 c596defd malc
#define CRNAND XO19(225)
342 c596defd malc
#define CROR   XO19(449)
343 b0809bf7 malc
#define CRNOR  XO19( 33)
344 2662e13f bellard
345 2662e13f bellard
#define EXTSB  XO31(954)
346 2662e13f bellard
#define EXTSH  XO31(922)
347 2662e13f bellard
#define ADD    XO31(266)
348 2662e13f bellard
#define ADDE   XO31(138)
349 2662e13f bellard
#define ADDC   XO31( 10)
350 2662e13f bellard
#define AND    XO31( 28)
351 2662e13f bellard
#define SUBF   XO31( 40)
352 2662e13f bellard
#define SUBFC  XO31(  8)
353 2662e13f bellard
#define SUBFE  XO31(136)
354 2662e13f bellard
#define OR     XO31(444)
355 2662e13f bellard
#define XOR    XO31(316)
356 2662e13f bellard
#define MULLW  XO31(235)
357 2662e13f bellard
#define MULHWU XO31( 11)
358 2662e13f bellard
#define DIVW   XO31(491)
359 2662e13f bellard
#define DIVWU  XO31(459)
360 2662e13f bellard
#define CMP    XO31(  0)
361 2662e13f bellard
#define CMPL   XO31( 32)
362 2662e13f bellard
#define LHBRX  XO31(790)
363 2662e13f bellard
#define LWBRX  XO31(534)
364 2662e13f bellard
#define STHBRX XO31(918)
365 2662e13f bellard
#define STWBRX XO31(662)
366 2662e13f bellard
#define MFSPR  XO31(339)
367 2662e13f bellard
#define MTSPR  XO31(467)
368 2662e13f bellard
#define SRAWI  XO31(824)
369 2662e13f bellard
#define NEG    XO31(104)
370 b0809bf7 malc
#define MFCR   XO31( 19)
371 b0809bf7 malc
#define CNTLZW XO31( 26)
372 2662e13f bellard
373 2662e13f bellard
#define LBZX   XO31( 87)
374 4f4a67ae malc
#define LHZX   XO31(279)
375 2662e13f bellard
#define LHAX   XO31(343)
376 2662e13f bellard
#define LWZX   XO31( 23)
377 2662e13f bellard
#define STBX   XO31(215)
378 2662e13f bellard
#define STHX   XO31(407)
379 2662e13f bellard
#define STWX   XO31(151)
380 2662e13f bellard
381 2662e13f bellard
#define SPR(a,b) ((((a)<<5)|(b))<<11)
382 2662e13f bellard
#define LR     SPR(8, 0)
383 2662e13f bellard
#define CTR    SPR(9, 0)
384 2662e13f bellard
385 2662e13f bellard
#define SLW    XO31( 24)
386 2662e13f bellard
#define SRW    XO31(536)
387 2662e13f bellard
#define SRAW   XO31(792)
388 2662e13f bellard
389 2662e13f bellard
#define TW     XO31(4)
390 2662e13f bellard
#define TRAP   (TW | TO (31))
391 2662e13f bellard
392 2662e13f bellard
#define RT(r) ((r)<<21)
393 2662e13f bellard
#define RS(r) ((r)<<21)
394 2662e13f bellard
#define RA(r) ((r)<<16)
395 2662e13f bellard
#define RB(r) ((r)<<11)
396 2662e13f bellard
#define TO(t) ((t)<<21)
397 2662e13f bellard
#define SH(s) ((s)<<11)
398 2662e13f bellard
#define MB(b) ((b)<<6)
399 2662e13f bellard
#define ME(e) ((e)<<1)
400 2662e13f bellard
#define BO(o) ((o)<<21)
401 2662e13f bellard
402 2662e13f bellard
#define LK    1
403 2662e13f bellard
404 2662e13f bellard
#define TAB(t,a,b) (RT(t) | RA(a) | RB(b))
405 2662e13f bellard
#define SAB(s,a,b) (RS(s) | RA(a) | RB(b))
406 2662e13f bellard
407 2662e13f bellard
#define BF(n)    ((n)<<23)
408 2662e13f bellard
#define BI(n, c) (((c)+((n)*4))<<16)
409 2662e13f bellard
#define BT(n, c) (((c)+((n)*4))<<21)
410 2662e13f bellard
#define BA(n, c) (((c)+((n)*4))<<16)
411 2662e13f bellard
#define BB(n, c) (((c)+((n)*4))<<11)
412 2662e13f bellard
413 2662e13f bellard
#define BO_COND_TRUE  BO (12)
414 2662e13f bellard
#define BO_COND_FALSE BO (4)
415 2662e13f bellard
#define BO_ALWAYS     BO (20)
416 2662e13f bellard
417 2662e13f bellard
enum {
418 2662e13f bellard
    CR_LT,
419 2662e13f bellard
    CR_GT,
420 2662e13f bellard
    CR_EQ,
421 2662e13f bellard
    CR_SO
422 2662e13f bellard
};
423 2662e13f bellard
424 2662e13f bellard
static const uint32_t tcg_to_bc[10] = {
425 2662e13f bellard
    [TCG_COND_EQ]  = BC | BI (7, CR_EQ) | BO_COND_TRUE,
426 2662e13f bellard
    [TCG_COND_NE]  = BC | BI (7, CR_EQ) | BO_COND_FALSE,
427 2662e13f bellard
    [TCG_COND_LT]  = BC | BI (7, CR_LT) | BO_COND_TRUE,
428 2662e13f bellard
    [TCG_COND_GE]  = BC | BI (7, CR_LT) | BO_COND_FALSE,
429 2662e13f bellard
    [TCG_COND_LE]  = BC | BI (7, CR_GT) | BO_COND_FALSE,
430 2662e13f bellard
    [TCG_COND_GT]  = BC | BI (7, CR_GT) | BO_COND_TRUE,
431 2662e13f bellard
    [TCG_COND_LTU] = BC | BI (7, CR_LT) | BO_COND_TRUE,
432 2662e13f bellard
    [TCG_COND_GEU] = BC | BI (7, CR_LT) | BO_COND_FALSE,
433 2662e13f bellard
    [TCG_COND_LEU] = BC | BI (7, CR_GT) | BO_COND_FALSE,
434 2662e13f bellard
    [TCG_COND_GTU] = BC | BI (7, CR_GT) | BO_COND_TRUE,
435 2662e13f bellard
};
436 2662e13f bellard
437 2662e13f bellard
static void tcg_out_mov(TCGContext *s, int ret, int arg)
438 2662e13f bellard
{
439 2662e13f bellard
    tcg_out32 (s, OR | SAB (arg, ret, arg));
440 2662e13f bellard
}
441 2662e13f bellard
442 2662e13f bellard
static void tcg_out_movi(TCGContext *s, TCGType type,
443 2662e13f bellard
                         int ret, tcg_target_long arg)
444 2662e13f bellard
{
445 2662e13f bellard
    if (arg == (int16_t) arg)
446 2662e13f bellard
        tcg_out32 (s, ADDI | RT (ret) | RA (0) | (arg & 0xffff));
447 2662e13f bellard
    else {
448 2662e13f bellard
        tcg_out32 (s, ADDIS | RT (ret) | RA (0) | ((arg >> 16) & 0xffff));
449 2662e13f bellard
        if (arg & 0xffff)
450 0a878c47 malc
            tcg_out32 (s, ORI | RS (ret) | RA (ret) | (arg & 0xffff));
451 2662e13f bellard
    }
452 2662e13f bellard
}
453 2662e13f bellard
454 2662e13f bellard
static void tcg_out_ldst (TCGContext *s, int ret, int addr,
455 2662e13f bellard
                          int offset, int op1, int op2)
456 2662e13f bellard
{
457 2662e13f bellard
    if (offset == (int16_t) offset)
458 2662e13f bellard
        tcg_out32 (s, op1 | RT (ret) | RA (addr) | (offset & 0xffff));
459 2662e13f bellard
    else {
460 2662e13f bellard
        tcg_out_movi (s, TCG_TYPE_I32, 0, offset);
461 2662e13f bellard
        tcg_out32 (s, op2 | RT (ret) | RA (addr) | RB (0));
462 2662e13f bellard
    }
463 2662e13f bellard
}
464 2662e13f bellard
465 932a6909 bellard
static void tcg_out_b (TCGContext *s, int mask, tcg_target_long target)
466 932a6909 bellard
{
467 932a6909 bellard
    tcg_target_long disp;
468 932a6909 bellard
469 932a6909 bellard
    disp = target - (tcg_target_long) s->code_ptr;
470 932a6909 bellard
    if ((disp << 6) >> 6 == disp)
471 8c5e95d8 malc
        tcg_out32 (s, B | (disp & 0x3fffffc) | mask);
472 932a6909 bellard
    else {
473 932a6909 bellard
        tcg_out_movi (s, TCG_TYPE_I32, 0, (tcg_target_long) target);
474 932a6909 bellard
        tcg_out32 (s, MTSPR | RS (0) | CTR);
475 932a6909 bellard
        tcg_out32 (s, BCCTR | BO_ALWAYS | mask);
476 932a6909 bellard
    }
477 932a6909 bellard
}
478 932a6909 bellard
479 b29fe3ed malc
static void tcg_out_call (TCGContext *s, tcg_target_long arg, int const_arg)
480 b29fe3ed malc
{
481 6ec85236 malc
#ifdef _CALL_AIX
482 b29fe3ed malc
    int reg;
483 b29fe3ed malc
484 b29fe3ed malc
    if (const_arg) {
485 b29fe3ed malc
        reg = 2;
486 b29fe3ed malc
        tcg_out_movi (s, TCG_TYPE_I32, reg, arg);
487 b29fe3ed malc
    }
488 b29fe3ed malc
    else reg = arg;
489 b29fe3ed malc
490 b29fe3ed malc
    tcg_out32 (s, LWZ | RT (0) | RA (reg));
491 b29fe3ed malc
    tcg_out32 (s, MTSPR | RA (0) | CTR);
492 b29fe3ed malc
    tcg_out32 (s, LWZ | RT (2) | RA (reg) | 4);
493 b29fe3ed malc
    tcg_out32 (s, BCCTR | BO_ALWAYS | LK);
494 d9370327 malc
#else
495 d9370327 malc
    if (const_arg) {
496 d9370327 malc
        tcg_out_b (s, LK, arg);
497 d9370327 malc
    }
498 d9370327 malc
    else {
499 d9370327 malc
        tcg_out32 (s, MTSPR | RS (arg) | LR);
500 d9370327 malc
        tcg_out32 (s, BCLR | BO_ALWAYS | LK);
501 d9370327 malc
    }
502 b29fe3ed malc
#endif
503 d9370327 malc
}
504 b29fe3ed malc
505 2662e13f bellard
#if defined(CONFIG_SOFTMMU)
506 79383c9c blueswir1
507 79383c9c blueswir1
#include "../../softmmu_defs.h"
508 2662e13f bellard
509 2662e13f bellard
static void *qemu_ld_helpers[4] = {
510 2662e13f bellard
    __ldb_mmu,
511 2662e13f bellard
    __ldw_mmu,
512 2662e13f bellard
    __ldl_mmu,
513 2662e13f bellard
    __ldq_mmu,
514 2662e13f bellard
};
515 2662e13f bellard
516 2662e13f bellard
static void *qemu_st_helpers[4] = {
517 2662e13f bellard
    __stb_mmu,
518 2662e13f bellard
    __stw_mmu,
519 2662e13f bellard
    __stl_mmu,
520 2662e13f bellard
    __stq_mmu,
521 2662e13f bellard
};
522 2662e13f bellard
#endif
523 2662e13f bellard
524 2662e13f bellard
static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
525 2662e13f bellard
{
526 f6548c0a malc
    int addr_reg, data_reg, data_reg2, r0, r1, rbase, mem_index, s_bits, bswap;
527 2662e13f bellard
#ifdef CONFIG_SOFTMMU
528 f8edcbaa malc
    int r2;
529 2662e13f bellard
    void *label1_ptr, *label2_ptr;
530 2662e13f bellard
#endif
531 2662e13f bellard
#if TARGET_LONG_BITS == 64
532 2662e13f bellard
    int addr_reg2;
533 2662e13f bellard
#endif
534 2662e13f bellard
535 2662e13f bellard
    data_reg = *args++;
536 2662e13f bellard
    if (opc == 3)
537 2662e13f bellard
        data_reg2 = *args++;
538 2662e13f bellard
    else
539 2662e13f bellard
        data_reg2 = 0;
540 2662e13f bellard
    addr_reg = *args++;
541 2662e13f bellard
#if TARGET_LONG_BITS == 64
542 2662e13f bellard
    addr_reg2 = *args++;
543 2662e13f bellard
#endif
544 2662e13f bellard
    mem_index = *args;
545 2662e13f bellard
    s_bits = opc & 3;
546 2662e13f bellard
547 2662e13f bellard
#ifdef CONFIG_SOFTMMU
548 2662e13f bellard
    r0 = 3;
549 2662e13f bellard
    r1 = 4;
550 2662e13f bellard
    r2 = 0;
551 f6548c0a malc
    rbase = 0;
552 2662e13f bellard
553 2662e13f bellard
    tcg_out32 (s, (RLWINM
554 2662e13f bellard
                   | RA (r0)
555 2662e13f bellard
                   | RS (addr_reg)
556 2662e13f bellard
                   | SH (32 - (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS))
557 2662e13f bellard
                   | MB (32 - (CPU_TLB_BITS + CPU_TLB_ENTRY_BITS))
558 2662e13f bellard
                   | ME (31 - CPU_TLB_ENTRY_BITS)
559 2662e13f bellard
                   )
560 2662e13f bellard
        );
561 2662e13f bellard
    tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (TCG_AREG0));
562 2662e13f bellard
    tcg_out32 (s, (LWZU
563 2662e13f bellard
                   | RT (r1)
564 2662e13f bellard
                   | RA (r0)
565 2662e13f bellard
                   | offsetof (CPUState, tlb_table[mem_index][0].addr_read)
566 2662e13f bellard
                   )
567 2662e13f bellard
        );
568 2662e13f bellard
    tcg_out32 (s, (RLWINM
569 2662e13f bellard
                   | RA (r2)
570 2662e13f bellard
                   | RS (addr_reg)
571 2662e13f bellard
                   | SH (0)
572 2662e13f bellard
                   | MB ((32 - s_bits) & 31)
573 2662e13f bellard
                   | ME (31 - TARGET_PAGE_BITS)
574 2662e13f bellard
                   )
575 2662e13f bellard
        );
576 2662e13f bellard
577 2662e13f bellard
    tcg_out32 (s, CMP | BF (7) | RA (r2) | RB (r1));
578 2662e13f bellard
#if TARGET_LONG_BITS == 64
579 2662e13f bellard
    tcg_out32 (s, LWZ | RT (r1) | RA (r0) | 4);
580 2662e13f bellard
    tcg_out32 (s, CMP | BF (6) | RA (addr_reg2) | RB (r1));
581 2662e13f bellard
    tcg_out32 (s, CRAND | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, CR_EQ));
582 2662e13f bellard
#endif
583 2662e13f bellard
584 2662e13f bellard
    label1_ptr = s->code_ptr;
585 2662e13f bellard
#ifdef FAST_PATH
586 2662e13f bellard
    tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE);
587 2662e13f bellard
#endif
588 2662e13f bellard
589 2662e13f bellard
    /* slow path */
590 2662e13f bellard
#if TARGET_LONG_BITS == 32
591 2662e13f bellard
    tcg_out_mov (s, 3, addr_reg);
592 2662e13f bellard
    tcg_out_movi (s, TCG_TYPE_I32, 4, mem_index);
593 2662e13f bellard
#else
594 2662e13f bellard
    tcg_out_mov (s, 3, addr_reg2);
595 2662e13f bellard
    tcg_out_mov (s, 4, addr_reg);
596 2662e13f bellard
    tcg_out_movi (s, TCG_TYPE_I32, 5, mem_index);
597 2662e13f bellard
#endif
598 2662e13f bellard
599 b29fe3ed malc
    tcg_out_call (s, (tcg_target_long) qemu_ld_helpers[s_bits], 1);
600 2662e13f bellard
    switch (opc) {
601 2662e13f bellard
    case 0|4:
602 2662e13f bellard
        tcg_out32 (s, EXTSB | RA (data_reg) | RS (3));
603 2662e13f bellard
        break;
604 2662e13f bellard
    case 1|4:
605 2662e13f bellard
        tcg_out32 (s, EXTSH | RA (data_reg) | RS (3));
606 2662e13f bellard
        break;
607 2662e13f bellard
    case 0:
608 2662e13f bellard
    case 1:
609 2662e13f bellard
    case 2:
610 2662e13f bellard
        if (data_reg != 3)
611 2662e13f bellard
            tcg_out_mov (s, data_reg, 3);
612 2662e13f bellard
        break;
613 2662e13f bellard
    case 3:
614 2662e13f bellard
        if (data_reg == 3) {
615 2662e13f bellard
            if (data_reg2 == 4) {
616 2662e13f bellard
                tcg_out_mov (s, 0, 4);
617 2662e13f bellard
                tcg_out_mov (s, 4, 3);
618 2662e13f bellard
                tcg_out_mov (s, 3, 0);
619 2662e13f bellard
            }
620 2662e13f bellard
            else {
621 2662e13f bellard
                tcg_out_mov (s, data_reg2, 3);
622 2662e13f bellard
                tcg_out_mov (s, 3, 4);
623 2662e13f bellard
            }
624 2662e13f bellard
        }
625 2662e13f bellard
        else {
626 2662e13f bellard
            if (data_reg != 4) tcg_out_mov (s, data_reg, 4);
627 2662e13f bellard
            if (data_reg2 != 3) tcg_out_mov (s, data_reg2, 3);
628 2662e13f bellard
        }
629 2662e13f bellard
        break;
630 2662e13f bellard
    }
631 2662e13f bellard
    label2_ptr = s->code_ptr;
632 2662e13f bellard
    tcg_out32 (s, B);
633 2662e13f bellard
634 2662e13f bellard
    /* label1: fast path */
635 2662e13f bellard
#ifdef FAST_PATH
636 2662e13f bellard
    reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr);
637 2662e13f bellard
#endif
638 2662e13f bellard
639 2662e13f bellard
    /* r0 now contains &env->tlb_table[mem_index][index].addr_read */
640 2662e13f bellard
    tcg_out32 (s, (LWZ
641 2662e13f bellard
                   | RT (r0)
642 2662e13f bellard
                   | RA (r0)
643 2662e13f bellard
                   | (ADDEND_OFFSET + offsetof (CPUTLBEntry, addend)
644 2662e13f bellard
                      - offsetof (CPUTLBEntry, addr_read))
645 2662e13f bellard
                   ));
646 2662e13f bellard
    /* r0 = env->tlb_table[mem_index][index].addend */
647 2662e13f bellard
    tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (addr_reg));
648 2662e13f bellard
    /* r0 = env->tlb_table[mem_index][index].addend + addr */
649 2662e13f bellard
650 2662e13f bellard
#else  /* !CONFIG_SOFTMMU */
651 2662e13f bellard
    r0 = addr_reg;
652 f8edcbaa malc
    r1 = 3;
653 f6548c0a malc
    rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
654 2662e13f bellard
#endif
655 2662e13f bellard
656 2662e13f bellard
#ifdef TARGET_WORDS_BIGENDIAN
657 2662e13f bellard
    bswap = 0;
658 2662e13f bellard
#else
659 2662e13f bellard
    bswap = 1;
660 2662e13f bellard
#endif
661 f6548c0a malc
662 2662e13f bellard
    switch (opc) {
663 2662e13f bellard
    default:
664 2662e13f bellard
    case 0:
665 f6548c0a malc
        tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));
666 2662e13f bellard
        break;
667 2662e13f bellard
    case 0|4:
668 f6548c0a malc
        tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));
669 2662e13f bellard
        tcg_out32 (s, EXTSB | RA (data_reg) | RS (data_reg));
670 2662e13f bellard
        break;
671 2662e13f bellard
    case 1:
672 f6548c0a malc
        if (bswap)
673 f6548c0a malc
            tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));
674 f6548c0a malc
        else
675 f6548c0a malc
            tcg_out32 (s, LHZX | TAB (data_reg, rbase, r0));
676 2662e13f bellard
        break;
677 2662e13f bellard
    case 1|4:
678 2662e13f bellard
        if (bswap) {
679 f6548c0a malc
            tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));
680 2662e13f bellard
            tcg_out32 (s, EXTSH | RA (data_reg) | RS (data_reg));
681 2662e13f bellard
        }
682 f6548c0a malc
        else tcg_out32 (s, LHAX | TAB (data_reg, rbase, r0));
683 2662e13f bellard
        break;
684 2662e13f bellard
    case 2:
685 f6548c0a malc
        if (bswap)
686 f6548c0a malc
            tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
687 f6548c0a malc
        else
688 f6548c0a malc
            tcg_out32 (s, LWZX | TAB (data_reg, rbase, r0));
689 2662e13f bellard
        break;
690 2662e13f bellard
    case 3:
691 2662e13f bellard
        if (bswap) {
692 f6548c0a malc
            tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
693 f6548c0a malc
            tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
694 f6548c0a malc
            tcg_out32 (s, LWBRX | TAB (data_reg2, rbase, r1));
695 2662e13f bellard
        }
696 2662e13f bellard
        else {
697 f6548c0a malc
#ifdef CONFIG_USE_GUEST_BASE
698 f6548c0a malc
            tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
699 f6548c0a malc
            tcg_out32 (s, LWZX | TAB (data_reg2, rbase, r0));
700 f6548c0a malc
            tcg_out32 (s, LWZX | TAB (data_reg, rbase, r1));
701 f6548c0a malc
#else
702 2662e13f bellard
            if (r0 == data_reg2) {
703 2662e13f bellard
                tcg_out32 (s, LWZ | RT (0) | RA (r0));
704 2662e13f bellard
                tcg_out32 (s, LWZ | RT (data_reg) | RA (r0) | 4);
705 2662e13f bellard
                tcg_out_mov (s, data_reg2, 0);
706 2662e13f bellard
            }
707 2662e13f bellard
            else {
708 2662e13f bellard
                tcg_out32 (s, LWZ | RT (data_reg2) | RA (r0));
709 2662e13f bellard
                tcg_out32 (s, LWZ | RT (data_reg) | RA (r0) | 4);
710 2662e13f bellard
            }
711 f6548c0a malc
#endif
712 2662e13f bellard
        }
713 2662e13f bellard
        break;
714 2662e13f bellard
    }
715 2662e13f bellard
716 2662e13f bellard
#ifdef CONFIG_SOFTMMU
717 2662e13f bellard
    reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr);
718 2662e13f bellard
#endif
719 2662e13f bellard
}
720 2662e13f bellard
721 2662e13f bellard
static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
722 2662e13f bellard
{
723 f6548c0a malc
    int addr_reg, r0, r1, data_reg, data_reg2, mem_index, bswap, rbase;
724 2662e13f bellard
#ifdef CONFIG_SOFTMMU
725 2662e13f bellard
    int r2, ir;
726 2662e13f bellard
    void *label1_ptr, *label2_ptr;
727 2662e13f bellard
#endif
728 2662e13f bellard
#if TARGET_LONG_BITS == 64
729 2662e13f bellard
    int addr_reg2;
730 2662e13f bellard
#endif
731 2662e13f bellard
732 2662e13f bellard
    data_reg = *args++;
733 2662e13f bellard
    if (opc == 3)
734 2662e13f bellard
        data_reg2 = *args++;
735 2662e13f bellard
    else
736 2662e13f bellard
        data_reg2 = 0;
737 2662e13f bellard
    addr_reg = *args++;
738 2662e13f bellard
#if TARGET_LONG_BITS == 64
739 2662e13f bellard
    addr_reg2 = *args++;
740 2662e13f bellard
#endif
741 2662e13f bellard
    mem_index = *args;
742 2662e13f bellard
743 2662e13f bellard
#ifdef CONFIG_SOFTMMU
744 2662e13f bellard
    r0 = 3;
745 2662e13f bellard
    r1 = 4;
746 2662e13f bellard
    r2 = 0;
747 f6548c0a malc
    rbase = 0;
748 2662e13f bellard
749 2662e13f bellard
    tcg_out32 (s, (RLWINM
750 2662e13f bellard
                   | RA (r0)
751 2662e13f bellard
                   | RS (addr_reg)
752 2662e13f bellard
                   | SH (32 - (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS))
753 2662e13f bellard
                   | MB (32 - (CPU_TLB_ENTRY_BITS + CPU_TLB_BITS))
754 2662e13f bellard
                   | ME (31 - CPU_TLB_ENTRY_BITS)
755 2662e13f bellard
                   )
756 2662e13f bellard
        );
757 2662e13f bellard
    tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (TCG_AREG0));
758 2662e13f bellard
    tcg_out32 (s, (LWZU
759 2662e13f bellard
                   | RT (r1)
760 2662e13f bellard
                   | RA (r0)
761 2662e13f bellard
                   | offsetof (CPUState, tlb_table[mem_index][0].addr_write)
762 2662e13f bellard
                   )
763 2662e13f bellard
        );
764 2662e13f bellard
    tcg_out32 (s, (RLWINM
765 2662e13f bellard
                   | RA (r2)
766 2662e13f bellard
                   | RS (addr_reg)
767 2662e13f bellard
                   | SH (0)
768 2662e13f bellard
                   | MB ((32 - opc) & 31)
769 2662e13f bellard
                   | ME (31 - TARGET_PAGE_BITS)
770 2662e13f bellard
                   )
771 2662e13f bellard
        );
772 2662e13f bellard
773 2662e13f bellard
    tcg_out32 (s, CMP | (7 << 23) | RA (r2) | RB (r1));
774 2662e13f bellard
#if TARGET_LONG_BITS == 64
775 2662e13f bellard
    tcg_out32 (s, LWZ | RT (r1) | RA (r0) | 4);
776 2662e13f bellard
    tcg_out32 (s, CMP | BF (6) | RA (addr_reg2) | RB (r1));
777 2662e13f bellard
    tcg_out32 (s, CRAND | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, CR_EQ));
778 2662e13f bellard
#endif
779 2662e13f bellard
780 2662e13f bellard
    label1_ptr = s->code_ptr;
781 2662e13f bellard
#ifdef FAST_PATH
782 2662e13f bellard
    tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE);
783 2662e13f bellard
#endif
784 2662e13f bellard
785 2662e13f bellard
    /* slow path */
786 2662e13f bellard
#if TARGET_LONG_BITS == 32
787 2662e13f bellard
    tcg_out_mov (s, 3, addr_reg);
788 2662e13f bellard
    ir = 4;
789 2662e13f bellard
#else
790 2662e13f bellard
    tcg_out_mov (s, 3, addr_reg2);
791 2662e13f bellard
    tcg_out_mov (s, 4, addr_reg);
792 f9bf2987 malc
#ifdef TCG_TARGET_CALL_ALIGN_ARGS
793 2662e13f bellard
    ir = 5;
794 f9bf2987 malc
#else
795 f9bf2987 malc
    ir = 4;
796 f9bf2987 malc
#endif
797 2662e13f bellard
#endif
798 2662e13f bellard
799 2662e13f bellard
    switch (opc) {
800 2662e13f bellard
    case 0:
801 2662e13f bellard
        tcg_out32 (s, (RLWINM
802 2662e13f bellard
                       | RA (ir)
803 2662e13f bellard
                       | RS (data_reg)
804 2662e13f bellard
                       | SH (0)
805 2662e13f bellard
                       | MB (24)
806 2662e13f bellard
                       | ME (31)));
807 2662e13f bellard
        break;
808 2662e13f bellard
    case 1:
809 2662e13f bellard
        tcg_out32 (s, (RLWINM
810 2662e13f bellard
                       | RA (ir)
811 2662e13f bellard
                       | RS (data_reg)
812 2662e13f bellard
                       | SH (0)
813 2662e13f bellard
                       | MB (16)
814 2662e13f bellard
                       | ME (31)));
815 2662e13f bellard
        break;
816 2662e13f bellard
    case 2:
817 2662e13f bellard
        tcg_out_mov (s, ir, data_reg);
818 2662e13f bellard
        break;
819 2662e13f bellard
    case 3:
820 f9bf2987 malc
#ifdef TCG_TARGET_CALL_ALIGN_ARGS
821 f9bf2987 malc
        ir = 5;
822 f9bf2987 malc
#endif
823 f9bf2987 malc
        tcg_out_mov (s, ir++, data_reg2);
824 f9bf2987 malc
        tcg_out_mov (s, ir, data_reg);
825 2662e13f bellard
        break;
826 2662e13f bellard
    }
827 2662e13f bellard
    ir++;
828 2662e13f bellard
829 2662e13f bellard
    tcg_out_movi (s, TCG_TYPE_I32, ir, mem_index);
830 b29fe3ed malc
    tcg_out_call (s, (tcg_target_long) qemu_st_helpers[opc], 1);
831 2662e13f bellard
    label2_ptr = s->code_ptr;
832 2662e13f bellard
    tcg_out32 (s, B);
833 2662e13f bellard
834 2662e13f bellard
    /* label1: fast path */
835 2662e13f bellard
#ifdef FAST_PATH
836 2662e13f bellard
    reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr);
837 2662e13f bellard
#endif
838 2662e13f bellard
839 2662e13f bellard
    tcg_out32 (s, (LWZ
840 2662e13f bellard
                   | RT (r0)
841 2662e13f bellard
                   | RA (r0)
842 2662e13f bellard
                   | (ADDEND_OFFSET + offsetof (CPUTLBEntry, addend)
843 2662e13f bellard
                      - offsetof (CPUTLBEntry, addr_write))
844 2662e13f bellard
                   ));
845 2662e13f bellard
    /* r0 = env->tlb_table[mem_index][index].addend */
846 2662e13f bellard
    tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (addr_reg));
847 2662e13f bellard
    /* r0 = env->tlb_table[mem_index][index].addend + addr */
848 2662e13f bellard
849 2662e13f bellard
#else  /* !CONFIG_SOFTMMU */
850 2662e13f bellard
    r0 = addr_reg;
851 f6548c0a malc
    r1 = 3;
852 a71836de malc
    rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
853 2662e13f bellard
#endif
854 2662e13f bellard
855 2662e13f bellard
#ifdef TARGET_WORDS_BIGENDIAN
856 2662e13f bellard
    bswap = 0;
857 2662e13f bellard
#else
858 2662e13f bellard
    bswap = 1;
859 2662e13f bellard
#endif
860 2662e13f bellard
    switch (opc) {
861 2662e13f bellard
    case 0:
862 f6548c0a malc
        tcg_out32 (s, STBX | SAB (data_reg, rbase, r0));
863 2662e13f bellard
        break;
864 2662e13f bellard
    case 1:
865 f6548c0a malc
        if (bswap)
866 f6548c0a malc
            tcg_out32 (s, STHBRX | SAB (data_reg, rbase, r0));
867 f6548c0a malc
        else
868 f6548c0a malc
            tcg_out32 (s, STHX | SAB (data_reg, rbase, r0));
869 2662e13f bellard
        break;
870 2662e13f bellard
    case 2:
871 f6548c0a malc
        if (bswap)
872 f6548c0a malc
            tcg_out32 (s, STWBRX | SAB (data_reg, rbase, r0));
873 f6548c0a malc
        else
874 f6548c0a malc
            tcg_out32 (s, STWX | SAB (data_reg, rbase, r0));
875 2662e13f bellard
        break;
876 2662e13f bellard
    case 3:
877 2662e13f bellard
        if (bswap) {
878 2662e13f bellard
            tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
879 f6548c0a malc
            tcg_out32 (s, STWBRX | SAB (data_reg,  rbase, r0));
880 f6548c0a malc
            tcg_out32 (s, STWBRX | SAB (data_reg2, rbase, r1));
881 2662e13f bellard
        }
882 2662e13f bellard
        else {
883 f6548c0a malc
#ifdef CONFIG_USE_GUEST_BASE
884 f6548c0a malc
            tcg_out32 (s, STWX | SAB (data_reg2, rbase, r0));
885 f6548c0a malc
            tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
886 f6548c0a malc
            tcg_out32 (s, STWX | SAB (data_reg,  rbase, r1));
887 f6548c0a malc
#else
888 2662e13f bellard
            tcg_out32 (s, STW | RS (data_reg2) | RA (r0));
889 2662e13f bellard
            tcg_out32 (s, STW | RS (data_reg) | RA (r0) | 4);
890 f6548c0a malc
#endif
891 2662e13f bellard
        }
892 2662e13f bellard
        break;
893 2662e13f bellard
    }
894 2662e13f bellard
895 2662e13f bellard
#ifdef CONFIG_SOFTMMU
896 2662e13f bellard
    reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr);
897 2662e13f bellard
#endif
898 2662e13f bellard
}
899 2662e13f bellard
900 2662e13f bellard
void tcg_target_qemu_prologue (TCGContext *s)
901 2662e13f bellard
{
902 0d5bd363 malc
    int i, frame_size;
903 2662e13f bellard
904 2662e13f bellard
    frame_size = 0
905 f9bf2987 malc
        + LINKAGE_AREA_SIZE
906 2662e13f bellard
        + TCG_STATIC_CALL_ARGS_SIZE
907 2662e13f bellard
        + ARRAY_SIZE (tcg_target_callee_save_regs) * 4
908 2662e13f bellard
        ;
909 2662e13f bellard
    frame_size = (frame_size + 15) & ~15;
910 2662e13f bellard
911 6ec85236 malc
#ifdef _CALL_AIX
912 b29fe3ed malc
    {
913 b29fe3ed malc
        uint32_t addr;
914 b29fe3ed malc
915 b29fe3ed malc
        /* First emit adhoc function descriptor */
916 b29fe3ed malc
        addr = (uint32_t) s->code_ptr + 12;
917 b29fe3ed malc
        tcg_out32 (s, addr);        /* entry point */
918 b29fe3ed malc
        s->code_ptr += 8;           /* skip TOC and environment pointer */
919 b29fe3ed malc
    }
920 b29fe3ed malc
#endif
921 2662e13f bellard
    tcg_out32 (s, MFSPR | RT (0) | LR);
922 2662e13f bellard
    tcg_out32 (s, STWU | RS (1) | RA (1) | (-frame_size & 0xffff));
923 2662e13f bellard
    for (i = 0; i < ARRAY_SIZE (tcg_target_callee_save_regs); ++i)
924 2662e13f bellard
        tcg_out32 (s, (STW
925 2662e13f bellard
                       | RS (tcg_target_callee_save_regs[i])
926 2662e13f bellard
                       | RA (1)
927 f9bf2987 malc
                       | (i * 4 + LINKAGE_AREA_SIZE + TCG_STATIC_CALL_ARGS_SIZE)
928 2662e13f bellard
                       )
929 2662e13f bellard
            );
930 2946898b malc
    tcg_out32 (s, STW | RS (0) | RA (1) | (frame_size + LR_OFFSET));
931 2662e13f bellard
932 f6548c0a malc
#ifdef CONFIG_USE_GUEST_BASE
933 f6548c0a malc
    tcg_out_movi (s, TCG_TYPE_I32, TCG_GUEST_BASE_REG, GUEST_BASE);
934 f6548c0a malc
#endif
935 f6548c0a malc
936 2662e13f bellard
    tcg_out32 (s, MTSPR | RS (3) | CTR);
937 2662e13f bellard
    tcg_out32 (s, BCCTR | BO_ALWAYS);
938 2662e13f bellard
    tb_ret_addr = s->code_ptr;
939 2662e13f bellard
940 2662e13f bellard
    for (i = 0; i < ARRAY_SIZE (tcg_target_callee_save_regs); ++i)
941 2662e13f bellard
        tcg_out32 (s, (LWZ
942 2662e13f bellard
                       | RT (tcg_target_callee_save_regs[i])
943 2662e13f bellard
                       | RA (1)
944 f9bf2987 malc
                       | (i * 4 + LINKAGE_AREA_SIZE + TCG_STATIC_CALL_ARGS_SIZE)
945 2662e13f bellard
                       )
946 2662e13f bellard
            );
947 2946898b malc
    tcg_out32 (s, LWZ | RT (0) | RA (1) | (frame_size + LR_OFFSET));
948 2662e13f bellard
    tcg_out32 (s, MTSPR | RS (0) | LR);
949 2662e13f bellard
    tcg_out32 (s, ADDI | RT (1) | RA (1) | frame_size);
950 2662e13f bellard
    tcg_out32 (s, BCLR | BO_ALWAYS);
951 2662e13f bellard
}
952 2662e13f bellard
953 2662e13f bellard
static void tcg_out_ld (TCGContext *s, TCGType type, int ret, int arg1,
954 2662e13f bellard
                        tcg_target_long arg2)
955 2662e13f bellard
{
956 2662e13f bellard
    tcg_out_ldst (s, ret, arg1, arg2, LWZ, LWZX);
957 2662e13f bellard
}
958 2662e13f bellard
959 2662e13f bellard
static void tcg_out_st (TCGContext *s, TCGType type, int arg, int arg1,
960 2662e13f bellard
                        tcg_target_long arg2)
961 2662e13f bellard
{
962 2662e13f bellard
    tcg_out_ldst (s, arg, arg1, arg2, STW, STWX);
963 2662e13f bellard
}
964 2662e13f bellard
965 2662e13f bellard
static void ppc_addi (TCGContext *s, int rt, int ra, tcg_target_long si)
966 2662e13f bellard
{
967 2662e13f bellard
    if (!si && rt == ra)
968 2662e13f bellard
        return;
969 2662e13f bellard
970 2662e13f bellard
    if (si == (int16_t) si)
971 2662e13f bellard
        tcg_out32 (s, ADDI | RT (rt) | RA (ra) | (si & 0xffff));
972 2662e13f bellard
    else {
973 2662e13f bellard
        uint16_t h = ((si >> 16) & 0xffff) + ((uint16_t) si >> 15);
974 2662e13f bellard
        tcg_out32 (s, ADDIS | RT (rt) | RA (ra) | h);
975 2662e13f bellard
        tcg_out32 (s, ADDI | RT (rt) | RA (rt) | (si & 0xffff));
976 2662e13f bellard
    }
977 2662e13f bellard
}
978 2662e13f bellard
979 2662e13f bellard
static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
980 2662e13f bellard
{
981 2662e13f bellard
    ppc_addi (s, reg, reg, val);
982 2662e13f bellard
}
983 2662e13f bellard
984 c596defd malc
static void tcg_out_cmp (TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
985 c596defd malc
                         int const_arg2, int cr)
986 2662e13f bellard
{
987 2662e13f bellard
    int imm;
988 2662e13f bellard
    uint32_t op;
989 2662e13f bellard
990 2662e13f bellard
    switch (cond) {
991 f3f478a7 bellard
    case TCG_COND_EQ:
992 f3f478a7 bellard
    case TCG_COND_NE:
993 f3f478a7 bellard
        if (const_arg2) {
994 f3f478a7 bellard
            if ((int16_t) arg2 == arg2) {
995 f3f478a7 bellard
                op = CMPI;
996 f3f478a7 bellard
                imm = 1;
997 f3f478a7 bellard
                break;
998 f3f478a7 bellard
            }
999 f3f478a7 bellard
            else if ((uint16_t) arg2 == arg2) {
1000 f3f478a7 bellard
                op = CMPLI;
1001 f3f478a7 bellard
                imm = 1;
1002 f3f478a7 bellard
                break;
1003 f3f478a7 bellard
            }
1004 f3f478a7 bellard
        }
1005 f3f478a7 bellard
        op = CMPL;
1006 f3f478a7 bellard
        imm = 0;
1007 f3f478a7 bellard
        break;
1008 f3f478a7 bellard
1009 f3f478a7 bellard
    case TCG_COND_LT:
1010 f3f478a7 bellard
    case TCG_COND_GE:
1011 f3f478a7 bellard
    case TCG_COND_LE:
1012 f3f478a7 bellard
    case TCG_COND_GT:
1013 f3f478a7 bellard
        if (const_arg2) {
1014 f3f478a7 bellard
            if ((int16_t) arg2 == arg2) {
1015 f3f478a7 bellard
                op = CMPI;
1016 f3f478a7 bellard
                imm = 1;
1017 f3f478a7 bellard
                break;
1018 f3f478a7 bellard
            }
1019 f3f478a7 bellard
        }
1020 f3f478a7 bellard
        op = CMP;
1021 f3f478a7 bellard
        imm = 0;
1022 f3f478a7 bellard
        break;
1023 f3f478a7 bellard
1024 f3f478a7 bellard
    case TCG_COND_LTU:
1025 f3f478a7 bellard
    case TCG_COND_GEU:
1026 f3f478a7 bellard
    case TCG_COND_LEU:
1027 f3f478a7 bellard
    case TCG_COND_GTU:
1028 f3f478a7 bellard
        if (const_arg2) {
1029 f3f478a7 bellard
            if ((uint16_t) arg2 == arg2) {
1030 f3f478a7 bellard
                op = CMPLI;
1031 f3f478a7 bellard
                imm = 1;
1032 f3f478a7 bellard
                break;
1033 f3f478a7 bellard
            }
1034 f3f478a7 bellard
        }
1035 f3f478a7 bellard
        op = CMPL;
1036 f3f478a7 bellard
        imm = 0;
1037 f3f478a7 bellard
        break;
1038 f3f478a7 bellard
1039 2662e13f bellard
    default:
1040 2662e13f bellard
        tcg_abort ();
1041 2662e13f bellard
    }
1042 c596defd malc
    op |= BF (cr);
1043 2662e13f bellard
1044 2662e13f bellard
    if (imm)
1045 2662e13f bellard
        tcg_out32 (s, op | RA (arg1) | (arg2 & 0xffff));
1046 2662e13f bellard
    else {
1047 2662e13f bellard
        if (const_arg2) {
1048 2662e13f bellard
            tcg_out_movi (s, TCG_TYPE_I32, 0, arg2);
1049 2662e13f bellard
            tcg_out32 (s, op | RA (arg1) | RB (0));
1050 2662e13f bellard
        }
1051 2662e13f bellard
        else
1052 2662e13f bellard
            tcg_out32 (s, op | RA (arg1) | RB (arg2));
1053 2662e13f bellard
    }
1054 2662e13f bellard
1055 c596defd malc
}
1056 c596defd malc
1057 c596defd malc
static void tcg_out_bc (TCGContext *s, int bc, int label_index)
1058 c596defd malc
{
1059 c596defd malc
    TCGLabel *l = &s->labels[label_index];
1060 c596defd malc
1061 0a878c47 malc
    if (l->has_value)
1062 c596defd malc
        tcg_out32 (s, bc | reloc_pc14_val (s->code_ptr, l->u.value));
1063 2662e13f bellard
    else {
1064 0a878c47 malc
        uint16_t val = *(uint16_t *) &s->code_ptr[2];
1065 0a878c47 malc
1066 0a878c47 malc
        /* Thanks to Andrzej Zaborowski */
1067 c596defd malc
        tcg_out32 (s, bc | (val & 0xfffc));
1068 2662e13f bellard
        tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL14, label_index, 0);
1069 2662e13f bellard
    }
1070 2662e13f bellard
}
1071 2662e13f bellard
1072 b0809bf7 malc
static void tcg_out_cr7eq_from_cond (TCGContext *s, const TCGArg *args,
1073 b0809bf7 malc
                                     const int *const_args)
1074 c596defd malc
{
1075 b0809bf7 malc
    int cond = args[4], op;
1076 c596defd malc
    struct { int bit1; int bit2; int cond2; } bits[] = {
1077 c596defd malc
        [TCG_COND_LT ] = { CR_LT, CR_LT, TCG_COND_LT  },
1078 c596defd malc
        [TCG_COND_LE ] = { CR_LT, CR_GT, TCG_COND_LT  },
1079 c596defd malc
        [TCG_COND_GT ] = { CR_GT, CR_GT, TCG_COND_GT  },
1080 c596defd malc
        [TCG_COND_GE ] = { CR_GT, CR_LT, TCG_COND_GT  },
1081 c596defd malc
        [TCG_COND_LTU] = { CR_LT, CR_LT, TCG_COND_LTU },
1082 c596defd malc
        [TCG_COND_LEU] = { CR_LT, CR_GT, TCG_COND_LTU },
1083 c596defd malc
        [TCG_COND_GTU] = { CR_GT, CR_GT, TCG_COND_GTU },
1084 c596defd malc
        [TCG_COND_GEU] = { CR_GT, CR_LT, TCG_COND_GTU },
1085 c596defd malc
    }, *b = &bits[cond];
1086 c596defd malc
1087 c596defd malc
    switch (cond) {
1088 2662e13f bellard
    case TCG_COND_EQ:
1089 2662e13f bellard
    case TCG_COND_NE:
1090 e924c485 malc
        op = (cond == TCG_COND_EQ) ? CRAND : CRNAND;
1091 e924c485 malc
        tcg_out_cmp (s, cond, args[0], args[2], const_args[2], 6);
1092 e924c485 malc
        tcg_out_cmp (s, cond, args[1], args[3], const_args[3], 7);
1093 e924c485 malc
        tcg_out32 (s, op | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, CR_EQ));
1094 2662e13f bellard
        break;
1095 2662e13f bellard
    case TCG_COND_LT:
1096 2662e13f bellard
    case TCG_COND_LE:
1097 2662e13f bellard
    case TCG_COND_GT:
1098 2662e13f bellard
    case TCG_COND_GE:
1099 2662e13f bellard
    case TCG_COND_LTU:
1100 2662e13f bellard
    case TCG_COND_LEU:
1101 2662e13f bellard
    case TCG_COND_GTU:
1102 2662e13f bellard
    case TCG_COND_GEU:
1103 c596defd malc
        op = (b->bit1 != b->bit2) ? CRANDC : CRAND;
1104 c596defd malc
        tcg_out_cmp (s, b->cond2, args[1], args[3], const_args[3], 5);
1105 c596defd malc
        tcg_out_cmp (s, TCG_COND_EQ, args[1], args[3], const_args[3], 6);
1106 c596defd malc
        tcg_out_cmp (s, cond, args[0], args[2], const_args[2], 7);
1107 c596defd malc
        tcg_out32 (s, op | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, b->bit2));
1108 c596defd malc
        tcg_out32 (s, CROR | BT (7, CR_EQ) | BA (5, b->bit1) | BB (7, CR_EQ));
1109 2662e13f bellard
        break;
1110 2662e13f bellard
    default:
1111 2662e13f bellard
        tcg_abort();
1112 2662e13f bellard
    }
1113 b0809bf7 malc
}
1114 b0809bf7 malc
1115 b0809bf7 malc
static void tcg_out_setcond (TCGContext *s, int cond, TCGArg arg0,
1116 b0809bf7 malc
                             TCGArg arg1, TCGArg arg2, int const_arg2)
1117 b0809bf7 malc
{
1118 b0809bf7 malc
    int crop, sh, arg;
1119 b0809bf7 malc
1120 b0809bf7 malc
    switch (cond) {
1121 b0809bf7 malc
    case TCG_COND_EQ:
1122 b0809bf7 malc
        if (const_arg2) {
1123 b0809bf7 malc
            if (!arg2) {
1124 b0809bf7 malc
                arg = arg1;
1125 b0809bf7 malc
            }
1126 b0809bf7 malc
            else {
1127 b0809bf7 malc
                arg = 0;
1128 b0809bf7 malc
                if ((uint16_t) arg2 == arg2) {
1129 b0809bf7 malc
                    tcg_out32 (s, XORI | RS (arg1) | RA (0) | arg2);
1130 b0809bf7 malc
                }
1131 b0809bf7 malc
                else {
1132 b0809bf7 malc
                    tcg_out_movi (s, TCG_TYPE_I32, 0, arg2);
1133 b0809bf7 malc
                    tcg_out32 (s, XOR | SAB (arg1, 0, 0));
1134 b0809bf7 malc
                }
1135 b0809bf7 malc
            }
1136 b0809bf7 malc
        }
1137 b0809bf7 malc
        else {
1138 b0809bf7 malc
            arg = 0;
1139 b0809bf7 malc
            tcg_out32 (s, XOR | SAB (arg1, 0, arg2));
1140 b0809bf7 malc
        }
1141 b0809bf7 malc
        tcg_out32 (s, CNTLZW | RS (arg) | RA (0));
1142 b0809bf7 malc
        tcg_out32 (s, (RLWINM
1143 b0809bf7 malc
                       | RA (arg0)
1144 b0809bf7 malc
                       | RS (0)
1145 b0809bf7 malc
                       | SH (27)
1146 b0809bf7 malc
                       | MB (5)
1147 b0809bf7 malc
                       | ME (31)
1148 b0809bf7 malc
                       )
1149 b0809bf7 malc
            );
1150 27a7797b malc
        break;
1151 b0809bf7 malc
1152 b0809bf7 malc
    case TCG_COND_NE:
1153 b0809bf7 malc
        if (const_arg2) {
1154 b0809bf7 malc
            if (!arg2) {
1155 b0809bf7 malc
                arg = arg1;
1156 b0809bf7 malc
            }
1157 b0809bf7 malc
            else {
1158 b0809bf7 malc
                arg = 0;
1159 b0809bf7 malc
                if ((uint16_t) arg2 == arg2) {
1160 b0809bf7 malc
                    tcg_out32 (s, XORI | RS (arg1) | RA (0) | arg2);
1161 b0809bf7 malc
                }
1162 b0809bf7 malc
                else {
1163 b0809bf7 malc
                    tcg_out_movi (s, TCG_TYPE_I32, 0, arg2);
1164 b0809bf7 malc
                    tcg_out32 (s, XOR | SAB (arg1, 0, 0));
1165 b0809bf7 malc
                }
1166 b0809bf7 malc
            }
1167 b0809bf7 malc
        }
1168 b0809bf7 malc
        else {
1169 b0809bf7 malc
            arg = 0;
1170 b0809bf7 malc
            tcg_out32 (s, XOR | SAB (arg1, 0, arg2));
1171 b0809bf7 malc
        }
1172 b0809bf7 malc
1173 b0809bf7 malc
        if (arg == arg1 && arg1 == arg0) {
1174 b0809bf7 malc
            tcg_out32 (s, ADDIC | RT (0) | RA (arg) | 0xffff);
1175 b0809bf7 malc
            tcg_out32 (s, SUBFE | TAB (arg0, 0, arg));
1176 b0809bf7 malc
        }
1177 b0809bf7 malc
        else {
1178 b0809bf7 malc
            tcg_out32 (s, ADDIC | RT (arg0) | RA (arg) | 0xffff);
1179 b0809bf7 malc
            tcg_out32 (s, SUBFE | TAB (arg0, arg0, arg));
1180 b0809bf7 malc
        }
1181 27a7797b malc
        break;
1182 27a7797b malc
1183 27a7797b malc
    case TCG_COND_GT:
1184 27a7797b malc
    case TCG_COND_GTU:
1185 27a7797b malc
        sh = 30;
1186 27a7797b malc
        crop = 0;
1187 27a7797b malc
        goto crtest;
1188 b0809bf7 malc
1189 b0809bf7 malc
    case TCG_COND_LT:
1190 27a7797b malc
    case TCG_COND_LTU:
1191 b0809bf7 malc
        sh = 29;
1192 b0809bf7 malc
        crop = 0;
1193 27a7797b malc
        goto crtest;
1194 b0809bf7 malc
1195 b0809bf7 malc
    case TCG_COND_GE:
1196 27a7797b malc
    case TCG_COND_GEU:
1197 b0809bf7 malc
        sh = 31;
1198 b0809bf7 malc
        crop = CRNOR | BT (7, CR_EQ) | BA (7, CR_LT) | BB (7, CR_LT);
1199 27a7797b malc
        goto crtest;
1200 b0809bf7 malc
1201 b0809bf7 malc
    case TCG_COND_LE:
1202 27a7797b malc
    case TCG_COND_LEU:
1203 b0809bf7 malc
        sh = 31;
1204 b0809bf7 malc
        crop = CRNOR | BT (7, CR_EQ) | BA (7, CR_GT) | BB (7, CR_GT);
1205 27a7797b malc
    crtest:
1206 27a7797b malc
        tcg_out_cmp (s, cond, arg1, arg2, const_arg2, 7);
1207 27a7797b malc
        if (crop) tcg_out32 (s, crop);
1208 27a7797b malc
        tcg_out32 (s, MFCR | RT (0));
1209 27a7797b malc
        tcg_out32 (s, (RLWINM
1210 27a7797b malc
                       | RA (arg0)
1211 27a7797b malc
                       | RS (0)
1212 27a7797b malc
                       | SH (sh)
1213 27a7797b malc
                       | MB (31)
1214 27a7797b malc
                       | ME (31)
1215 27a7797b malc
                       )
1216 27a7797b malc
            );
1217 b0809bf7 malc
        break;
1218 b0809bf7 malc
1219 b0809bf7 malc
    default:
1220 b0809bf7 malc
        tcg_abort ();
1221 b0809bf7 malc
    }
1222 b0809bf7 malc
}
1223 b0809bf7 malc
1224 b0809bf7 malc
static void tcg_out_setcond2 (TCGContext *s, const TCGArg *args,
1225 b0809bf7 malc
                              const int *const_args)
1226 b0809bf7 malc
{
1227 b0809bf7 malc
    tcg_out_cr7eq_from_cond (s, args + 1, const_args + 1);
1228 b0809bf7 malc
    tcg_out32 (s, MFCR | RT (0));
1229 b0809bf7 malc
    tcg_out32 (s, (RLWINM
1230 b0809bf7 malc
                   | RA (args[0])
1231 b0809bf7 malc
                   | RS (0)
1232 b0809bf7 malc
                   | SH (31)
1233 b0809bf7 malc
                   | MB (31)
1234 b0809bf7 malc
                   | ME (31)
1235 b0809bf7 malc
                   )
1236 b0809bf7 malc
        );
1237 b0809bf7 malc
}
1238 b0809bf7 malc
1239 b0809bf7 malc
static void tcg_out_brcond (TCGContext *s, int cond,
1240 b0809bf7 malc
                            TCGArg arg1, TCGArg arg2, int const_arg2,
1241 b0809bf7 malc
                            int label_index)
1242 b0809bf7 malc
{
1243 b0809bf7 malc
    tcg_out_cmp (s, cond, arg1, arg2, const_arg2, 7);
1244 b0809bf7 malc
    tcg_out_bc (s, tcg_to_bc[cond], label_index);
1245 b0809bf7 malc
}
1246 b0809bf7 malc
1247 b0809bf7 malc
/* XXX: we implement it at the target level to avoid having to
1248 b0809bf7 malc
   handle cross basic blocks temporaries */
1249 b0809bf7 malc
static void tcg_out_brcond2 (TCGContext *s, const TCGArg *args,
1250 b0809bf7 malc
                             const int *const_args)
1251 b0809bf7 malc
{
1252 b0809bf7 malc
    tcg_out_cr7eq_from_cond (s, args, const_args);
1253 b0809bf7 malc
    tcg_out_bc (s, (BC | BI (7, CR_EQ) | BO_COND_TRUE), args[5]);
1254 2662e13f bellard
}
1255 2662e13f bellard
1256 52781543 malc
void ppc_tb_set_jmp_target (unsigned long jmp_addr, unsigned long addr)
1257 52781543 malc
{
1258 52781543 malc
    uint32_t *ptr;
1259 52781543 malc
    long disp = addr - jmp_addr;
1260 52781543 malc
    unsigned long patch_size;
1261 52781543 malc
1262 52781543 malc
    ptr = (uint32_t *)jmp_addr;
1263 52781543 malc
1264 52781543 malc
    if ((disp << 6) >> 6 != disp) {
1265 52781543 malc
        ptr[0] = 0x3c000000 | (addr >> 16);    /* lis 0,addr@ha */
1266 52781543 malc
        ptr[1] = 0x60000000 | (addr & 0xffff); /* la  0,addr@l(0) */
1267 52781543 malc
        ptr[2] = 0x7c0903a6;                   /* mtctr 0 */
1268 52781543 malc
        ptr[3] = 0x4e800420;                   /* brctr */
1269 52781543 malc
        patch_size = 16;
1270 52781543 malc
    } else {
1271 52781543 malc
        /* patch the branch destination */
1272 52781543 malc
        if (disp != 16) {
1273 52781543 malc
            *ptr = 0x48000000 | (disp & 0x03fffffc); /* b disp */
1274 52781543 malc
            patch_size = 4;
1275 52781543 malc
        } else {
1276 52781543 malc
            ptr[0] = 0x60000000; /* nop */
1277 52781543 malc
            ptr[1] = 0x60000000;
1278 52781543 malc
            ptr[2] = 0x60000000;
1279 52781543 malc
            ptr[3] = 0x60000000;
1280 52781543 malc
            patch_size = 16;
1281 52781543 malc
        }
1282 52781543 malc
    }
1283 52781543 malc
    /* flush icache */
1284 52781543 malc
    flush_icache_range(jmp_addr, jmp_addr + patch_size);
1285 52781543 malc
}
1286 52781543 malc
1287 2662e13f bellard
static void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
1288 2662e13f bellard
                       const int *const_args)
1289 2662e13f bellard
{
1290 2662e13f bellard
    switch (opc) {
1291 2662e13f bellard
    case INDEX_op_exit_tb:
1292 2662e13f bellard
        tcg_out_movi (s, TCG_TYPE_I32, TCG_REG_R3, args[0]);
1293 932a6909 bellard
        tcg_out_b (s, 0, (tcg_target_long) tb_ret_addr);
1294 2662e13f bellard
        break;
1295 2662e13f bellard
    case INDEX_op_goto_tb:
1296 2662e13f bellard
        if (s->tb_jmp_offset) {
1297 2662e13f bellard
            /* direct jump method */
1298 932a6909 bellard
1299 2662e13f bellard
            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
1300 0a878c47 malc
            s->code_ptr += 16;
1301 932a6909 bellard
        }
1302 932a6909 bellard
        else {
1303 2662e13f bellard
            tcg_abort ();
1304 2662e13f bellard
        }
1305 2662e13f bellard
        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1306 2662e13f bellard
        break;
1307 2662e13f bellard
    case INDEX_op_br:
1308 2662e13f bellard
        {
1309 2662e13f bellard
            TCGLabel *l = &s->labels[args[0]];
1310 2662e13f bellard
1311 2662e13f bellard
            if (l->has_value) {
1312 932a6909 bellard
                tcg_out_b (s, 0, l->u.value);
1313 2662e13f bellard
            }
1314 2662e13f bellard
            else {
1315 0a878c47 malc
                uint32_t val = *(uint32_t *) s->code_ptr;
1316 0a878c47 malc
1317 0a878c47 malc
                /* Thanks to Andrzej Zaborowski */
1318 0a878c47 malc
                tcg_out32 (s, B | (val & 0x3fffffc));
1319 2662e13f bellard
                tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL24, args[0], 0);
1320 2662e13f bellard
            }
1321 2662e13f bellard
        }
1322 2662e13f bellard
        break;
1323 2662e13f bellard
    case INDEX_op_call:
1324 b29fe3ed malc
        tcg_out_call (s, args[0], const_args[0]);
1325 2662e13f bellard
        break;
1326 2662e13f bellard
    case INDEX_op_jmp:
1327 2662e13f bellard
        if (const_args[0]) {
1328 932a6909 bellard
            tcg_out_b (s, 0, args[0]);
1329 2662e13f bellard
        }
1330 2662e13f bellard
        else {
1331 2662e13f bellard
            tcg_out32 (s, MTSPR | RS (args[0]) | CTR);
1332 2662e13f bellard
            tcg_out32 (s, BCCTR | BO_ALWAYS);
1333 2662e13f bellard
        }
1334 2662e13f bellard
        break;
1335 2662e13f bellard
    case INDEX_op_movi_i32:
1336 2662e13f bellard
        tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
1337 2662e13f bellard
        break;
1338 2662e13f bellard
    case INDEX_op_ld8u_i32:
1339 2662e13f bellard
        tcg_out_ldst (s, args[0], args[1], args[2], LBZ, LBZX);
1340 2662e13f bellard
        break;
1341 2662e13f bellard
    case INDEX_op_ld8s_i32:
1342 2662e13f bellard
        tcg_out_ldst (s, args[0], args[1], args[2], LBZ, LBZX);
1343 2662e13f bellard
        tcg_out32 (s, EXTSB | RS (args[0]) | RA (args[0]));
1344 2662e13f bellard
        break;
1345 2662e13f bellard
    case INDEX_op_ld16u_i32:
1346 2662e13f bellard
        tcg_out_ldst (s, args[0], args[1], args[2], LHZ, LHZX);
1347 2662e13f bellard
        break;
1348 2662e13f bellard
    case INDEX_op_ld16s_i32:
1349 2662e13f bellard
        tcg_out_ldst (s, args[0], args[1], args[2], LHA, LHAX);
1350 2662e13f bellard
        break;
1351 2662e13f bellard
    case INDEX_op_ld_i32:
1352 2662e13f bellard
        tcg_out_ldst (s, args[0], args[1], args[2], LWZ, LWZX);
1353 2662e13f bellard
        break;
1354 2662e13f bellard
    case INDEX_op_st8_i32:
1355 2662e13f bellard
        tcg_out_ldst (s, args[0], args[1], args[2], STB, STBX);
1356 2662e13f bellard
        break;
1357 2662e13f bellard
    case INDEX_op_st16_i32:
1358 2662e13f bellard
        tcg_out_ldst (s, args[0], args[1], args[2], STH, STHX);
1359 2662e13f bellard
        break;
1360 2662e13f bellard
    case INDEX_op_st_i32:
1361 2662e13f bellard
        tcg_out_ldst (s, args[0], args[1], args[2], STW, STWX);
1362 2662e13f bellard
        break;
1363 2662e13f bellard
1364 2662e13f bellard
    case INDEX_op_add_i32:
1365 2662e13f bellard
        if (const_args[2])
1366 2662e13f bellard
            ppc_addi (s, args[0], args[1], args[2]);
1367 2662e13f bellard
        else
1368 2662e13f bellard
            tcg_out32 (s, ADD | TAB (args[0], args[1], args[2]));
1369 2662e13f bellard
        break;
1370 2662e13f bellard
    case INDEX_op_sub_i32:
1371 2662e13f bellard
        if (const_args[2])
1372 2662e13f bellard
            ppc_addi (s, args[0], args[1], -args[2]);
1373 2662e13f bellard
        else
1374 2662e13f bellard
            tcg_out32 (s, SUBF | TAB (args[0], args[2], args[1]));
1375 2662e13f bellard
        break;
1376 2662e13f bellard
1377 2662e13f bellard
    case INDEX_op_and_i32:
1378 2662e13f bellard
        if (const_args[2]) {
1379 c45851c4 malc
            uint32_t c;
1380 c45851c4 malc
1381 c45851c4 malc
            c = args[2];
1382 c45851c4 malc
1383 c45851c4 malc
            if (!c) {
1384 c45851c4 malc
                tcg_out_movi (s, TCG_TYPE_I32, args[0], 0);
1385 c45851c4 malc
                break;
1386 c45851c4 malc
            }
1387 c45851c4 malc
#ifdef __PPU__
1388 c45851c4 malc
            uint32_t t, n;
1389 c45851c4 malc
            int mb, me;
1390 c45851c4 malc
1391 c45851c4 malc
            n = c ^ -(c & 1);
1392 c45851c4 malc
            t = n + (n & -n);
1393 c45851c4 malc
1394 c45851c4 malc
            if ((t & (t - 1)) == 0) {
1395 c45851c4 malc
                int lzc, tzc;
1396 c45851c4 malc
1397 c45851c4 malc
                if ((c & 0x80000001) == 0x80000001) {
1398 c45851c4 malc
                    lzc = clz32 (n);
1399 c45851c4 malc
                    tzc = ctz32 (n);
1400 c45851c4 malc
1401 c45851c4 malc
                    mb = 32 - tzc;
1402 c45851c4 malc
                    me = lzc - 1;
1403 c45851c4 malc
                }
1404 c45851c4 malc
                else {
1405 c45851c4 malc
                    lzc = clz32 (c);
1406 c45851c4 malc
                    tzc = ctz32 (c);
1407 c45851c4 malc
1408 c45851c4 malc
                    mb = lzc;
1409 c45851c4 malc
                    me = 31 - tzc;
1410 c45851c4 malc
                }
1411 c45851c4 malc
1412 c45851c4 malc
                tcg_out32 (s, (RLWINM
1413 c45851c4 malc
                               | RA (args[0])
1414 c45851c4 malc
                               | RS (args[1])
1415 c45851c4 malc
                               | SH (0)
1416 c45851c4 malc
                               | MB (mb)
1417 c45851c4 malc
                               | ME (me)
1418 c45851c4 malc
                               )
1419 c45851c4 malc
                    );
1420 c45851c4 malc
            }
1421 c45851c4 malc
            else
1422 c45851c4 malc
#endif /* !__PPU__ */
1423 c45851c4 malc
            {
1424 c45851c4 malc
                if ((c & 0xffff) == c)
1425 c45851c4 malc
                    tcg_out32 (s, ANDI | RS (args[1]) | RA (args[0]) | c);
1426 c45851c4 malc
                else if ((c & 0xffff0000) == c)
1427 c45851c4 malc
                    tcg_out32 (s, ANDIS | RS (args[1]) | RA (args[0])
1428 c45851c4 malc
                               | ((c >> 16) & 0xffff));
1429 c45851c4 malc
                else {
1430 c45851c4 malc
                    tcg_out_movi (s, TCG_TYPE_I32, 0, c);
1431 c45851c4 malc
                    tcg_out32 (s, AND | SAB (args[1], args[0], 0));
1432 c45851c4 malc
                }
1433 2662e13f bellard
            }
1434 2662e13f bellard
        }
1435 2662e13f bellard
        else
1436 2662e13f bellard
            tcg_out32 (s, AND | SAB (args[1], args[0], args[2]));
1437 2662e13f bellard
        break;
1438 2662e13f bellard
    case INDEX_op_or_i32:
1439 2662e13f bellard
        if (const_args[2]) {
1440 000a2d86 malc
            if (args[2] & 0xffff) {
1441 000a2d86 malc
                tcg_out32 (s, ORI | RS (args[1])  | RA (args[0])
1442 000a2d86 malc
                           | (args[2] & 0xffff));
1443 000a2d86 malc
                if (args[2] >> 16)
1444 000a2d86 malc
                    tcg_out32 (s, ORIS | RS (args[0])  | RA (args[0])
1445 2662e13f bellard
                               | ((args[2] >> 16) & 0xffff));
1446 2662e13f bellard
            }
1447 2662e13f bellard
            else {
1448 000a2d86 malc
                tcg_out32 (s, ORIS | RS (args[1])  | RA (args[0])
1449 000a2d86 malc
                           | ((args[2] >> 16) & 0xffff));
1450 2662e13f bellard
            }
1451 2662e13f bellard
        }
1452 2662e13f bellard
        else
1453 2662e13f bellard
            tcg_out32 (s, OR | SAB (args[1], args[0], args[2]));
1454 2662e13f bellard
        break;
1455 2662e13f bellard
    case INDEX_op_xor_i32:
1456 2662e13f bellard
        if (const_args[2]) {
1457 000a2d86 malc
            if ((args[2] & 0xffff) == args[2])
1458 000a2d86 malc
                tcg_out32 (s, XORI | RS (args[1])  | RA (args[0])
1459 000a2d86 malc
                           | (args[2] & 0xffff));
1460 000a2d86 malc
            else if ((args[2] & 0xffff0000) == args[2])
1461 000a2d86 malc
                tcg_out32 (s, XORIS | RS (args[1])  | RA (args[0])
1462 000a2d86 malc
                           | ((args[2] >> 16) & 0xffff));
1463 2662e13f bellard
            else {
1464 000a2d86 malc
                tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]);
1465 000a2d86 malc
                tcg_out32 (s, XOR | SAB (args[1], args[0], 0));
1466 2662e13f bellard
            }
1467 2662e13f bellard
        }
1468 2662e13f bellard
        else
1469 2662e13f bellard
            tcg_out32 (s, XOR | SAB (args[1], args[0], args[2]));
1470 2662e13f bellard
        break;
1471 2662e13f bellard
1472 2662e13f bellard
    case INDEX_op_mul_i32:
1473 2662e13f bellard
        if (const_args[2]) {
1474 2662e13f bellard
            if (args[2] == (int16_t) args[2])
1475 2662e13f bellard
                tcg_out32 (s, MULLI | RT (args[0]) | RA (args[1])
1476 2662e13f bellard
                           | (args[2] & 0xffff));
1477 2662e13f bellard
            else {
1478 2662e13f bellard
                tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]);
1479 2662e13f bellard
                tcg_out32 (s, MULLW | TAB (args[0], args[1], 0));
1480 2662e13f bellard
            }
1481 2662e13f bellard
        }
1482 2662e13f bellard
        else
1483 2662e13f bellard
            tcg_out32 (s, MULLW | TAB (args[0], args[1], args[2]));
1484 2662e13f bellard
        break;
1485 77b73de6 malc
1486 77b73de6 malc
    case INDEX_op_div_i32:
1487 77b73de6 malc
        tcg_out32 (s, DIVW | TAB (args[0], args[1], args[2]));
1488 77b73de6 malc
        break;
1489 77b73de6 malc
1490 77b73de6 malc
    case INDEX_op_divu_i32:
1491 77b73de6 malc
        tcg_out32 (s, DIVWU | TAB (args[0], args[1], args[2]));
1492 77b73de6 malc
        break;
1493 77b73de6 malc
1494 77b73de6 malc
    case INDEX_op_rem_i32:
1495 77b73de6 malc
        tcg_out32 (s, DIVW | TAB (0, args[1], args[2]));
1496 77b73de6 malc
        tcg_out32 (s, MULLW | TAB (0, 0, args[2]));
1497 77b73de6 malc
        tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
1498 77b73de6 malc
        break;
1499 77b73de6 malc
1500 77b73de6 malc
    case INDEX_op_remu_i32:
1501 77b73de6 malc
        tcg_out32 (s, DIVWU | TAB (0, args[1], args[2]));
1502 77b73de6 malc
        tcg_out32 (s, MULLW | TAB (0, 0, args[2]));
1503 77b73de6 malc
        tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
1504 77b73de6 malc
        break;
1505 77b73de6 malc
1506 2662e13f bellard
    case INDEX_op_mulu2_i32:
1507 2662e13f bellard
        if (args[0] == args[2] || args[0] == args[3]) {
1508 2662e13f bellard
            tcg_out32 (s, MULLW | TAB (0, args[2], args[3]));
1509 2662e13f bellard
            tcg_out32 (s, MULHWU | TAB (args[1], args[2], args[3]));
1510 2662e13f bellard
            tcg_out_mov (s, args[0], 0);
1511 2662e13f bellard
        }
1512 2662e13f bellard
        else {
1513 2662e13f bellard
            tcg_out32 (s, MULLW | TAB (args[0], args[2], args[3]));
1514 2662e13f bellard
            tcg_out32 (s, MULHWU | TAB (args[1], args[2], args[3]));
1515 2662e13f bellard
        }
1516 2662e13f bellard
        break;
1517 2662e13f bellard
1518 2662e13f bellard
    case INDEX_op_shl_i32:
1519 2662e13f bellard
        if (const_args[2]) {
1520 000a2d86 malc
            tcg_out32 (s, (RLWINM
1521 000a2d86 malc
                           | RA (args[0])
1522 000a2d86 malc
                           | RS (args[1])
1523 000a2d86 malc
                           | SH (args[2])
1524 000a2d86 malc
                           | MB (0)
1525 000a2d86 malc
                           | ME (31 - args[2])
1526 000a2d86 malc
                           )
1527 000a2d86 malc
                );
1528 2662e13f bellard
        }
1529 2662e13f bellard
        else
1530 2662e13f bellard
            tcg_out32 (s, SLW | SAB (args[1], args[0], args[2]));
1531 2662e13f bellard
        break;
1532 2662e13f bellard
    case INDEX_op_shr_i32:
1533 2662e13f bellard
        if (const_args[2]) {
1534 000a2d86 malc
            tcg_out32 (s, (RLWINM
1535 000a2d86 malc
                           | RA (args[0])
1536 000a2d86 malc
                           | RS (args[1])
1537 000a2d86 malc
                           | SH (32 - args[2])
1538 000a2d86 malc
                           | MB (args[2])
1539 000a2d86 malc
                           | ME (31)
1540 000a2d86 malc
                           )
1541 000a2d86 malc
                );
1542 2662e13f bellard
        }
1543 2662e13f bellard
        else
1544 2662e13f bellard
            tcg_out32 (s, SRW | SAB (args[1], args[0], args[2]));
1545 2662e13f bellard
        break;
1546 2662e13f bellard
    case INDEX_op_sar_i32:
1547 2662e13f bellard
        if (const_args[2])
1548 2662e13f bellard
            tcg_out32 (s, SRAWI | RS (args[1]) | RA (args[0]) | SH (args[2]));
1549 2662e13f bellard
        else
1550 2662e13f bellard
            tcg_out32 (s, SRAW | SAB (args[1], args[0], args[2]));
1551 2662e13f bellard
        break;
1552 2662e13f bellard
1553 2662e13f bellard
    case INDEX_op_add2_i32:
1554 2662e13f bellard
        if (args[0] == args[3] || args[0] == args[5]) {
1555 2662e13f bellard
            tcg_out32 (s, ADDC | TAB (0, args[2], args[4]));
1556 2662e13f bellard
            tcg_out32 (s, ADDE | TAB (args[1], args[3], args[5]));
1557 2662e13f bellard
            tcg_out_mov (s, args[0], 0);
1558 2662e13f bellard
        }
1559 2662e13f bellard
        else {
1560 2662e13f bellard
            tcg_out32 (s, ADDC | TAB (args[0], args[2], args[4]));
1561 2662e13f bellard
            tcg_out32 (s, ADDE | TAB (args[1], args[3], args[5]));
1562 2662e13f bellard
        }
1563 2662e13f bellard
        break;
1564 2662e13f bellard
    case INDEX_op_sub2_i32:
1565 2662e13f bellard
        if (args[0] == args[3] || args[0] == args[5]) {
1566 2662e13f bellard
            tcg_out32 (s, SUBFC | TAB (0, args[4], args[2]));
1567 2662e13f bellard
            tcg_out32 (s, SUBFE | TAB (args[1], args[5], args[3]));
1568 2662e13f bellard
            tcg_out_mov (s, args[0], 0);
1569 2662e13f bellard
        }
1570 2662e13f bellard
        else {
1571 2662e13f bellard
            tcg_out32 (s, SUBFC | TAB (args[0], args[4], args[2]));
1572 2662e13f bellard
            tcg_out32 (s, SUBFE | TAB (args[1], args[5], args[3]));
1573 2662e13f bellard
        }
1574 2662e13f bellard
        break;
1575 2662e13f bellard
1576 2662e13f bellard
    case INDEX_op_brcond_i32:
1577 2662e13f bellard
        /*
1578 2662e13f bellard
          args[0] = r0
1579 2662e13f bellard
          args[1] = r1
1580 2662e13f bellard
          args[2] = cond
1581 2662e13f bellard
          args[3] = r1 is const
1582 2662e13f bellard
          args[4] = label_index
1583 2662e13f bellard
        */
1584 2662e13f bellard
        tcg_out_brcond (s, args[2], args[0], args[1], const_args[1], args[3]);
1585 2662e13f bellard
        break;
1586 2662e13f bellard
    case INDEX_op_brcond2_i32:
1587 2662e13f bellard
        tcg_out_brcond2(s, args, const_args);
1588 2662e13f bellard
        break;
1589 2662e13f bellard
1590 2662e13f bellard
    case INDEX_op_neg_i32:
1591 2662e13f bellard
        tcg_out32 (s, NEG | RT (args[0]) | RA (args[1]));
1592 2662e13f bellard
        break;
1593 2662e13f bellard
1594 2662e13f bellard
    case INDEX_op_qemu_ld8u:
1595 2662e13f bellard
        tcg_out_qemu_ld(s, args, 0);
1596 2662e13f bellard
        break;
1597 2662e13f bellard
    case INDEX_op_qemu_ld8s:
1598 2662e13f bellard
        tcg_out_qemu_ld(s, args, 0 | 4);
1599 2662e13f bellard
        break;
1600 2662e13f bellard
    case INDEX_op_qemu_ld16u:
1601 2662e13f bellard
        tcg_out_qemu_ld(s, args, 1);
1602 2662e13f bellard
        break;
1603 2662e13f bellard
    case INDEX_op_qemu_ld16s:
1604 2662e13f bellard
        tcg_out_qemu_ld(s, args, 1 | 4);
1605 2662e13f bellard
        break;
1606 2662e13f bellard
    case INDEX_op_qemu_ld32u:
1607 2662e13f bellard
        tcg_out_qemu_ld(s, args, 2);
1608 2662e13f bellard
        break;
1609 2662e13f bellard
    case INDEX_op_qemu_ld64:
1610 2662e13f bellard
        tcg_out_qemu_ld(s, args, 3);
1611 2662e13f bellard
        break;
1612 2662e13f bellard
    case INDEX_op_qemu_st8:
1613 2662e13f bellard
        tcg_out_qemu_st(s, args, 0);
1614 2662e13f bellard
        break;
1615 2662e13f bellard
    case INDEX_op_qemu_st16:
1616 2662e13f bellard
        tcg_out_qemu_st(s, args, 1);
1617 2662e13f bellard
        break;
1618 2662e13f bellard
    case INDEX_op_qemu_st32:
1619 2662e13f bellard
        tcg_out_qemu_st(s, args, 2);
1620 2662e13f bellard
        break;
1621 2662e13f bellard
    case INDEX_op_qemu_st64:
1622 2662e13f bellard
        tcg_out_qemu_st(s, args, 3);
1623 2662e13f bellard
        break;
1624 2662e13f bellard
1625 e46b9681 malc
    case INDEX_op_ext8s_i32:
1626 e46b9681 malc
        tcg_out32 (s, EXTSB | RS (args[1]) | RA (args[0]));
1627 e46b9681 malc
        break;
1628 e46b9681 malc
    case INDEX_op_ext16s_i32:
1629 e46b9681 malc
        tcg_out32 (s, EXTSH | RS (args[1]) | RA (args[0]));
1630 e46b9681 malc
        break;
1631 e46b9681 malc
1632 b0809bf7 malc
    case INDEX_op_setcond_i32:
1633 b0809bf7 malc
        tcg_out_setcond (s, args[3], args[0], args[1], args[2], const_args[2]);
1634 b0809bf7 malc
        break;
1635 b0809bf7 malc
    case INDEX_op_setcond2_i32:
1636 b0809bf7 malc
        tcg_out_setcond2 (s, args, const_args);
1637 b0809bf7 malc
        break;
1638 b0809bf7 malc
1639 2662e13f bellard
    default:
1640 2662e13f bellard
        tcg_dump_ops (s, stderr);
1641 2662e13f bellard
        tcg_abort ();
1642 2662e13f bellard
    }
1643 2662e13f bellard
}
1644 2662e13f bellard
1645 2662e13f bellard
static const TCGTargetOpDef ppc_op_defs[] = {
1646 2662e13f bellard
    { INDEX_op_exit_tb, { } },
1647 2662e13f bellard
    { INDEX_op_goto_tb, { } },
1648 932a6909 bellard
    { INDEX_op_call, { "ri" } },
1649 932a6909 bellard
    { INDEX_op_jmp, { "ri" } },
1650 2662e13f bellard
    { INDEX_op_br, { } },
1651 2662e13f bellard
1652 2662e13f bellard
    { INDEX_op_mov_i32, { "r", "r" } },
1653 2662e13f bellard
    { INDEX_op_movi_i32, { "r" } },
1654 2662e13f bellard
    { INDEX_op_ld8u_i32, { "r", "r" } },
1655 2662e13f bellard
    { INDEX_op_ld8s_i32, { "r", "r" } },
1656 2662e13f bellard
    { INDEX_op_ld16u_i32, { "r", "r" } },
1657 2662e13f bellard
    { INDEX_op_ld16s_i32, { "r", "r" } },
1658 2662e13f bellard
    { INDEX_op_ld_i32, { "r", "r" } },
1659 2662e13f bellard
    { INDEX_op_st8_i32, { "r", "r" } },
1660 2662e13f bellard
    { INDEX_op_st16_i32, { "r", "r" } },
1661 2662e13f bellard
    { INDEX_op_st_i32, { "r", "r" } },
1662 2662e13f bellard
1663 2662e13f bellard
    { INDEX_op_add_i32, { "r", "r", "ri" } },
1664 2662e13f bellard
    { INDEX_op_mul_i32, { "r", "r", "ri" } },
1665 77b73de6 malc
    { INDEX_op_div_i32, { "r", "r", "r" } },
1666 77b73de6 malc
    { INDEX_op_divu_i32, { "r", "r", "r" } },
1667 77b73de6 malc
    { INDEX_op_rem_i32, { "r", "r", "r" } },
1668 77b73de6 malc
    { INDEX_op_remu_i32, { "r", "r", "r" } },
1669 2662e13f bellard
    { INDEX_op_mulu2_i32, { "r", "r", "r", "r" } },
1670 2662e13f bellard
    { INDEX_op_sub_i32, { "r", "r", "ri" } },
1671 2662e13f bellard
    { INDEX_op_and_i32, { "r", "r", "ri" } },
1672 2662e13f bellard
    { INDEX_op_or_i32, { "r", "r", "ri" } },
1673 2662e13f bellard
    { INDEX_op_xor_i32, { "r", "r", "ri" } },
1674 2662e13f bellard
1675 2662e13f bellard
    { INDEX_op_shl_i32, { "r", "r", "ri" } },
1676 2662e13f bellard
    { INDEX_op_shr_i32, { "r", "r", "ri" } },
1677 2662e13f bellard
    { INDEX_op_sar_i32, { "r", "r", "ri" } },
1678 2662e13f bellard
1679 2662e13f bellard
    { INDEX_op_brcond_i32, { "r", "ri" } },
1680 2662e13f bellard
1681 2662e13f bellard
    { INDEX_op_add2_i32, { "r", "r", "r", "r", "r", "r" } },
1682 2662e13f bellard
    { INDEX_op_sub2_i32, { "r", "r", "r", "r", "r", "r" } },
1683 2662e13f bellard
    { INDEX_op_brcond2_i32, { "r", "r", "r", "r" } },
1684 2662e13f bellard
1685 2662e13f bellard
    { INDEX_op_neg_i32, { "r", "r" } },
1686 2662e13f bellard
1687 b0809bf7 malc
    { INDEX_op_setcond_i32, { "r", "r", "ri" } },
1688 b0809bf7 malc
    { INDEX_op_setcond2_i32, { "r", "r", "r", "ri", "ri" } },
1689 b0809bf7 malc
1690 2662e13f bellard
#if TARGET_LONG_BITS == 32
1691 2662e13f bellard
    { INDEX_op_qemu_ld8u, { "r", "L" } },
1692 2662e13f bellard
    { INDEX_op_qemu_ld8s, { "r", "L" } },
1693 2662e13f bellard
    { INDEX_op_qemu_ld16u, { "r", "L" } },
1694 2662e13f bellard
    { INDEX_op_qemu_ld16s, { "r", "L" } },
1695 2662e13f bellard
    { INDEX_op_qemu_ld32u, { "r", "L" } },
1696 2662e13f bellard
    { INDEX_op_qemu_ld32s, { "r", "L" } },
1697 2662e13f bellard
    { INDEX_op_qemu_ld64, { "r", "r", "L" } },
1698 2662e13f bellard
1699 2662e13f bellard
    { INDEX_op_qemu_st8, { "K", "K" } },
1700 2662e13f bellard
    { INDEX_op_qemu_st16, { "K", "K" } },
1701 2662e13f bellard
    { INDEX_op_qemu_st32, { "K", "K" } },
1702 2662e13f bellard
    { INDEX_op_qemu_st64, { "M", "M", "M" } },
1703 2662e13f bellard
#else
1704 2662e13f bellard
    { INDEX_op_qemu_ld8u, { "r", "L", "L" } },
1705 2662e13f bellard
    { INDEX_op_qemu_ld8s, { "r", "L", "L" } },
1706 2662e13f bellard
    { INDEX_op_qemu_ld16u, { "r", "L", "L" } },
1707 2662e13f bellard
    { INDEX_op_qemu_ld16s, { "r", "L", "L" } },
1708 2662e13f bellard
    { INDEX_op_qemu_ld32u, { "r", "L", "L" } },
1709 2662e13f bellard
    { INDEX_op_qemu_ld32s, { "r", "L", "L" } },
1710 2662e13f bellard
    { INDEX_op_qemu_ld64, { "r", "L", "L", "L" } },
1711 2662e13f bellard
1712 2662e13f bellard
    { INDEX_op_qemu_st8, { "K", "K", "K" } },
1713 2662e13f bellard
    { INDEX_op_qemu_st16, { "K", "K", "K" } },
1714 2662e13f bellard
    { INDEX_op_qemu_st32, { "K", "K", "K" } },
1715 2662e13f bellard
    { INDEX_op_qemu_st64, { "M", "M", "M", "M" } },
1716 2662e13f bellard
#endif
1717 2662e13f bellard
1718 e46b9681 malc
    { INDEX_op_ext8s_i32, { "r", "r" } },
1719 e46b9681 malc
    { INDEX_op_ext16s_i32, { "r", "r" } },
1720 e46b9681 malc
1721 2662e13f bellard
    { -1 },
1722 2662e13f bellard
};
1723 2662e13f bellard
1724 2662e13f bellard
void tcg_target_init(TCGContext *s)
1725 2662e13f bellard
{
1726 2662e13f bellard
    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
1727 2662e13f bellard
    tcg_regset_set32(tcg_target_call_clobber_regs, 0,
1728 2662e13f bellard
                     (1 << TCG_REG_R0) |
1729 6ec85236 malc
#ifdef _CALL_DARWIN
1730 f9bf2987 malc
                     (1 << TCG_REG_R2) |
1731 f9bf2987 malc
#endif
1732 2662e13f bellard
                     (1 << TCG_REG_R3) |
1733 2662e13f bellard
                     (1 << TCG_REG_R4) |
1734 2662e13f bellard
                     (1 << TCG_REG_R5) |
1735 2662e13f bellard
                     (1 << TCG_REG_R6) |
1736 2662e13f bellard
                     (1 << TCG_REG_R7) |
1737 2662e13f bellard
                     (1 << TCG_REG_R8) |
1738 2662e13f bellard
                     (1 << TCG_REG_R9) |
1739 2662e13f bellard
                     (1 << TCG_REG_R10) |
1740 2662e13f bellard
                     (1 << TCG_REG_R11) |
1741 2662e13f bellard
                     (1 << TCG_REG_R12)
1742 2662e13f bellard
        );
1743 2662e13f bellard
1744 2662e13f bellard
    tcg_regset_clear(s->reserved_regs);
1745 2662e13f bellard
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);
1746 2662e13f bellard
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R1);
1747 6ec85236 malc
#ifndef _CALL_DARWIN
1748 2662e13f bellard
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R2);
1749 f9bf2987 malc
#endif
1750 6ec85236 malc
#ifdef _CALL_SYSV
1751 5db3ee79 malc
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R13);
1752 5db3ee79 malc
#endif
1753 f6548c0a malc
#ifdef CONFIG_USE_GUEST_BASE
1754 f6548c0a malc
    tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
1755 f6548c0a malc
#endif
1756 2662e13f bellard
1757 2662e13f bellard
    tcg_add_target_add_op_defs(ppc_op_defs);
1758 2662e13f bellard
}