Statistics
| Branch: | Revision:

root / tcg / ppc64 / tcg-target.c @ 1d58ee9f

History | View | Annotate | Download (40 kB)

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