Statistics
| Branch: | Revision:

root / tcg / ppc64 / tcg-target.c @ ee924fa6

History | View | Annotate | Download (47.9 kB)

1
/*
2
 * Tiny Code Generator for QEMU
3
 *
4
 * Copyright (c) 2008 Fabrice Bellard
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24

    
25
#define TCG_CT_CONST_S16  0x100
26
#define TCG_CT_CONST_U16  0x200
27
#define TCG_CT_CONST_S32  0x400
28
#define TCG_CT_CONST_U32  0x800
29
#define TCG_CT_CONST_ZERO 0x1000
30

    
31
static uint8_t *tb_ret_addr;
32

    
33
#define FAST_PATH
34

    
35
#if TARGET_LONG_BITS == 32
36
#define LD_ADDR LWZU
37
#define CMP_L 0
38
#else
39
#define LD_ADDR LDU
40
#define CMP_L (1<<21)
41
#endif
42

    
43
#ifndef GUEST_BASE
44
#define GUEST_BASE 0
45
#endif
46

    
47
#ifdef CONFIG_USE_GUEST_BASE
48
#define TCG_GUEST_BASE_REG 30
49
#else
50
#define TCG_GUEST_BASE_REG 0
51
#endif
52

    
53
#ifndef NDEBUG
54
static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
55
    "r0",
56
    "r1",
57
    "r2",
58
    "r3",
59
    "r4",
60
    "r5",
61
    "r6",
62
    "r7",
63
    "r8",
64
    "r9",
65
    "r10",
66
    "r11",
67
    "r12",
68
    "r13",
69
    "r14",
70
    "r15",
71
    "r16",
72
    "r17",
73
    "r18",
74
    "r19",
75
    "r20",
76
    "r21",
77
    "r22",
78
    "r23",
79
    "r24",
80
    "r25",
81
    "r26",
82
    "r27",
83
    "r28",
84
    "r29",
85
    "r30",
86
    "r31"
87
};
88
#endif
89

    
90
static const int tcg_target_reg_alloc_order[] = {
91
    TCG_REG_R14,
92
    TCG_REG_R15,
93
    TCG_REG_R16,
94
    TCG_REG_R17,
95
    TCG_REG_R18,
96
    TCG_REG_R19,
97
    TCG_REG_R20,
98
    TCG_REG_R21,
99
    TCG_REG_R22,
100
    TCG_REG_R23,
101
    TCG_REG_R28,
102
    TCG_REG_R29,
103
    TCG_REG_R30,
104
    TCG_REG_R31,
105
#ifdef __APPLE__
106
    TCG_REG_R2,
107
#endif
108
    TCG_REG_R3,
109
    TCG_REG_R4,
110
    TCG_REG_R5,
111
    TCG_REG_R6,
112
    TCG_REG_R7,
113
    TCG_REG_R8,
114
    TCG_REG_R9,
115
    TCG_REG_R10,
116
#ifndef __APPLE__
117
    TCG_REG_R11,
118
#endif
119
    TCG_REG_R12,
120
    TCG_REG_R24,
121
    TCG_REG_R25,
122
    TCG_REG_R26,
123
    TCG_REG_R27
124
};
125

    
126
static const int tcg_target_call_iarg_regs[] = {
127
    TCG_REG_R3,
128
    TCG_REG_R4,
129
    TCG_REG_R5,
130
    TCG_REG_R6,
131
    TCG_REG_R7,
132
    TCG_REG_R8,
133
    TCG_REG_R9,
134
    TCG_REG_R10
135
};
136

    
137
static const int tcg_target_call_oarg_regs[] = {
138
    TCG_REG_R3
139
};
140

    
141
static const int tcg_target_callee_save_regs[] = {
142
#ifdef __APPLE__
143
    TCG_REG_R11,
144
#endif
145
    TCG_REG_R14,
146
    TCG_REG_R15,
147
    TCG_REG_R16,
148
    TCG_REG_R17,
149
    TCG_REG_R18,
150
    TCG_REG_R19,
151
    TCG_REG_R20,
152
    TCG_REG_R21,
153
    TCG_REG_R22,
154
    TCG_REG_R23,
155
    TCG_REG_R24,
156
    TCG_REG_R25,
157
    TCG_REG_R26,
158
    TCG_REG_R27, /* currently used for the global env */
159
    TCG_REG_R28,
160
    TCG_REG_R29,
161
    TCG_REG_R30,
162
    TCG_REG_R31
163
};
164

    
165
static uint32_t reloc_pc24_val (void *pc, tcg_target_long target)
166
{
167
    tcg_target_long disp;
168

    
169
    disp = target - (tcg_target_long) pc;
170
    if ((disp << 38) >> 38 != disp)
171
        tcg_abort ();
172

    
173
    return disp & 0x3fffffc;
174
}
175

    
176
static void reloc_pc24 (void *pc, tcg_target_long target)
177
{
178
    *(uint32_t *) pc = (*(uint32_t *) pc & ~0x3fffffc)
179
        | reloc_pc24_val (pc, target);
180
}
181

    
182
static uint16_t reloc_pc14_val (void *pc, tcg_target_long target)
183
{
184
    tcg_target_long disp;
185

    
186
    disp = target - (tcg_target_long) pc;
187
    if (disp != (int16_t) disp)
188
        tcg_abort ();
189

    
190
    return disp & 0xfffc;
191
}
192

    
193
static void reloc_pc14 (void *pc, tcg_target_long target)
194
{
195
    *(uint32_t *) pc = (*(uint32_t *) pc & ~0xfffc)
196
        | reloc_pc14_val (pc, target);
197
}
198

    
199
static void patch_reloc (uint8_t *code_ptr, int type,
200
                         tcg_target_long value, tcg_target_long addend)
201
{
202
    value += addend;
203
    switch (type) {
204
    case R_PPC_REL14:
205
        reloc_pc14 (code_ptr, value);
206
        break;
207
    case R_PPC_REL24:
208
        reloc_pc24 (code_ptr, value);
209
        break;
210
    default:
211
        tcg_abort ();
212
    }
213
}
214

    
215
/* parse target specific constraints */
216
static int target_parse_constraint (TCGArgConstraint *ct, const char **pct_str)
217
{
218
    const char *ct_str;
219

    
220
    ct_str = *pct_str;
221
    switch (ct_str[0]) {
222
    case 'A': case 'B': case 'C': case 'D':
223
        ct->ct |= TCG_CT_REG;
224
        tcg_regset_set_reg (ct->u.regs, 3 + ct_str[0] - 'A');
225
        break;
226
    case 'r':
227
        ct->ct |= TCG_CT_REG;
228
        tcg_regset_set32 (ct->u.regs, 0, 0xffffffff);
229
        break;
230
    case 'L':                   /* qemu_ld constraint */
231
        ct->ct |= TCG_CT_REG;
232
        tcg_regset_set32 (ct->u.regs, 0, 0xffffffff);
233
        tcg_regset_reset_reg (ct->u.regs, TCG_REG_R3);
234
#ifdef CONFIG_SOFTMMU
235
        tcg_regset_reset_reg (ct->u.regs, TCG_REG_R4);
236
        tcg_regset_reset_reg (ct->u.regs, TCG_REG_R5);
237
#endif
238
        break;
239
    case 'S':                   /* qemu_st constraint */
240
        ct->ct |= TCG_CT_REG;
241
        tcg_regset_set32 (ct->u.regs, 0, 0xffffffff);
242
        tcg_regset_reset_reg (ct->u.regs, TCG_REG_R3);
243
#ifdef CONFIG_SOFTMMU
244
        tcg_regset_reset_reg (ct->u.regs, TCG_REG_R4);
245
        tcg_regset_reset_reg (ct->u.regs, TCG_REG_R5);
246
        tcg_regset_reset_reg (ct->u.regs, TCG_REG_R6);
247
#endif
248
        break;
249
    case 'I':
250
        ct->ct |= TCG_CT_CONST_S16;
251
        break;
252
    case 'J':
253
        ct->ct |= TCG_CT_CONST_U16;
254
        break;
255
    case 'T':
256
        ct->ct |= TCG_CT_CONST_S32;
257
        break;
258
    case 'U':
259
        ct->ct |= TCG_CT_CONST_U32;
260
        break;
261
    case 'Z':
262
        ct->ct |= TCG_CT_CONST_ZERO;
263
        break;
264
    default:
265
        return -1;
266
    }
267
    ct_str++;
268
    *pct_str = ct_str;
269
    return 0;
270
}
271

    
272
/* test if a constant matches the constraint */
273
static int tcg_target_const_match (tcg_target_long val,
274
                                   const TCGArgConstraint *arg_ct)
275
{
276
    int ct = arg_ct->ct;
277
    if (ct & TCG_CT_CONST) {
278
        return 1;
279
    } else if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val) {
280
        return 1;
281
    } else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val) {
282
        return 1;
283
    } else if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) {
284
        return 1;
285
    } else if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val) {
286
        return 1;
287
    } else if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
288
        return 1;
289
    }
290
    return 0;
291
}
292

    
293
#define OPCD(opc) ((opc)<<26)
294
#define XO19(opc) (OPCD(19)|((opc)<<1))
295
#define XO30(opc) (OPCD(30)|((opc)<<2))
296
#define XO31(opc) (OPCD(31)|((opc)<<1))
297
#define XO58(opc) (OPCD(58)|(opc))
298
#define XO62(opc) (OPCD(62)|(opc))
299

    
300
#define B      OPCD( 18)
301
#define BC     OPCD( 16)
302
#define LBZ    OPCD( 34)
303
#define LHZ    OPCD( 40)
304
#define LHA    OPCD( 42)
305
#define LWZ    OPCD( 32)
306
#define STB    OPCD( 38)
307
#define STH    OPCD( 44)
308
#define STW    OPCD( 36)
309

    
310
#define STD    XO62(  0)
311
#define STDU   XO62(  1)
312
#define STDX   XO31(149)
313

    
314
#define LD     XO58(  0)
315
#define LDX    XO31( 21)
316
#define LDU    XO58(  1)
317
#define LWA    XO58(  2)
318
#define LWAX   XO31(341)
319

    
320
#define ADDIC  OPCD( 12)
321
#define ADDI   OPCD( 14)
322
#define ADDIS  OPCD( 15)
323
#define ORI    OPCD( 24)
324
#define ORIS   OPCD( 25)
325
#define XORI   OPCD( 26)
326
#define XORIS  OPCD( 27)
327
#define ANDI   OPCD( 28)
328
#define ANDIS  OPCD( 29)
329
#define MULLI  OPCD(  7)
330
#define CMPLI  OPCD( 10)
331
#define CMPI   OPCD( 11)
332

    
333
#define LWZU   OPCD( 33)
334
#define STWU   OPCD( 37)
335

    
336
#define RLWINM OPCD( 21)
337

    
338
#define RLDICL XO30(  0)
339
#define RLDICR XO30(  1)
340
#define RLDIMI XO30(  3)
341

    
342
#define BCLR   XO19( 16)
343
#define BCCTR  XO19(528)
344
#define CRAND  XO19(257)
345
#define CRANDC XO19(129)
346
#define CRNAND XO19(225)
347
#define CROR   XO19(449)
348
#define CRNOR  XO19( 33)
349

    
350
#define EXTSB  XO31(954)
351
#define EXTSH  XO31(922)
352
#define EXTSW  XO31(986)
353
#define ADD    XO31(266)
354
#define ADDE   XO31(138)
355
#define ADDC   XO31( 10)
356
#define AND    XO31( 28)
357
#define SUBF   XO31( 40)
358
#define SUBFC  XO31(  8)
359
#define SUBFE  XO31(136)
360
#define OR     XO31(444)
361
#define XOR    XO31(316)
362
#define MULLW  XO31(235)
363
#define MULHWU XO31( 11)
364
#define DIVW   XO31(491)
365
#define DIVWU  XO31(459)
366
#define CMP    XO31(  0)
367
#define CMPL   XO31( 32)
368
#define LHBRX  XO31(790)
369
#define LWBRX  XO31(534)
370
#define STHBRX XO31(918)
371
#define STWBRX XO31(662)
372
#define MFSPR  XO31(339)
373
#define MTSPR  XO31(467)
374
#define SRAWI  XO31(824)
375
#define NEG    XO31(104)
376
#define MFCR   XO31( 19)
377
#define NOR    XO31(124)
378
#define CNTLZW XO31( 26)
379
#define CNTLZD XO31( 58)
380

    
381
#define MULLD  XO31(233)
382
#define MULHD  XO31( 73)
383
#define MULHDU XO31(  9)
384
#define DIVD   XO31(489)
385
#define DIVDU  XO31(457)
386

    
387
#define LBZX   XO31( 87)
388
#define LHZX   XO31(279)
389
#define LHAX   XO31(343)
390
#define LWZX   XO31( 23)
391
#define STBX   XO31(215)
392
#define STHX   XO31(407)
393
#define STWX   XO31(151)
394

    
395
#define SPR(a,b) ((((a)<<5)|(b))<<11)
396
#define LR     SPR(8, 0)
397
#define CTR    SPR(9, 0)
398

    
399
#define SLW    XO31( 24)
400
#define SRW    XO31(536)
401
#define SRAW   XO31(792)
402

    
403
#define SLD    XO31( 27)
404
#define SRD    XO31(539)
405
#define SRAD   XO31(794)
406
#define SRADI  XO31(413<<1)
407

    
408
#define TW     XO31( 4)
409
#define TRAP   (TW | TO (31))
410

    
411
#define RT(r) ((r)<<21)
412
#define RS(r) ((r)<<21)
413
#define RA(r) ((r)<<16)
414
#define RB(r) ((r)<<11)
415
#define TO(t) ((t)<<21)
416
#define SH(s) ((s)<<11)
417
#define MB(b) ((b)<<6)
418
#define ME(e) ((e)<<1)
419
#define BO(o) ((o)<<21)
420
#define MB64(b) ((b)<<5)
421

    
422
#define LK    1
423

    
424
#define TAB(t, a, b) (RT(t) | RA(a) | RB(b))
425
#define SAB(s, a, b) (RS(s) | RA(a) | RB(b))
426
#define TAI(s, a, i) (RT(s) | RA(a) | ((i) & 0xffff))
427
#define SAI(s, a, i) (RS(s) | RA(a) | ((i) & 0xffff))
428

    
429
#define BF(n)    ((n)<<23)
430
#define BI(n, c) (((c)+((n)*4))<<16)
431
#define BT(n, c) (((c)+((n)*4))<<21)
432
#define BA(n, c) (((c)+((n)*4))<<16)
433
#define BB(n, c) (((c)+((n)*4))<<11)
434

    
435
#define BO_COND_TRUE  BO (12)
436
#define BO_COND_FALSE BO ( 4)
437
#define BO_ALWAYS     BO (20)
438

    
439
enum {
440
    CR_LT,
441
    CR_GT,
442
    CR_EQ,
443
    CR_SO
444
};
445

    
446
static const uint32_t tcg_to_bc[] = {
447
    [TCG_COND_EQ]  = BC | BI (7, CR_EQ) | BO_COND_TRUE,
448
    [TCG_COND_NE]  = BC | BI (7, CR_EQ) | BO_COND_FALSE,
449
    [TCG_COND_LT]  = BC | BI (7, CR_LT) | BO_COND_TRUE,
450
    [TCG_COND_GE]  = BC | BI (7, CR_LT) | BO_COND_FALSE,
451
    [TCG_COND_LE]  = BC | BI (7, CR_GT) | BO_COND_FALSE,
452
    [TCG_COND_GT]  = BC | BI (7, CR_GT) | BO_COND_TRUE,
453
    [TCG_COND_LTU] = BC | BI (7, CR_LT) | BO_COND_TRUE,
454
    [TCG_COND_GEU] = BC | BI (7, CR_LT) | BO_COND_FALSE,
455
    [TCG_COND_LEU] = BC | BI (7, CR_GT) | BO_COND_FALSE,
456
    [TCG_COND_GTU] = BC | BI (7, CR_GT) | BO_COND_TRUE,
457
};
458

    
459
static inline void tcg_out_mov(TCGContext *s, TCGType type,
460
                               TCGReg ret, TCGReg arg)
461
{
462
    tcg_out32 (s, OR | SAB (arg, ret, arg));
463
}
464

    
465
static inline void tcg_out_rld(TCGContext *s, int op, TCGReg ra, TCGReg rs,
466
                               int sh, int mb)
467
{
468
    sh = SH (sh & 0x1f) | (((sh >> 5) & 1) << 1);
469
    mb = MB64 ((mb >> 5) | ((mb << 1) & 0x3f));
470
    tcg_out32 (s, op | RA (ra) | RS (rs) | sh | mb);
471
}
472

    
473
static inline void tcg_out_rlw(TCGContext *s, int op, TCGReg ra, TCGReg rs,
474
                               int sh, int mb, int me)
475
{
476
    tcg_out32(s, op | RA(ra) | RS(rs) | SH(sh) | MB(mb) | ME(me));
477
}
478

    
479
static inline void tcg_out_ext32u(TCGContext *s, TCGReg dst, TCGReg src)
480
{
481
    tcg_out_rld(s, RLDICL, dst, src, 0, 32);
482
}
483

    
484
static inline void tcg_out_shli64(TCGContext *s, TCGReg dst, TCGReg src, int c)
485
{
486
    tcg_out_rld(s, RLDICR, dst, src, c, 63 - c);
487
}
488

    
489
static inline void tcg_out_shri64(TCGContext *s, TCGReg dst, TCGReg src, int c)
490
{
491
    tcg_out_rld(s, RLDICL, dst, src, 64 - c, c);
492
}
493

    
494
static void tcg_out_movi32(TCGContext *s, TCGReg ret, int32_t arg)
495
{
496
    if (arg == (int16_t) arg) {
497
        tcg_out32(s, ADDI | TAI(ret, 0, arg));
498
    } else {
499
        tcg_out32(s, ADDIS | TAI(ret, 0, arg >> 16));
500
        if (arg & 0xffff) {
501
            tcg_out32(s, ORI | SAI(ret, ret, arg));
502
        }
503
    }
504
}
505

    
506
static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg ret,
507
                         tcg_target_long arg)
508
{
509
    if (type == TCG_TYPE_I32 || arg == (int32_t)arg) {
510
        tcg_out_movi32(s, ret, arg);
511
    } else if (arg == (uint32_t)arg && !(arg & 0x8000)) {
512
        tcg_out32(s, ADDI | TAI(ret, 0, arg));
513
        tcg_out32(s, ORIS | SAI(ret, ret, arg >> 16));
514
    } else {
515
        int32_t high = arg >> 32;
516
        tcg_out_movi32(s, ret, high);
517
        if (high) {
518
            tcg_out_shli64(s, ret, ret, 32);
519
        }
520
        if (arg & 0xffff0000) {
521
            tcg_out32(s, ORIS | SAI(ret, ret, arg >> 16));
522
        }
523
        if (arg & 0xffff) {
524
            tcg_out32(s, ORI | SAI(ret, ret, arg));
525
        }
526
    }
527
}
528

    
529
static void tcg_out_b (TCGContext *s, int mask, tcg_target_long target)
530
{
531
    tcg_target_long disp;
532

    
533
    disp = target - (tcg_target_long) s->code_ptr;
534
    if ((disp << 38) >> 38 == disp)
535
        tcg_out32 (s, B | (disp & 0x3fffffc) | mask);
536
    else {
537
        tcg_out_movi (s, TCG_TYPE_I64, 0, (tcg_target_long) target);
538
        tcg_out32 (s, MTSPR | RS (0) | CTR);
539
        tcg_out32 (s, BCCTR | BO_ALWAYS | mask);
540
    }
541
}
542

    
543
static void tcg_out_call (TCGContext *s, tcg_target_long arg, int const_arg)
544
{
545
#ifdef __APPLE__
546
    if (const_arg) {
547
        tcg_out_b (s, LK, arg);
548
    }
549
    else {
550
        tcg_out32 (s, MTSPR | RS (arg) | LR);
551
        tcg_out32 (s, BCLR | BO_ALWAYS | LK);
552
    }
553
#else
554
    int reg;
555

    
556
    if (const_arg) {
557
        reg = 2;
558
        tcg_out_movi (s, TCG_TYPE_I64, reg, arg);
559
    }
560
    else reg = arg;
561

    
562
    tcg_out32 (s, LD | RT (0) | RA (reg));
563
    tcg_out32 (s, MTSPR | RA (0) | CTR);
564
    tcg_out32 (s, LD | RT (11) | RA (reg) | 16);
565
    tcg_out32 (s, LD | RT (2) | RA (reg) | 8);
566
    tcg_out32 (s, BCCTR | BO_ALWAYS | LK);
567
#endif
568
}
569

    
570
static void tcg_out_ldst(TCGContext *s, TCGReg ret, TCGReg addr,
571
                         int offset, int op1, int op2)
572
{
573
    if (offset == (int16_t) offset) {
574
        tcg_out32(s, op1 | TAI(ret, addr, offset));
575
    } else {
576
        tcg_out_movi(s, TCG_TYPE_I64, 0, offset);
577
        tcg_out32(s, op2 | TAB(ret, addr, 0));
578
    }
579
}
580

    
581
static void tcg_out_ldsta(TCGContext *s, TCGReg ret, TCGReg addr,
582
                          int offset, int op1, int op2)
583
{
584
    if (offset == (int16_t) (offset & ~3)) {
585
        tcg_out32(s, op1 | TAI(ret, addr, offset));
586
    } else {
587
        tcg_out_movi(s, TCG_TYPE_I64, 0, offset);
588
        tcg_out32(s, op2 | TAB(ret, addr, 0));
589
    }
590
}
591

    
592
#if defined (CONFIG_SOFTMMU)
593

    
594
#include "exec/softmmu_defs.h"
595

    
596
/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
597
   int mmu_idx) */
598
static const void * const qemu_ld_helpers[4] = {
599
    helper_ldb_mmu,
600
    helper_ldw_mmu,
601
    helper_ldl_mmu,
602
    helper_ldq_mmu,
603
};
604

    
605
/* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
606
   uintxx_t val, int mmu_idx) */
607
static const void * const qemu_st_helpers[4] = {
608
    helper_stb_mmu,
609
    helper_stw_mmu,
610
    helper_stl_mmu,
611
    helper_stq_mmu,
612
};
613

    
614
static void tcg_out_tlb_read(TCGContext *s, TCGReg r0, TCGReg r1, TCGReg r2,
615
                             TCGReg addr_reg, int s_bits, int offset)
616
{
617
#if TARGET_LONG_BITS == 32
618
    tcg_out_ext32u(s, addr_reg, addr_reg);
619

    
620
    tcg_out_rlw(s, RLWINM, r0, addr_reg,
621
                32 - (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
622
                32 - (CPU_TLB_BITS + CPU_TLB_ENTRY_BITS),
623
                31 - CPU_TLB_ENTRY_BITS);
624
    tcg_out32(s, ADD | TAB(r0, r0, TCG_AREG0));
625
    tcg_out32(s, LWZU | TAI(r1, r0, offset));
626
    tcg_out_rlw(s, RLWINM, r2, addr_reg, 0,
627
                (32 - s_bits) & 31, 31 - TARGET_PAGE_BITS);
628
#else
629
    tcg_out_rld (s, RLDICL, r0, addr_reg,
630
                 64 - TARGET_PAGE_BITS,
631
                 64 - CPU_TLB_BITS);
632
    tcg_out_shli64(s, r0, r0, CPU_TLB_ENTRY_BITS);
633

    
634
    tcg_out32(s, ADD | TAB(r0, r0, TCG_AREG0));
635
    tcg_out32(s, LD_ADDR | TAI(r1, r0, offset));
636

    
637
    if (!s_bits) {
638
        tcg_out_rld (s, RLDICR, r2, addr_reg, 0, 63 - TARGET_PAGE_BITS);
639
    }
640
    else {
641
        tcg_out_rld (s, RLDICL, r2, addr_reg,
642
                     64 - TARGET_PAGE_BITS,
643
                     TARGET_PAGE_BITS - s_bits);
644
        tcg_out_rld (s, RLDICL, r2, r2, TARGET_PAGE_BITS, 0);
645
    }
646
#endif
647
}
648
#endif
649

    
650
static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
651
{
652
    TCGReg addr_reg, data_reg, r0, r1, rbase;
653
    int bswap;
654
#ifdef CONFIG_SOFTMMU
655
    TCGReg r2, ir;
656
    int mem_index, s_bits;
657
    void *label1_ptr, *label2_ptr;
658
#endif
659

    
660
    data_reg = *args++;
661
    addr_reg = *args++;
662

    
663
#ifdef CONFIG_SOFTMMU
664
    mem_index = *args;
665
    s_bits = opc & 3;
666

    
667
    r0 = 3;
668
    r1 = 4;
669
    r2 = 0;
670
    rbase = 0;
671

    
672
    tcg_out_tlb_read (s, r0, r1, r2, addr_reg, s_bits,
673
                      offsetof (CPUArchState, tlb_table[mem_index][0].addr_read));
674

    
675
    tcg_out32 (s, CMP | BF (7) | RA (r2) | RB (r1) | CMP_L);
676

    
677
    label1_ptr = s->code_ptr;
678
#ifdef FAST_PATH
679
    tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE);
680
#endif
681

    
682
    /* slow path */
683
    ir = 3;
684
    tcg_out_mov (s, TCG_TYPE_I64, ir++, TCG_AREG0);
685
    tcg_out_mov (s, TCG_TYPE_I64, ir++, addr_reg);
686
    tcg_out_movi (s, TCG_TYPE_I64, ir++, mem_index);
687

    
688
    tcg_out_call (s, (tcg_target_long) qemu_ld_helpers[s_bits], 1);
689

    
690
    switch (opc) {
691
    case 0|4:
692
        tcg_out32 (s, EXTSB | RA (data_reg) | RS (3));
693
        break;
694
    case 1|4:
695
        tcg_out32 (s, EXTSH | RA (data_reg) | RS (3));
696
        break;
697
    case 2|4:
698
        tcg_out32 (s, EXTSW | RA (data_reg) | RS (3));
699
        break;
700
    case 0:
701
    case 1:
702
    case 2:
703
    case 3:
704
        if (data_reg != 3)
705
            tcg_out_mov (s, TCG_TYPE_I64, data_reg, 3);
706
        break;
707
    }
708
    label2_ptr = s->code_ptr;
709
    tcg_out32 (s, B);
710

    
711
    /* label1: fast path */
712
#ifdef FAST_PATH
713
    reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr);
714
#endif
715

    
716
    /* r0 now contains &env->tlb_table[mem_index][index].addr_read */
717
    tcg_out32(s, LD | TAI(r0, r0,
718
                          offsetof(CPUTLBEntry, addend)
719
                          - offsetof(CPUTLBEntry, addr_read)));
720
    /* r0 = env->tlb_table[mem_index][index].addend */
721
    tcg_out32(s, ADD | TAB(r0, r0, addr_reg));
722
    /* r0 = env->tlb_table[mem_index][index].addend + addr */
723

    
724
#else  /* !CONFIG_SOFTMMU */
725
#if TARGET_LONG_BITS == 32
726
    tcg_out_ext32u(s, addr_reg, addr_reg);
727
#endif
728
    r0 = addr_reg;
729
    r1 = 3;
730
    rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
731
#endif
732

    
733
#ifdef TARGET_WORDS_BIGENDIAN
734
    bswap = 0;
735
#else
736
    bswap = 1;
737
#endif
738
    switch (opc) {
739
    default:
740
    case 0:
741
        tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));
742
        break;
743
    case 0|4:
744
        tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));
745
        tcg_out32 (s, EXTSB | RA (data_reg) | RS (data_reg));
746
        break;
747
    case 1:
748
        if (bswap)
749
            tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));
750
        else
751
            tcg_out32 (s, LHZX | TAB (data_reg, rbase, r0));
752
        break;
753
    case 1|4:
754
        if (bswap) {
755
            tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));
756
            tcg_out32 (s, EXTSH | RA (data_reg) | RS (data_reg));
757
        }
758
        else tcg_out32 (s, LHAX | TAB (data_reg, rbase, r0));
759
        break;
760
    case 2:
761
        if (bswap)
762
            tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
763
        else
764
            tcg_out32 (s, LWZX | TAB (data_reg, rbase, r0));
765
        break;
766
    case 2|4:
767
        if (bswap) {
768
            tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
769
            tcg_out32 (s, EXTSW | RA (data_reg) | RS (data_reg));
770
        }
771
        else tcg_out32 (s, LWAX | TAB (data_reg, rbase, r0));
772
        break;
773
    case 3:
774
#ifdef CONFIG_USE_GUEST_BASE
775
        if (bswap) {
776
            tcg_out32(s, ADDI | TAI(r1, r0, 4));
777
            tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
778
            tcg_out32 (s, LWBRX | TAB (      r1, rbase, r1));
779
            tcg_out_rld (s, RLDIMI, data_reg, r1, 32, 0);
780
        }
781
        else tcg_out32 (s, LDX | TAB (data_reg, rbase, r0));
782
#else
783
        if (bswap) {
784
            tcg_out_movi32 (s, 0, 4);
785
            tcg_out32 (s, LWBRX | RT (data_reg) | RB (r0));
786
            tcg_out32 (s, LWBRX | RT (      r1) | RA (r0));
787
            tcg_out_rld (s, RLDIMI, data_reg, r1, 32, 0);
788
        }
789
        else tcg_out32 (s, LD | RT (data_reg) | RA (r0));
790
#endif
791
        break;
792
    }
793

    
794
#ifdef CONFIG_SOFTMMU
795
    reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr);
796
#endif
797
}
798

    
799
static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
800
{
801
    TCGReg addr_reg, r0, r1, rbase, data_reg;
802
    int bswap;
803
#ifdef CONFIG_SOFTMMU
804
    TCGReg r2, ir;
805
    int mem_index;
806
    void *label1_ptr, *label2_ptr;
807
#endif
808

    
809
    data_reg = *args++;
810
    addr_reg = *args++;
811

    
812
#ifdef CONFIG_SOFTMMU
813
    mem_index = *args;
814

    
815
    r0 = 3;
816
    r1 = 4;
817
    r2 = 0;
818
    rbase = 0;
819

    
820
    tcg_out_tlb_read (s, r0, r1, r2, addr_reg, opc,
821
                      offsetof (CPUArchState, tlb_table[mem_index][0].addr_write));
822

    
823
    tcg_out32 (s, CMP | BF (7) | RA (r2) | RB (r1) | CMP_L);
824

    
825
    label1_ptr = s->code_ptr;
826
#ifdef FAST_PATH
827
    tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE);
828
#endif
829

    
830
    /* slow path */
831
    ir = 3;
832
    tcg_out_mov (s, TCG_TYPE_I64, ir++, TCG_AREG0);
833
    tcg_out_mov (s, TCG_TYPE_I64, ir++, addr_reg);
834
    tcg_out_rld (s, RLDICL, ir++, data_reg, 0, 64 - (1 << (3 + opc)));
835
    tcg_out_movi (s, TCG_TYPE_I64, ir++, mem_index);
836

    
837
    tcg_out_call (s, (tcg_target_long) qemu_st_helpers[opc], 1);
838

    
839
    label2_ptr = s->code_ptr;
840
    tcg_out32 (s, B);
841

    
842
    /* label1: fast path */
843
#ifdef FAST_PATH
844
    reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr);
845
#endif
846

    
847
    tcg_out32 (s, (LD
848
                   | RT (r0)
849
                   | RA (r0)
850
                   | (offsetof (CPUTLBEntry, addend)
851
                      - offsetof (CPUTLBEntry, addr_write))
852
                   ));
853
    /* r0 = env->tlb_table[mem_index][index].addend */
854
    tcg_out32(s, ADD | TAB(r0, r0, addr_reg));
855
    /* r0 = env->tlb_table[mem_index][index].addend + addr */
856

    
857
#else  /* !CONFIG_SOFTMMU */
858
#if TARGET_LONG_BITS == 32
859
    tcg_out_ext32u(s, addr_reg, addr_reg);
860
#endif
861
    r1 = 3;
862
    r0 = addr_reg;
863
    rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
864
#endif
865

    
866
#ifdef TARGET_WORDS_BIGENDIAN
867
    bswap = 0;
868
#else
869
    bswap = 1;
870
#endif
871
    switch (opc) {
872
    case 0:
873
        tcg_out32 (s, STBX | SAB (data_reg, rbase, r0));
874
        break;
875
    case 1:
876
        if (bswap)
877
            tcg_out32 (s, STHBRX | SAB (data_reg, rbase, r0));
878
        else
879
            tcg_out32 (s, STHX | SAB (data_reg, rbase, r0));
880
        break;
881
    case 2:
882
        if (bswap)
883
            tcg_out32 (s, STWBRX | SAB (data_reg, rbase, r0));
884
        else
885
            tcg_out32 (s, STWX | SAB (data_reg, rbase, r0));
886
        break;
887
    case 3:
888
        if (bswap) {
889
            tcg_out32 (s, STWBRX | SAB (data_reg, rbase, r0));
890
            tcg_out32(s, ADDI | TAI(r1, r0, 4));
891
            tcg_out_shri64(s, 0, data_reg, 32);
892
            tcg_out32 (s, STWBRX | SAB (0, rbase, r1));
893
        }
894
        else tcg_out32 (s, STDX | SAB (data_reg, rbase, r0));
895
        break;
896
    }
897

    
898
#ifdef CONFIG_SOFTMMU
899
    reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr);
900
#endif
901
}
902

    
903
static void tcg_target_qemu_prologue (TCGContext *s)
904
{
905
    int i, frame_size;
906
#ifndef __APPLE__
907
    uint64_t addr;
908
#endif
909

    
910
    frame_size = 0
911
        + 8                     /* back chain */
912
        + 8                     /* CR */
913
        + 8                     /* LR */
914
        + 8                     /* compiler doubleword */
915
        + 8                     /* link editor doubleword */
916
        + 8                     /* TOC save area */
917
        + TCG_STATIC_CALL_ARGS_SIZE
918
        + ARRAY_SIZE (tcg_target_callee_save_regs) * 8
919
        + CPU_TEMP_BUF_NLONGS * sizeof(long)
920
        ;
921
    frame_size = (frame_size + 15) & ~15;
922

    
923
    tcg_set_frame (s, TCG_REG_CALL_STACK, frame_size
924
                   - CPU_TEMP_BUF_NLONGS * sizeof (long),
925
                   CPU_TEMP_BUF_NLONGS * sizeof (long));
926

    
927
#ifndef __APPLE__
928
    /* First emit adhoc function descriptor */
929
    addr = (uint64_t) s->code_ptr + 24;
930
    tcg_out32 (s, addr >> 32); tcg_out32 (s, addr); /* entry point */
931
    s->code_ptr += 16;          /* skip TOC and environment pointer */
932
#endif
933

    
934
    /* Prologue */
935
    tcg_out32 (s, MFSPR | RT (0) | LR);
936
    tcg_out32 (s, STDU | RS (1) | RA (1) | (-frame_size & 0xffff));
937
    for (i = 0; i < ARRAY_SIZE (tcg_target_callee_save_regs); ++i)
938
        tcg_out32 (s, (STD
939
                       | RS (tcg_target_callee_save_regs[i])
940
                       | RA (1)
941
                       | (i * 8 + 48 + TCG_STATIC_CALL_ARGS_SIZE)
942
                       )
943
            );
944
    tcg_out32 (s, STD | RS (0) | RA (1) | (frame_size + 16));
945

    
946
#ifdef CONFIG_USE_GUEST_BASE
947
    if (GUEST_BASE) {
948
        tcg_out_movi (s, TCG_TYPE_I64, TCG_GUEST_BASE_REG, GUEST_BASE);
949
        tcg_regset_set_reg (s->reserved_regs, TCG_GUEST_BASE_REG);
950
    }
951
#endif
952

    
953
    tcg_out_mov (s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
954
    tcg_out32 (s, MTSPR | RS (tcg_target_call_iarg_regs[1]) | CTR);
955
    tcg_out32 (s, BCCTR | BO_ALWAYS);
956

    
957
    /* Epilogue */
958
    tb_ret_addr = s->code_ptr;
959

    
960
    for (i = 0; i < ARRAY_SIZE (tcg_target_callee_save_regs); ++i)
961
        tcg_out32 (s, (LD
962
                       | RT (tcg_target_callee_save_regs[i])
963
                       | RA (1)
964
                       | (i * 8 + 48 + TCG_STATIC_CALL_ARGS_SIZE)
965
                       )
966
            );
967
    tcg_out32(s, LD | TAI(0, 1, frame_size + 16));
968
    tcg_out32(s, MTSPR | RS(0) | LR);
969
    tcg_out32(s, ADDI | TAI(1, 1, frame_size));
970
    tcg_out32(s, BCLR | BO_ALWAYS);
971
}
972

    
973
static void tcg_out_ld (TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
974
                        tcg_target_long arg2)
975
{
976
    if (type == TCG_TYPE_I32)
977
        tcg_out_ldst (s, ret, arg1, arg2, LWZ, LWZX);
978
    else
979
        tcg_out_ldsta (s, ret, arg1, arg2, LD, LDX);
980
}
981

    
982
static void tcg_out_st (TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
983
                        tcg_target_long arg2)
984
{
985
    if (type == TCG_TYPE_I32)
986
        tcg_out_ldst (s, arg, arg1, arg2, STW, STWX);
987
    else
988
        tcg_out_ldsta (s, arg, arg1, arg2, STD, STDX);
989
}
990

    
991
static void tcg_out_cmp (TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
992
                         int const_arg2, int cr, int arch64)
993
{
994
    int imm;
995
    uint32_t op;
996

    
997
    switch (cond) {
998
    case TCG_COND_EQ:
999
    case TCG_COND_NE:
1000
        if (const_arg2) {
1001
            if ((int16_t) arg2 == arg2) {
1002
                op = CMPI;
1003
                imm = 1;
1004
                break;
1005
            }
1006
            else if ((uint16_t) arg2 == arg2) {
1007
                op = CMPLI;
1008
                imm = 1;
1009
                break;
1010
            }
1011
        }
1012
        op = CMPL;
1013
        imm = 0;
1014
        break;
1015

    
1016
    case TCG_COND_LT:
1017
    case TCG_COND_GE:
1018
    case TCG_COND_LE:
1019
    case TCG_COND_GT:
1020
        if (const_arg2) {
1021
            if ((int16_t) arg2 == arg2) {
1022
                op = CMPI;
1023
                imm = 1;
1024
                break;
1025
            }
1026
        }
1027
        op = CMP;
1028
        imm = 0;
1029
        break;
1030

    
1031
    case TCG_COND_LTU:
1032
    case TCG_COND_GEU:
1033
    case TCG_COND_LEU:
1034
    case TCG_COND_GTU:
1035
        if (const_arg2) {
1036
            if ((uint16_t) arg2 == arg2) {
1037
                op = CMPLI;
1038
                imm = 1;
1039
                break;
1040
            }
1041
        }
1042
        op = CMPL;
1043
        imm = 0;
1044
        break;
1045

    
1046
    default:
1047
        tcg_abort ();
1048
    }
1049
    op |= BF (cr) | (arch64 << 21);
1050

    
1051
    if (imm)
1052
        tcg_out32 (s, op | RA (arg1) | (arg2 & 0xffff));
1053
    else {
1054
        if (const_arg2) {
1055
            tcg_out_movi (s, TCG_TYPE_I64, 0, arg2);
1056
            tcg_out32 (s, op | RA (arg1) | RB (0));
1057
        }
1058
        else
1059
            tcg_out32 (s, op | RA (arg1) | RB (arg2));
1060
    }
1061

    
1062
}
1063

    
1064
static void tcg_out_setcond (TCGContext *s, TCGType type, TCGCond cond,
1065
                             TCGArg arg0, TCGArg arg1, TCGArg arg2,
1066
                             int const_arg2)
1067
{
1068
    int crop, sh, arg;
1069

    
1070
    switch (cond) {
1071
    case TCG_COND_EQ:
1072
        if (const_arg2) {
1073
            if (!arg2) {
1074
                arg = arg1;
1075
            }
1076
            else {
1077
                arg = 0;
1078
                if ((uint16_t) arg2 == arg2) {
1079
                    tcg_out32(s, XORI | SAI(arg1, 0, arg2));
1080
                }
1081
                else {
1082
                    tcg_out_movi (s, type, 0, arg2);
1083
                    tcg_out32 (s, XOR | SAB (arg1, 0, 0));
1084
                }
1085
            }
1086
        }
1087
        else {
1088
            arg = 0;
1089
            tcg_out32 (s, XOR | SAB (arg1, 0, arg2));
1090
        }
1091

    
1092
        if (type == TCG_TYPE_I64) {
1093
            tcg_out32 (s, CNTLZD | RS (arg) | RA (0));
1094
            tcg_out_rld (s, RLDICL, arg0, 0, 58, 6);
1095
        }
1096
        else {
1097
            tcg_out32 (s, CNTLZW | RS (arg) | RA (0));
1098
            tcg_out_rlw(s, RLWINM, arg0, 0, 27, 5, 31);
1099
        }
1100
        break;
1101

    
1102
    case TCG_COND_NE:
1103
        if (const_arg2) {
1104
            if (!arg2) {
1105
                arg = arg1;
1106
            }
1107
            else {
1108
                arg = 0;
1109
                if ((uint16_t) arg2 == arg2) {
1110
                    tcg_out32(s, XORI | SAI(arg1, 0, arg2));
1111
                } else {
1112
                    tcg_out_movi (s, type, 0, arg2);
1113
                    tcg_out32 (s, XOR | SAB (arg1, 0, 0));
1114
                }
1115
            }
1116
        }
1117
        else {
1118
            arg = 0;
1119
            tcg_out32 (s, XOR | SAB (arg1, 0, arg2));
1120
        }
1121

    
1122
        /* Make sure and discard the high 32-bits of the input.  */
1123
        if (type == TCG_TYPE_I32) {
1124
            tcg_out32(s, EXTSW | RA(TCG_REG_R0) | RS(arg));
1125
            arg = TCG_REG_R0;
1126
        }
1127

    
1128
        if (arg == arg1 && arg1 == arg0) {
1129
            tcg_out32(s, ADDIC | TAI(0, arg, -1));
1130
            tcg_out32(s, SUBFE | TAB(arg0, 0, arg));
1131
        }
1132
        else {
1133
            tcg_out32(s, ADDIC | TAI(arg0, arg, -1));
1134
            tcg_out32(s, SUBFE | TAB(arg0, arg0, arg));
1135
        }
1136
        break;
1137

    
1138
    case TCG_COND_GT:
1139
    case TCG_COND_GTU:
1140
        sh = 30;
1141
        crop = 0;
1142
        goto crtest;
1143

    
1144
    case TCG_COND_LT:
1145
    case TCG_COND_LTU:
1146
        sh = 29;
1147
        crop = 0;
1148
        goto crtest;
1149

    
1150
    case TCG_COND_GE:
1151
    case TCG_COND_GEU:
1152
        sh = 31;
1153
        crop = CRNOR | BT (7, CR_EQ) | BA (7, CR_LT) | BB (7, CR_LT);
1154
        goto crtest;
1155

    
1156
    case TCG_COND_LE:
1157
    case TCG_COND_LEU:
1158
        sh = 31;
1159
        crop = CRNOR | BT (7, CR_EQ) | BA (7, CR_GT) | BB (7, CR_GT);
1160
    crtest:
1161
        tcg_out_cmp (s, cond, arg1, arg2, const_arg2, 7, type == TCG_TYPE_I64);
1162
        if (crop) tcg_out32 (s, crop);
1163
        tcg_out32 (s, MFCR | RT (0));
1164
        tcg_out_rlw(s, RLWINM, arg0, 0, sh, 31, 31);
1165
        break;
1166

    
1167
    default:
1168
        tcg_abort ();
1169
    }
1170
}
1171

    
1172
static void tcg_out_bc (TCGContext *s, int bc, int label_index)
1173
{
1174
    TCGLabel *l = &s->labels[label_index];
1175

    
1176
    if (l->has_value)
1177
        tcg_out32 (s, bc | reloc_pc14_val (s->code_ptr, l->u.value));
1178
    else {
1179
        uint16_t val = *(uint16_t *) &s->code_ptr[2];
1180

    
1181
        /* Thanks to Andrzej Zaborowski */
1182
        tcg_out32 (s, bc | (val & 0xfffc));
1183
        tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL14, label_index, 0);
1184
    }
1185
}
1186

    
1187
static void tcg_out_brcond (TCGContext *s, TCGCond cond,
1188
                            TCGArg arg1, TCGArg arg2, int const_arg2,
1189
                            int label_index, int arch64)
1190
{
1191
    tcg_out_cmp (s, cond, arg1, arg2, const_arg2, 7, arch64);
1192
    tcg_out_bc (s, tcg_to_bc[cond], label_index);
1193
}
1194

    
1195
void ppc_tb_set_jmp_target (unsigned long jmp_addr, unsigned long addr)
1196
{
1197
    TCGContext s;
1198
    unsigned long patch_size;
1199

    
1200
    s.code_ptr = (uint8_t *) jmp_addr;
1201
    tcg_out_b (&s, 0, addr);
1202
    patch_size = s.code_ptr - (uint8_t *) jmp_addr;
1203
    flush_icache_range (jmp_addr, jmp_addr + patch_size);
1204
}
1205

    
1206
static void tcg_out_op (TCGContext *s, TCGOpcode opc, const TCGArg *args,
1207
                        const int *const_args)
1208
{
1209
    TCGArg a0, a1, a2;
1210
    int c;
1211

    
1212
    switch (opc) {
1213
    case INDEX_op_exit_tb:
1214
        tcg_out_movi (s, TCG_TYPE_I64, TCG_REG_R3, args[0]);
1215
        tcg_out_b (s, 0, (tcg_target_long) tb_ret_addr);
1216
        break;
1217
    case INDEX_op_goto_tb:
1218
        if (s->tb_jmp_offset) {
1219
            /* direct jump method */
1220

    
1221
            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
1222
            s->code_ptr += 28;
1223
        }
1224
        else {
1225
            tcg_abort ();
1226
        }
1227
        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1228
        break;
1229
    case INDEX_op_br:
1230
        {
1231
            TCGLabel *l = &s->labels[args[0]];
1232

    
1233
            if (l->has_value) {
1234
                tcg_out_b (s, 0, l->u.value);
1235
            }
1236
            else {
1237
                uint32_t val = *(uint32_t *) s->code_ptr;
1238

    
1239
                /* Thanks to Andrzej Zaborowski */
1240
                tcg_out32 (s, B | (val & 0x3fffffc));
1241
                tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL24, args[0], 0);
1242
            }
1243
        }
1244
        break;
1245
    case INDEX_op_call:
1246
        tcg_out_call (s, args[0], const_args[0]);
1247
        break;
1248
    case INDEX_op_movi_i32:
1249
        tcg_out_movi (s, TCG_TYPE_I32, args[0], args[1]);
1250
        break;
1251
    case INDEX_op_movi_i64:
1252
        tcg_out_movi (s, TCG_TYPE_I64, args[0], args[1]);
1253
        break;
1254
    case INDEX_op_ld8u_i32:
1255
    case INDEX_op_ld8u_i64:
1256
        tcg_out_ldst (s, args[0], args[1], args[2], LBZ, LBZX);
1257
        break;
1258
    case INDEX_op_ld8s_i32:
1259
    case INDEX_op_ld8s_i64:
1260
        tcg_out_ldst (s, args[0], args[1], args[2], LBZ, LBZX);
1261
        tcg_out32 (s, EXTSB | RS (args[0]) | RA (args[0]));
1262
        break;
1263
    case INDEX_op_ld16u_i32:
1264
    case INDEX_op_ld16u_i64:
1265
        tcg_out_ldst (s, args[0], args[1], args[2], LHZ, LHZX);
1266
        break;
1267
    case INDEX_op_ld16s_i32:
1268
    case INDEX_op_ld16s_i64:
1269
        tcg_out_ldst (s, args[0], args[1], args[2], LHA, LHAX);
1270
        break;
1271
    case INDEX_op_ld_i32:
1272
    case INDEX_op_ld32u_i64:
1273
        tcg_out_ldst (s, args[0], args[1], args[2], LWZ, LWZX);
1274
        break;
1275
    case INDEX_op_ld32s_i64:
1276
        tcg_out_ldsta (s, args[0], args[1], args[2], LWA, LWAX);
1277
        break;
1278
    case INDEX_op_ld_i64:
1279
        tcg_out_ldsta (s, args[0], args[1], args[2], LD, LDX);
1280
        break;
1281
    case INDEX_op_st8_i32:
1282
    case INDEX_op_st8_i64:
1283
        tcg_out_ldst (s, args[0], args[1], args[2], STB, STBX);
1284
        break;
1285
    case INDEX_op_st16_i32:
1286
    case INDEX_op_st16_i64:
1287
        tcg_out_ldst (s, args[0], args[1], args[2], STH, STHX);
1288
        break;
1289
    case INDEX_op_st_i32:
1290
    case INDEX_op_st32_i64:
1291
        tcg_out_ldst (s, args[0], args[1], args[2], STW, STWX);
1292
        break;
1293
    case INDEX_op_st_i64:
1294
        tcg_out_ldsta (s, args[0], args[1], args[2], STD, STDX);
1295
        break;
1296

    
1297
    case INDEX_op_add_i32:
1298
        a0 = args[0], a1 = args[1], a2 = args[2];
1299
        if (const_args[2]) {
1300
            int32_t l, h;
1301
        do_addi_32:
1302
            l = (int16_t)a2;
1303
            h = a2 - l;
1304
            if (h) {
1305
                tcg_out32(s, ADDIS | TAI(a0, a1, h >> 16));
1306
                a1 = a0;
1307
            }
1308
            if (l || a0 != a1) {
1309
                tcg_out32(s, ADDI | TAI(a0, a1, l));
1310
            }
1311
        } else {
1312
            tcg_out32(s, ADD | TAB(a0, a1, a2));
1313
        }
1314
        break;
1315
    case INDEX_op_sub_i32:
1316
        a0 = args[0], a1 = args[1], a2 = args[2];
1317
        if (const_args[2]) {
1318
            a2 = -a2;
1319
            goto do_addi_32;
1320
        } else {
1321
            tcg_out32(s, SUBF | TAB(a0, a2, a1));
1322
        }
1323
        break;
1324

    
1325
    case INDEX_op_and_i64:
1326
    case INDEX_op_and_i32:
1327
        if (const_args[2]) {
1328
            if ((args[2] & 0xffff) == args[2]) {
1329
                tcg_out32(s, ANDI | SAI(args[1], args[0], args[2]));
1330
            } else if ((args[2] & 0xffff0000) == args[2]) {
1331
                tcg_out32(s, ANDIS | SAI(args[1], args[0], args[2] >> 16));
1332
            } else {
1333
                tcg_out_movi (s, (opc == INDEX_op_and_i32
1334
                                  ? TCG_TYPE_I32
1335
                                  : TCG_TYPE_I64),
1336
                              0, args[2]);
1337
                tcg_out32 (s, AND | SAB (args[1], args[0], 0));
1338
            }
1339
        }
1340
        else
1341
            tcg_out32 (s, AND | SAB (args[1], args[0], args[2]));
1342
        break;
1343
    case INDEX_op_or_i64:
1344
    case INDEX_op_or_i32:
1345
        if (const_args[2]) {
1346
            if (args[2] & 0xffff) {
1347
                tcg_out32(s, ORI | SAI(args[1], args[0], args[2]));
1348
                if (args[2] >> 16) {
1349
                    tcg_out32(s, ORIS | SAI(args[0], args[0], args[2] >> 16));
1350
                }
1351
            }
1352
            else {
1353
                tcg_out32(s, ORIS | SAI(args[1], args[0], args[2] >> 16));
1354
            }
1355
        }
1356
        else
1357
            tcg_out32 (s, OR | SAB (args[1], args[0], args[2]));
1358
        break;
1359
    case INDEX_op_xor_i64:
1360
    case INDEX_op_xor_i32:
1361
        if (const_args[2]) {
1362
            if ((args[2] & 0xffff) == args[2]) {
1363
                tcg_out32(s, XORI | SAI(args[1], args[0], args[2]));
1364
            } else if ((args[2] & 0xffff0000) == args[2]) {
1365
                tcg_out32(s, XORIS | SAI(args[1], args[0], args[2] >> 16));
1366
            } else {
1367
                tcg_out_movi (s, (opc == INDEX_op_and_i32
1368
                                  ? TCG_TYPE_I32
1369
                                  : TCG_TYPE_I64),
1370
                              0, args[2]);
1371
                tcg_out32 (s, XOR | SAB (args[1], args[0], 0));
1372
            }
1373
        }
1374
        else
1375
            tcg_out32 (s, XOR | SAB (args[1], args[0], args[2]));
1376
        break;
1377

    
1378
    case INDEX_op_mul_i32:
1379
        if (const_args[2]) {
1380
            if (args[2] == (int16_t) args[2])
1381
                tcg_out32 (s, MULLI | RT (args[0]) | RA (args[1])
1382
                           | (args[2] & 0xffff));
1383
            else {
1384
                tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]);
1385
                tcg_out32 (s, MULLW | TAB (args[0], args[1], 0));
1386
            }
1387
        }
1388
        else
1389
            tcg_out32 (s, MULLW | TAB (args[0], args[1], args[2]));
1390
        break;
1391

    
1392
    case INDEX_op_div_i32:
1393
        tcg_out32 (s, DIVW | TAB (args[0], args[1], args[2]));
1394
        break;
1395

    
1396
    case INDEX_op_divu_i32:
1397
        tcg_out32 (s, DIVWU | TAB (args[0], args[1], args[2]));
1398
        break;
1399

    
1400
    case INDEX_op_rem_i32:
1401
        tcg_out32 (s, DIVW | TAB (0, args[1], args[2]));
1402
        tcg_out32 (s, MULLW | TAB (0, 0, args[2]));
1403
        tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
1404
        break;
1405

    
1406
    case INDEX_op_remu_i32:
1407
        tcg_out32 (s, DIVWU | TAB (0, args[1], args[2]));
1408
        tcg_out32 (s, MULLW | TAB (0, 0, args[2]));
1409
        tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
1410
        break;
1411

    
1412
    case INDEX_op_shl_i32:
1413
        if (const_args[2]) {
1414
            tcg_out_rlw(s, RLWINM, args[0], args[1], args[2], 0, 31 - args[2]);
1415
        } else {
1416
            tcg_out32 (s, SLW | SAB (args[1], args[0], args[2]));
1417
        }
1418
        break;
1419
    case INDEX_op_shr_i32:
1420
        if (const_args[2]) {
1421
            tcg_out_rlw(s, RLWINM, args[0], args[1], 32 - args[2], args[2], 31);
1422
        } else {
1423
            tcg_out32 (s, SRW | SAB (args[1], args[0], args[2]));
1424
        }
1425
        break;
1426
    case INDEX_op_sar_i32:
1427
        if (const_args[2])
1428
            tcg_out32 (s, SRAWI | RS (args[1]) | RA (args[0]) | SH (args[2]));
1429
        else
1430
            tcg_out32 (s, SRAW | SAB (args[1], args[0], args[2]));
1431
        break;
1432

    
1433
    case INDEX_op_brcond_i32:
1434
        tcg_out_brcond (s, args[2], args[0], args[1], const_args[1], args[3], 0);
1435
        break;
1436

    
1437
    case INDEX_op_brcond_i64:
1438
        tcg_out_brcond (s, args[2], args[0], args[1], const_args[1], args[3], 1);
1439
        break;
1440

    
1441
    case INDEX_op_neg_i32:
1442
    case INDEX_op_neg_i64:
1443
        tcg_out32 (s, NEG | RT (args[0]) | RA (args[1]));
1444
        break;
1445

    
1446
    case INDEX_op_not_i32:
1447
    case INDEX_op_not_i64:
1448
        tcg_out32 (s, NOR | SAB (args[1], args[0], args[1]));
1449
        break;
1450

    
1451
    case INDEX_op_add_i64:
1452
        a0 = args[0], a1 = args[1], a2 = args[2];
1453
        if (const_args[2]) {
1454
            int32_t l0, h1, h2;
1455
        do_addi_64:
1456
            /* We can always split any 32-bit signed constant into 3 pieces.
1457
               Note the positive 0x80000000 coming from the sub_i64 path,
1458
               handled with the same code we need for eg 0x7fff8000.  */
1459
            assert(a2 == (int32_t)a2 || a2 == 0x80000000);
1460
            l0 = (int16_t)a2;
1461
            h1 = a2 - l0;
1462
            h2 = 0;
1463
            if (h1 < 0 && (int64_t)a2 > 0) {
1464
                h2 = 0x40000000;
1465
                h1 = a2 - h2 - l0;
1466
            }
1467
            assert((TCGArg)h2 + h1 + l0 == a2);
1468

    
1469
            if (h2) {
1470
                tcg_out32(s, ADDIS | TAI(a0, a1, h2 >> 16));
1471
                a1 = a0;
1472
            }
1473
            if (h1) {
1474
                tcg_out32(s, ADDIS | TAI(a0, a1, h1 >> 16));
1475
                a1 = a0;
1476
            }
1477
            if (l0 || a0 != a1) {
1478
                tcg_out32(s, ADDI | TAI(a0, a1, l0));
1479
            }
1480
        } else {
1481
            tcg_out32(s, ADD | TAB(a0, a1, a2));
1482
        }
1483
        break;
1484
    case INDEX_op_sub_i64:
1485
        a0 = args[0], a1 = args[1], a2 = args[2];
1486
        if (const_args[2]) {
1487
            a2 = -a2;
1488
            goto do_addi_64;
1489
        } else {
1490
            tcg_out32(s, SUBF | TAB(a0, a2, a1));
1491
        }
1492
        break;
1493

    
1494
    case INDEX_op_shl_i64:
1495
        if (const_args[2])
1496
            tcg_out_shli64(s, args[0], args[1], args[2]);
1497
        else
1498
            tcg_out32 (s, SLD | SAB (args[1], args[0], args[2]));
1499
        break;
1500
    case INDEX_op_shr_i64:
1501
        if (const_args[2])
1502
            tcg_out_shri64(s, args[0], args[1], args[2]);
1503
        else
1504
            tcg_out32 (s, SRD | SAB (args[1], args[0], args[2]));
1505
        break;
1506
    case INDEX_op_sar_i64:
1507
        if (const_args[2]) {
1508
            int sh = SH (args[2] & 0x1f) | (((args[2] >> 5) & 1) << 1);
1509
            tcg_out32 (s, SRADI | RA (args[0]) | RS (args[1]) | sh);
1510
        }
1511
        else
1512
            tcg_out32 (s, SRAD | SAB (args[1], args[0], args[2]));
1513
        break;
1514

    
1515
    case INDEX_op_mul_i64:
1516
        tcg_out32 (s, MULLD | TAB (args[0], args[1], args[2]));
1517
        break;
1518
    case INDEX_op_div_i64:
1519
        tcg_out32 (s, DIVD | TAB (args[0], args[1], args[2]));
1520
        break;
1521
    case INDEX_op_divu_i64:
1522
        tcg_out32 (s, DIVDU | TAB (args[0], args[1], args[2]));
1523
        break;
1524
    case INDEX_op_rem_i64:
1525
        tcg_out32 (s, DIVD | TAB (0, args[1], args[2]));
1526
        tcg_out32 (s, MULLD | TAB (0, 0, args[2]));
1527
        tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
1528
        break;
1529
    case INDEX_op_remu_i64:
1530
        tcg_out32 (s, DIVDU | TAB (0, args[1], args[2]));
1531
        tcg_out32 (s, MULLD | TAB (0, 0, args[2]));
1532
        tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
1533
        break;
1534

    
1535
    case INDEX_op_qemu_ld8u:
1536
        tcg_out_qemu_ld (s, args, 0);
1537
        break;
1538
    case INDEX_op_qemu_ld8s:
1539
        tcg_out_qemu_ld (s, args, 0 | 4);
1540
        break;
1541
    case INDEX_op_qemu_ld16u:
1542
        tcg_out_qemu_ld (s, args, 1);
1543
        break;
1544
    case INDEX_op_qemu_ld16s:
1545
        tcg_out_qemu_ld (s, args, 1 | 4);
1546
        break;
1547
    case INDEX_op_qemu_ld32:
1548
    case INDEX_op_qemu_ld32u:
1549
        tcg_out_qemu_ld (s, args, 2);
1550
        break;
1551
    case INDEX_op_qemu_ld32s:
1552
        tcg_out_qemu_ld (s, args, 2 | 4);
1553
        break;
1554
    case INDEX_op_qemu_ld64:
1555
        tcg_out_qemu_ld (s, args, 3);
1556
        break;
1557
    case INDEX_op_qemu_st8:
1558
        tcg_out_qemu_st (s, args, 0);
1559
        break;
1560
    case INDEX_op_qemu_st16:
1561
        tcg_out_qemu_st (s, args, 1);
1562
        break;
1563
    case INDEX_op_qemu_st32:
1564
        tcg_out_qemu_st (s, args, 2);
1565
        break;
1566
    case INDEX_op_qemu_st64:
1567
        tcg_out_qemu_st (s, args, 3);
1568
        break;
1569

    
1570
    case INDEX_op_ext8s_i32:
1571
    case INDEX_op_ext8s_i64:
1572
        c = EXTSB;
1573
        goto gen_ext;
1574
    case INDEX_op_ext16s_i32:
1575
    case INDEX_op_ext16s_i64:
1576
        c = EXTSH;
1577
        goto gen_ext;
1578
    case INDEX_op_ext32s_i64:
1579
        c = EXTSW;
1580
        goto gen_ext;
1581
    gen_ext:
1582
        tcg_out32 (s, c | RS (args[1]) | RA (args[0]));
1583
        break;
1584

    
1585
    case INDEX_op_ext32u_i64:
1586
        tcg_out_ext32u(s, args[0], args[1]);
1587
        break;
1588

    
1589
    case INDEX_op_setcond_i32:
1590
        tcg_out_setcond (s, TCG_TYPE_I32, args[3], args[0], args[1], args[2],
1591
                         const_args[2]);
1592
        break;
1593
    case INDEX_op_setcond_i64:
1594
        tcg_out_setcond (s, TCG_TYPE_I64, args[3], args[0], args[1], args[2],
1595
                         const_args[2]);
1596
        break;
1597

    
1598
    default:
1599
        tcg_dump_ops (s);
1600
        tcg_abort ();
1601
    }
1602
}
1603

    
1604
static const TCGTargetOpDef ppc_op_defs[] = {
1605
    { INDEX_op_exit_tb, { } },
1606
    { INDEX_op_goto_tb, { } },
1607
    { INDEX_op_call, { "ri" } },
1608
    { INDEX_op_br, { } },
1609

    
1610
    { INDEX_op_mov_i32, { "r", "r" } },
1611
    { INDEX_op_mov_i64, { "r", "r" } },
1612
    { INDEX_op_movi_i32, { "r" } },
1613
    { INDEX_op_movi_i64, { "r" } },
1614

    
1615
    { INDEX_op_ld8u_i32, { "r", "r" } },
1616
    { INDEX_op_ld8s_i32, { "r", "r" } },
1617
    { INDEX_op_ld16u_i32, { "r", "r" } },
1618
    { INDEX_op_ld16s_i32, { "r", "r" } },
1619
    { INDEX_op_ld_i32, { "r", "r" } },
1620
    { INDEX_op_ld_i64, { "r", "r" } },
1621
    { INDEX_op_st8_i32, { "r", "r" } },
1622
    { INDEX_op_st8_i64, { "r", "r" } },
1623
    { INDEX_op_st16_i32, { "r", "r" } },
1624
    { INDEX_op_st16_i64, { "r", "r" } },
1625
    { INDEX_op_st_i32, { "r", "r" } },
1626
    { INDEX_op_st_i64, { "r", "r" } },
1627
    { INDEX_op_st32_i64, { "r", "r" } },
1628

    
1629
    { INDEX_op_ld8u_i64, { "r", "r" } },
1630
    { INDEX_op_ld8s_i64, { "r", "r" } },
1631
    { INDEX_op_ld16u_i64, { "r", "r" } },
1632
    { INDEX_op_ld16s_i64, { "r", "r" } },
1633
    { INDEX_op_ld32u_i64, { "r", "r" } },
1634
    { INDEX_op_ld32s_i64, { "r", "r" } },
1635

    
1636
    { INDEX_op_add_i32, { "r", "r", "ri" } },
1637
    { INDEX_op_mul_i32, { "r", "r", "ri" } },
1638
    { INDEX_op_div_i32, { "r", "r", "r" } },
1639
    { INDEX_op_divu_i32, { "r", "r", "r" } },
1640
    { INDEX_op_rem_i32, { "r", "r", "r" } },
1641
    { INDEX_op_remu_i32, { "r", "r", "r" } },
1642
    { INDEX_op_sub_i32, { "r", "r", "ri" } },
1643
    { INDEX_op_and_i32, { "r", "r", "ri" } },
1644
    { INDEX_op_or_i32, { "r", "r", "ri" } },
1645
    { INDEX_op_xor_i32, { "r", "r", "ri" } },
1646

    
1647
    { INDEX_op_shl_i32, { "r", "r", "ri" } },
1648
    { INDEX_op_shr_i32, { "r", "r", "ri" } },
1649
    { INDEX_op_sar_i32, { "r", "r", "ri" } },
1650

    
1651
    { INDEX_op_brcond_i32, { "r", "ri" } },
1652
    { INDEX_op_brcond_i64, { "r", "ri" } },
1653

    
1654
    { INDEX_op_neg_i32, { "r", "r" } },
1655
    { INDEX_op_not_i32, { "r", "r" } },
1656

    
1657
    { INDEX_op_add_i64, { "r", "r", "rT" } },
1658
    { INDEX_op_sub_i64, { "r", "r", "rT" } },
1659
    { INDEX_op_and_i64, { "r", "r", "rU" } },
1660
    { INDEX_op_or_i64, { "r", "r", "rU" } },
1661
    { INDEX_op_xor_i64, { "r", "r", "rU" } },
1662

    
1663
    { INDEX_op_shl_i64, { "r", "r", "ri" } },
1664
    { INDEX_op_shr_i64, { "r", "r", "ri" } },
1665
    { INDEX_op_sar_i64, { "r", "r", "ri" } },
1666

    
1667
    { INDEX_op_mul_i64, { "r", "r", "r" } },
1668
    { INDEX_op_div_i64, { "r", "r", "r" } },
1669
    { INDEX_op_divu_i64, { "r", "r", "r" } },
1670
    { INDEX_op_rem_i64, { "r", "r", "r" } },
1671
    { INDEX_op_remu_i64, { "r", "r", "r" } },
1672

    
1673
    { INDEX_op_neg_i64, { "r", "r" } },
1674
    { INDEX_op_not_i64, { "r", "r" } },
1675

    
1676
    { INDEX_op_qemu_ld8u, { "r", "L" } },
1677
    { INDEX_op_qemu_ld8s, { "r", "L" } },
1678
    { INDEX_op_qemu_ld16u, { "r", "L" } },
1679
    { INDEX_op_qemu_ld16s, { "r", "L" } },
1680
    { INDEX_op_qemu_ld32, { "r", "L" } },
1681
    { INDEX_op_qemu_ld32u, { "r", "L" } },
1682
    { INDEX_op_qemu_ld32s, { "r", "L" } },
1683
    { INDEX_op_qemu_ld64, { "r", "L" } },
1684

    
1685
    { INDEX_op_qemu_st8, { "S", "S" } },
1686
    { INDEX_op_qemu_st16, { "S", "S" } },
1687
    { INDEX_op_qemu_st32, { "S", "S" } },
1688
    { INDEX_op_qemu_st64, { "S", "S" } },
1689

    
1690
    { INDEX_op_ext8s_i32, { "r", "r" } },
1691
    { INDEX_op_ext16s_i32, { "r", "r" } },
1692
    { INDEX_op_ext8s_i64, { "r", "r" } },
1693
    { INDEX_op_ext16s_i64, { "r", "r" } },
1694
    { INDEX_op_ext32s_i64, { "r", "r" } },
1695
    { INDEX_op_ext32u_i64, { "r", "r" } },
1696

    
1697
    { INDEX_op_setcond_i32, { "r", "r", "ri" } },
1698
    { INDEX_op_setcond_i64, { "r", "r", "ri" } },
1699

    
1700
    { -1 },
1701
};
1702

    
1703
static void tcg_target_init (TCGContext *s)
1704
{
1705
    tcg_regset_set32 (tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
1706
    tcg_regset_set32 (tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff);
1707
    tcg_regset_set32 (tcg_target_call_clobber_regs, 0,
1708
                     (1 << TCG_REG_R0) |
1709
#ifdef __APPLE__
1710
                     (1 << TCG_REG_R2) |
1711
#endif
1712
                     (1 << TCG_REG_R3) |
1713
                     (1 << TCG_REG_R4) |
1714
                     (1 << TCG_REG_R5) |
1715
                     (1 << TCG_REG_R6) |
1716
                     (1 << TCG_REG_R7) |
1717
                     (1 << TCG_REG_R8) |
1718
                     (1 << TCG_REG_R9) |
1719
                     (1 << TCG_REG_R10) |
1720
                     (1 << TCG_REG_R11) |
1721
                     (1 << TCG_REG_R12)
1722
        );
1723

    
1724
    tcg_regset_clear (s->reserved_regs);
1725
    tcg_regset_set_reg (s->reserved_regs, TCG_REG_R0);
1726
    tcg_regset_set_reg (s->reserved_regs, TCG_REG_R1);
1727
#ifndef __APPLE__
1728
    tcg_regset_set_reg (s->reserved_regs, TCG_REG_R2);
1729
#endif
1730
    tcg_regset_set_reg (s->reserved_regs, TCG_REG_R13);
1731

    
1732
    tcg_add_target_add_op_defs (ppc_op_defs);
1733
}