Statistics
| Branch: | Revision:

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

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