Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (52.8 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 2662e13f bellard
static void tcg_out_mov(TCGContext *s, 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 2662e13f bellard
    tcg_out_mov (s, 3, addr_reg);
595 2662e13f bellard
    tcg_out_movi (s, TCG_TYPE_I32, 4, mem_index);
596 2662e13f bellard
#else
597 2662e13f bellard
    tcg_out_mov (s, 3, addr_reg2);
598 2662e13f bellard
    tcg_out_mov (s, 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 2662e13f bellard
            tcg_out_mov (s, 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 2662e13f bellard
                tcg_out_mov (s, 0, 4);
620 2662e13f bellard
                tcg_out_mov (s, 4, 3);
621 2662e13f bellard
                tcg_out_mov (s, 3, 0);
622 2662e13f bellard
            }
623 2662e13f bellard
            else {
624 2662e13f bellard
                tcg_out_mov (s, data_reg2, 3);
625 2662e13f bellard
                tcg_out_mov (s, 3, 4);
626 2662e13f bellard
            }
627 2662e13f bellard
        }
628 2662e13f bellard
        else {
629 2662e13f bellard
            if (data_reg != 4) tcg_out_mov (s, data_reg, 4);
630 2662e13f bellard
            if (data_reg2 != 3) tcg_out_mov (s, 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 2662e13f bellard
                tcg_out_mov (s, 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 2662e13f bellard
    tcg_out_mov (s, 3, addr_reg);
791 2662e13f bellard
    ir = 4;
792 2662e13f bellard
#else
793 2662e13f bellard
    tcg_out_mov (s, 3, addr_reg2);
794 2662e13f bellard
    tcg_out_mov (s, 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 2662e13f bellard
        tcg_out_mov (s, 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 f9bf2987 malc
        tcg_out_mov (s, ir++, data_reg2);
827 f9bf2987 malc
        tcg_out_mov (s, 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 2662e13f bellard
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 f6548c0a malc
    tcg_out_movi (s, TCG_TYPE_I32, TCG_GUEST_BASE_REG, GUEST_BASE);
937 f6548c0a malc
#endif
938 f6548c0a malc
939 2662e13f bellard
    tcg_out32 (s, MTSPR | RS (3) | CTR);
940 2662e13f bellard
    tcg_out32 (s, BCCTR | BO_ALWAYS);
941 2662e13f bellard
    tb_ret_addr = s->code_ptr;
942 2662e13f bellard
943 2662e13f bellard
    for (i = 0; i < ARRAY_SIZE (tcg_target_callee_save_regs); ++i)
944 2662e13f bellard
        tcg_out32 (s, (LWZ
945 2662e13f bellard
                       | RT (tcg_target_callee_save_regs[i])
946 2662e13f bellard
                       | RA (1)
947 f9bf2987 malc
                       | (i * 4 + LINKAGE_AREA_SIZE + TCG_STATIC_CALL_ARGS_SIZE)
948 2662e13f bellard
                       )
949 2662e13f bellard
            );
950 2946898b malc
    tcg_out32 (s, LWZ | RT (0) | RA (1) | (frame_size + LR_OFFSET));
951 2662e13f bellard
    tcg_out32 (s, MTSPR | RS (0) | LR);
952 2662e13f bellard
    tcg_out32 (s, ADDI | RT (1) | RA (1) | frame_size);
953 2662e13f bellard
    tcg_out32 (s, BCLR | BO_ALWAYS);
954 2662e13f bellard
}
955 2662e13f bellard
956 2662e13f bellard
static void tcg_out_ld (TCGContext *s, TCGType type, int ret, int arg1,
957 2662e13f bellard
                        tcg_target_long arg2)
958 2662e13f bellard
{
959 2662e13f bellard
    tcg_out_ldst (s, ret, arg1, arg2, LWZ, LWZX);
960 2662e13f bellard
}
961 2662e13f bellard
962 2662e13f bellard
static void tcg_out_st (TCGContext *s, TCGType type, int arg, int arg1,
963 2662e13f bellard
                        tcg_target_long arg2)
964 2662e13f bellard
{
965 2662e13f bellard
    tcg_out_ldst (s, arg, arg1, arg2, STW, STWX);
966 2662e13f bellard
}
967 2662e13f bellard
968 2662e13f bellard
static void ppc_addi (TCGContext *s, int rt, int ra, tcg_target_long si)
969 2662e13f bellard
{
970 2662e13f bellard
    if (!si && rt == ra)
971 2662e13f bellard
        return;
972 2662e13f bellard
973 2662e13f bellard
    if (si == (int16_t) si)
974 2662e13f bellard
        tcg_out32 (s, ADDI | RT (rt) | RA (ra) | (si & 0xffff));
975 2662e13f bellard
    else {
976 2662e13f bellard
        uint16_t h = ((si >> 16) & 0xffff) + ((uint16_t) si >> 15);
977 2662e13f bellard
        tcg_out32 (s, ADDIS | RT (rt) | RA (ra) | h);
978 2662e13f bellard
        tcg_out32 (s, ADDI | RT (rt) | RA (rt) | (si & 0xffff));
979 2662e13f bellard
    }
980 2662e13f bellard
}
981 2662e13f bellard
982 2662e13f bellard
static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
983 2662e13f bellard
{
984 2662e13f bellard
    ppc_addi (s, reg, reg, val);
985 2662e13f bellard
}
986 2662e13f bellard
987 c596defd malc
static void tcg_out_cmp (TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
988 c596defd malc
                         int const_arg2, int cr)
989 2662e13f bellard
{
990 2662e13f bellard
    int imm;
991 2662e13f bellard
    uint32_t op;
992 2662e13f bellard
993 2662e13f bellard
    switch (cond) {
994 f3f478a7 bellard
    case TCG_COND_EQ:
995 f3f478a7 bellard
    case TCG_COND_NE:
996 f3f478a7 bellard
        if (const_arg2) {
997 f3f478a7 bellard
            if ((int16_t) arg2 == arg2) {
998 f3f478a7 bellard
                op = CMPI;
999 f3f478a7 bellard
                imm = 1;
1000 f3f478a7 bellard
                break;
1001 f3f478a7 bellard
            }
1002 f3f478a7 bellard
            else if ((uint16_t) arg2 == arg2) {
1003 f3f478a7 bellard
                op = CMPLI;
1004 f3f478a7 bellard
                imm = 1;
1005 f3f478a7 bellard
                break;
1006 f3f478a7 bellard
            }
1007 f3f478a7 bellard
        }
1008 f3f478a7 bellard
        op = CMPL;
1009 f3f478a7 bellard
        imm = 0;
1010 f3f478a7 bellard
        break;
1011 f3f478a7 bellard
1012 f3f478a7 bellard
    case TCG_COND_LT:
1013 f3f478a7 bellard
    case TCG_COND_GE:
1014 f3f478a7 bellard
    case TCG_COND_LE:
1015 f3f478a7 bellard
    case TCG_COND_GT:
1016 f3f478a7 bellard
        if (const_arg2) {
1017 f3f478a7 bellard
            if ((int16_t) arg2 == arg2) {
1018 f3f478a7 bellard
                op = CMPI;
1019 f3f478a7 bellard
                imm = 1;
1020 f3f478a7 bellard
                break;
1021 f3f478a7 bellard
            }
1022 f3f478a7 bellard
        }
1023 f3f478a7 bellard
        op = CMP;
1024 f3f478a7 bellard
        imm = 0;
1025 f3f478a7 bellard
        break;
1026 f3f478a7 bellard
1027 f3f478a7 bellard
    case TCG_COND_LTU:
1028 f3f478a7 bellard
    case TCG_COND_GEU:
1029 f3f478a7 bellard
    case TCG_COND_LEU:
1030 f3f478a7 bellard
    case TCG_COND_GTU:
1031 f3f478a7 bellard
        if (const_arg2) {
1032 f3f478a7 bellard
            if ((uint16_t) arg2 == arg2) {
1033 f3f478a7 bellard
                op = CMPLI;
1034 f3f478a7 bellard
                imm = 1;
1035 f3f478a7 bellard
                break;
1036 f3f478a7 bellard
            }
1037 f3f478a7 bellard
        }
1038 f3f478a7 bellard
        op = CMPL;
1039 f3f478a7 bellard
        imm = 0;
1040 f3f478a7 bellard
        break;
1041 f3f478a7 bellard
1042 2662e13f bellard
    default:
1043 2662e13f bellard
        tcg_abort ();
1044 2662e13f bellard
    }
1045 c596defd malc
    op |= BF (cr);
1046 2662e13f bellard
1047 2662e13f bellard
    if (imm)
1048 2662e13f bellard
        tcg_out32 (s, op | RA (arg1) | (arg2 & 0xffff));
1049 2662e13f bellard
    else {
1050 2662e13f bellard
        if (const_arg2) {
1051 2662e13f bellard
            tcg_out_movi (s, TCG_TYPE_I32, 0, arg2);
1052 2662e13f bellard
            tcg_out32 (s, op | RA (arg1) | RB (0));
1053 2662e13f bellard
        }
1054 2662e13f bellard
        else
1055 2662e13f bellard
            tcg_out32 (s, op | RA (arg1) | RB (arg2));
1056 2662e13f bellard
    }
1057 2662e13f bellard
1058 c596defd malc
}
1059 c596defd malc
1060 c596defd malc
static void tcg_out_bc (TCGContext *s, int bc, int label_index)
1061 c596defd malc
{
1062 c596defd malc
    TCGLabel *l = &s->labels[label_index];
1063 c596defd malc
1064 0a878c47 malc
    if (l->has_value)
1065 c596defd malc
        tcg_out32 (s, bc | reloc_pc14_val (s->code_ptr, l->u.value));
1066 2662e13f bellard
    else {
1067 0a878c47 malc
        uint16_t val = *(uint16_t *) &s->code_ptr[2];
1068 0a878c47 malc
1069 0a878c47 malc
        /* Thanks to Andrzej Zaborowski */
1070 c596defd malc
        tcg_out32 (s, bc | (val & 0xfffc));
1071 2662e13f bellard
        tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL14, label_index, 0);
1072 2662e13f bellard
    }
1073 2662e13f bellard
}
1074 2662e13f bellard
1075 b0809bf7 malc
static void tcg_out_cr7eq_from_cond (TCGContext *s, const TCGArg *args,
1076 b0809bf7 malc
                                     const int *const_args)
1077 c596defd malc
{
1078 8a56e840 Richard Henderson
    TCGCond cond = args[4];
1079 8a56e840 Richard Henderson
    int op;
1080 c596defd malc
    struct { int bit1; int bit2; int cond2; } bits[] = {
1081 c596defd malc
        [TCG_COND_LT ] = { CR_LT, CR_LT, TCG_COND_LT  },
1082 c596defd malc
        [TCG_COND_LE ] = { CR_LT, CR_GT, TCG_COND_LT  },
1083 c596defd malc
        [TCG_COND_GT ] = { CR_GT, CR_GT, TCG_COND_GT  },
1084 c596defd malc
        [TCG_COND_GE ] = { CR_GT, CR_LT, TCG_COND_GT  },
1085 c596defd malc
        [TCG_COND_LTU] = { CR_LT, CR_LT, TCG_COND_LTU },
1086 c596defd malc
        [TCG_COND_LEU] = { CR_LT, CR_GT, TCG_COND_LTU },
1087 c596defd malc
        [TCG_COND_GTU] = { CR_GT, CR_GT, TCG_COND_GTU },
1088 c596defd malc
        [TCG_COND_GEU] = { CR_GT, CR_LT, TCG_COND_GTU },
1089 c596defd malc
    }, *b = &bits[cond];
1090 c596defd malc
1091 c596defd malc
    switch (cond) {
1092 2662e13f bellard
    case TCG_COND_EQ:
1093 2662e13f bellard
    case TCG_COND_NE:
1094 e924c485 malc
        op = (cond == TCG_COND_EQ) ? CRAND : CRNAND;
1095 e924c485 malc
        tcg_out_cmp (s, cond, args[0], args[2], const_args[2], 6);
1096 e924c485 malc
        tcg_out_cmp (s, cond, args[1], args[3], const_args[3], 7);
1097 e924c485 malc
        tcg_out32 (s, op | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, CR_EQ));
1098 2662e13f bellard
        break;
1099 2662e13f bellard
    case TCG_COND_LT:
1100 2662e13f bellard
    case TCG_COND_LE:
1101 2662e13f bellard
    case TCG_COND_GT:
1102 2662e13f bellard
    case TCG_COND_GE:
1103 2662e13f bellard
    case TCG_COND_LTU:
1104 2662e13f bellard
    case TCG_COND_LEU:
1105 2662e13f bellard
    case TCG_COND_GTU:
1106 2662e13f bellard
    case TCG_COND_GEU:
1107 c596defd malc
        op = (b->bit1 != b->bit2) ? CRANDC : CRAND;
1108 c596defd malc
        tcg_out_cmp (s, b->cond2, args[1], args[3], const_args[3], 5);
1109 c596defd malc
        tcg_out_cmp (s, TCG_COND_EQ, args[1], args[3], const_args[3], 6);
1110 efe72c8d malc
        tcg_out_cmp (s, tcg_unsigned_cond (cond), args[0], args[2],
1111 efe72c8d malc
                     const_args[2], 7);
1112 c596defd malc
        tcg_out32 (s, op | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, b->bit2));
1113 c596defd malc
        tcg_out32 (s, CROR | BT (7, CR_EQ) | BA (5, b->bit1) | BB (7, CR_EQ));
1114 2662e13f bellard
        break;
1115 2662e13f bellard
    default:
1116 2662e13f bellard
        tcg_abort();
1117 2662e13f bellard
    }
1118 b0809bf7 malc
}
1119 b0809bf7 malc
1120 8a56e840 Richard Henderson
static void tcg_out_setcond (TCGContext *s, TCGCond cond, TCGArg arg0,
1121 b0809bf7 malc
                             TCGArg arg1, TCGArg arg2, int const_arg2)
1122 b0809bf7 malc
{
1123 b0809bf7 malc
    int crop, sh, arg;
1124 b0809bf7 malc
1125 b0809bf7 malc
    switch (cond) {
1126 b0809bf7 malc
    case TCG_COND_EQ:
1127 b0809bf7 malc
        if (const_arg2) {
1128 b0809bf7 malc
            if (!arg2) {
1129 b0809bf7 malc
                arg = arg1;
1130 b0809bf7 malc
            }
1131 b0809bf7 malc
            else {
1132 b0809bf7 malc
                arg = 0;
1133 b0809bf7 malc
                if ((uint16_t) arg2 == arg2) {
1134 b0809bf7 malc
                    tcg_out32 (s, XORI | RS (arg1) | RA (0) | arg2);
1135 b0809bf7 malc
                }
1136 b0809bf7 malc
                else {
1137 b0809bf7 malc
                    tcg_out_movi (s, TCG_TYPE_I32, 0, arg2);
1138 b0809bf7 malc
                    tcg_out32 (s, XOR | SAB (arg1, 0, 0));
1139 b0809bf7 malc
                }
1140 b0809bf7 malc
            }
1141 b0809bf7 malc
        }
1142 b0809bf7 malc
        else {
1143 b0809bf7 malc
            arg = 0;
1144 b0809bf7 malc
            tcg_out32 (s, XOR | SAB (arg1, 0, arg2));
1145 b0809bf7 malc
        }
1146 b0809bf7 malc
        tcg_out32 (s, CNTLZW | RS (arg) | RA (0));
1147 b0809bf7 malc
        tcg_out32 (s, (RLWINM
1148 b0809bf7 malc
                       | RA (arg0)
1149 b0809bf7 malc
                       | RS (0)
1150 b0809bf7 malc
                       | SH (27)
1151 b0809bf7 malc
                       | MB (5)
1152 b0809bf7 malc
                       | ME (31)
1153 b0809bf7 malc
                       )
1154 b0809bf7 malc
            );
1155 27a7797b malc
        break;
1156 b0809bf7 malc
1157 b0809bf7 malc
    case TCG_COND_NE:
1158 b0809bf7 malc
        if (const_arg2) {
1159 b0809bf7 malc
            if (!arg2) {
1160 b0809bf7 malc
                arg = arg1;
1161 b0809bf7 malc
            }
1162 b0809bf7 malc
            else {
1163 b0809bf7 malc
                arg = 0;
1164 b0809bf7 malc
                if ((uint16_t) arg2 == arg2) {
1165 b0809bf7 malc
                    tcg_out32 (s, XORI | RS (arg1) | RA (0) | arg2);
1166 b0809bf7 malc
                }
1167 b0809bf7 malc
                else {
1168 b0809bf7 malc
                    tcg_out_movi (s, TCG_TYPE_I32, 0, arg2);
1169 b0809bf7 malc
                    tcg_out32 (s, XOR | SAB (arg1, 0, 0));
1170 b0809bf7 malc
                }
1171 b0809bf7 malc
            }
1172 b0809bf7 malc
        }
1173 b0809bf7 malc
        else {
1174 b0809bf7 malc
            arg = 0;
1175 b0809bf7 malc
            tcg_out32 (s, XOR | SAB (arg1, 0, arg2));
1176 b0809bf7 malc
        }
1177 b0809bf7 malc
1178 b0809bf7 malc
        if (arg == arg1 && arg1 == arg0) {
1179 b0809bf7 malc
            tcg_out32 (s, ADDIC | RT (0) | RA (arg) | 0xffff);
1180 b0809bf7 malc
            tcg_out32 (s, SUBFE | TAB (arg0, 0, arg));
1181 b0809bf7 malc
        }
1182 b0809bf7 malc
        else {
1183 b0809bf7 malc
            tcg_out32 (s, ADDIC | RT (arg0) | RA (arg) | 0xffff);
1184 b0809bf7 malc
            tcg_out32 (s, SUBFE | TAB (arg0, arg0, arg));
1185 b0809bf7 malc
        }
1186 27a7797b malc
        break;
1187 27a7797b malc
1188 27a7797b malc
    case TCG_COND_GT:
1189 27a7797b malc
    case TCG_COND_GTU:
1190 27a7797b malc
        sh = 30;
1191 27a7797b malc
        crop = 0;
1192 27a7797b malc
        goto crtest;
1193 b0809bf7 malc
1194 b0809bf7 malc
    case TCG_COND_LT:
1195 27a7797b malc
    case TCG_COND_LTU:
1196 b0809bf7 malc
        sh = 29;
1197 b0809bf7 malc
        crop = 0;
1198 27a7797b malc
        goto crtest;
1199 b0809bf7 malc
1200 b0809bf7 malc
    case TCG_COND_GE:
1201 27a7797b malc
    case TCG_COND_GEU:
1202 b0809bf7 malc
        sh = 31;
1203 b0809bf7 malc
        crop = CRNOR | BT (7, CR_EQ) | BA (7, CR_LT) | BB (7, CR_LT);
1204 27a7797b malc
        goto crtest;
1205 b0809bf7 malc
1206 b0809bf7 malc
    case TCG_COND_LE:
1207 27a7797b malc
    case TCG_COND_LEU:
1208 b0809bf7 malc
        sh = 31;
1209 b0809bf7 malc
        crop = CRNOR | BT (7, CR_EQ) | BA (7, CR_GT) | BB (7, CR_GT);
1210 27a7797b malc
    crtest:
1211 27a7797b malc
        tcg_out_cmp (s, cond, arg1, arg2, const_arg2, 7);
1212 27a7797b malc
        if (crop) tcg_out32 (s, crop);
1213 27a7797b malc
        tcg_out32 (s, MFCR | RT (0));
1214 27a7797b malc
        tcg_out32 (s, (RLWINM
1215 27a7797b malc
                       | RA (arg0)
1216 27a7797b malc
                       | RS (0)
1217 27a7797b malc
                       | SH (sh)
1218 27a7797b malc
                       | MB (31)
1219 27a7797b malc
                       | ME (31)
1220 27a7797b malc
                       )
1221 27a7797b malc
            );
1222 b0809bf7 malc
        break;
1223 b0809bf7 malc
1224 b0809bf7 malc
    default:
1225 b0809bf7 malc
        tcg_abort ();
1226 b0809bf7 malc
    }
1227 b0809bf7 malc
}
1228 b0809bf7 malc
1229 b0809bf7 malc
static void tcg_out_setcond2 (TCGContext *s, const TCGArg *args,
1230 b0809bf7 malc
                              const int *const_args)
1231 b0809bf7 malc
{
1232 b0809bf7 malc
    tcg_out_cr7eq_from_cond (s, args + 1, const_args + 1);
1233 b0809bf7 malc
    tcg_out32 (s, MFCR | RT (0));
1234 b0809bf7 malc
    tcg_out32 (s, (RLWINM
1235 b0809bf7 malc
                   | RA (args[0])
1236 b0809bf7 malc
                   | RS (0)
1237 b0809bf7 malc
                   | SH (31)
1238 b0809bf7 malc
                   | MB (31)
1239 b0809bf7 malc
                   | ME (31)
1240 b0809bf7 malc
                   )
1241 b0809bf7 malc
        );
1242 b0809bf7 malc
}
1243 b0809bf7 malc
1244 8a56e840 Richard Henderson
static void tcg_out_brcond (TCGContext *s, TCGCond cond,
1245 b0809bf7 malc
                            TCGArg arg1, TCGArg arg2, int const_arg2,
1246 b0809bf7 malc
                            int label_index)
1247 b0809bf7 malc
{
1248 b0809bf7 malc
    tcg_out_cmp (s, cond, arg1, arg2, const_arg2, 7);
1249 b0809bf7 malc
    tcg_out_bc (s, tcg_to_bc[cond], label_index);
1250 b0809bf7 malc
}
1251 b0809bf7 malc
1252 b0809bf7 malc
/* XXX: we implement it at the target level to avoid having to
1253 b0809bf7 malc
   handle cross basic blocks temporaries */
1254 b0809bf7 malc
static void tcg_out_brcond2 (TCGContext *s, const TCGArg *args,
1255 b0809bf7 malc
                             const int *const_args)
1256 b0809bf7 malc
{
1257 b0809bf7 malc
    tcg_out_cr7eq_from_cond (s, args, const_args);
1258 b0809bf7 malc
    tcg_out_bc (s, (BC | BI (7, CR_EQ) | BO_COND_TRUE), args[5]);
1259 2662e13f bellard
}
1260 2662e13f bellard
1261 52781543 malc
void ppc_tb_set_jmp_target (unsigned long jmp_addr, unsigned long addr)
1262 52781543 malc
{
1263 52781543 malc
    uint32_t *ptr;
1264 52781543 malc
    long disp = addr - jmp_addr;
1265 52781543 malc
    unsigned long patch_size;
1266 52781543 malc
1267 52781543 malc
    ptr = (uint32_t *)jmp_addr;
1268 52781543 malc
1269 52781543 malc
    if ((disp << 6) >> 6 != disp) {
1270 52781543 malc
        ptr[0] = 0x3c000000 | (addr >> 16);    /* lis 0,addr@ha */
1271 52781543 malc
        ptr[1] = 0x60000000 | (addr & 0xffff); /* la  0,addr@l(0) */
1272 52781543 malc
        ptr[2] = 0x7c0903a6;                   /* mtctr 0 */
1273 52781543 malc
        ptr[3] = 0x4e800420;                   /* brctr */
1274 52781543 malc
        patch_size = 16;
1275 52781543 malc
    } else {
1276 52781543 malc
        /* patch the branch destination */
1277 52781543 malc
        if (disp != 16) {
1278 52781543 malc
            *ptr = 0x48000000 | (disp & 0x03fffffc); /* b disp */
1279 52781543 malc
            patch_size = 4;
1280 52781543 malc
        } else {
1281 52781543 malc
            ptr[0] = 0x60000000; /* nop */
1282 52781543 malc
            ptr[1] = 0x60000000;
1283 52781543 malc
            ptr[2] = 0x60000000;
1284 52781543 malc
            ptr[3] = 0x60000000;
1285 52781543 malc
            patch_size = 16;
1286 52781543 malc
        }
1287 52781543 malc
    }
1288 52781543 malc
    /* flush icache */
1289 52781543 malc
    flush_icache_range(jmp_addr, jmp_addr + patch_size);
1290 52781543 malc
}
1291 52781543 malc
1292 a9751609 Richard Henderson
static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
1293 2662e13f bellard
                       const int *const_args)
1294 2662e13f bellard
{
1295 2662e13f bellard
    switch (opc) {
1296 2662e13f bellard
    case INDEX_op_exit_tb:
1297 2662e13f bellard
        tcg_out_movi (s, TCG_TYPE_I32, TCG_REG_R3, args[0]);
1298 932a6909 bellard
        tcg_out_b (s, 0, (tcg_target_long) tb_ret_addr);
1299 2662e13f bellard
        break;
1300 2662e13f bellard
    case INDEX_op_goto_tb:
1301 2662e13f bellard
        if (s->tb_jmp_offset) {
1302 2662e13f bellard
            /* direct jump method */
1303 932a6909 bellard
1304 2662e13f bellard
            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
1305 0a878c47 malc
            s->code_ptr += 16;
1306 932a6909 bellard
        }
1307 932a6909 bellard
        else {
1308 2662e13f bellard
            tcg_abort ();
1309 2662e13f bellard
        }
1310 2662e13f bellard
        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1311 2662e13f bellard
        break;
1312 2662e13f bellard
    case INDEX_op_br:
1313 2662e13f bellard
        {
1314 2662e13f bellard
            TCGLabel *l = &s->labels[args[0]];
1315 2662e13f bellard
1316 2662e13f bellard
            if (l->has_value) {
1317 932a6909 bellard
                tcg_out_b (s, 0, l->u.value);
1318 2662e13f bellard
            }
1319 2662e13f bellard
            else {
1320 0a878c47 malc
                uint32_t val = *(uint32_t *) s->code_ptr;
1321 0a878c47 malc
1322 0a878c47 malc
                /* Thanks to Andrzej Zaborowski */
1323 0a878c47 malc
                tcg_out32 (s, B | (val & 0x3fffffc));
1324 2662e13f bellard
                tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL24, args[0], 0);
1325 2662e13f bellard
            }
1326 2662e13f bellard
        }
1327 2662e13f bellard
        break;
1328 2662e13f bellard
    case INDEX_op_call:
1329 b29fe3ed malc
        tcg_out_call (s, args[0], const_args[0]);
1330 2662e13f bellard
        break;
1331 2662e13f bellard
    case INDEX_op_jmp:
1332 2662e13f bellard
        if (const_args[0]) {
1333 932a6909 bellard
            tcg_out_b (s, 0, args[0]);
1334 2662e13f bellard
        }
1335 2662e13f bellard
        else {
1336 2662e13f bellard
            tcg_out32 (s, MTSPR | RS (args[0]) | CTR);
1337 2662e13f bellard
            tcg_out32 (s, BCCTR | BO_ALWAYS);
1338 2662e13f bellard
        }
1339 2662e13f bellard
        break;
1340 2662e13f bellard
    case INDEX_op_movi_i32:
1341 2662e13f bellard
        tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
1342 2662e13f bellard
        break;
1343 2662e13f bellard
    case INDEX_op_ld8u_i32:
1344 2662e13f bellard
        tcg_out_ldst (s, args[0], args[1], args[2], LBZ, LBZX);
1345 2662e13f bellard
        break;
1346 2662e13f bellard
    case INDEX_op_ld8s_i32:
1347 2662e13f bellard
        tcg_out_ldst (s, args[0], args[1], args[2], LBZ, LBZX);
1348 2662e13f bellard
        tcg_out32 (s, EXTSB | RS (args[0]) | RA (args[0]));
1349 2662e13f bellard
        break;
1350 2662e13f bellard
    case INDEX_op_ld16u_i32:
1351 2662e13f bellard
        tcg_out_ldst (s, args[0], args[1], args[2], LHZ, LHZX);
1352 2662e13f bellard
        break;
1353 2662e13f bellard
    case INDEX_op_ld16s_i32:
1354 2662e13f bellard
        tcg_out_ldst (s, args[0], args[1], args[2], LHA, LHAX);
1355 2662e13f bellard
        break;
1356 2662e13f bellard
    case INDEX_op_ld_i32:
1357 2662e13f bellard
        tcg_out_ldst (s, args[0], args[1], args[2], LWZ, LWZX);
1358 2662e13f bellard
        break;
1359 2662e13f bellard
    case INDEX_op_st8_i32:
1360 2662e13f bellard
        tcg_out_ldst (s, args[0], args[1], args[2], STB, STBX);
1361 2662e13f bellard
        break;
1362 2662e13f bellard
    case INDEX_op_st16_i32:
1363 2662e13f bellard
        tcg_out_ldst (s, args[0], args[1], args[2], STH, STHX);
1364 2662e13f bellard
        break;
1365 2662e13f bellard
    case INDEX_op_st_i32:
1366 2662e13f bellard
        tcg_out_ldst (s, args[0], args[1], args[2], STW, STWX);
1367 2662e13f bellard
        break;
1368 2662e13f bellard
1369 2662e13f bellard
    case INDEX_op_add_i32:
1370 2662e13f bellard
        if (const_args[2])
1371 2662e13f bellard
            ppc_addi (s, args[0], args[1], args[2]);
1372 2662e13f bellard
        else
1373 2662e13f bellard
            tcg_out32 (s, ADD | TAB (args[0], args[1], args[2]));
1374 2662e13f bellard
        break;
1375 2662e13f bellard
    case INDEX_op_sub_i32:
1376 2662e13f bellard
        if (const_args[2])
1377 2662e13f bellard
            ppc_addi (s, args[0], args[1], -args[2]);
1378 2662e13f bellard
        else
1379 2662e13f bellard
            tcg_out32 (s, SUBF | TAB (args[0], args[2], args[1]));
1380 2662e13f bellard
        break;
1381 2662e13f bellard
1382 2662e13f bellard
    case INDEX_op_and_i32:
1383 2662e13f bellard
        if (const_args[2]) {
1384 c45851c4 malc
            uint32_t c;
1385 c45851c4 malc
1386 c45851c4 malc
            c = args[2];
1387 c45851c4 malc
1388 c45851c4 malc
            if (!c) {
1389 c45851c4 malc
                tcg_out_movi (s, TCG_TYPE_I32, args[0], 0);
1390 c45851c4 malc
                break;
1391 c45851c4 malc
            }
1392 c45851c4 malc
#ifdef __PPU__
1393 c45851c4 malc
            uint32_t t, n;
1394 c45851c4 malc
            int mb, me;
1395 c45851c4 malc
1396 c45851c4 malc
            n = c ^ -(c & 1);
1397 c45851c4 malc
            t = n + (n & -n);
1398 c45851c4 malc
1399 c45851c4 malc
            if ((t & (t - 1)) == 0) {
1400 c45851c4 malc
                int lzc, tzc;
1401 c45851c4 malc
1402 c45851c4 malc
                if ((c & 0x80000001) == 0x80000001) {
1403 c45851c4 malc
                    lzc = clz32 (n);
1404 c45851c4 malc
                    tzc = ctz32 (n);
1405 c45851c4 malc
1406 c45851c4 malc
                    mb = 32 - tzc;
1407 c45851c4 malc
                    me = lzc - 1;
1408 c45851c4 malc
                }
1409 c45851c4 malc
                else {
1410 c45851c4 malc
                    lzc = clz32 (c);
1411 c45851c4 malc
                    tzc = ctz32 (c);
1412 c45851c4 malc
1413 c45851c4 malc
                    mb = lzc;
1414 c45851c4 malc
                    me = 31 - tzc;
1415 c45851c4 malc
                }
1416 c45851c4 malc
1417 c45851c4 malc
                tcg_out32 (s, (RLWINM
1418 c45851c4 malc
                               | RA (args[0])
1419 c45851c4 malc
                               | RS (args[1])
1420 c45851c4 malc
                               | SH (0)
1421 c45851c4 malc
                               | MB (mb)
1422 c45851c4 malc
                               | ME (me)
1423 c45851c4 malc
                               )
1424 c45851c4 malc
                    );
1425 c45851c4 malc
            }
1426 c45851c4 malc
            else
1427 c45851c4 malc
#endif /* !__PPU__ */
1428 c45851c4 malc
            {
1429 c45851c4 malc
                if ((c & 0xffff) == c)
1430 c45851c4 malc
                    tcg_out32 (s, ANDI | RS (args[1]) | RA (args[0]) | c);
1431 c45851c4 malc
                else if ((c & 0xffff0000) == c)
1432 c45851c4 malc
                    tcg_out32 (s, ANDIS | RS (args[1]) | RA (args[0])
1433 c45851c4 malc
                               | ((c >> 16) & 0xffff));
1434 c45851c4 malc
                else {
1435 c45851c4 malc
                    tcg_out_movi (s, TCG_TYPE_I32, 0, c);
1436 c45851c4 malc
                    tcg_out32 (s, AND | SAB (args[1], args[0], 0));
1437 c45851c4 malc
                }
1438 2662e13f bellard
            }
1439 2662e13f bellard
        }
1440 2662e13f bellard
        else
1441 2662e13f bellard
            tcg_out32 (s, AND | SAB (args[1], args[0], args[2]));
1442 2662e13f bellard
        break;
1443 2662e13f bellard
    case INDEX_op_or_i32:
1444 2662e13f bellard
        if (const_args[2]) {
1445 000a2d86 malc
            if (args[2] & 0xffff) {
1446 000a2d86 malc
                tcg_out32 (s, ORI | RS (args[1])  | RA (args[0])
1447 000a2d86 malc
                           | (args[2] & 0xffff));
1448 000a2d86 malc
                if (args[2] >> 16)
1449 000a2d86 malc
                    tcg_out32 (s, ORIS | RS (args[0])  | RA (args[0])
1450 2662e13f bellard
                               | ((args[2] >> 16) & 0xffff));
1451 2662e13f bellard
            }
1452 2662e13f bellard
            else {
1453 000a2d86 malc
                tcg_out32 (s, ORIS | RS (args[1])  | RA (args[0])
1454 000a2d86 malc
                           | ((args[2] >> 16) & 0xffff));
1455 2662e13f bellard
            }
1456 2662e13f bellard
        }
1457 2662e13f bellard
        else
1458 2662e13f bellard
            tcg_out32 (s, OR | SAB (args[1], args[0], args[2]));
1459 2662e13f bellard
        break;
1460 2662e13f bellard
    case INDEX_op_xor_i32:
1461 2662e13f bellard
        if (const_args[2]) {
1462 000a2d86 malc
            if ((args[2] & 0xffff) == args[2])
1463 000a2d86 malc
                tcg_out32 (s, XORI | RS (args[1])  | RA (args[0])
1464 000a2d86 malc
                           | (args[2] & 0xffff));
1465 000a2d86 malc
            else if ((args[2] & 0xffff0000) == args[2])
1466 000a2d86 malc
                tcg_out32 (s, XORIS | RS (args[1])  | RA (args[0])
1467 000a2d86 malc
                           | ((args[2] >> 16) & 0xffff));
1468 2662e13f bellard
            else {
1469 000a2d86 malc
                tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]);
1470 000a2d86 malc
                tcg_out32 (s, XOR | SAB (args[1], args[0], 0));
1471 2662e13f bellard
            }
1472 2662e13f bellard
        }
1473 2662e13f bellard
        else
1474 2662e13f bellard
            tcg_out32 (s, XOR | SAB (args[1], args[0], args[2]));
1475 2662e13f bellard
        break;
1476 65fe043e malc
    case INDEX_op_andc_i32:
1477 65fe043e malc
        tcg_out32 (s, ANDC | SAB (args[1], args[0], args[2]));
1478 65fe043e malc
        break;
1479 65fe043e malc
    case INDEX_op_orc_i32:
1480 65fe043e malc
        tcg_out32 (s, ORC | SAB (args[1], args[0], args[2]));
1481 65fe043e malc
        break;
1482 aa77bebd malc
    case INDEX_op_eqv_i32:
1483 aa77bebd malc
        tcg_out32 (s, EQV | SAB (args[1], args[0], args[2]));
1484 aa77bebd malc
        break;
1485 aa77bebd malc
    case INDEX_op_nand_i32:
1486 aa77bebd malc
        tcg_out32 (s, NAND | SAB (args[1], args[0], args[2]));
1487 aa77bebd malc
        break;
1488 aa77bebd malc
    case INDEX_op_nor_i32:
1489 aa77bebd malc
        tcg_out32 (s, NOR | SAB (args[1], args[0], args[2]));
1490 aa77bebd malc
        break;
1491 2662e13f bellard
1492 2662e13f bellard
    case INDEX_op_mul_i32:
1493 2662e13f bellard
        if (const_args[2]) {
1494 2662e13f bellard
            if (args[2] == (int16_t) args[2])
1495 2662e13f bellard
                tcg_out32 (s, MULLI | RT (args[0]) | RA (args[1])
1496 2662e13f bellard
                           | (args[2] & 0xffff));
1497 2662e13f bellard
            else {
1498 2662e13f bellard
                tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]);
1499 2662e13f bellard
                tcg_out32 (s, MULLW | TAB (args[0], args[1], 0));
1500 2662e13f bellard
            }
1501 2662e13f bellard
        }
1502 2662e13f bellard
        else
1503 2662e13f bellard
            tcg_out32 (s, MULLW | TAB (args[0], args[1], args[2]));
1504 2662e13f bellard
        break;
1505 77b73de6 malc
1506 77b73de6 malc
    case INDEX_op_div_i32:
1507 77b73de6 malc
        tcg_out32 (s, DIVW | TAB (args[0], args[1], args[2]));
1508 77b73de6 malc
        break;
1509 77b73de6 malc
1510 77b73de6 malc
    case INDEX_op_divu_i32:
1511 77b73de6 malc
        tcg_out32 (s, DIVWU | TAB (args[0], args[1], args[2]));
1512 77b73de6 malc
        break;
1513 77b73de6 malc
1514 77b73de6 malc
    case INDEX_op_rem_i32:
1515 77b73de6 malc
        tcg_out32 (s, DIVW | TAB (0, args[1], args[2]));
1516 77b73de6 malc
        tcg_out32 (s, MULLW | TAB (0, 0, args[2]));
1517 77b73de6 malc
        tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
1518 77b73de6 malc
        break;
1519 77b73de6 malc
1520 77b73de6 malc
    case INDEX_op_remu_i32:
1521 77b73de6 malc
        tcg_out32 (s, DIVWU | TAB (0, args[1], args[2]));
1522 77b73de6 malc
        tcg_out32 (s, MULLW | TAB (0, 0, args[2]));
1523 77b73de6 malc
        tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
1524 77b73de6 malc
        break;
1525 77b73de6 malc
1526 2662e13f bellard
    case INDEX_op_mulu2_i32:
1527 2662e13f bellard
        if (args[0] == args[2] || args[0] == args[3]) {
1528 2662e13f bellard
            tcg_out32 (s, MULLW | TAB (0, args[2], args[3]));
1529 2662e13f bellard
            tcg_out32 (s, MULHWU | TAB (args[1], args[2], args[3]));
1530 2662e13f bellard
            tcg_out_mov (s, args[0], 0);
1531 2662e13f bellard
        }
1532 2662e13f bellard
        else {
1533 2662e13f bellard
            tcg_out32 (s, MULLW | TAB (args[0], args[2], args[3]));
1534 2662e13f bellard
            tcg_out32 (s, MULHWU | TAB (args[1], args[2], args[3]));
1535 2662e13f bellard
        }
1536 2662e13f bellard
        break;
1537 2662e13f bellard
1538 2662e13f bellard
    case INDEX_op_shl_i32:
1539 2662e13f bellard
        if (const_args[2]) {
1540 000a2d86 malc
            tcg_out32 (s, (RLWINM
1541 000a2d86 malc
                           | RA (args[0])
1542 000a2d86 malc
                           | RS (args[1])
1543 000a2d86 malc
                           | SH (args[2])
1544 000a2d86 malc
                           | MB (0)
1545 000a2d86 malc
                           | ME (31 - args[2])
1546 000a2d86 malc
                           )
1547 000a2d86 malc
                );
1548 2662e13f bellard
        }
1549 2662e13f bellard
        else
1550 2662e13f bellard
            tcg_out32 (s, SLW | SAB (args[1], args[0], args[2]));
1551 2662e13f bellard
        break;
1552 2662e13f bellard
    case INDEX_op_shr_i32:
1553 2662e13f bellard
        if (const_args[2]) {
1554 000a2d86 malc
            tcg_out32 (s, (RLWINM
1555 000a2d86 malc
                           | RA (args[0])
1556 000a2d86 malc
                           | RS (args[1])
1557 000a2d86 malc
                           | SH (32 - args[2])
1558 000a2d86 malc
                           | MB (args[2])
1559 000a2d86 malc
                           | ME (31)
1560 000a2d86 malc
                           )
1561 000a2d86 malc
                );
1562 2662e13f bellard
        }
1563 2662e13f bellard
        else
1564 2662e13f bellard
            tcg_out32 (s, SRW | SAB (args[1], args[0], args[2]));
1565 2662e13f bellard
        break;
1566 2662e13f bellard
    case INDEX_op_sar_i32:
1567 2662e13f bellard
        if (const_args[2])
1568 2662e13f bellard
            tcg_out32 (s, SRAWI | RS (args[1]) | RA (args[0]) | SH (args[2]));
1569 2662e13f bellard
        else
1570 2662e13f bellard
            tcg_out32 (s, SRAW | SAB (args[1], args[0], args[2]));
1571 2662e13f bellard
        break;
1572 65fe043e malc
    case INDEX_op_rotl_i32:
1573 65fe043e malc
        {
1574 65fe043e malc
            int op = 0
1575 65fe043e malc
                | RA (args[0])
1576 65fe043e malc
                | RS (args[1])
1577 65fe043e malc
                | MB (0)
1578 65fe043e malc
                | ME (31)
1579 65fe043e malc
                | (const_args[2] ? RLWINM | SH (args[2])
1580 65fe043e malc
                                 : RLWNM | RB (args[2]))
1581 65fe043e malc
                ;
1582 65fe043e malc
            tcg_out32 (s, op);
1583 65fe043e malc
        }
1584 65fe043e malc
        break;
1585 65fe043e malc
    case INDEX_op_rotr_i32:
1586 65fe043e malc
        if (const_args[2]) {
1587 65fe043e malc
            if (!args[2]) {
1588 98b8d951 malc
                tcg_out_mov (s, args[0], args[1]);
1589 65fe043e malc
            }
1590 65fe043e malc
            else {
1591 65fe043e malc
                tcg_out32 (s, RLWINM
1592 65fe043e malc
                           | RA (args[0])
1593 65fe043e malc
                           | RS (args[1])
1594 65fe043e malc
                           | SH (32 - args[2])
1595 65fe043e malc
                           | MB (0)
1596 65fe043e malc
                           | ME (31)
1597 65fe043e malc
                    );
1598 65fe043e malc
            }
1599 65fe043e malc
        }
1600 65fe043e malc
        else {
1601 d616cf1d malc
            tcg_out32 (s, SUBFIC | RT (0) | RA (args[2]) | 32);
1602 65fe043e malc
            tcg_out32 (s, RLWNM
1603 65fe043e malc
                       | RA (args[0])
1604 65fe043e malc
                       | RS (args[1])
1605 65fe043e malc
                       | RB (0)
1606 65fe043e malc
                       | MB (0)
1607 65fe043e malc
                       | ME (31)
1608 65fe043e malc
                );
1609 65fe043e malc
        }
1610 65fe043e malc
        break;
1611 2662e13f bellard
1612 2662e13f bellard
    case INDEX_op_add2_i32:
1613 2662e13f bellard
        if (args[0] == args[3] || args[0] == args[5]) {
1614 2662e13f bellard
            tcg_out32 (s, ADDC | TAB (0, args[2], args[4]));
1615 2662e13f bellard
            tcg_out32 (s, ADDE | TAB (args[1], args[3], args[5]));
1616 2662e13f bellard
            tcg_out_mov (s, args[0], 0);
1617 2662e13f bellard
        }
1618 2662e13f bellard
        else {
1619 2662e13f bellard
            tcg_out32 (s, ADDC | TAB (args[0], args[2], args[4]));
1620 2662e13f bellard
            tcg_out32 (s, ADDE | TAB (args[1], args[3], args[5]));
1621 2662e13f bellard
        }
1622 2662e13f bellard
        break;
1623 2662e13f bellard
    case INDEX_op_sub2_i32:
1624 2662e13f bellard
        if (args[0] == args[3] || args[0] == args[5]) {
1625 2662e13f bellard
            tcg_out32 (s, SUBFC | TAB (0, args[4], args[2]));
1626 2662e13f bellard
            tcg_out32 (s, SUBFE | TAB (args[1], args[5], args[3]));
1627 2662e13f bellard
            tcg_out_mov (s, args[0], 0);
1628 2662e13f bellard
        }
1629 2662e13f bellard
        else {
1630 2662e13f bellard
            tcg_out32 (s, SUBFC | TAB (args[0], args[4], args[2]));
1631 2662e13f bellard
            tcg_out32 (s, SUBFE | TAB (args[1], args[5], args[3]));
1632 2662e13f bellard
        }
1633 2662e13f bellard
        break;
1634 2662e13f bellard
1635 2662e13f bellard
    case INDEX_op_brcond_i32:
1636 2662e13f bellard
        /*
1637 2662e13f bellard
          args[0] = r0
1638 2662e13f bellard
          args[1] = r1
1639 2662e13f bellard
          args[2] = cond
1640 2662e13f bellard
          args[3] = r1 is const
1641 2662e13f bellard
          args[4] = label_index
1642 2662e13f bellard
        */
1643 2662e13f bellard
        tcg_out_brcond (s, args[2], args[0], args[1], const_args[1], args[3]);
1644 2662e13f bellard
        break;
1645 2662e13f bellard
    case INDEX_op_brcond2_i32:
1646 2662e13f bellard
        tcg_out_brcond2(s, args, const_args);
1647 2662e13f bellard
        break;
1648 2662e13f bellard
1649 2662e13f bellard
    case INDEX_op_neg_i32:
1650 2662e13f bellard
        tcg_out32 (s, NEG | RT (args[0]) | RA (args[1]));
1651 2662e13f bellard
        break;
1652 2662e13f bellard
1653 65fe043e malc
    case INDEX_op_not_i32:
1654 36368cf0 malc
        tcg_out32 (s, NOR | SAB (args[1], args[0], args[1]));
1655 65fe043e malc
        break;
1656 65fe043e malc
1657 2662e13f bellard
    case INDEX_op_qemu_ld8u:
1658 2662e13f bellard
        tcg_out_qemu_ld(s, args, 0);
1659 2662e13f bellard
        break;
1660 2662e13f bellard
    case INDEX_op_qemu_ld8s:
1661 2662e13f bellard
        tcg_out_qemu_ld(s, args, 0 | 4);
1662 2662e13f bellard
        break;
1663 2662e13f bellard
    case INDEX_op_qemu_ld16u:
1664 2662e13f bellard
        tcg_out_qemu_ld(s, args, 1);
1665 2662e13f bellard
        break;
1666 2662e13f bellard
    case INDEX_op_qemu_ld16s:
1667 2662e13f bellard
        tcg_out_qemu_ld(s, args, 1 | 4);
1668 2662e13f bellard
        break;
1669 86feb1c8 Richard Henderson
    case INDEX_op_qemu_ld32:
1670 2662e13f bellard
        tcg_out_qemu_ld(s, args, 2);
1671 2662e13f bellard
        break;
1672 2662e13f bellard
    case INDEX_op_qemu_ld64:
1673 2662e13f bellard
        tcg_out_qemu_ld(s, args, 3);
1674 2662e13f bellard
        break;
1675 2662e13f bellard
    case INDEX_op_qemu_st8:
1676 2662e13f bellard
        tcg_out_qemu_st(s, args, 0);
1677 2662e13f bellard
        break;
1678 2662e13f bellard
    case INDEX_op_qemu_st16:
1679 2662e13f bellard
        tcg_out_qemu_st(s, args, 1);
1680 2662e13f bellard
        break;
1681 2662e13f bellard
    case INDEX_op_qemu_st32:
1682 2662e13f bellard
        tcg_out_qemu_st(s, args, 2);
1683 2662e13f bellard
        break;
1684 2662e13f bellard
    case INDEX_op_qemu_st64:
1685 2662e13f bellard
        tcg_out_qemu_st(s, args, 3);
1686 2662e13f bellard
        break;
1687 2662e13f bellard
1688 e46b9681 malc
    case INDEX_op_ext8s_i32:
1689 e46b9681 malc
        tcg_out32 (s, EXTSB | RS (args[1]) | RA (args[0]));
1690 e46b9681 malc
        break;
1691 65fe043e malc
    case INDEX_op_ext8u_i32:
1692 65fe043e malc
        tcg_out32 (s, RLWINM
1693 65fe043e malc
                   | RA (args[0])
1694 65fe043e malc
                   | RS (args[1])
1695 65fe043e malc
                   | SH (0)
1696 65fe043e malc
                   | MB (24)
1697 65fe043e malc
                   | ME (31)
1698 65fe043e malc
            );
1699 65fe043e malc
        break;
1700 e46b9681 malc
    case INDEX_op_ext16s_i32:
1701 e46b9681 malc
        tcg_out32 (s, EXTSH | RS (args[1]) | RA (args[0]));
1702 e46b9681 malc
        break;
1703 65fe043e malc
    case INDEX_op_ext16u_i32:
1704 65fe043e malc
        tcg_out32 (s, RLWINM
1705 65fe043e malc
                   | RA (args[0])
1706 65fe043e malc
                   | RS (args[1])
1707 65fe043e malc
                   | SH (0)
1708 65fe043e malc
                   | MB (16)
1709 65fe043e malc
                   | ME (31)
1710 65fe043e malc
            );
1711 65fe043e malc
        break;
1712 e46b9681 malc
1713 b0809bf7 malc
    case INDEX_op_setcond_i32:
1714 b0809bf7 malc
        tcg_out_setcond (s, args[3], args[0], args[1], args[2], const_args[2]);
1715 b0809bf7 malc
        break;
1716 b0809bf7 malc
    case INDEX_op_setcond2_i32:
1717 b0809bf7 malc
        tcg_out_setcond2 (s, args, const_args);
1718 b0809bf7 malc
        break;
1719 b0809bf7 malc
1720 a884dcb8 malc
    case INDEX_op_bswap16_i32:
1721 a884dcb8 malc
        /* Stolen from gcc's builtin_bswap16 */
1722 a884dcb8 malc
1723 a884dcb8 malc
        /* a1 = abcd */
1724 a884dcb8 malc
1725 a884dcb8 malc
        /* r0 = (a1 << 8) & 0xff00 # 00d0 */
1726 a884dcb8 malc
        tcg_out32 (s, RLWINM
1727 a884dcb8 malc
                   | RA (0)
1728 a884dcb8 malc
                   | RS (args[1])
1729 a884dcb8 malc
                   | SH (8)
1730 a884dcb8 malc
                   | MB (16)
1731 a884dcb8 malc
                   | ME (23)
1732 a884dcb8 malc
            );
1733 a884dcb8 malc
1734 a884dcb8 malc
        /* a0 = rotate_left (a1, 24) & 0xff # 000c */
1735 a884dcb8 malc
        tcg_out32 (s, RLWINM
1736 a884dcb8 malc
                   | RA (args[0])
1737 a884dcb8 malc
                   | RS (args[1])
1738 a884dcb8 malc
                   | SH (24)
1739 a884dcb8 malc
                   | MB (24)
1740 a884dcb8 malc
                   | ME (31)
1741 a884dcb8 malc
            );
1742 a884dcb8 malc
1743 a884dcb8 malc
        /* a0 = a0 | r0 # 00dc */
1744 a884dcb8 malc
        tcg_out32 (s, OR | SAB (0, args[0], args[0]));
1745 a884dcb8 malc
        break;
1746 a884dcb8 malc
1747 a884dcb8 malc
    case INDEX_op_bswap32_i32:
1748 a884dcb8 malc
        /* Stolen from gcc's builtin_bswap32 */
1749 a884dcb8 malc
        {
1750 a884dcb8 malc
            int a0 = args[0];
1751 a884dcb8 malc
1752 a884dcb8 malc
            /* a1 = args[1] # abcd */
1753 a884dcb8 malc
1754 a884dcb8 malc
            if (a0 == args[1]) {
1755 a884dcb8 malc
                a0 = 0;
1756 a884dcb8 malc
            }
1757 a884dcb8 malc
1758 a884dcb8 malc
            /* a0 = rotate_left (a1, 8) # bcda */
1759 a884dcb8 malc
            tcg_out32 (s, RLWINM
1760 a884dcb8 malc
                       | RA (a0)
1761 a884dcb8 malc
                       | RS (args[1])
1762 a884dcb8 malc
                       | SH (8)
1763 a884dcb8 malc
                       | MB (0)
1764 a884dcb8 malc
                       | ME (31)
1765 a884dcb8 malc
                );
1766 a884dcb8 malc
1767 a884dcb8 malc
            /* a0 = (a0 & ~0xff000000) | ((a1 << 24) & 0xff000000) # dcda */
1768 a884dcb8 malc
            tcg_out32 (s, RLWIMI
1769 a884dcb8 malc
                       | RA (a0)
1770 a884dcb8 malc
                       | RS (args[1])
1771 a884dcb8 malc
                       | SH (24)
1772 a884dcb8 malc
                       | MB (0)
1773 a884dcb8 malc
                       | ME (7)
1774 a884dcb8 malc
                );
1775 a884dcb8 malc
1776 a884dcb8 malc
            /* a0 = (a0 & ~0x0000ff00) | ((a1 << 24) & 0x0000ff00) # dcba */
1777 a884dcb8 malc
            tcg_out32 (s, RLWIMI
1778 a884dcb8 malc
                       | RA (a0)
1779 a884dcb8 malc
                       | RS (args[1])
1780 a884dcb8 malc
                       | SH (24)
1781 a884dcb8 malc
                       | MB (16)
1782 a884dcb8 malc
                       | ME (23)
1783 a884dcb8 malc
                );
1784 a884dcb8 malc
1785 a884dcb8 malc
            if (!a0) {
1786 a884dcb8 malc
                tcg_out_mov (s, args[0], a0);
1787 a884dcb8 malc
            }
1788 a884dcb8 malc
        }
1789 a884dcb8 malc
        break;
1790 a884dcb8 malc
1791 2662e13f bellard
    default:
1792 2662e13f bellard
        tcg_dump_ops (s, stderr);
1793 2662e13f bellard
        tcg_abort ();
1794 2662e13f bellard
    }
1795 2662e13f bellard
}
1796 2662e13f bellard
1797 2662e13f bellard
static const TCGTargetOpDef ppc_op_defs[] = {
1798 2662e13f bellard
    { INDEX_op_exit_tb, { } },
1799 2662e13f bellard
    { INDEX_op_goto_tb, { } },
1800 932a6909 bellard
    { INDEX_op_call, { "ri" } },
1801 932a6909 bellard
    { INDEX_op_jmp, { "ri" } },
1802 2662e13f bellard
    { INDEX_op_br, { } },
1803 2662e13f bellard
1804 2662e13f bellard
    { INDEX_op_mov_i32, { "r", "r" } },
1805 2662e13f bellard
    { INDEX_op_movi_i32, { "r" } },
1806 2662e13f bellard
    { INDEX_op_ld8u_i32, { "r", "r" } },
1807 2662e13f bellard
    { INDEX_op_ld8s_i32, { "r", "r" } },
1808 2662e13f bellard
    { INDEX_op_ld16u_i32, { "r", "r" } },
1809 2662e13f bellard
    { INDEX_op_ld16s_i32, { "r", "r" } },
1810 2662e13f bellard
    { INDEX_op_ld_i32, { "r", "r" } },
1811 2662e13f bellard
    { INDEX_op_st8_i32, { "r", "r" } },
1812 2662e13f bellard
    { INDEX_op_st16_i32, { "r", "r" } },
1813 2662e13f bellard
    { INDEX_op_st_i32, { "r", "r" } },
1814 2662e13f bellard
1815 2662e13f bellard
    { INDEX_op_add_i32, { "r", "r", "ri" } },
1816 2662e13f bellard
    { INDEX_op_mul_i32, { "r", "r", "ri" } },
1817 77b73de6 malc
    { INDEX_op_div_i32, { "r", "r", "r" } },
1818 77b73de6 malc
    { INDEX_op_divu_i32, { "r", "r", "r" } },
1819 77b73de6 malc
    { INDEX_op_rem_i32, { "r", "r", "r" } },
1820 77b73de6 malc
    { INDEX_op_remu_i32, { "r", "r", "r" } },
1821 2662e13f bellard
    { INDEX_op_mulu2_i32, { "r", "r", "r", "r" } },
1822 2662e13f bellard
    { INDEX_op_sub_i32, { "r", "r", "ri" } },
1823 2662e13f bellard
    { INDEX_op_and_i32, { "r", "r", "ri" } },
1824 2662e13f bellard
    { INDEX_op_or_i32, { "r", "r", "ri" } },
1825 2662e13f bellard
    { INDEX_op_xor_i32, { "r", "r", "ri" } },
1826 2662e13f bellard
1827 2662e13f bellard
    { INDEX_op_shl_i32, { "r", "r", "ri" } },
1828 2662e13f bellard
    { INDEX_op_shr_i32, { "r", "r", "ri" } },
1829 2662e13f bellard
    { INDEX_op_sar_i32, { "r", "r", "ri" } },
1830 2662e13f bellard
1831 65fe043e malc
    { INDEX_op_rotl_i32, { "r", "r", "ri" } },
1832 65fe043e malc
    { INDEX_op_rotr_i32, { "r", "r", "ri" } },
1833 65fe043e malc
1834 2662e13f bellard
    { INDEX_op_brcond_i32, { "r", "ri" } },
1835 2662e13f bellard
1836 2662e13f bellard
    { INDEX_op_add2_i32, { "r", "r", "r", "r", "r", "r" } },
1837 2662e13f bellard
    { INDEX_op_sub2_i32, { "r", "r", "r", "r", "r", "r" } },
1838 2662e13f bellard
    { INDEX_op_brcond2_i32, { "r", "r", "r", "r" } },
1839 2662e13f bellard
1840 2662e13f bellard
    { INDEX_op_neg_i32, { "r", "r" } },
1841 65fe043e malc
    { INDEX_op_not_i32, { "r", "r" } },
1842 65fe043e malc
1843 65fe043e malc
    { INDEX_op_andc_i32, { "r", "r", "r" } },
1844 65fe043e malc
    { INDEX_op_orc_i32, { "r", "r", "r" } },
1845 aa77bebd malc
    { INDEX_op_eqv_i32, { "r", "r", "r" } },
1846 aa77bebd malc
    { INDEX_op_nand_i32, { "r", "r", "r" } },
1847 aa77bebd malc
    { INDEX_op_nor_i32, { "r", "r", "r" } },
1848 2662e13f bellard
1849 b0809bf7 malc
    { INDEX_op_setcond_i32, { "r", "r", "ri" } },
1850 b0809bf7 malc
    { INDEX_op_setcond2_i32, { "r", "r", "r", "ri", "ri" } },
1851 b0809bf7 malc
1852 a884dcb8 malc
    { INDEX_op_bswap16_i32, { "r", "r" } },
1853 a884dcb8 malc
    { INDEX_op_bswap32_i32, { "r", "r" } },
1854 a884dcb8 malc
1855 2662e13f bellard
#if TARGET_LONG_BITS == 32
1856 2662e13f bellard
    { INDEX_op_qemu_ld8u, { "r", "L" } },
1857 2662e13f bellard
    { INDEX_op_qemu_ld8s, { "r", "L" } },
1858 2662e13f bellard
    { INDEX_op_qemu_ld16u, { "r", "L" } },
1859 2662e13f bellard
    { INDEX_op_qemu_ld16s, { "r", "L" } },
1860 86feb1c8 Richard Henderson
    { INDEX_op_qemu_ld32, { "r", "L" } },
1861 2662e13f bellard
    { INDEX_op_qemu_ld64, { "r", "r", "L" } },
1862 2662e13f bellard
1863 2662e13f bellard
    { INDEX_op_qemu_st8, { "K", "K" } },
1864 2662e13f bellard
    { INDEX_op_qemu_st16, { "K", "K" } },
1865 2662e13f bellard
    { INDEX_op_qemu_st32, { "K", "K" } },
1866 2662e13f bellard
    { INDEX_op_qemu_st64, { "M", "M", "M" } },
1867 2662e13f bellard
#else
1868 2662e13f bellard
    { INDEX_op_qemu_ld8u, { "r", "L", "L" } },
1869 2662e13f bellard
    { INDEX_op_qemu_ld8s, { "r", "L", "L" } },
1870 2662e13f bellard
    { INDEX_op_qemu_ld16u, { "r", "L", "L" } },
1871 2662e13f bellard
    { INDEX_op_qemu_ld16s, { "r", "L", "L" } },
1872 86feb1c8 Richard Henderson
    { INDEX_op_qemu_ld32, { "r", "L", "L" } },
1873 2662e13f bellard
    { INDEX_op_qemu_ld64, { "r", "L", "L", "L" } },
1874 2662e13f bellard
1875 2662e13f bellard
    { INDEX_op_qemu_st8, { "K", "K", "K" } },
1876 2662e13f bellard
    { INDEX_op_qemu_st16, { "K", "K", "K" } },
1877 2662e13f bellard
    { INDEX_op_qemu_st32, { "K", "K", "K" } },
1878 2662e13f bellard
    { INDEX_op_qemu_st64, { "M", "M", "M", "M" } },
1879 2662e13f bellard
#endif
1880 2662e13f bellard
1881 e46b9681 malc
    { INDEX_op_ext8s_i32, { "r", "r" } },
1882 65fe043e malc
    { INDEX_op_ext8u_i32, { "r", "r" } },
1883 e46b9681 malc
    { INDEX_op_ext16s_i32, { "r", "r" } },
1884 65fe043e malc
    { INDEX_op_ext16u_i32, { "r", "r" } },
1885 e46b9681 malc
1886 2662e13f bellard
    { -1 },
1887 2662e13f bellard
};
1888 2662e13f bellard
1889 2662e13f bellard
void tcg_target_init(TCGContext *s)
1890 2662e13f bellard
{
1891 2662e13f bellard
    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
1892 2662e13f bellard
    tcg_regset_set32(tcg_target_call_clobber_regs, 0,
1893 2662e13f bellard
                     (1 << TCG_REG_R0) |
1894 6ec85236 malc
#ifdef _CALL_DARWIN
1895 f9bf2987 malc
                     (1 << TCG_REG_R2) |
1896 f9bf2987 malc
#endif
1897 2662e13f bellard
                     (1 << TCG_REG_R3) |
1898 2662e13f bellard
                     (1 << TCG_REG_R4) |
1899 2662e13f bellard
                     (1 << TCG_REG_R5) |
1900 2662e13f bellard
                     (1 << TCG_REG_R6) |
1901 2662e13f bellard
                     (1 << TCG_REG_R7) |
1902 2662e13f bellard
                     (1 << TCG_REG_R8) |
1903 2662e13f bellard
                     (1 << TCG_REG_R9) |
1904 2662e13f bellard
                     (1 << TCG_REG_R10) |
1905 2662e13f bellard
                     (1 << TCG_REG_R11) |
1906 2662e13f bellard
                     (1 << TCG_REG_R12)
1907 2662e13f bellard
        );
1908 2662e13f bellard
1909 2662e13f bellard
    tcg_regset_clear(s->reserved_regs);
1910 2662e13f bellard
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);
1911 2662e13f bellard
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R1);
1912 6ec85236 malc
#ifndef _CALL_DARWIN
1913 2662e13f bellard
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R2);
1914 f9bf2987 malc
#endif
1915 6ec85236 malc
#ifdef _CALL_SYSV
1916 5db3ee79 malc
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R13);
1917 5db3ee79 malc
#endif
1918 f6548c0a malc
#ifdef CONFIG_USE_GUEST_BASE
1919 f6548c0a malc
    tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
1920 f6548c0a malc
#endif
1921 2662e13f bellard
1922 2662e13f bellard
    tcg_add_target_add_op_defs(ppc_op_defs);
1923 2662e13f bellard
}