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