Statistics
| Branch: | Revision:

root / tcg / ppc64 / tcg-target.c @ 016b2b28

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