Statistics
| Branch: | Revision:

root / tcg / ppc / tcg-target.c @ 475dc65f

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