Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (41.7 kB)

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