Statistics
| Branch: | Revision:

root / tcg / ppc / tcg-target.c @ 8d625cf1

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