Statistics
| Branch: | Revision:

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

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