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#include "elf.h" 26#include "../tcg-pool.c.inc" 27#include "../tcg-ldst.c.inc" 28 29/* 30 * Standardize on the _CALL_FOO symbols used by GCC: 31 * Apple XCode does not define _CALL_DARWIN. 32 * Clang defines _CALL_ELF (64-bit) but not _CALL_SYSV (32-bit). 33 */ 34#if !defined(_CALL_SYSV) && \ 35 !defined(_CALL_DARWIN) && \ 36 !defined(_CALL_AIX) && \ 37 !defined(_CALL_ELF) 38# if defined(__APPLE__) 39# define _CALL_DARWIN 40# elif defined(__ELF__) && TCG_TARGET_REG_BITS == 32 41# define _CALL_SYSV 42# else 43# error "Unknown ABI" 44# endif 45#endif 46 47#if TCG_TARGET_REG_BITS == 64 48# define TCG_TARGET_CALL_ARG_I32 TCG_CALL_ARG_EXTEND 49#else 50# define TCG_TARGET_CALL_ARG_I32 TCG_CALL_ARG_NORMAL 51#endif 52#ifdef _CALL_SYSV 53# define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_EVEN 54#else 55# define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_NORMAL 56#endif 57/* Note sysv arg alignment applies only to 2-word types, not more. */ 58#define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_NORMAL 59#define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_NORMAL 60 61/* For some memory operations, we need a scratch that isn't R0. For the AIX 62 calling convention, we can re-use the TOC register since we'll be reloading 63 it at every call. Otherwise R12 will do nicely as neither a call-saved 64 register nor a parameter register. */ 65#ifdef _CALL_AIX 66# define TCG_REG_TMP1 TCG_REG_R2 67#else 68# define TCG_REG_TMP1 TCG_REG_R12 69#endif 70 71#define TCG_VEC_TMP1 TCG_REG_V0 72#define TCG_VEC_TMP2 TCG_REG_V1 73 74#define TCG_REG_TB TCG_REG_R31 75#define USE_REG_TB (TCG_TARGET_REG_BITS == 64) 76 77/* Shorthand for size of a pointer. Avoid promotion to unsigned. */ 78#define SZP ((int)sizeof(void *)) 79 80/* Shorthand for size of a register. */ 81#define SZR (TCG_TARGET_REG_BITS / 8) 82 83#define TCG_CT_CONST_S16 0x100 84#define TCG_CT_CONST_U16 0x200 85#define TCG_CT_CONST_S32 0x400 86#define TCG_CT_CONST_U32 0x800 87#define TCG_CT_CONST_ZERO 0x1000 88#define TCG_CT_CONST_MONE 0x2000 89#define TCG_CT_CONST_WSZ 0x4000 90 91#define ALL_GENERAL_REGS 0xffffffffu 92#define ALL_VECTOR_REGS 0xffffffff00000000ull 93 94#ifdef CONFIG_SOFTMMU 95#define ALL_QLOAD_REGS \ 96 (ALL_GENERAL_REGS & \ 97 ~((1 << TCG_REG_R3) | (1 << TCG_REG_R4) | (1 << TCG_REG_R5))) 98#define ALL_QSTORE_REGS \ 99 (ALL_GENERAL_REGS & ~((1 << TCG_REG_R3) | (1 << TCG_REG_R4) | \ 100 (1 << TCG_REG_R5) | (1 << TCG_REG_R6))) 101#else 102#define ALL_QLOAD_REGS (ALL_GENERAL_REGS & ~(1 << TCG_REG_R3)) 103#define ALL_QSTORE_REGS ALL_QLOAD_REGS 104#endif 105 106TCGPowerISA have_isa; 107static bool have_isel; 108bool have_altivec; 109bool have_vsx; 110 111#ifndef CONFIG_SOFTMMU 112#define TCG_GUEST_BASE_REG 30 113#endif 114 115#ifdef CONFIG_DEBUG_TCG 116static const char tcg_target_reg_names[TCG_TARGET_NB_REGS][4] = { 117 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 118 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 119 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 120 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 121 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", 122 "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", 123 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", 124 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", 125}; 126#endif 127 128static const int tcg_target_reg_alloc_order[] = { 129 TCG_REG_R14, /* call saved registers */ 130 TCG_REG_R15, 131 TCG_REG_R16, 132 TCG_REG_R17, 133 TCG_REG_R18, 134 TCG_REG_R19, 135 TCG_REG_R20, 136 TCG_REG_R21, 137 TCG_REG_R22, 138 TCG_REG_R23, 139 TCG_REG_R24, 140 TCG_REG_R25, 141 TCG_REG_R26, 142 TCG_REG_R27, 143 TCG_REG_R28, 144 TCG_REG_R29, 145 TCG_REG_R30, 146 TCG_REG_R31, 147 TCG_REG_R12, /* call clobbered, non-arguments */ 148 TCG_REG_R11, 149 TCG_REG_R2, 150 TCG_REG_R13, 151 TCG_REG_R10, /* call clobbered, arguments */ 152 TCG_REG_R9, 153 TCG_REG_R8, 154 TCG_REG_R7, 155 TCG_REG_R6, 156 TCG_REG_R5, 157 TCG_REG_R4, 158 TCG_REG_R3, 159 160 /* V0 and V1 reserved as temporaries; V20 - V31 are call-saved */ 161 TCG_REG_V2, /* call clobbered, vectors */ 162 TCG_REG_V3, 163 TCG_REG_V4, 164 TCG_REG_V5, 165 TCG_REG_V6, 166 TCG_REG_V7, 167 TCG_REG_V8, 168 TCG_REG_V9, 169 TCG_REG_V10, 170 TCG_REG_V11, 171 TCG_REG_V12, 172 TCG_REG_V13, 173 TCG_REG_V14, 174 TCG_REG_V15, 175 TCG_REG_V16, 176 TCG_REG_V17, 177 TCG_REG_V18, 178 TCG_REG_V19, 179}; 180 181static const int tcg_target_call_iarg_regs[] = { 182 TCG_REG_R3, 183 TCG_REG_R4, 184 TCG_REG_R5, 185 TCG_REG_R6, 186 TCG_REG_R7, 187 TCG_REG_R8, 188 TCG_REG_R9, 189 TCG_REG_R10 190}; 191 192static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot) 193{ 194 tcg_debug_assert(kind == TCG_CALL_RET_NORMAL); 195 tcg_debug_assert(slot >= 0 && slot <= 1); 196 return TCG_REG_R3 + slot; 197} 198 199static const int tcg_target_callee_save_regs[] = { 200#ifdef _CALL_DARWIN 201 TCG_REG_R11, 202#endif 203 TCG_REG_R14, 204 TCG_REG_R15, 205 TCG_REG_R16, 206 TCG_REG_R17, 207 TCG_REG_R18, 208 TCG_REG_R19, 209 TCG_REG_R20, 210 TCG_REG_R21, 211 TCG_REG_R22, 212 TCG_REG_R23, 213 TCG_REG_R24, 214 TCG_REG_R25, 215 TCG_REG_R26, 216 TCG_REG_R27, /* currently used for the global env */ 217 TCG_REG_R28, 218 TCG_REG_R29, 219 TCG_REG_R30, 220 TCG_REG_R31 221}; 222 223static inline bool in_range_b(tcg_target_long target) 224{ 225 return target == sextract64(target, 0, 26); 226} 227 228static uint32_t reloc_pc24_val(const tcg_insn_unit *pc, 229 const tcg_insn_unit *target) 230{ 231 ptrdiff_t disp = tcg_ptr_byte_diff(target, pc); 232 tcg_debug_assert(in_range_b(disp)); 233 return disp & 0x3fffffc; 234} 235 236static bool reloc_pc24(tcg_insn_unit *src_rw, const tcg_insn_unit *target) 237{ 238 const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw); 239 ptrdiff_t disp = tcg_ptr_byte_diff(target, src_rx); 240 241 if (in_range_b(disp)) { 242 *src_rw = (*src_rw & ~0x3fffffc) | (disp & 0x3fffffc); 243 return true; 244 } 245 return false; 246} 247 248static uint16_t reloc_pc14_val(const tcg_insn_unit *pc, 249 const tcg_insn_unit *target) 250{ 251 ptrdiff_t disp = tcg_ptr_byte_diff(target, pc); 252 tcg_debug_assert(disp == (int16_t) disp); 253 return disp & 0xfffc; 254} 255 256static bool reloc_pc14(tcg_insn_unit *src_rw, const tcg_insn_unit *target) 257{ 258 const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw); 259 ptrdiff_t disp = tcg_ptr_byte_diff(target, src_rx); 260 261 if (disp == (int16_t) disp) { 262 *src_rw = (*src_rw & ~0xfffc) | (disp & 0xfffc); 263 return true; 264 } 265 return false; 266} 267 268/* test if a constant matches the constraint */ 269static bool tcg_target_const_match(int64_t val, TCGType type, int ct) 270{ 271 if (ct & TCG_CT_CONST) { 272 return 1; 273 } 274 275 /* The only 32-bit constraint we use aside from 276 TCG_CT_CONST is TCG_CT_CONST_S16. */ 277 if (type == TCG_TYPE_I32) { 278 val = (int32_t)val; 279 } 280 281 if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val) { 282 return 1; 283 } else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val) { 284 return 1; 285 } else if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) { 286 return 1; 287 } else if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val) { 288 return 1; 289 } else if ((ct & TCG_CT_CONST_ZERO) && val == 0) { 290 return 1; 291 } else if ((ct & TCG_CT_CONST_MONE) && val == -1) { 292 return 1; 293 } else if ((ct & TCG_CT_CONST_WSZ) 294 && val == (type == TCG_TYPE_I32 ? 32 : 64)) { 295 return 1; 296 } 297 return 0; 298} 299 300#define OPCD(opc) ((opc)<<26) 301#define XO19(opc) (OPCD(19)|((opc)<<1)) 302#define MD30(opc) (OPCD(30)|((opc)<<2)) 303#define MDS30(opc) (OPCD(30)|((opc)<<1)) 304#define XO31(opc) (OPCD(31)|((opc)<<1)) 305#define XO58(opc) (OPCD(58)|(opc)) 306#define XO62(opc) (OPCD(62)|(opc)) 307#define VX4(opc) (OPCD(4)|(opc)) 308 309#define B OPCD( 18) 310#define BC OPCD( 16) 311#define LBZ OPCD( 34) 312#define LHZ OPCD( 40) 313#define LHA OPCD( 42) 314#define LWZ OPCD( 32) 315#define LWZUX XO31( 55) 316#define STB OPCD( 38) 317#define STH OPCD( 44) 318#define STW OPCD( 36) 319 320#define STD XO62( 0) 321#define STDU XO62( 1) 322#define STDX XO31(149) 323 324#define LD XO58( 0) 325#define LDX XO31( 21) 326#define LDU XO58( 1) 327#define LDUX XO31( 53) 328#define LWA XO58( 2) 329#define LWAX XO31(341) 330 331#define ADDIC OPCD( 12) 332#define ADDI OPCD( 14) 333#define ADDIS OPCD( 15) 334#define ORI OPCD( 24) 335#define ORIS OPCD( 25) 336#define XORI OPCD( 26) 337#define XORIS OPCD( 27) 338#define ANDI OPCD( 28) 339#define ANDIS OPCD( 29) 340#define MULLI OPCD( 7) 341#define CMPLI OPCD( 10) 342#define CMPI OPCD( 11) 343#define SUBFIC OPCD( 8) 344 345#define LWZU OPCD( 33) 346#define STWU OPCD( 37) 347 348#define RLWIMI OPCD( 20) 349#define RLWINM OPCD( 21) 350#define RLWNM OPCD( 23) 351 352#define RLDICL MD30( 0) 353#define RLDICR MD30( 1) 354#define RLDIMI MD30( 3) 355#define RLDCL MDS30( 8) 356 357#define BCLR XO19( 16) 358#define BCCTR XO19(528) 359#define CRAND XO19(257) 360#define CRANDC XO19(129) 361#define CRNAND XO19(225) 362#define CROR XO19(449) 363#define CRNOR XO19( 33) 364 365#define EXTSB XO31(954) 366#define EXTSH XO31(922) 367#define EXTSW XO31(986) 368#define ADD XO31(266) 369#define ADDE XO31(138) 370#define ADDME XO31(234) 371#define ADDZE XO31(202) 372#define ADDC XO31( 10) 373#define AND XO31( 28) 374#define SUBF XO31( 40) 375#define SUBFC XO31( 8) 376#define SUBFE XO31(136) 377#define SUBFME XO31(232) 378#define SUBFZE XO31(200) 379#define OR XO31(444) 380#define XOR XO31(316) 381#define MULLW XO31(235) 382#define MULHW XO31( 75) 383#define MULHWU XO31( 11) 384#define DIVW XO31(491) 385#define DIVWU XO31(459) 386#define MODSW XO31(779) 387#define MODUW XO31(267) 388#define CMP XO31( 0) 389#define CMPL XO31( 32) 390#define LHBRX XO31(790) 391#define LWBRX XO31(534) 392#define LDBRX XO31(532) 393#define STHBRX XO31(918) 394#define STWBRX XO31(662) 395#define STDBRX XO31(660) 396#define MFSPR XO31(339) 397#define MTSPR XO31(467) 398#define SRAWI XO31(824) 399#define NEG XO31(104) 400#define MFCR XO31( 19) 401#define MFOCRF (MFCR | (1u << 20)) 402#define NOR XO31(124) 403#define CNTLZW XO31( 26) 404#define CNTLZD XO31( 58) 405#define CNTTZW XO31(538) 406#define CNTTZD XO31(570) 407#define CNTPOPW XO31(378) 408#define CNTPOPD XO31(506) 409#define ANDC XO31( 60) 410#define ORC XO31(412) 411#define EQV XO31(284) 412#define NAND XO31(476) 413#define ISEL XO31( 15) 414 415#define MULLD XO31(233) 416#define MULHD XO31( 73) 417#define MULHDU XO31( 9) 418#define DIVD XO31(489) 419#define DIVDU XO31(457) 420#define MODSD XO31(777) 421#define MODUD XO31(265) 422 423#define LBZX XO31( 87) 424#define LHZX XO31(279) 425#define LHAX XO31(343) 426#define LWZX XO31( 23) 427#define STBX XO31(215) 428#define STHX XO31(407) 429#define STWX XO31(151) 430 431#define EIEIO XO31(854) 432#define HWSYNC XO31(598) 433#define LWSYNC (HWSYNC | (1u << 21)) 434 435#define SPR(a, b) ((((a)<<5)|(b))<<11) 436#define LR SPR(8, 0) 437#define CTR SPR(9, 0) 438 439#define SLW XO31( 24) 440#define SRW XO31(536) 441#define SRAW XO31(792) 442 443#define SLD XO31( 27) 444#define SRD XO31(539) 445#define SRAD XO31(794) 446#define SRADI XO31(413<<1) 447 448#define BRH XO31(219) 449#define BRW XO31(155) 450#define BRD XO31(187) 451 452#define TW XO31( 4) 453#define TRAP (TW | TO(31)) 454 455#define NOP ORI /* ori 0,0,0 */ 456 457#define LVX XO31(103) 458#define LVEBX XO31(7) 459#define LVEHX XO31(39) 460#define LVEWX XO31(71) 461#define LXSDX (XO31(588) | 1) /* v2.06, force tx=1 */ 462#define LXVDSX (XO31(332) | 1) /* v2.06, force tx=1 */ 463#define LXSIWZX (XO31(12) | 1) /* v2.07, force tx=1 */ 464#define LXV (OPCD(61) | 8 | 1) /* v3.00, force tx=1 */ 465#define LXSD (OPCD(57) | 2) /* v3.00 */ 466#define LXVWSX (XO31(364) | 1) /* v3.00, force tx=1 */ 467 468#define STVX XO31(231) 469#define STVEWX XO31(199) 470#define STXSDX (XO31(716) | 1) /* v2.06, force sx=1 */ 471#define STXSIWX (XO31(140) | 1) /* v2.07, force sx=1 */ 472#define STXV (OPCD(61) | 8 | 5) /* v3.00, force sx=1 */ 473#define STXSD (OPCD(61) | 2) /* v3.00 */ 474 475#define VADDSBS VX4(768) 476#define VADDUBS VX4(512) 477#define VADDUBM VX4(0) 478#define VADDSHS VX4(832) 479#define VADDUHS VX4(576) 480#define VADDUHM VX4(64) 481#define VADDSWS VX4(896) 482#define VADDUWS VX4(640) 483#define VADDUWM VX4(128) 484#define VADDUDM VX4(192) /* v2.07 */ 485 486#define VSUBSBS VX4(1792) 487#define VSUBUBS VX4(1536) 488#define VSUBUBM VX4(1024) 489#define VSUBSHS VX4(1856) 490#define VSUBUHS VX4(1600) 491#define VSUBUHM VX4(1088) 492#define VSUBSWS VX4(1920) 493#define VSUBUWS VX4(1664) 494#define VSUBUWM VX4(1152) 495#define VSUBUDM VX4(1216) /* v2.07 */ 496 497#define VNEGW (VX4(1538) | (6 << 16)) /* v3.00 */ 498#define VNEGD (VX4(1538) | (7 << 16)) /* v3.00 */ 499 500#define VMAXSB VX4(258) 501#define VMAXSH VX4(322) 502#define VMAXSW VX4(386) 503#define VMAXSD VX4(450) /* v2.07 */ 504#define VMAXUB VX4(2) 505#define VMAXUH VX4(66) 506#define VMAXUW VX4(130) 507#define VMAXUD VX4(194) /* v2.07 */ 508#define VMINSB VX4(770) 509#define VMINSH VX4(834) 510#define VMINSW VX4(898) 511#define VMINSD VX4(962) /* v2.07 */ 512#define VMINUB VX4(514) 513#define VMINUH VX4(578) 514#define VMINUW VX4(642) 515#define VMINUD VX4(706) /* v2.07 */ 516 517#define VCMPEQUB VX4(6) 518#define VCMPEQUH VX4(70) 519#define VCMPEQUW VX4(134) 520#define VCMPEQUD VX4(199) /* v2.07 */ 521#define VCMPGTSB VX4(774) 522#define VCMPGTSH VX4(838) 523#define VCMPGTSW VX4(902) 524#define VCMPGTSD VX4(967) /* v2.07 */ 525#define VCMPGTUB VX4(518) 526#define VCMPGTUH VX4(582) 527#define VCMPGTUW VX4(646) 528#define VCMPGTUD VX4(711) /* v2.07 */ 529#define VCMPNEB VX4(7) /* v3.00 */ 530#define VCMPNEH VX4(71) /* v3.00 */ 531#define VCMPNEW VX4(135) /* v3.00 */ 532 533#define VSLB VX4(260) 534#define VSLH VX4(324) 535#define VSLW VX4(388) 536#define VSLD VX4(1476) /* v2.07 */ 537#define VSRB VX4(516) 538#define VSRH VX4(580) 539#define VSRW VX4(644) 540#define VSRD VX4(1732) /* v2.07 */ 541#define VSRAB VX4(772) 542#define VSRAH VX4(836) 543#define VSRAW VX4(900) 544#define VSRAD VX4(964) /* v2.07 */ 545#define VRLB VX4(4) 546#define VRLH VX4(68) 547#define VRLW VX4(132) 548#define VRLD VX4(196) /* v2.07 */ 549 550#define VMULEUB VX4(520) 551#define VMULEUH VX4(584) 552#define VMULEUW VX4(648) /* v2.07 */ 553#define VMULOUB VX4(8) 554#define VMULOUH VX4(72) 555#define VMULOUW VX4(136) /* v2.07 */ 556#define VMULUWM VX4(137) /* v2.07 */ 557#define VMULLD VX4(457) /* v3.10 */ 558#define VMSUMUHM VX4(38) 559 560#define VMRGHB VX4(12) 561#define VMRGHH VX4(76) 562#define VMRGHW VX4(140) 563#define VMRGLB VX4(268) 564#define VMRGLH VX4(332) 565#define VMRGLW VX4(396) 566 567#define VPKUHUM VX4(14) 568#define VPKUWUM VX4(78) 569 570#define VAND VX4(1028) 571#define VANDC VX4(1092) 572#define VNOR VX4(1284) 573#define VOR VX4(1156) 574#define VXOR VX4(1220) 575#define VEQV VX4(1668) /* v2.07 */ 576#define VNAND VX4(1412) /* v2.07 */ 577#define VORC VX4(1348) /* v2.07 */ 578 579#define VSPLTB VX4(524) 580#define VSPLTH VX4(588) 581#define VSPLTW VX4(652) 582#define VSPLTISB VX4(780) 583#define VSPLTISH VX4(844) 584#define VSPLTISW VX4(908) 585 586#define VSLDOI VX4(44) 587 588#define XXPERMDI (OPCD(60) | (10 << 3) | 7) /* v2.06, force ax=bx=tx=1 */ 589#define XXSEL (OPCD(60) | (3 << 4) | 0xf) /* v2.06, force ax=bx=cx=tx=1 */ 590#define XXSPLTIB (OPCD(60) | (360 << 1) | 1) /* v3.00, force tx=1 */ 591 592#define MFVSRD (XO31(51) | 1) /* v2.07, force sx=1 */ 593#define MFVSRWZ (XO31(115) | 1) /* v2.07, force sx=1 */ 594#define MTVSRD (XO31(179) | 1) /* v2.07, force tx=1 */ 595#define MTVSRWZ (XO31(243) | 1) /* v2.07, force tx=1 */ 596#define MTVSRDD (XO31(435) | 1) /* v3.00, force tx=1 */ 597#define MTVSRWS (XO31(403) | 1) /* v3.00, force tx=1 */ 598 599#define RT(r) ((r)<<21) 600#define RS(r) ((r)<<21) 601#define RA(r) ((r)<<16) 602#define RB(r) ((r)<<11) 603#define TO(t) ((t)<<21) 604#define SH(s) ((s)<<11) 605#define MB(b) ((b)<<6) 606#define ME(e) ((e)<<1) 607#define BO(o) ((o)<<21) 608#define MB64(b) ((b)<<5) 609#define FXM(b) (1 << (19 - (b))) 610 611#define VRT(r) (((r) & 31) << 21) 612#define VRA(r) (((r) & 31) << 16) 613#define VRB(r) (((r) & 31) << 11) 614#define VRC(r) (((r) & 31) << 6) 615 616#define LK 1 617 618#define TAB(t, a, b) (RT(t) | RA(a) | RB(b)) 619#define SAB(s, a, b) (RS(s) | RA(a) | RB(b)) 620#define TAI(s, a, i) (RT(s) | RA(a) | ((i) & 0xffff)) 621#define SAI(s, a, i) (RS(s) | RA(a) | ((i) & 0xffff)) 622 623#define BF(n) ((n)<<23) 624#define BI(n, c) (((c)+((n)*4))<<16) 625#define BT(n, c) (((c)+((n)*4))<<21) 626#define BA(n, c) (((c)+((n)*4))<<16) 627#define BB(n, c) (((c)+((n)*4))<<11) 628#define BC_(n, c) (((c)+((n)*4))<<6) 629 630#define BO_COND_TRUE BO(12) 631#define BO_COND_FALSE BO( 4) 632#define BO_ALWAYS BO(20) 633 634enum { 635 CR_LT, 636 CR_GT, 637 CR_EQ, 638 CR_SO 639}; 640 641static const uint32_t tcg_to_bc[] = { 642 [TCG_COND_EQ] = BC | BI(7, CR_EQ) | BO_COND_TRUE, 643 [TCG_COND_NE] = BC | BI(7, CR_EQ) | BO_COND_FALSE, 644 [TCG_COND_LT] = BC | BI(7, CR_LT) | BO_COND_TRUE, 645 [TCG_COND_GE] = BC | BI(7, CR_LT) | BO_COND_FALSE, 646 [TCG_COND_LE] = BC | BI(7, CR_GT) | BO_COND_FALSE, 647 [TCG_COND_GT] = BC | BI(7, CR_GT) | BO_COND_TRUE, 648 [TCG_COND_LTU] = BC | BI(7, CR_LT) | BO_COND_TRUE, 649 [TCG_COND_GEU] = BC | BI(7, CR_LT) | BO_COND_FALSE, 650 [TCG_COND_LEU] = BC | BI(7, CR_GT) | BO_COND_FALSE, 651 [TCG_COND_GTU] = BC | BI(7, CR_GT) | BO_COND_TRUE, 652}; 653 654/* The low bit here is set if the RA and RB fields must be inverted. */ 655static const uint32_t tcg_to_isel[] = { 656 [TCG_COND_EQ] = ISEL | BC_(7, CR_EQ), 657 [TCG_COND_NE] = ISEL | BC_(7, CR_EQ) | 1, 658 [TCG_COND_LT] = ISEL | BC_(7, CR_LT), 659 [TCG_COND_GE] = ISEL | BC_(7, CR_LT) | 1, 660 [TCG_COND_LE] = ISEL | BC_(7, CR_GT) | 1, 661 [TCG_COND_GT] = ISEL | BC_(7, CR_GT), 662 [TCG_COND_LTU] = ISEL | BC_(7, CR_LT), 663 [TCG_COND_GEU] = ISEL | BC_(7, CR_LT) | 1, 664 [TCG_COND_LEU] = ISEL | BC_(7, CR_GT) | 1, 665 [TCG_COND_GTU] = ISEL | BC_(7, CR_GT), 666}; 667 668static bool patch_reloc(tcg_insn_unit *code_ptr, int type, 669 intptr_t value, intptr_t addend) 670{ 671 const tcg_insn_unit *target; 672 int16_t lo; 673 int32_t hi; 674 675 value += addend; 676 target = (const tcg_insn_unit *)value; 677 678 switch (type) { 679 case R_PPC_REL14: 680 return reloc_pc14(code_ptr, target); 681 case R_PPC_REL24: 682 return reloc_pc24(code_ptr, target); 683 case R_PPC_ADDR16: 684 /* 685 * We are (slightly) abusing this relocation type. In particular, 686 * assert that the low 2 bits are zero, and do not modify them. 687 * That way we can use this with LD et al that have opcode bits 688 * in the low 2 bits of the insn. 689 */ 690 if ((value & 3) || value != (int16_t)value) { 691 return false; 692 } 693 *code_ptr = (*code_ptr & ~0xfffc) | (value & 0xfffc); 694 break; 695 case R_PPC_ADDR32: 696 /* 697 * We are abusing this relocation type. Again, this points to 698 * a pair of insns, lis + load. This is an absolute address 699 * relocation for PPC32 so the lis cannot be removed. 700 */ 701 lo = value; 702 hi = value - lo; 703 if (hi + lo != value) { 704 return false; 705 } 706 code_ptr[0] = deposit32(code_ptr[0], 0, 16, hi >> 16); 707 code_ptr[1] = deposit32(code_ptr[1], 0, 16, lo); 708 break; 709 default: 710 g_assert_not_reached(); 711 } 712 return true; 713} 714 715static void tcg_out_mem_long(TCGContext *s, int opi, int opx, TCGReg rt, 716 TCGReg base, tcg_target_long offset); 717 718static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg) 719{ 720 if (ret == arg) { 721 return true; 722 } 723 switch (type) { 724 case TCG_TYPE_I64: 725 tcg_debug_assert(TCG_TARGET_REG_BITS == 64); 726 /* fallthru */ 727 case TCG_TYPE_I32: 728 if (ret < TCG_REG_V0) { 729 if (arg < TCG_REG_V0) { 730 tcg_out32(s, OR | SAB(arg, ret, arg)); 731 break; 732 } else if (have_isa_2_07) { 733 tcg_out32(s, (type == TCG_TYPE_I32 ? MFVSRWZ : MFVSRD) 734 | VRT(arg) | RA(ret)); 735 break; 736 } else { 737 /* Altivec does not support vector->integer moves. */ 738 return false; 739 } 740 } else if (arg < TCG_REG_V0) { 741 if (have_isa_2_07) { 742 tcg_out32(s, (type == TCG_TYPE_I32 ? MTVSRWZ : MTVSRD) 743 | VRT(ret) | RA(arg)); 744 break; 745 } else { 746 /* Altivec does not support integer->vector moves. */ 747 return false; 748 } 749 } 750 /* fallthru */ 751 case TCG_TYPE_V64: 752 case TCG_TYPE_V128: 753 tcg_debug_assert(ret >= TCG_REG_V0 && arg >= TCG_REG_V0); 754 tcg_out32(s, VOR | VRT(ret) | VRA(arg) | VRB(arg)); 755 break; 756 default: 757 g_assert_not_reached(); 758 } 759 return true; 760} 761 762static inline void tcg_out_rld(TCGContext *s, int op, TCGReg ra, TCGReg rs, 763 int sh, int mb) 764{ 765 tcg_debug_assert(TCG_TARGET_REG_BITS == 64); 766 sh = SH(sh & 0x1f) | (((sh >> 5) & 1) << 1); 767 mb = MB64((mb >> 5) | ((mb << 1) & 0x3f)); 768 tcg_out32(s, op | RA(ra) | RS(rs) | sh | mb); 769} 770 771static inline void tcg_out_rlw(TCGContext *s, int op, TCGReg ra, TCGReg rs, 772 int sh, int mb, int me) 773{ 774 tcg_out32(s, op | RA(ra) | RS(rs) | SH(sh) | MB(mb) | ME(me)); 775} 776 777static inline void tcg_out_ext8s(TCGContext *s, TCGReg dst, TCGReg src) 778{ 779 tcg_out32(s, EXTSB | RA(dst) | RS(src)); 780} 781 782static inline void tcg_out_ext16s(TCGContext *s, TCGReg dst, TCGReg src) 783{ 784 tcg_out32(s, EXTSH | RA(dst) | RS(src)); 785} 786 787static inline void tcg_out_ext16u(TCGContext *s, TCGReg dst, TCGReg src) 788{ 789 tcg_out32(s, ANDI | SAI(src, dst, 0xffff)); 790} 791 792static inline void tcg_out_ext32s(TCGContext *s, TCGReg dst, TCGReg src) 793{ 794 tcg_out32(s, EXTSW | RA(dst) | RS(src)); 795} 796 797static inline void tcg_out_ext32u(TCGContext *s, TCGReg dst, TCGReg src) 798{ 799 tcg_out_rld(s, RLDICL, dst, src, 0, 32); 800} 801 802static inline void tcg_out_shli32(TCGContext *s, TCGReg dst, TCGReg src, int c) 803{ 804 tcg_out_rlw(s, RLWINM, dst, src, c, 0, 31 - c); 805} 806 807static inline void tcg_out_shli64(TCGContext *s, TCGReg dst, TCGReg src, int c) 808{ 809 tcg_out_rld(s, RLDICR, dst, src, c, 63 - c); 810} 811 812static inline void tcg_out_sari32(TCGContext *s, TCGReg dst, TCGReg src, int c) 813{ 814 /* Limit immediate shift count lest we create an illegal insn. */ 815 tcg_out32(s, SRAWI | RA(dst) | RS(src) | SH(c & 31)); 816} 817 818static inline void tcg_out_shri32(TCGContext *s, TCGReg dst, TCGReg src, int c) 819{ 820 tcg_out_rlw(s, RLWINM, dst, src, 32 - c, c, 31); 821} 822 823static inline void tcg_out_shri64(TCGContext *s, TCGReg dst, TCGReg src, int c) 824{ 825 tcg_out_rld(s, RLDICL, dst, src, 64 - c, c); 826} 827 828static inline void tcg_out_sari64(TCGContext *s, TCGReg dst, TCGReg src, int c) 829{ 830 tcg_out32(s, SRADI | RA(dst) | RS(src) | SH(c & 0x1f) | ((c >> 4) & 2)); 831} 832 833static void tcg_out_bswap16(TCGContext *s, TCGReg dst, TCGReg src, int flags) 834{ 835 TCGReg tmp = dst == src ? TCG_REG_R0 : dst; 836 837 if (have_isa_3_10) { 838 tcg_out32(s, BRH | RA(dst) | RS(src)); 839 if (flags & TCG_BSWAP_OS) { 840 tcg_out_ext16s(s, dst, dst); 841 } else if ((flags & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) { 842 tcg_out_ext16u(s, dst, dst); 843 } 844 return; 845 } 846 847 /* 848 * In the following, 849 * dep(a, b, m) -> (a & ~m) | (b & m) 850 * 851 * Begin with: src = xxxxabcd 852 */ 853 /* tmp = rol32(src, 24) & 0x000000ff = 0000000c */ 854 tcg_out_rlw(s, RLWINM, tmp, src, 24, 24, 31); 855 /* tmp = dep(tmp, rol32(src, 8), 0x0000ff00) = 000000dc */ 856 tcg_out_rlw(s, RLWIMI, tmp, src, 8, 16, 23); 857 858 if (flags & TCG_BSWAP_OS) { 859 tcg_out_ext16s(s, dst, tmp); 860 } else { 861 tcg_out_mov(s, TCG_TYPE_REG, dst, tmp); 862 } 863} 864 865static void tcg_out_bswap32(TCGContext *s, TCGReg dst, TCGReg src, int flags) 866{ 867 TCGReg tmp = dst == src ? TCG_REG_R0 : dst; 868 869 if (have_isa_3_10) { 870 tcg_out32(s, BRW | RA(dst) | RS(src)); 871 if (flags & TCG_BSWAP_OS) { 872 tcg_out_ext32s(s, dst, dst); 873 } else if ((flags & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) { 874 tcg_out_ext32u(s, dst, dst); 875 } 876 return; 877 } 878 879 /* 880 * Stolen from gcc's builtin_bswap32. 881 * In the following, 882 * dep(a, b, m) -> (a & ~m) | (b & m) 883 * 884 * Begin with: src = xxxxabcd 885 */ 886 /* tmp = rol32(src, 8) & 0xffffffff = 0000bcda */ 887 tcg_out_rlw(s, RLWINM, tmp, src, 8, 0, 31); 888 /* tmp = dep(tmp, rol32(src, 24), 0xff000000) = 0000dcda */ 889 tcg_out_rlw(s, RLWIMI, tmp, src, 24, 0, 7); 890 /* tmp = dep(tmp, rol32(src, 24), 0x0000ff00) = 0000dcba */ 891 tcg_out_rlw(s, RLWIMI, tmp, src, 24, 16, 23); 892 893 if (flags & TCG_BSWAP_OS) { 894 tcg_out_ext32s(s, dst, tmp); 895 } else { 896 tcg_out_mov(s, TCG_TYPE_REG, dst, tmp); 897 } 898} 899 900static void tcg_out_bswap64(TCGContext *s, TCGReg dst, TCGReg src) 901{ 902 TCGReg t0 = dst == src ? TCG_REG_R0 : dst; 903 TCGReg t1 = dst == src ? dst : TCG_REG_R0; 904 905 if (have_isa_3_10) { 906 tcg_out32(s, BRD | RA(dst) | RS(src)); 907 return; 908 } 909 910 /* 911 * In the following, 912 * dep(a, b, m) -> (a & ~m) | (b & m) 913 * 914 * Begin with: src = abcdefgh 915 */ 916 /* t0 = rol32(src, 8) & 0xffffffff = 0000fghe */ 917 tcg_out_rlw(s, RLWINM, t0, src, 8, 0, 31); 918 /* t0 = dep(t0, rol32(src, 24), 0xff000000) = 0000hghe */ 919 tcg_out_rlw(s, RLWIMI, t0, src, 24, 0, 7); 920 /* t0 = dep(t0, rol32(src, 24), 0x0000ff00) = 0000hgfe */ 921 tcg_out_rlw(s, RLWIMI, t0, src, 24, 16, 23); 922 923 /* t0 = rol64(t0, 32) = hgfe0000 */ 924 tcg_out_rld(s, RLDICL, t0, t0, 32, 0); 925 /* t1 = rol64(src, 32) = efghabcd */ 926 tcg_out_rld(s, RLDICL, t1, src, 32, 0); 927 928 /* t0 = dep(t0, rol32(t1, 24), 0xffffffff) = hgfebcda */ 929 tcg_out_rlw(s, RLWIMI, t0, t1, 8, 0, 31); 930 /* t0 = dep(t0, rol32(t1, 24), 0xff000000) = hgfedcda */ 931 tcg_out_rlw(s, RLWIMI, t0, t1, 24, 0, 7); 932 /* t0 = dep(t0, rol32(t1, 24), 0x0000ff00) = hgfedcba */ 933 tcg_out_rlw(s, RLWIMI, t0, t1, 24, 16, 23); 934 935 tcg_out_mov(s, TCG_TYPE_REG, dst, t0); 936} 937 938/* Emit a move into ret of arg, if it can be done in one insn. */ 939static bool tcg_out_movi_one(TCGContext *s, TCGReg ret, tcg_target_long arg) 940{ 941 if (arg == (int16_t)arg) { 942 tcg_out32(s, ADDI | TAI(ret, 0, arg)); 943 return true; 944 } 945 if (arg == (int32_t)arg && (arg & 0xffff) == 0) { 946 tcg_out32(s, ADDIS | TAI(ret, 0, arg >> 16)); 947 return true; 948 } 949 return false; 950} 951 952static void tcg_out_movi_int(TCGContext *s, TCGType type, TCGReg ret, 953 tcg_target_long arg, bool in_prologue) 954{ 955 intptr_t tb_diff; 956 tcg_target_long tmp; 957 int shift; 958 959 tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32); 960 961 if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) { 962 arg = (int32_t)arg; 963 } 964 965 /* Load 16-bit immediates with one insn. */ 966 if (tcg_out_movi_one(s, ret, arg)) { 967 return; 968 } 969 970 /* Load addresses within the TB with one insn. */ 971 tb_diff = tcg_tbrel_diff(s, (void *)arg); 972 if (!in_prologue && USE_REG_TB && tb_diff == (int16_t)tb_diff) { 973 tcg_out32(s, ADDI | TAI(ret, TCG_REG_TB, tb_diff)); 974 return; 975 } 976 977 /* Load 32-bit immediates with two insns. Note that we've already 978 eliminated bare ADDIS, so we know both insns are required. */ 979 if (TCG_TARGET_REG_BITS == 32 || arg == (int32_t)arg) { 980 tcg_out32(s, ADDIS | TAI(ret, 0, arg >> 16)); 981 tcg_out32(s, ORI | SAI(ret, ret, arg)); 982 return; 983 } 984 if (arg == (uint32_t)arg && !(arg & 0x8000)) { 985 tcg_out32(s, ADDI | TAI(ret, 0, arg)); 986 tcg_out32(s, ORIS | SAI(ret, ret, arg >> 16)); 987 return; 988 } 989 990 /* Load masked 16-bit value. */ 991 if (arg > 0 && (arg & 0x8000)) { 992 tmp = arg | 0x7fff; 993 if ((tmp & (tmp + 1)) == 0) { 994 int mb = clz64(tmp + 1) + 1; 995 tcg_out32(s, ADDI | TAI(ret, 0, arg)); 996 tcg_out_rld(s, RLDICL, ret, ret, 0, mb); 997 return; 998 } 999 } 1000 1001 /* Load common masks with 2 insns. */ 1002 shift = ctz64(arg); 1003 tmp = arg >> shift; 1004 if (tmp == (int16_t)tmp) { 1005 tcg_out32(s, ADDI | TAI(ret, 0, tmp)); 1006 tcg_out_shli64(s, ret, ret, shift); 1007 return; 1008 } 1009 shift = clz64(arg); 1010 if (tcg_out_movi_one(s, ret, arg << shift)) { 1011 tcg_out_shri64(s, ret, ret, shift); 1012 return; 1013 } 1014 1015 /* Load addresses within 2GB of TB with 2 (or rarely 3) insns. */ 1016 if (!in_prologue && USE_REG_TB && tb_diff == (int32_t)tb_diff) { 1017 tcg_out_mem_long(s, ADDI, ADD, ret, TCG_REG_TB, tb_diff); 1018 return; 1019 } 1020 1021 /* Use the constant pool, if possible. */ 1022 if (!in_prologue && USE_REG_TB) { 1023 new_pool_label(s, arg, R_PPC_ADDR16, s->code_ptr, 1024 tcg_tbrel_diff(s, NULL)); 1025 tcg_out32(s, LD | TAI(ret, TCG_REG_TB, 0)); 1026 return; 1027 } 1028 1029 tmp = arg >> 31 >> 1; 1030 tcg_out_movi(s, TCG_TYPE_I32, ret, tmp); 1031 if (tmp) { 1032 tcg_out_shli64(s, ret, ret, 32); 1033 } 1034 if (arg & 0xffff0000) { 1035 tcg_out32(s, ORIS | SAI(ret, ret, arg >> 16)); 1036 } 1037 if (arg & 0xffff) { 1038 tcg_out32(s, ORI | SAI(ret, ret, arg)); 1039 } 1040} 1041 1042static void tcg_out_dupi_vec(TCGContext *s, TCGType type, unsigned vece, 1043 TCGReg ret, int64_t val) 1044{ 1045 uint32_t load_insn; 1046 int rel, low; 1047 intptr_t add; 1048 1049 switch (vece) { 1050 case MO_8: 1051 low = (int8_t)val; 1052 if (low >= -16 && low < 16) { 1053 tcg_out32(s, VSPLTISB | VRT(ret) | ((val & 31) << 16)); 1054 return; 1055 } 1056 if (have_isa_3_00) { 1057 tcg_out32(s, XXSPLTIB | VRT(ret) | ((val & 0xff) << 11)); 1058 return; 1059 } 1060 break; 1061 1062 case MO_16: 1063 low = (int16_t)val; 1064 if (low >= -16 && low < 16) { 1065 tcg_out32(s, VSPLTISH | VRT(ret) | ((val & 31) << 16)); 1066 return; 1067 } 1068 break; 1069 1070 case MO_32: 1071 low = (int32_t)val; 1072 if (low >= -16 && low < 16) { 1073 tcg_out32(s, VSPLTISW | VRT(ret) | ((val & 31) << 16)); 1074 return; 1075 } 1076 break; 1077 } 1078 1079 /* 1080 * Otherwise we must load the value from the constant pool. 1081 */ 1082 if (USE_REG_TB) { 1083 rel = R_PPC_ADDR16; 1084 add = tcg_tbrel_diff(s, NULL); 1085 } else { 1086 rel = R_PPC_ADDR32; 1087 add = 0; 1088 } 1089 1090 if (have_vsx) { 1091 load_insn = type == TCG_TYPE_V64 ? LXSDX : LXVDSX; 1092 load_insn |= VRT(ret) | RB(TCG_REG_TMP1); 1093 if (TCG_TARGET_REG_BITS == 64) { 1094 new_pool_label(s, val, rel, s->code_ptr, add); 1095 } else { 1096 new_pool_l2(s, rel, s->code_ptr, add, val >> 32, val); 1097 } 1098 } else { 1099 load_insn = LVX | VRT(ret) | RB(TCG_REG_TMP1); 1100 if (TCG_TARGET_REG_BITS == 64) { 1101 new_pool_l2(s, rel, s->code_ptr, add, val, val); 1102 } else { 1103 new_pool_l4(s, rel, s->code_ptr, add, 1104 val >> 32, val, val >> 32, val); 1105 } 1106 } 1107 1108 if (USE_REG_TB) { 1109 tcg_out32(s, ADDI | TAI(TCG_REG_TMP1, 0, 0)); 1110 load_insn |= RA(TCG_REG_TB); 1111 } else { 1112 tcg_out32(s, ADDIS | TAI(TCG_REG_TMP1, 0, 0)); 1113 tcg_out32(s, ADDI | TAI(TCG_REG_TMP1, TCG_REG_TMP1, 0)); 1114 } 1115 tcg_out32(s, load_insn); 1116} 1117 1118static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg ret, 1119 tcg_target_long arg) 1120{ 1121 switch (type) { 1122 case TCG_TYPE_I32: 1123 case TCG_TYPE_I64: 1124 tcg_debug_assert(ret < TCG_REG_V0); 1125 tcg_out_movi_int(s, type, ret, arg, false); 1126 break; 1127 1128 default: 1129 g_assert_not_reached(); 1130 } 1131} 1132 1133static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, 1134 tcg_target_long imm) 1135{ 1136 /* This function is only used for passing structs by reference. */ 1137 g_assert_not_reached(); 1138} 1139 1140static bool mask_operand(uint32_t c, int *mb, int *me) 1141{ 1142 uint32_t lsb, test; 1143 1144 /* Accept a bit pattern like: 1145 0....01....1 1146 1....10....0 1147 0..01..10..0 1148 Keep track of the transitions. */ 1149 if (c == 0 || c == -1) { 1150 return false; 1151 } 1152 test = c; 1153 lsb = test & -test; 1154 test += lsb; 1155 if (test & (test - 1)) { 1156 return false; 1157 } 1158 1159 *me = clz32(lsb); 1160 *mb = test ? clz32(test & -test) + 1 : 0; 1161 return true; 1162} 1163 1164static bool mask64_operand(uint64_t c, int *mb, int *me) 1165{ 1166 uint64_t lsb; 1167 1168 if (c == 0) { 1169 return false; 1170 } 1171 1172 lsb = c & -c; 1173 /* Accept 1..10..0. */ 1174 if (c == -lsb) { 1175 *mb = 0; 1176 *me = clz64(lsb); 1177 return true; 1178 } 1179 /* Accept 0..01..1. */ 1180 if (lsb == 1 && (c & (c + 1)) == 0) { 1181 *mb = clz64(c + 1) + 1; 1182 *me = 63; 1183 return true; 1184 } 1185 return false; 1186} 1187 1188static void tcg_out_andi32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c) 1189{ 1190 int mb, me; 1191 1192 if (mask_operand(c, &mb, &me)) { 1193 tcg_out_rlw(s, RLWINM, dst, src, 0, mb, me); 1194 } else if ((c & 0xffff) == c) { 1195 tcg_out32(s, ANDI | SAI(src, dst, c)); 1196 return; 1197 } else if ((c & 0xffff0000) == c) { 1198 tcg_out32(s, ANDIS | SAI(src, dst, c >> 16)); 1199 return; 1200 } else { 1201 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R0, c); 1202 tcg_out32(s, AND | SAB(src, dst, TCG_REG_R0)); 1203 } 1204} 1205 1206static void tcg_out_andi64(TCGContext *s, TCGReg dst, TCGReg src, uint64_t c) 1207{ 1208 int mb, me; 1209 1210 tcg_debug_assert(TCG_TARGET_REG_BITS == 64); 1211 if (mask64_operand(c, &mb, &me)) { 1212 if (mb == 0) { 1213 tcg_out_rld(s, RLDICR, dst, src, 0, me); 1214 } else { 1215 tcg_out_rld(s, RLDICL, dst, src, 0, mb); 1216 } 1217 } else if ((c & 0xffff) == c) { 1218 tcg_out32(s, ANDI | SAI(src, dst, c)); 1219 return; 1220 } else if ((c & 0xffff0000) == c) { 1221 tcg_out32(s, ANDIS | SAI(src, dst, c >> 16)); 1222 return; 1223 } else { 1224 tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R0, c); 1225 tcg_out32(s, AND | SAB(src, dst, TCG_REG_R0)); 1226 } 1227} 1228 1229static void tcg_out_zori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c, 1230 int op_lo, int op_hi) 1231{ 1232 if (c >> 16) { 1233 tcg_out32(s, op_hi | SAI(src, dst, c >> 16)); 1234 src = dst; 1235 } 1236 if (c & 0xffff) { 1237 tcg_out32(s, op_lo | SAI(src, dst, c)); 1238 src = dst; 1239 } 1240} 1241 1242static void tcg_out_ori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c) 1243{ 1244 tcg_out_zori32(s, dst, src, c, ORI, ORIS); 1245} 1246 1247static void tcg_out_xori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c) 1248{ 1249 tcg_out_zori32(s, dst, src, c, XORI, XORIS); 1250} 1251 1252static void tcg_out_b(TCGContext *s, int mask, const tcg_insn_unit *target) 1253{ 1254 ptrdiff_t disp = tcg_pcrel_diff(s, target); 1255 if (in_range_b(disp)) { 1256 tcg_out32(s, B | (disp & 0x3fffffc) | mask); 1257 } else { 1258 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R0, (uintptr_t)target); 1259 tcg_out32(s, MTSPR | RS(TCG_REG_R0) | CTR); 1260 tcg_out32(s, BCCTR | BO_ALWAYS | mask); 1261 } 1262} 1263 1264static void tcg_out_mem_long(TCGContext *s, int opi, int opx, TCGReg rt, 1265 TCGReg base, tcg_target_long offset) 1266{ 1267 tcg_target_long orig = offset, l0, l1, extra = 0, align = 0; 1268 bool is_int_store = false; 1269 TCGReg rs = TCG_REG_TMP1; 1270 1271 switch (opi) { 1272 case LD: case LWA: 1273 align = 3; 1274 /* FALLTHRU */ 1275 default: 1276 if (rt > TCG_REG_R0 && rt < TCG_REG_V0) { 1277 rs = rt; 1278 break; 1279 } 1280 break; 1281 case LXSD: 1282 case STXSD: 1283 align = 3; 1284 break; 1285 case LXV: 1286 case STXV: 1287 align = 15; 1288 break; 1289 case STD: 1290 align = 3; 1291 /* FALLTHRU */ 1292 case STB: case STH: case STW: 1293 is_int_store = true; 1294 break; 1295 } 1296 1297 /* For unaligned, or very large offsets, use the indexed form. */ 1298 if (offset & align || offset != (int32_t)offset || opi == 0) { 1299 if (rs == base) { 1300 rs = TCG_REG_R0; 1301 } 1302 tcg_debug_assert(!is_int_store || rs != rt); 1303 tcg_out_movi(s, TCG_TYPE_PTR, rs, orig); 1304 tcg_out32(s, opx | TAB(rt & 31, base, rs)); 1305 return; 1306 } 1307 1308 l0 = (int16_t)offset; 1309 offset = (offset - l0) >> 16; 1310 l1 = (int16_t)offset; 1311 1312 if (l1 < 0 && orig >= 0) { 1313 extra = 0x4000; 1314 l1 = (int16_t)(offset - 0x4000); 1315 } 1316 if (l1) { 1317 tcg_out32(s, ADDIS | TAI(rs, base, l1)); 1318 base = rs; 1319 } 1320 if (extra) { 1321 tcg_out32(s, ADDIS | TAI(rs, base, extra)); 1322 base = rs; 1323 } 1324 if (opi != ADDI || base != rt || l0 != 0) { 1325 tcg_out32(s, opi | TAI(rt & 31, base, l0)); 1326 } 1327} 1328 1329static void tcg_out_vsldoi(TCGContext *s, TCGReg ret, 1330 TCGReg va, TCGReg vb, int shb) 1331{ 1332 tcg_out32(s, VSLDOI | VRT(ret) | VRA(va) | VRB(vb) | (shb << 6)); 1333} 1334 1335static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, 1336 TCGReg base, intptr_t offset) 1337{ 1338 int shift; 1339 1340 switch (type) { 1341 case TCG_TYPE_I32: 1342 if (ret < TCG_REG_V0) { 1343 tcg_out_mem_long(s, LWZ, LWZX, ret, base, offset); 1344 break; 1345 } 1346 if (have_isa_2_07 && have_vsx) { 1347 tcg_out_mem_long(s, 0, LXSIWZX, ret, base, offset); 1348 break; 1349 } 1350 tcg_debug_assert((offset & 3) == 0); 1351 tcg_out_mem_long(s, 0, LVEWX, ret, base, offset); 1352 shift = (offset - 4) & 0xc; 1353 if (shift) { 1354 tcg_out_vsldoi(s, ret, ret, ret, shift); 1355 } 1356 break; 1357 case TCG_TYPE_I64: 1358 if (ret < TCG_REG_V0) { 1359 tcg_debug_assert(TCG_TARGET_REG_BITS == 64); 1360 tcg_out_mem_long(s, LD, LDX, ret, base, offset); 1361 break; 1362 } 1363 /* fallthru */ 1364 case TCG_TYPE_V64: 1365 tcg_debug_assert(ret >= TCG_REG_V0); 1366 if (have_vsx) { 1367 tcg_out_mem_long(s, have_isa_3_00 ? LXSD : 0, LXSDX, 1368 ret, base, offset); 1369 break; 1370 } 1371 tcg_debug_assert((offset & 7) == 0); 1372 tcg_out_mem_long(s, 0, LVX, ret, base, offset & -16); 1373 if (offset & 8) { 1374 tcg_out_vsldoi(s, ret, ret, ret, 8); 1375 } 1376 break; 1377 case TCG_TYPE_V128: 1378 tcg_debug_assert(ret >= TCG_REG_V0); 1379 tcg_debug_assert((offset & 15) == 0); 1380 tcg_out_mem_long(s, have_isa_3_00 ? LXV : 0, 1381 LVX, ret, base, offset); 1382 break; 1383 default: 1384 g_assert_not_reached(); 1385 } 1386} 1387 1388static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, 1389 TCGReg base, intptr_t offset) 1390{ 1391 int shift; 1392 1393 switch (type) { 1394 case TCG_TYPE_I32: 1395 if (arg < TCG_REG_V0) { 1396 tcg_out_mem_long(s, STW, STWX, arg, base, offset); 1397 break; 1398 } 1399 if (have_isa_2_07 && have_vsx) { 1400 tcg_out_mem_long(s, 0, STXSIWX, arg, base, offset); 1401 break; 1402 } 1403 assert((offset & 3) == 0); 1404 tcg_debug_assert((offset & 3) == 0); 1405 shift = (offset - 4) & 0xc; 1406 if (shift) { 1407 tcg_out_vsldoi(s, TCG_VEC_TMP1, arg, arg, shift); 1408 arg = TCG_VEC_TMP1; 1409 } 1410 tcg_out_mem_long(s, 0, STVEWX, arg, base, offset); 1411 break; 1412 case TCG_TYPE_I64: 1413 if (arg < TCG_REG_V0) { 1414 tcg_debug_assert(TCG_TARGET_REG_BITS == 64); 1415 tcg_out_mem_long(s, STD, STDX, arg, base, offset); 1416 break; 1417 } 1418 /* fallthru */ 1419 case TCG_TYPE_V64: 1420 tcg_debug_assert(arg >= TCG_REG_V0); 1421 if (have_vsx) { 1422 tcg_out_mem_long(s, have_isa_3_00 ? STXSD : 0, 1423 STXSDX, arg, base, offset); 1424 break; 1425 } 1426 tcg_debug_assert((offset & 7) == 0); 1427 if (offset & 8) { 1428 tcg_out_vsldoi(s, TCG_VEC_TMP1, arg, arg, 8); 1429 arg = TCG_VEC_TMP1; 1430 } 1431 tcg_out_mem_long(s, 0, STVEWX, arg, base, offset); 1432 tcg_out_mem_long(s, 0, STVEWX, arg, base, offset + 4); 1433 break; 1434 case TCG_TYPE_V128: 1435 tcg_debug_assert(arg >= TCG_REG_V0); 1436 tcg_out_mem_long(s, have_isa_3_00 ? STXV : 0, 1437 STVX, arg, base, offset); 1438 break; 1439 default: 1440 g_assert_not_reached(); 1441 } 1442} 1443 1444static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val, 1445 TCGReg base, intptr_t ofs) 1446{ 1447 return false; 1448} 1449 1450static void tcg_out_cmp(TCGContext *s, int cond, TCGArg arg1, TCGArg arg2, 1451 int const_arg2, int cr, TCGType type) 1452{ 1453 int imm; 1454 uint32_t op; 1455 1456 tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32); 1457 1458 /* Simplify the comparisons below wrt CMPI. */ 1459 if (type == TCG_TYPE_I32) { 1460 arg2 = (int32_t)arg2; 1461 } 1462 1463 switch (cond) { 1464 case TCG_COND_EQ: 1465 case TCG_COND_NE: 1466 if (const_arg2) { 1467 if ((int16_t) arg2 == arg2) { 1468 op = CMPI; 1469 imm = 1; 1470 break; 1471 } else if ((uint16_t) arg2 == arg2) { 1472 op = CMPLI; 1473 imm = 1; 1474 break; 1475 } 1476 } 1477 op = CMPL; 1478 imm = 0; 1479 break; 1480 1481 case TCG_COND_LT: 1482 case TCG_COND_GE: 1483 case TCG_COND_LE: 1484 case TCG_COND_GT: 1485 if (const_arg2) { 1486 if ((int16_t) arg2 == arg2) { 1487 op = CMPI; 1488 imm = 1; 1489 break; 1490 } 1491 } 1492 op = CMP; 1493 imm = 0; 1494 break; 1495 1496 case TCG_COND_LTU: 1497 case TCG_COND_GEU: 1498 case TCG_COND_LEU: 1499 case TCG_COND_GTU: 1500 if (const_arg2) { 1501 if ((uint16_t) arg2 == arg2) { 1502 op = CMPLI; 1503 imm = 1; 1504 break; 1505 } 1506 } 1507 op = CMPL; 1508 imm = 0; 1509 break; 1510 1511 default: 1512 tcg_abort(); 1513 } 1514 op |= BF(cr) | ((type == TCG_TYPE_I64) << 21); 1515 1516 if (imm) { 1517 tcg_out32(s, op | RA(arg1) | (arg2 & 0xffff)); 1518 } else { 1519 if (const_arg2) { 1520 tcg_out_movi(s, type, TCG_REG_R0, arg2); 1521 arg2 = TCG_REG_R0; 1522 } 1523 tcg_out32(s, op | RA(arg1) | RB(arg2)); 1524 } 1525} 1526 1527static void tcg_out_setcond_eq0(TCGContext *s, TCGType type, 1528 TCGReg dst, TCGReg src) 1529{ 1530 if (type == TCG_TYPE_I32) { 1531 tcg_out32(s, CNTLZW | RS(src) | RA(dst)); 1532 tcg_out_shri32(s, dst, dst, 5); 1533 } else { 1534 tcg_out32(s, CNTLZD | RS(src) | RA(dst)); 1535 tcg_out_shri64(s, dst, dst, 6); 1536 } 1537} 1538 1539static void tcg_out_setcond_ne0(TCGContext *s, TCGReg dst, TCGReg src) 1540{ 1541 /* X != 0 implies X + -1 generates a carry. Extra addition 1542 trickery means: R = X-1 + ~X + C = X-1 + (-X+1) + C = C. */ 1543 if (dst != src) { 1544 tcg_out32(s, ADDIC | TAI(dst, src, -1)); 1545 tcg_out32(s, SUBFE | TAB(dst, dst, src)); 1546 } else { 1547 tcg_out32(s, ADDIC | TAI(TCG_REG_R0, src, -1)); 1548 tcg_out32(s, SUBFE | TAB(dst, TCG_REG_R0, src)); 1549 } 1550} 1551 1552static TCGReg tcg_gen_setcond_xor(TCGContext *s, TCGReg arg1, TCGArg arg2, 1553 bool const_arg2) 1554{ 1555 if (const_arg2) { 1556 if ((uint32_t)arg2 == arg2) { 1557 tcg_out_xori32(s, TCG_REG_R0, arg1, arg2); 1558 } else { 1559 tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R0, arg2); 1560 tcg_out32(s, XOR | SAB(arg1, TCG_REG_R0, TCG_REG_R0)); 1561 } 1562 } else { 1563 tcg_out32(s, XOR | SAB(arg1, TCG_REG_R0, arg2)); 1564 } 1565 return TCG_REG_R0; 1566} 1567 1568static void tcg_out_setcond(TCGContext *s, TCGType type, TCGCond cond, 1569 TCGArg arg0, TCGArg arg1, TCGArg arg2, 1570 int const_arg2) 1571{ 1572 int crop, sh; 1573 1574 tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32); 1575 1576 /* Ignore high bits of a potential constant arg2. */ 1577 if (type == TCG_TYPE_I32) { 1578 arg2 = (uint32_t)arg2; 1579 } 1580 1581 /* Handle common and trivial cases before handling anything else. */ 1582 if (arg2 == 0) { 1583 switch (cond) { 1584 case TCG_COND_EQ: 1585 tcg_out_setcond_eq0(s, type, arg0, arg1); 1586 return; 1587 case TCG_COND_NE: 1588 if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) { 1589 tcg_out_ext32u(s, TCG_REG_R0, arg1); 1590 arg1 = TCG_REG_R0; 1591 } 1592 tcg_out_setcond_ne0(s, arg0, arg1); 1593 return; 1594 case TCG_COND_GE: 1595 tcg_out32(s, NOR | SAB(arg1, arg0, arg1)); 1596 arg1 = arg0; 1597 /* FALLTHRU */ 1598 case TCG_COND_LT: 1599 /* Extract the sign bit. */ 1600 if (type == TCG_TYPE_I32) { 1601 tcg_out_shri32(s, arg0, arg1, 31); 1602 } else { 1603 tcg_out_shri64(s, arg0, arg1, 63); 1604 } 1605 return; 1606 default: 1607 break; 1608 } 1609 } 1610 1611 /* If we have ISEL, we can implement everything with 3 or 4 insns. 1612 All other cases below are also at least 3 insns, so speed up the 1613 code generator by not considering them and always using ISEL. */ 1614 if (have_isel) { 1615 int isel, tab; 1616 1617 tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type); 1618 1619 isel = tcg_to_isel[cond]; 1620 1621 tcg_out_movi(s, type, arg0, 1); 1622 if (isel & 1) { 1623 /* arg0 = (bc ? 0 : 1) */ 1624 tab = TAB(arg0, 0, arg0); 1625 isel &= ~1; 1626 } else { 1627 /* arg0 = (bc ? 1 : 0) */ 1628 tcg_out_movi(s, type, TCG_REG_R0, 0); 1629 tab = TAB(arg0, arg0, TCG_REG_R0); 1630 } 1631 tcg_out32(s, isel | tab); 1632 return; 1633 } 1634 1635 switch (cond) { 1636 case TCG_COND_EQ: 1637 arg1 = tcg_gen_setcond_xor(s, arg1, arg2, const_arg2); 1638 tcg_out_setcond_eq0(s, type, arg0, arg1); 1639 return; 1640 1641 case TCG_COND_NE: 1642 arg1 = tcg_gen_setcond_xor(s, arg1, arg2, const_arg2); 1643 /* Discard the high bits only once, rather than both inputs. */ 1644 if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) { 1645 tcg_out_ext32u(s, TCG_REG_R0, arg1); 1646 arg1 = TCG_REG_R0; 1647 } 1648 tcg_out_setcond_ne0(s, arg0, arg1); 1649 return; 1650 1651 case TCG_COND_GT: 1652 case TCG_COND_GTU: 1653 sh = 30; 1654 crop = 0; 1655 goto crtest; 1656 1657 case TCG_COND_LT: 1658 case TCG_COND_LTU: 1659 sh = 29; 1660 crop = 0; 1661 goto crtest; 1662 1663 case TCG_COND_GE: 1664 case TCG_COND_GEU: 1665 sh = 31; 1666 crop = CRNOR | BT(7, CR_EQ) | BA(7, CR_LT) | BB(7, CR_LT); 1667 goto crtest; 1668 1669 case TCG_COND_LE: 1670 case TCG_COND_LEU: 1671 sh = 31; 1672 crop = CRNOR | BT(7, CR_EQ) | BA(7, CR_GT) | BB(7, CR_GT); 1673 crtest: 1674 tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type); 1675 if (crop) { 1676 tcg_out32(s, crop); 1677 } 1678 tcg_out32(s, MFOCRF | RT(TCG_REG_R0) | FXM(7)); 1679 tcg_out_rlw(s, RLWINM, arg0, TCG_REG_R0, sh, 31, 31); 1680 break; 1681 1682 default: 1683 tcg_abort(); 1684 } 1685} 1686 1687static void tcg_out_bc(TCGContext *s, int bc, TCGLabel *l) 1688{ 1689 if (l->has_value) { 1690 bc |= reloc_pc14_val(tcg_splitwx_to_rx(s->code_ptr), l->u.value_ptr); 1691 } else { 1692 tcg_out_reloc(s, s->code_ptr, R_PPC_REL14, l, 0); 1693 } 1694 tcg_out32(s, bc); 1695} 1696 1697static void tcg_out_brcond(TCGContext *s, TCGCond cond, 1698 TCGArg arg1, TCGArg arg2, int const_arg2, 1699 TCGLabel *l, TCGType type) 1700{ 1701 tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type); 1702 tcg_out_bc(s, tcg_to_bc[cond], l); 1703} 1704 1705static void tcg_out_movcond(TCGContext *s, TCGType type, TCGCond cond, 1706 TCGArg dest, TCGArg c1, TCGArg c2, TCGArg v1, 1707 TCGArg v2, bool const_c2) 1708{ 1709 /* If for some reason both inputs are zero, don't produce bad code. */ 1710 if (v1 == 0 && v2 == 0) { 1711 tcg_out_movi(s, type, dest, 0); 1712 return; 1713 } 1714 1715 tcg_out_cmp(s, cond, c1, c2, const_c2, 7, type); 1716 1717 if (have_isel) { 1718 int isel = tcg_to_isel[cond]; 1719 1720 /* Swap the V operands if the operation indicates inversion. */ 1721 if (isel & 1) { 1722 int t = v1; 1723 v1 = v2; 1724 v2 = t; 1725 isel &= ~1; 1726 } 1727 /* V1 == 0 is handled by isel; V2 == 0 must be handled by hand. */ 1728 if (v2 == 0) { 1729 tcg_out_movi(s, type, TCG_REG_R0, 0); 1730 } 1731 tcg_out32(s, isel | TAB(dest, v1, v2)); 1732 } else { 1733 if (dest == v2) { 1734 cond = tcg_invert_cond(cond); 1735 v2 = v1; 1736 } else if (dest != v1) { 1737 if (v1 == 0) { 1738 tcg_out_movi(s, type, dest, 0); 1739 } else { 1740 tcg_out_mov(s, type, dest, v1); 1741 } 1742 } 1743 /* Branch forward over one insn */ 1744 tcg_out32(s, tcg_to_bc[cond] | 8); 1745 if (v2 == 0) { 1746 tcg_out_movi(s, type, dest, 0); 1747 } else { 1748 tcg_out_mov(s, type, dest, v2); 1749 } 1750 } 1751} 1752 1753static void tcg_out_cntxz(TCGContext *s, TCGType type, uint32_t opc, 1754 TCGArg a0, TCGArg a1, TCGArg a2, bool const_a2) 1755{ 1756 if (const_a2 && a2 == (type == TCG_TYPE_I32 ? 32 : 64)) { 1757 tcg_out32(s, opc | RA(a0) | RS(a1)); 1758 } else { 1759 tcg_out_cmp(s, TCG_COND_EQ, a1, 0, 1, 7, type); 1760 /* Note that the only other valid constant for a2 is 0. */ 1761 if (have_isel) { 1762 tcg_out32(s, opc | RA(TCG_REG_R0) | RS(a1)); 1763 tcg_out32(s, tcg_to_isel[TCG_COND_EQ] | TAB(a0, a2, TCG_REG_R0)); 1764 } else if (!const_a2 && a0 == a2) { 1765 tcg_out32(s, tcg_to_bc[TCG_COND_EQ] | 8); 1766 tcg_out32(s, opc | RA(a0) | RS(a1)); 1767 } else { 1768 tcg_out32(s, opc | RA(a0) | RS(a1)); 1769 tcg_out32(s, tcg_to_bc[TCG_COND_NE] | 8); 1770 if (const_a2) { 1771 tcg_out_movi(s, type, a0, 0); 1772 } else { 1773 tcg_out_mov(s, type, a0, a2); 1774 } 1775 } 1776 } 1777} 1778 1779static void tcg_out_cmp2(TCGContext *s, const TCGArg *args, 1780 const int *const_args) 1781{ 1782 static const struct { uint8_t bit1, bit2; } bits[] = { 1783 [TCG_COND_LT ] = { CR_LT, CR_LT }, 1784 [TCG_COND_LE ] = { CR_LT, CR_GT }, 1785 [TCG_COND_GT ] = { CR_GT, CR_GT }, 1786 [TCG_COND_GE ] = { CR_GT, CR_LT }, 1787 [TCG_COND_LTU] = { CR_LT, CR_LT }, 1788 [TCG_COND_LEU] = { CR_LT, CR_GT }, 1789 [TCG_COND_GTU] = { CR_GT, CR_GT }, 1790 [TCG_COND_GEU] = { CR_GT, CR_LT }, 1791 }; 1792 1793 TCGCond cond = args[4], cond2; 1794 TCGArg al, ah, bl, bh; 1795 int blconst, bhconst; 1796 int op, bit1, bit2; 1797 1798 al = args[0]; 1799 ah = args[1]; 1800 bl = args[2]; 1801 bh = args[3]; 1802 blconst = const_args[2]; 1803 bhconst = const_args[3]; 1804 1805 switch (cond) { 1806 case TCG_COND_EQ: 1807 op = CRAND; 1808 goto do_equality; 1809 case TCG_COND_NE: 1810 op = CRNAND; 1811 do_equality: 1812 tcg_out_cmp(s, cond, al, bl, blconst, 6, TCG_TYPE_I32); 1813 tcg_out_cmp(s, cond, ah, bh, bhconst, 7, TCG_TYPE_I32); 1814 tcg_out32(s, op | BT(7, CR_EQ) | BA(6, CR_EQ) | BB(7, CR_EQ)); 1815 break; 1816 1817 case TCG_COND_LT: 1818 case TCG_COND_LE: 1819 case TCG_COND_GT: 1820 case TCG_COND_GE: 1821 case TCG_COND_LTU: 1822 case TCG_COND_LEU: 1823 case TCG_COND_GTU: 1824 case TCG_COND_GEU: 1825 bit1 = bits[cond].bit1; 1826 bit2 = bits[cond].bit2; 1827 op = (bit1 != bit2 ? CRANDC : CRAND); 1828 cond2 = tcg_unsigned_cond(cond); 1829 1830 tcg_out_cmp(s, cond, ah, bh, bhconst, 6, TCG_TYPE_I32); 1831 tcg_out_cmp(s, cond2, al, bl, blconst, 7, TCG_TYPE_I32); 1832 tcg_out32(s, op | BT(7, CR_EQ) | BA(6, CR_EQ) | BB(7, bit2)); 1833 tcg_out32(s, CROR | BT(7, CR_EQ) | BA(6, bit1) | BB(7, CR_EQ)); 1834 break; 1835 1836 default: 1837 tcg_abort(); 1838 } 1839} 1840 1841static void tcg_out_setcond2(TCGContext *s, const TCGArg *args, 1842 const int *const_args) 1843{ 1844 tcg_out_cmp2(s, args + 1, const_args + 1); 1845 tcg_out32(s, MFOCRF | RT(TCG_REG_R0) | FXM(7)); 1846 tcg_out_rlw(s, RLWINM, args[0], TCG_REG_R0, 31, 31, 31); 1847} 1848 1849static void tcg_out_brcond2 (TCGContext *s, const TCGArg *args, 1850 const int *const_args) 1851{ 1852 tcg_out_cmp2(s, args, const_args); 1853 tcg_out_bc(s, BC | BI(7, CR_EQ) | BO_COND_TRUE, arg_label(args[5])); 1854} 1855 1856static void tcg_out_mb(TCGContext *s, TCGArg a0) 1857{ 1858 uint32_t insn; 1859 1860 if (a0 & TCG_MO_ST_LD) { 1861 insn = HWSYNC; 1862 } else { 1863 insn = LWSYNC; 1864 } 1865 1866 tcg_out32(s, insn); 1867} 1868 1869static void tcg_out_call_int(TCGContext *s, int lk, 1870 const tcg_insn_unit *target) 1871{ 1872#ifdef _CALL_AIX 1873 /* Look through the descriptor. If the branch is in range, and we 1874 don't have to spend too much effort on building the toc. */ 1875 const void *tgt = ((const void * const *)target)[0]; 1876 uintptr_t toc = ((const uintptr_t *)target)[1]; 1877 intptr_t diff = tcg_pcrel_diff(s, tgt); 1878 1879 if (in_range_b(diff) && toc == (uint32_t)toc) { 1880 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP1, toc); 1881 tcg_out_b(s, lk, tgt); 1882 } else { 1883 /* Fold the low bits of the constant into the addresses below. */ 1884 intptr_t arg = (intptr_t)target; 1885 int ofs = (int16_t)arg; 1886 1887 if (ofs + 8 < 0x8000) { 1888 arg -= ofs; 1889 } else { 1890 ofs = 0; 1891 } 1892 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP1, arg); 1893 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R0, TCG_REG_TMP1, ofs); 1894 tcg_out32(s, MTSPR | RA(TCG_REG_R0) | CTR); 1895 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R2, TCG_REG_TMP1, ofs + SZP); 1896 tcg_out32(s, BCCTR | BO_ALWAYS | lk); 1897 } 1898#elif defined(_CALL_ELF) && _CALL_ELF == 2 1899 intptr_t diff; 1900 1901 /* In the ELFv2 ABI, we have to set up r12 to contain the destination 1902 address, which the callee uses to compute its TOC address. */ 1903 /* FIXME: when the branch is in range, we could avoid r12 load if we 1904 knew that the destination uses the same TOC, and what its local 1905 entry point offset is. */ 1906 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R12, (intptr_t)target); 1907 1908 diff = tcg_pcrel_diff(s, target); 1909 if (in_range_b(diff)) { 1910 tcg_out_b(s, lk, target); 1911 } else { 1912 tcg_out32(s, MTSPR | RS(TCG_REG_R12) | CTR); 1913 tcg_out32(s, BCCTR | BO_ALWAYS | lk); 1914 } 1915#else 1916 tcg_out_b(s, lk, target); 1917#endif 1918} 1919 1920static void tcg_out_call(TCGContext *s, const tcg_insn_unit *target, 1921 const TCGHelperInfo *info) 1922{ 1923 tcg_out_call_int(s, LK, target); 1924} 1925 1926static const uint32_t qemu_ldx_opc[(MO_SSIZE + MO_BSWAP) + 1] = { 1927 [MO_UB] = LBZX, 1928 [MO_UW] = LHZX, 1929 [MO_UL] = LWZX, 1930 [MO_UQ] = LDX, 1931 [MO_SW] = LHAX, 1932 [MO_SL] = LWAX, 1933 [MO_BSWAP | MO_UB] = LBZX, 1934 [MO_BSWAP | MO_UW] = LHBRX, 1935 [MO_BSWAP | MO_UL] = LWBRX, 1936 [MO_BSWAP | MO_UQ] = LDBRX, 1937}; 1938 1939static const uint32_t qemu_stx_opc[(MO_SIZE + MO_BSWAP) + 1] = { 1940 [MO_UB] = STBX, 1941 [MO_UW] = STHX, 1942 [MO_UL] = STWX, 1943 [MO_UQ] = STDX, 1944 [MO_BSWAP | MO_UB] = STBX, 1945 [MO_BSWAP | MO_UW] = STHBRX, 1946 [MO_BSWAP | MO_UL] = STWBRX, 1947 [MO_BSWAP | MO_UQ] = STDBRX, 1948}; 1949 1950static const uint32_t qemu_exts_opc[4] = { 1951 EXTSB, EXTSH, EXTSW, 0 1952}; 1953 1954#if defined (CONFIG_SOFTMMU) 1955/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr, 1956 * int mmu_idx, uintptr_t ra) 1957 */ 1958static void * const qemu_ld_helpers[(MO_SIZE | MO_BSWAP) + 1] = { 1959 [MO_UB] = helper_ret_ldub_mmu, 1960 [MO_LEUW] = helper_le_lduw_mmu, 1961 [MO_LEUL] = helper_le_ldul_mmu, 1962 [MO_LEUQ] = helper_le_ldq_mmu, 1963 [MO_BEUW] = helper_be_lduw_mmu, 1964 [MO_BEUL] = helper_be_ldul_mmu, 1965 [MO_BEUQ] = helper_be_ldq_mmu, 1966}; 1967 1968/* helper signature: helper_st_mmu(CPUState *env, target_ulong addr, 1969 * uintxx_t val, int mmu_idx, uintptr_t ra) 1970 */ 1971static void * const qemu_st_helpers[(MO_SIZE | MO_BSWAP) + 1] = { 1972 [MO_UB] = helper_ret_stb_mmu, 1973 [MO_LEUW] = helper_le_stw_mmu, 1974 [MO_LEUL] = helper_le_stl_mmu, 1975 [MO_LEUQ] = helper_le_stq_mmu, 1976 [MO_BEUW] = helper_be_stw_mmu, 1977 [MO_BEUL] = helper_be_stl_mmu, 1978 [MO_BEUQ] = helper_be_stq_mmu, 1979}; 1980 1981/* We expect to use a 16-bit negative offset from ENV. */ 1982QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0); 1983QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -32768); 1984 1985/* Perform the TLB load and compare. Places the result of the comparison 1986 in CR7, loads the addend of the TLB into R3, and returns the register 1987 containing the guest address (zero-extended into R4). Clobbers R0 and R2. */ 1988 1989static TCGReg tcg_out_tlb_read(TCGContext *s, MemOp opc, 1990 TCGReg addrlo, TCGReg addrhi, 1991 int mem_index, bool is_read) 1992{ 1993 int cmp_off 1994 = (is_read 1995 ? offsetof(CPUTLBEntry, addr_read) 1996 : offsetof(CPUTLBEntry, addr_write)); 1997 int fast_off = TLB_MASK_TABLE_OFS(mem_index); 1998 int mask_off = fast_off + offsetof(CPUTLBDescFast, mask); 1999 int table_off = fast_off + offsetof(CPUTLBDescFast, table); 2000 unsigned s_bits = opc & MO_SIZE; 2001 unsigned a_bits = get_alignment_bits(opc); 2002 2003 /* Load tlb_mask[mmu_idx] and tlb_table[mmu_idx]. */ 2004 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R3, TCG_AREG0, mask_off); 2005 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R4, TCG_AREG0, table_off); 2006 2007 /* Extract the page index, shifted into place for tlb index. */ 2008 if (TCG_TARGET_REG_BITS == 32) { 2009 tcg_out_shri32(s, TCG_REG_TMP1, addrlo, 2010 TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); 2011 } else { 2012 tcg_out_shri64(s, TCG_REG_TMP1, addrlo, 2013 TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); 2014 } 2015 tcg_out32(s, AND | SAB(TCG_REG_R3, TCG_REG_R3, TCG_REG_TMP1)); 2016 2017 /* Load the TLB comparator. */ 2018 if (cmp_off == 0 && TCG_TARGET_REG_BITS >= TARGET_LONG_BITS) { 2019 uint32_t lxu = (TCG_TARGET_REG_BITS == 32 || TARGET_LONG_BITS == 32 2020 ? LWZUX : LDUX); 2021 tcg_out32(s, lxu | TAB(TCG_REG_TMP1, TCG_REG_R3, TCG_REG_R4)); 2022 } else { 2023 tcg_out32(s, ADD | TAB(TCG_REG_R3, TCG_REG_R3, TCG_REG_R4)); 2024 if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) { 2025 tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_TMP1, TCG_REG_R3, cmp_off + 4); 2026 tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_R4, TCG_REG_R3, cmp_off); 2027 } else { 2028 tcg_out_ld(s, TCG_TYPE_TL, TCG_REG_TMP1, TCG_REG_R3, cmp_off); 2029 } 2030 } 2031 2032 /* Load the TLB addend for use on the fast path. Do this asap 2033 to minimize any load use delay. */ 2034 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R3, TCG_REG_R3, 2035 offsetof(CPUTLBEntry, addend)); 2036 2037 /* Clear the non-page, non-alignment bits from the address */ 2038 if (TCG_TARGET_REG_BITS == 32) { 2039 /* We don't support unaligned accesses on 32-bits. 2040 * Preserve the bottom bits and thus trigger a comparison 2041 * failure on unaligned accesses. 2042 */ 2043 if (a_bits < s_bits) { 2044 a_bits = s_bits; 2045 } 2046 tcg_out_rlw(s, RLWINM, TCG_REG_R0, addrlo, 0, 2047 (32 - a_bits) & 31, 31 - TARGET_PAGE_BITS); 2048 } else { 2049 TCGReg t = addrlo; 2050 2051 /* If the access is unaligned, we need to make sure we fail if we 2052 * cross a page boundary. The trick is to add the access size-1 2053 * to the address before masking the low bits. That will make the 2054 * address overflow to the next page if we cross a page boundary, 2055 * which will then force a mismatch of the TLB compare. 2056 */ 2057 if (a_bits < s_bits) { 2058 unsigned a_mask = (1 << a_bits) - 1; 2059 unsigned s_mask = (1 << s_bits) - 1; 2060 tcg_out32(s, ADDI | TAI(TCG_REG_R0, t, s_mask - a_mask)); 2061 t = TCG_REG_R0; 2062 } 2063 2064 /* Mask the address for the requested alignment. */ 2065 if (TARGET_LONG_BITS == 32) { 2066 tcg_out_rlw(s, RLWINM, TCG_REG_R0, t, 0, 2067 (32 - a_bits) & 31, 31 - TARGET_PAGE_BITS); 2068 /* Zero-extend the address for use in the final address. */ 2069 tcg_out_ext32u(s, TCG_REG_R4, addrlo); 2070 addrlo = TCG_REG_R4; 2071 } else if (a_bits == 0) { 2072 tcg_out_rld(s, RLDICR, TCG_REG_R0, t, 0, 63 - TARGET_PAGE_BITS); 2073 } else { 2074 tcg_out_rld(s, RLDICL, TCG_REG_R0, t, 2075 64 - TARGET_PAGE_BITS, TARGET_PAGE_BITS - a_bits); 2076 tcg_out_rld(s, RLDICL, TCG_REG_R0, TCG_REG_R0, TARGET_PAGE_BITS, 0); 2077 } 2078 } 2079 2080 if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) { 2081 tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP1, 2082 0, 7, TCG_TYPE_I32); 2083 tcg_out_cmp(s, TCG_COND_EQ, addrhi, TCG_REG_R4, 0, 6, TCG_TYPE_I32); 2084 tcg_out32(s, CRAND | BT(7, CR_EQ) | BA(6, CR_EQ) | BB(7, CR_EQ)); 2085 } else { 2086 tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP1, 2087 0, 7, TCG_TYPE_TL); 2088 } 2089 2090 return addrlo; 2091} 2092 2093/* Record the context of a call to the out of line helper code for the slow 2094 path for a load or store, so that we can later generate the correct 2095 helper code. */ 2096static void add_qemu_ldst_label(TCGContext *s, bool is_ld, MemOpIdx oi, 2097 TCGReg datalo_reg, TCGReg datahi_reg, 2098 TCGReg addrlo_reg, TCGReg addrhi_reg, 2099 tcg_insn_unit *raddr, tcg_insn_unit *lptr) 2100{ 2101 TCGLabelQemuLdst *label = new_ldst_label(s); 2102 2103 label->is_ld = is_ld; 2104 label->oi = oi; 2105 label->datalo_reg = datalo_reg; 2106 label->datahi_reg = datahi_reg; 2107 label->addrlo_reg = addrlo_reg; 2108 label->addrhi_reg = addrhi_reg; 2109 label->raddr = tcg_splitwx_to_rx(raddr); 2110 label->label_ptr[0] = lptr; 2111} 2112 2113static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) 2114{ 2115 MemOpIdx oi = lb->oi; 2116 MemOp opc = get_memop(oi); 2117 TCGReg hi, lo, arg = TCG_REG_R3; 2118 2119 if (!reloc_pc14(lb->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) { 2120 return false; 2121 } 2122 2123 tcg_out_mov(s, TCG_TYPE_PTR, arg++, TCG_AREG0); 2124 2125 lo = lb->addrlo_reg; 2126 hi = lb->addrhi_reg; 2127 if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) { 2128 arg |= (TCG_TARGET_CALL_ARG_I64 == TCG_CALL_ARG_EVEN); 2129 tcg_out_mov(s, TCG_TYPE_I32, arg++, hi); 2130 tcg_out_mov(s, TCG_TYPE_I32, arg++, lo); 2131 } else { 2132 /* If the address needed to be zero-extended, we'll have already 2133 placed it in R4. The only remaining case is 64-bit guest. */ 2134 tcg_out_mov(s, TCG_TYPE_TL, arg++, lo); 2135 } 2136 2137 tcg_out_movi(s, TCG_TYPE_I32, arg++, oi); 2138 tcg_out32(s, MFSPR | RT(arg) | LR); 2139 2140 tcg_out_call_int(s, LK, qemu_ld_helpers[opc & (MO_BSWAP | MO_SIZE)]); 2141 2142 lo = lb->datalo_reg; 2143 hi = lb->datahi_reg; 2144 if (TCG_TARGET_REG_BITS == 32 && (opc & MO_SIZE) == MO_64) { 2145 tcg_out_mov(s, TCG_TYPE_I32, lo, TCG_REG_R4); 2146 tcg_out_mov(s, TCG_TYPE_I32, hi, TCG_REG_R3); 2147 } else if (opc & MO_SIGN) { 2148 uint32_t insn = qemu_exts_opc[opc & MO_SIZE]; 2149 tcg_out32(s, insn | RA(lo) | RS(TCG_REG_R3)); 2150 } else { 2151 tcg_out_mov(s, TCG_TYPE_REG, lo, TCG_REG_R3); 2152 } 2153 2154 tcg_out_b(s, 0, lb->raddr); 2155 return true; 2156} 2157 2158static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) 2159{ 2160 MemOpIdx oi = lb->oi; 2161 MemOp opc = get_memop(oi); 2162 MemOp s_bits = opc & MO_SIZE; 2163 TCGReg hi, lo, arg = TCG_REG_R3; 2164 2165 if (!reloc_pc14(lb->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) { 2166 return false; 2167 } 2168 2169 tcg_out_mov(s, TCG_TYPE_PTR, arg++, TCG_AREG0); 2170 2171 lo = lb->addrlo_reg; 2172 hi = lb->addrhi_reg; 2173 if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) { 2174 arg |= (TCG_TARGET_CALL_ARG_I64 == TCG_CALL_ARG_EVEN); 2175 tcg_out_mov(s, TCG_TYPE_I32, arg++, hi); 2176 tcg_out_mov(s, TCG_TYPE_I32, arg++, lo); 2177 } else { 2178 /* If the address needed to be zero-extended, we'll have already 2179 placed it in R4. The only remaining case is 64-bit guest. */ 2180 tcg_out_mov(s, TCG_TYPE_TL, arg++, lo); 2181 } 2182 2183 lo = lb->datalo_reg; 2184 hi = lb->datahi_reg; 2185 if (TCG_TARGET_REG_BITS == 32) { 2186 switch (s_bits) { 2187 case MO_64: 2188 arg |= (TCG_TARGET_CALL_ARG_I64 == TCG_CALL_ARG_EVEN); 2189 tcg_out_mov(s, TCG_TYPE_I32, arg++, hi); 2190 /* FALLTHRU */ 2191 case MO_32: 2192 tcg_out_mov(s, TCG_TYPE_I32, arg++, lo); 2193 break; 2194 default: 2195 tcg_out_rlw(s, RLWINM, arg++, lo, 0, 32 - (8 << s_bits), 31); 2196 break; 2197 } 2198 } else { 2199 if (s_bits == MO_64) { 2200 tcg_out_mov(s, TCG_TYPE_I64, arg++, lo); 2201 } else { 2202 tcg_out_rld(s, RLDICL, arg++, lo, 0, 64 - (8 << s_bits)); 2203 } 2204 } 2205 2206 tcg_out_movi(s, TCG_TYPE_I32, arg++, oi); 2207 tcg_out32(s, MFSPR | RT(arg) | LR); 2208 2209 tcg_out_call_int(s, LK, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]); 2210 2211 tcg_out_b(s, 0, lb->raddr); 2212 return true; 2213} 2214#else 2215 2216static void tcg_out_test_alignment(TCGContext *s, bool is_ld, TCGReg addrlo, 2217 TCGReg addrhi, unsigned a_bits) 2218{ 2219 unsigned a_mask = (1 << a_bits) - 1; 2220 TCGLabelQemuLdst *label = new_ldst_label(s); 2221 2222 label->is_ld = is_ld; 2223 label->addrlo_reg = addrlo; 2224 label->addrhi_reg = addrhi; 2225 2226 /* We are expecting a_bits to max out at 7, much lower than ANDI. */ 2227 tcg_debug_assert(a_bits < 16); 2228 tcg_out32(s, ANDI | SAI(addrlo, TCG_REG_R0, a_mask)); 2229 2230 label->label_ptr[0] = s->code_ptr; 2231 tcg_out32(s, BC | BI(0, CR_EQ) | BO_COND_FALSE | LK); 2232 2233 label->raddr = tcg_splitwx_to_rx(s->code_ptr); 2234} 2235 2236static bool tcg_out_fail_alignment(TCGContext *s, TCGLabelQemuLdst *l) 2237{ 2238 if (!reloc_pc14(l->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) { 2239 return false; 2240 } 2241 2242 if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) { 2243 TCGReg arg = TCG_REG_R4; 2244 2245 arg |= (TCG_TARGET_CALL_ARG_I64 == TCG_CALL_ARG_EVEN); 2246 if (l->addrlo_reg != arg) { 2247 tcg_out_mov(s, TCG_TYPE_I32, arg, l->addrhi_reg); 2248 tcg_out_mov(s, TCG_TYPE_I32, arg + 1, l->addrlo_reg); 2249 } else if (l->addrhi_reg != arg + 1) { 2250 tcg_out_mov(s, TCG_TYPE_I32, arg + 1, l->addrlo_reg); 2251 tcg_out_mov(s, TCG_TYPE_I32, arg, l->addrhi_reg); 2252 } else { 2253 tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_R0, arg); 2254 tcg_out_mov(s, TCG_TYPE_I32, arg, arg + 1); 2255 tcg_out_mov(s, TCG_TYPE_I32, arg + 1, TCG_REG_R0); 2256 } 2257 } else { 2258 tcg_out_mov(s, TCG_TYPE_TL, TCG_REG_R4, l->addrlo_reg); 2259 } 2260 tcg_out_mov(s, TCG_TYPE_TL, TCG_REG_R3, TCG_AREG0); 2261 2262 /* "Tail call" to the helper, with the return address back inline. */ 2263 tcg_out_call_int(s, 0, (const void *)(l->is_ld ? helper_unaligned_ld 2264 : helper_unaligned_st)); 2265 return true; 2266} 2267 2268static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) 2269{ 2270 return tcg_out_fail_alignment(s, l); 2271} 2272 2273static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l) 2274{ 2275 return tcg_out_fail_alignment(s, l); 2276} 2277 2278#endif /* SOFTMMU */ 2279 2280static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64) 2281{ 2282 TCGReg datalo, datahi, addrlo, rbase; 2283 TCGReg addrhi __attribute__((unused)); 2284 MemOpIdx oi; 2285 MemOp opc, s_bits; 2286#ifdef CONFIG_SOFTMMU 2287 int mem_index; 2288 tcg_insn_unit *label_ptr; 2289#else 2290 unsigned a_bits; 2291#endif 2292 2293 datalo = *args++; 2294 datahi = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0); 2295 addrlo = *args++; 2296 addrhi = (TCG_TARGET_REG_BITS < TARGET_LONG_BITS ? *args++ : 0); 2297 oi = *args++; 2298 opc = get_memop(oi); 2299 s_bits = opc & MO_SIZE; 2300 2301#ifdef CONFIG_SOFTMMU 2302 mem_index = get_mmuidx(oi); 2303 addrlo = tcg_out_tlb_read(s, opc, addrlo, addrhi, mem_index, true); 2304 2305 /* Load a pointer into the current opcode w/conditional branch-link. */ 2306 label_ptr = s->code_ptr; 2307 tcg_out32(s, BC | BI(7, CR_EQ) | BO_COND_FALSE | LK); 2308 2309 rbase = TCG_REG_R3; 2310#else /* !CONFIG_SOFTMMU */ 2311 a_bits = get_alignment_bits(opc); 2312 if (a_bits) { 2313 tcg_out_test_alignment(s, true, addrlo, addrhi, a_bits); 2314 } 2315 rbase = guest_base ? TCG_GUEST_BASE_REG : 0; 2316 if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) { 2317 tcg_out_ext32u(s, TCG_REG_TMP1, addrlo); 2318 addrlo = TCG_REG_TMP1; 2319 } 2320#endif 2321 2322 if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) { 2323 if (opc & MO_BSWAP) { 2324 tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4)); 2325 tcg_out32(s, LWBRX | TAB(datalo, rbase, addrlo)); 2326 tcg_out32(s, LWBRX | TAB(datahi, rbase, TCG_REG_R0)); 2327 } else if (rbase != 0) { 2328 tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4)); 2329 tcg_out32(s, LWZX | TAB(datahi, rbase, addrlo)); 2330 tcg_out32(s, LWZX | TAB(datalo, rbase, TCG_REG_R0)); 2331 } else if (addrlo == datahi) { 2332 tcg_out32(s, LWZ | TAI(datalo, addrlo, 4)); 2333 tcg_out32(s, LWZ | TAI(datahi, addrlo, 0)); 2334 } else { 2335 tcg_out32(s, LWZ | TAI(datahi, addrlo, 0)); 2336 tcg_out32(s, LWZ | TAI(datalo, addrlo, 4)); 2337 } 2338 } else { 2339 uint32_t insn = qemu_ldx_opc[opc & (MO_BSWAP | MO_SSIZE)]; 2340 if (!have_isa_2_06 && insn == LDBRX) { 2341 tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4)); 2342 tcg_out32(s, LWBRX | TAB(datalo, rbase, addrlo)); 2343 tcg_out32(s, LWBRX | TAB(TCG_REG_R0, rbase, TCG_REG_R0)); 2344 tcg_out_rld(s, RLDIMI, datalo, TCG_REG_R0, 32, 0); 2345 } else if (insn) { 2346 tcg_out32(s, insn | TAB(datalo, rbase, addrlo)); 2347 } else { 2348 insn = qemu_ldx_opc[opc & (MO_SIZE | MO_BSWAP)]; 2349 tcg_out32(s, insn | TAB(datalo, rbase, addrlo)); 2350 insn = qemu_exts_opc[s_bits]; 2351 tcg_out32(s, insn | RA(datalo) | RS(datalo)); 2352 } 2353 } 2354 2355#ifdef CONFIG_SOFTMMU 2356 add_qemu_ldst_label(s, true, oi, datalo, datahi, addrlo, addrhi, 2357 s->code_ptr, label_ptr); 2358#endif 2359} 2360 2361static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64) 2362{ 2363 TCGReg datalo, datahi, addrlo, rbase; 2364 TCGReg addrhi __attribute__((unused)); 2365 MemOpIdx oi; 2366 MemOp opc, s_bits; 2367#ifdef CONFIG_SOFTMMU 2368 int mem_index; 2369 tcg_insn_unit *label_ptr; 2370#else 2371 unsigned a_bits; 2372#endif 2373 2374 datalo = *args++; 2375 datahi = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0); 2376 addrlo = *args++; 2377 addrhi = (TCG_TARGET_REG_BITS < TARGET_LONG_BITS ? *args++ : 0); 2378 oi = *args++; 2379 opc = get_memop(oi); 2380 s_bits = opc & MO_SIZE; 2381 2382#ifdef CONFIG_SOFTMMU 2383 mem_index = get_mmuidx(oi); 2384 addrlo = tcg_out_tlb_read(s, opc, addrlo, addrhi, mem_index, false); 2385 2386 /* Load a pointer into the current opcode w/conditional branch-link. */ 2387 label_ptr = s->code_ptr; 2388 tcg_out32(s, BC | BI(7, CR_EQ) | BO_COND_FALSE | LK); 2389 2390 rbase = TCG_REG_R3; 2391#else /* !CONFIG_SOFTMMU */ 2392 a_bits = get_alignment_bits(opc); 2393 if (a_bits) { 2394 tcg_out_test_alignment(s, false, addrlo, addrhi, a_bits); 2395 } 2396 rbase = guest_base ? TCG_GUEST_BASE_REG : 0; 2397 if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) { 2398 tcg_out_ext32u(s, TCG_REG_TMP1, addrlo); 2399 addrlo = TCG_REG_TMP1; 2400 } 2401#endif 2402 2403 if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) { 2404 if (opc & MO_BSWAP) { 2405 tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4)); 2406 tcg_out32(s, STWBRX | SAB(datalo, rbase, addrlo)); 2407 tcg_out32(s, STWBRX | SAB(datahi, rbase, TCG_REG_R0)); 2408 } else if (rbase != 0) { 2409 tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4)); 2410 tcg_out32(s, STWX | SAB(datahi, rbase, addrlo)); 2411 tcg_out32(s, STWX | SAB(datalo, rbase, TCG_REG_R0)); 2412 } else { 2413 tcg_out32(s, STW | TAI(datahi, addrlo, 0)); 2414 tcg_out32(s, STW | TAI(datalo, addrlo, 4)); 2415 } 2416 } else { 2417 uint32_t insn = qemu_stx_opc[opc & (MO_BSWAP | MO_SIZE)]; 2418 if (!have_isa_2_06 && insn == STDBRX) { 2419 tcg_out32(s, STWBRX | SAB(datalo, rbase, addrlo)); 2420 tcg_out32(s, ADDI | TAI(TCG_REG_TMP1, addrlo, 4)); 2421 tcg_out_shri64(s, TCG_REG_R0, datalo, 32); 2422 tcg_out32(s, STWBRX | SAB(TCG_REG_R0, rbase, TCG_REG_TMP1)); 2423 } else { 2424 tcg_out32(s, insn | SAB(datalo, rbase, addrlo)); 2425 } 2426 } 2427 2428#ifdef CONFIG_SOFTMMU 2429 add_qemu_ldst_label(s, false, oi, datalo, datahi, addrlo, addrhi, 2430 s->code_ptr, label_ptr); 2431#endif 2432} 2433 2434static void tcg_out_nop_fill(tcg_insn_unit *p, int count) 2435{ 2436 int i; 2437 for (i = 0; i < count; ++i) { 2438 p[i] = NOP; 2439 } 2440} 2441 2442/* Parameters for function call generation, used in tcg.c. */ 2443#define TCG_TARGET_STACK_ALIGN 16 2444 2445#ifdef _CALL_AIX 2446# define LINK_AREA_SIZE (6 * SZR) 2447# define LR_OFFSET (1 * SZR) 2448# define TCG_TARGET_CALL_STACK_OFFSET (LINK_AREA_SIZE + 8 * SZR) 2449#elif defined(_CALL_DARWIN) 2450# define LINK_AREA_SIZE (6 * SZR) 2451# define LR_OFFSET (2 * SZR) 2452#elif TCG_TARGET_REG_BITS == 64 2453# if defined(_CALL_ELF) && _CALL_ELF == 2 2454# define LINK_AREA_SIZE (4 * SZR) 2455# define LR_OFFSET (1 * SZR) 2456# endif 2457#else /* TCG_TARGET_REG_BITS == 32 */ 2458# if defined(_CALL_SYSV) 2459# define LINK_AREA_SIZE (2 * SZR) 2460# define LR_OFFSET (1 * SZR) 2461# endif 2462#endif 2463#ifndef LR_OFFSET 2464# error "Unhandled abi" 2465#endif 2466#ifndef TCG_TARGET_CALL_STACK_OFFSET 2467# define TCG_TARGET_CALL_STACK_OFFSET LINK_AREA_SIZE 2468#endif 2469 2470#define CPU_TEMP_BUF_SIZE (CPU_TEMP_BUF_NLONGS * (int)sizeof(long)) 2471#define REG_SAVE_SIZE ((int)ARRAY_SIZE(tcg_target_callee_save_regs) * SZR) 2472 2473#define FRAME_SIZE ((TCG_TARGET_CALL_STACK_OFFSET \ 2474 + TCG_STATIC_CALL_ARGS_SIZE \ 2475 + CPU_TEMP_BUF_SIZE \ 2476 + REG_SAVE_SIZE \ 2477 + TCG_TARGET_STACK_ALIGN - 1) \ 2478 & -TCG_TARGET_STACK_ALIGN) 2479 2480#define REG_SAVE_BOT (FRAME_SIZE - REG_SAVE_SIZE) 2481 2482static void tcg_target_qemu_prologue(TCGContext *s) 2483{ 2484 int i; 2485 2486#ifdef _CALL_AIX 2487 const void **desc = (const void **)s->code_ptr; 2488 desc[0] = tcg_splitwx_to_rx(desc + 2); /* entry point */ 2489 desc[1] = 0; /* environment pointer */ 2490 s->code_ptr = (void *)(desc + 2); /* skip over descriptor */ 2491#endif 2492 2493 tcg_set_frame(s, TCG_REG_CALL_STACK, REG_SAVE_BOT - CPU_TEMP_BUF_SIZE, 2494 CPU_TEMP_BUF_SIZE); 2495 2496 /* Prologue */ 2497 tcg_out32(s, MFSPR | RT(TCG_REG_R0) | LR); 2498 tcg_out32(s, (SZR == 8 ? STDU : STWU) 2499 | SAI(TCG_REG_R1, TCG_REG_R1, -FRAME_SIZE)); 2500 2501 for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); ++i) { 2502 tcg_out_st(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i], 2503 TCG_REG_R1, REG_SAVE_BOT + i * SZR); 2504 } 2505 tcg_out_st(s, TCG_TYPE_PTR, TCG_REG_R0, TCG_REG_R1, FRAME_SIZE+LR_OFFSET); 2506 2507#ifndef CONFIG_SOFTMMU 2508 if (guest_base) { 2509 tcg_out_movi_int(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base, true); 2510 tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG); 2511 } 2512#endif 2513 2514 tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); 2515 tcg_out32(s, MTSPR | RS(tcg_target_call_iarg_regs[1]) | CTR); 2516 if (USE_REG_TB) { 2517 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_TB, tcg_target_call_iarg_regs[1]); 2518 } 2519 tcg_out32(s, BCCTR | BO_ALWAYS); 2520 2521 /* Epilogue */ 2522 tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr); 2523 2524 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R0, TCG_REG_R1, FRAME_SIZE+LR_OFFSET); 2525 for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); ++i) { 2526 tcg_out_ld(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i], 2527 TCG_REG_R1, REG_SAVE_BOT + i * SZR); 2528 } 2529 tcg_out32(s, MTSPR | RS(TCG_REG_R0) | LR); 2530 tcg_out32(s, ADDI | TAI(TCG_REG_R1, TCG_REG_R1, FRAME_SIZE)); 2531 tcg_out32(s, BCLR | BO_ALWAYS); 2532} 2533 2534static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg) 2535{ 2536 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R3, arg); 2537 tcg_out_b(s, 0, tcg_code_gen_epilogue); 2538} 2539 2540static void tcg_out_goto_tb(TCGContext *s, int which) 2541{ 2542 uintptr_t ptr = get_jmp_target_addr(s, which); 2543 2544 if (USE_REG_TB) { 2545 ptrdiff_t offset = tcg_tbrel_diff(s, (void *)ptr); 2546 tcg_out_mem_long(s, LD, LDX, TCG_REG_TB, TCG_REG_TB, offset); 2547 2548 /* Direct branch will be patched by tb_target_set_jmp_target. */ 2549 set_jmp_insn_offset(s, which); 2550 tcg_out32(s, MTSPR | RS(TCG_REG_TB) | CTR); 2551 2552 /* When branch is out of range, fall through to indirect. */ 2553 tcg_out32(s, BCCTR | BO_ALWAYS); 2554 2555 /* For the unlinked case, need to reset TCG_REG_TB. */ 2556 set_jmp_reset_offset(s, which); 2557 tcg_out_mem_long(s, ADDI, ADD, TCG_REG_TB, TCG_REG_TB, 2558 -tcg_current_code_size(s)); 2559 } else { 2560 /* Direct branch will be patched by tb_target_set_jmp_target. */ 2561 set_jmp_insn_offset(s, which); 2562 tcg_out32(s, NOP); 2563 2564 /* When branch is out of range, fall through to indirect. */ 2565 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP1, ptr - (int16_t)ptr); 2566 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_REG_TMP1, (int16_t)ptr); 2567 tcg_out32(s, MTSPR | RS(TCG_REG_TMP1) | CTR); 2568 tcg_out32(s, BCCTR | BO_ALWAYS); 2569 set_jmp_reset_offset(s, which); 2570 } 2571} 2572 2573void tb_target_set_jmp_target(const TranslationBlock *tb, int n, 2574 uintptr_t jmp_rx, uintptr_t jmp_rw) 2575{ 2576 uintptr_t addr = tb->jmp_target_addr[n]; 2577 intptr_t diff = addr - jmp_rx; 2578 tcg_insn_unit insn; 2579 2580 if (in_range_b(diff)) { 2581 insn = B | (diff & 0x3fffffc); 2582 } else if (USE_REG_TB) { 2583 insn = MTSPR | RS(TCG_REG_TB) | CTR; 2584 } else { 2585 insn = NOP; 2586 } 2587 2588 qatomic_set((uint32_t *)jmp_rw, insn); 2589 flush_idcache_range(jmp_rx, jmp_rw, 4); 2590} 2591 2592static void tcg_out_op(TCGContext *s, TCGOpcode opc, 2593 const TCGArg args[TCG_MAX_OP_ARGS], 2594 const int const_args[TCG_MAX_OP_ARGS]) 2595{ 2596 TCGArg a0, a1, a2; 2597 2598 switch (opc) { 2599 case INDEX_op_goto_ptr: 2600 tcg_out32(s, MTSPR | RS(args[0]) | CTR); 2601 if (USE_REG_TB) { 2602 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_TB, args[0]); 2603 } 2604 tcg_out32(s, ADDI | TAI(TCG_REG_R3, 0, 0)); 2605 tcg_out32(s, BCCTR | BO_ALWAYS); 2606 break; 2607 case INDEX_op_br: 2608 { 2609 TCGLabel *l = arg_label(args[0]); 2610 uint32_t insn = B; 2611 2612 if (l->has_value) { 2613 insn |= reloc_pc24_val(tcg_splitwx_to_rx(s->code_ptr), 2614 l->u.value_ptr); 2615 } else { 2616 tcg_out_reloc(s, s->code_ptr, R_PPC_REL24, l, 0); 2617 } 2618 tcg_out32(s, insn); 2619 } 2620 break; 2621 case INDEX_op_ld8u_i32: 2622 case INDEX_op_ld8u_i64: 2623 tcg_out_mem_long(s, LBZ, LBZX, args[0], args[1], args[2]); 2624 break; 2625 case INDEX_op_ld8s_i32: 2626 case INDEX_op_ld8s_i64: 2627 tcg_out_mem_long(s, LBZ, LBZX, args[0], args[1], args[2]); 2628 tcg_out_ext8s(s, args[0], args[0]); 2629 break; 2630 case INDEX_op_ld16u_i32: 2631 case INDEX_op_ld16u_i64: 2632 tcg_out_mem_long(s, LHZ, LHZX, args[0], args[1], args[2]); 2633 break; 2634 case INDEX_op_ld16s_i32: 2635 case INDEX_op_ld16s_i64: 2636 tcg_out_mem_long(s, LHA, LHAX, args[0], args[1], args[2]); 2637 break; 2638 case INDEX_op_ld_i32: 2639 case INDEX_op_ld32u_i64: 2640 tcg_out_mem_long(s, LWZ, LWZX, args[0], args[1], args[2]); 2641 break; 2642 case INDEX_op_ld32s_i64: 2643 tcg_out_mem_long(s, LWA, LWAX, args[0], args[1], args[2]); 2644 break; 2645 case INDEX_op_ld_i64: 2646 tcg_out_mem_long(s, LD, LDX, args[0], args[1], args[2]); 2647 break; 2648 case INDEX_op_st8_i32: 2649 case INDEX_op_st8_i64: 2650 tcg_out_mem_long(s, STB, STBX, args[0], args[1], args[2]); 2651 break; 2652 case INDEX_op_st16_i32: 2653 case INDEX_op_st16_i64: 2654 tcg_out_mem_long(s, STH, STHX, args[0], args[1], args[2]); 2655 break; 2656 case INDEX_op_st_i32: 2657 case INDEX_op_st32_i64: 2658 tcg_out_mem_long(s, STW, STWX, args[0], args[1], args[2]); 2659 break; 2660 case INDEX_op_st_i64: 2661 tcg_out_mem_long(s, STD, STDX, args[0], args[1], args[2]); 2662 break; 2663 2664 case INDEX_op_add_i32: 2665 a0 = args[0], a1 = args[1], a2 = args[2]; 2666 if (const_args[2]) { 2667 do_addi_32: 2668 tcg_out_mem_long(s, ADDI, ADD, a0, a1, (int32_t)a2); 2669 } else { 2670 tcg_out32(s, ADD | TAB(a0, a1, a2)); 2671 } 2672 break; 2673 case INDEX_op_sub_i32: 2674 a0 = args[0], a1 = args[1], a2 = args[2]; 2675 if (const_args[1]) { 2676 if (const_args[2]) { 2677 tcg_out_movi(s, TCG_TYPE_I32, a0, a1 - a2); 2678 } else { 2679 tcg_out32(s, SUBFIC | TAI(a0, a2, a1)); 2680 } 2681 } else if (const_args[2]) { 2682 a2 = -a2; 2683 goto do_addi_32; 2684 } else { 2685 tcg_out32(s, SUBF | TAB(a0, a2, a1)); 2686 } 2687 break; 2688 2689 case INDEX_op_and_i32: 2690 a0 = args[0], a1 = args[1], a2 = args[2]; 2691 if (const_args[2]) { 2692 tcg_out_andi32(s, a0, a1, a2); 2693 } else { 2694 tcg_out32(s, AND | SAB(a1, a0, a2)); 2695 } 2696 break; 2697 case INDEX_op_and_i64: 2698 a0 = args[0], a1 = args[1], a2 = args[2]; 2699 if (const_args[2]) { 2700 tcg_out_andi64(s, a0, a1, a2); 2701 } else { 2702 tcg_out32(s, AND | SAB(a1, a0, a2)); 2703 } 2704 break; 2705 case INDEX_op_or_i64: 2706 case INDEX_op_or_i32: 2707 a0 = args[0], a1 = args[1], a2 = args[2]; 2708 if (const_args[2]) { 2709 tcg_out_ori32(s, a0, a1, a2); 2710 } else { 2711 tcg_out32(s, OR | SAB(a1, a0, a2)); 2712 } 2713 break; 2714 case INDEX_op_xor_i64: 2715 case INDEX_op_xor_i32: 2716 a0 = args[0], a1 = args[1], a2 = args[2]; 2717 if (const_args[2]) { 2718 tcg_out_xori32(s, a0, a1, a2); 2719 } else { 2720 tcg_out32(s, XOR | SAB(a1, a0, a2)); 2721 } 2722 break; 2723 case INDEX_op_andc_i32: 2724 a0 = args[0], a1 = args[1], a2 = args[2]; 2725 if (const_args[2]) { 2726 tcg_out_andi32(s, a0, a1, ~a2); 2727 } else { 2728 tcg_out32(s, ANDC | SAB(a1, a0, a2)); 2729 } 2730 break; 2731 case INDEX_op_andc_i64: 2732 a0 = args[0], a1 = args[1], a2 = args[2]; 2733 if (const_args[2]) { 2734 tcg_out_andi64(s, a0, a1, ~a2); 2735 } else { 2736 tcg_out32(s, ANDC | SAB(a1, a0, a2)); 2737 } 2738 break; 2739 case INDEX_op_orc_i32: 2740 if (const_args[2]) { 2741 tcg_out_ori32(s, args[0], args[1], ~args[2]); 2742 break; 2743 } 2744 /* FALLTHRU */ 2745 case INDEX_op_orc_i64: 2746 tcg_out32(s, ORC | SAB(args[1], args[0], args[2])); 2747 break; 2748 case INDEX_op_eqv_i32: 2749 if (const_args[2]) { 2750 tcg_out_xori32(s, args[0], args[1], ~args[2]); 2751 break; 2752 } 2753 /* FALLTHRU */ 2754 case INDEX_op_eqv_i64: 2755 tcg_out32(s, EQV | SAB(args[1], args[0], args[2])); 2756 break; 2757 case INDEX_op_nand_i32: 2758 case INDEX_op_nand_i64: 2759 tcg_out32(s, NAND | SAB(args[1], args[0], args[2])); 2760 break; 2761 case INDEX_op_nor_i32: 2762 case INDEX_op_nor_i64: 2763 tcg_out32(s, NOR | SAB(args[1], args[0], args[2])); 2764 break; 2765 2766 case INDEX_op_clz_i32: 2767 tcg_out_cntxz(s, TCG_TYPE_I32, CNTLZW, args[0], args[1], 2768 args[2], const_args[2]); 2769 break; 2770 case INDEX_op_ctz_i32: 2771 tcg_out_cntxz(s, TCG_TYPE_I32, CNTTZW, args[0], args[1], 2772 args[2], const_args[2]); 2773 break; 2774 case INDEX_op_ctpop_i32: 2775 tcg_out32(s, CNTPOPW | SAB(args[1], args[0], 0)); 2776 break; 2777 2778 case INDEX_op_clz_i64: 2779 tcg_out_cntxz(s, TCG_TYPE_I64, CNTLZD, args[0], args[1], 2780 args[2], const_args[2]); 2781 break; 2782 case INDEX_op_ctz_i64: 2783 tcg_out_cntxz(s, TCG_TYPE_I64, CNTTZD, args[0], args[1], 2784 args[2], const_args[2]); 2785 break; 2786 case INDEX_op_ctpop_i64: 2787 tcg_out32(s, CNTPOPD | SAB(args[1], args[0], 0)); 2788 break; 2789 2790 case INDEX_op_mul_i32: 2791 a0 = args[0], a1 = args[1], a2 = args[2]; 2792 if (const_args[2]) { 2793 tcg_out32(s, MULLI | TAI(a0, a1, a2)); 2794 } else { 2795 tcg_out32(s, MULLW | TAB(a0, a1, a2)); 2796 } 2797 break; 2798 2799 case INDEX_op_div_i32: 2800 tcg_out32(s, DIVW | TAB(args[0], args[1], args[2])); 2801 break; 2802 2803 case INDEX_op_divu_i32: 2804 tcg_out32(s, DIVWU | TAB(args[0], args[1], args[2])); 2805 break; 2806 2807 case INDEX_op_rem_i32: 2808 tcg_out32(s, MODSW | TAB(args[0], args[1], args[2])); 2809 break; 2810 2811 case INDEX_op_remu_i32: 2812 tcg_out32(s, MODUW | TAB(args[0], args[1], args[2])); 2813 break; 2814 2815 case INDEX_op_shl_i32: 2816 if (const_args[2]) { 2817 /* Limit immediate shift count lest we create an illegal insn. */ 2818 tcg_out_shli32(s, args[0], args[1], args[2] & 31); 2819 } else { 2820 tcg_out32(s, SLW | SAB(args[1], args[0], args[2])); 2821 } 2822 break; 2823 case INDEX_op_shr_i32: 2824 if (const_args[2]) { 2825 /* Limit immediate shift count lest we create an illegal insn. */ 2826 tcg_out_shri32(s, args[0], args[1], args[2] & 31); 2827 } else { 2828 tcg_out32(s, SRW | SAB(args[1], args[0], args[2])); 2829 } 2830 break; 2831 case INDEX_op_sar_i32: 2832 if (const_args[2]) { 2833 tcg_out_sari32(s, args[0], args[1], args[2]); 2834 } else { 2835 tcg_out32(s, SRAW | SAB(args[1], args[0], args[2])); 2836 } 2837 break; 2838 case INDEX_op_rotl_i32: 2839 if (const_args[2]) { 2840 tcg_out_rlw(s, RLWINM, args[0], args[1], args[2], 0, 31); 2841 } else { 2842 tcg_out32(s, RLWNM | SAB(args[1], args[0], args[2]) 2843 | MB(0) | ME(31)); 2844 } 2845 break; 2846 case INDEX_op_rotr_i32: 2847 if (const_args[2]) { 2848 tcg_out_rlw(s, RLWINM, args[0], args[1], 32 - args[2], 0, 31); 2849 } else { 2850 tcg_out32(s, SUBFIC | TAI(TCG_REG_R0, args[2], 32)); 2851 tcg_out32(s, RLWNM | SAB(args[1], args[0], TCG_REG_R0) 2852 | MB(0) | ME(31)); 2853 } 2854 break; 2855 2856 case INDEX_op_brcond_i32: 2857 tcg_out_brcond(s, args[2], args[0], args[1], const_args[1], 2858 arg_label(args[3]), TCG_TYPE_I32); 2859 break; 2860 case INDEX_op_brcond_i64: 2861 tcg_out_brcond(s, args[2], args[0], args[1], const_args[1], 2862 arg_label(args[3]), TCG_TYPE_I64); 2863 break; 2864 case INDEX_op_brcond2_i32: 2865 tcg_out_brcond2(s, args, const_args); 2866 break; 2867 2868 case INDEX_op_neg_i32: 2869 case INDEX_op_neg_i64: 2870 tcg_out32(s, NEG | RT(args[0]) | RA(args[1])); 2871 break; 2872 2873 case INDEX_op_not_i32: 2874 case INDEX_op_not_i64: 2875 tcg_out32(s, NOR | SAB(args[1], args[0], args[1])); 2876 break; 2877 2878 case INDEX_op_add_i64: 2879 a0 = args[0], a1 = args[1], a2 = args[2]; 2880 if (const_args[2]) { 2881 do_addi_64: 2882 tcg_out_mem_long(s, ADDI, ADD, a0, a1, a2); 2883 } else { 2884 tcg_out32(s, ADD | TAB(a0, a1, a2)); 2885 } 2886 break; 2887 case INDEX_op_sub_i64: 2888 a0 = args[0], a1 = args[1], a2 = args[2]; 2889 if (const_args[1]) { 2890 if (const_args[2]) { 2891 tcg_out_movi(s, TCG_TYPE_I64, a0, a1 - a2); 2892 } else { 2893 tcg_out32(s, SUBFIC | TAI(a0, a2, a1)); 2894 } 2895 } else if (const_args[2]) { 2896 a2 = -a2; 2897 goto do_addi_64; 2898 } else { 2899 tcg_out32(s, SUBF | TAB(a0, a2, a1)); 2900 } 2901 break; 2902 2903 case INDEX_op_shl_i64: 2904 if (const_args[2]) { 2905 /* Limit immediate shift count lest we create an illegal insn. */ 2906 tcg_out_shli64(s, args[0], args[1], args[2] & 63); 2907 } else { 2908 tcg_out32(s, SLD | SAB(args[1], args[0], args[2])); 2909 } 2910 break; 2911 case INDEX_op_shr_i64: 2912 if (const_args[2]) { 2913 /* Limit immediate shift count lest we create an illegal insn. */ 2914 tcg_out_shri64(s, args[0], args[1], args[2] & 63); 2915 } else { 2916 tcg_out32(s, SRD | SAB(args[1], args[0], args[2])); 2917 } 2918 break; 2919 case INDEX_op_sar_i64: 2920 if (const_args[2]) { 2921 tcg_out_sari64(s, args[0], args[1], args[2]); 2922 } else { 2923 tcg_out32(s, SRAD | SAB(args[1], args[0], args[2])); 2924 } 2925 break; 2926 case INDEX_op_rotl_i64: 2927 if (const_args[2]) { 2928 tcg_out_rld(s, RLDICL, args[0], args[1], args[2], 0); 2929 } else { 2930 tcg_out32(s, RLDCL | SAB(args[1], args[0], args[2]) | MB64(0)); 2931 } 2932 break; 2933 case INDEX_op_rotr_i64: 2934 if (const_args[2]) { 2935 tcg_out_rld(s, RLDICL, args[0], args[1], 64 - args[2], 0); 2936 } else { 2937 tcg_out32(s, SUBFIC | TAI(TCG_REG_R0, args[2], 64)); 2938 tcg_out32(s, RLDCL | SAB(args[1], args[0], TCG_REG_R0) | MB64(0)); 2939 } 2940 break; 2941 2942 case INDEX_op_mul_i64: 2943 a0 = args[0], a1 = args[1], a2 = args[2]; 2944 if (const_args[2]) { 2945 tcg_out32(s, MULLI | TAI(a0, a1, a2)); 2946 } else { 2947 tcg_out32(s, MULLD | TAB(a0, a1, a2)); 2948 } 2949 break; 2950 case INDEX_op_div_i64: 2951 tcg_out32(s, DIVD | TAB(args[0], args[1], args[2])); 2952 break; 2953 case INDEX_op_divu_i64: 2954 tcg_out32(s, DIVDU | TAB(args[0], args[1], args[2])); 2955 break; 2956 case INDEX_op_rem_i64: 2957 tcg_out32(s, MODSD | TAB(args[0], args[1], args[2])); 2958 break; 2959 case INDEX_op_remu_i64: 2960 tcg_out32(s, MODUD | TAB(args[0], args[1], args[2])); 2961 break; 2962 2963 case INDEX_op_qemu_ld_i32: 2964 tcg_out_qemu_ld(s, args, false); 2965 break; 2966 case INDEX_op_qemu_ld_i64: 2967 tcg_out_qemu_ld(s, args, true); 2968 break; 2969 case INDEX_op_qemu_st_i32: 2970 tcg_out_qemu_st(s, args, false); 2971 break; 2972 case INDEX_op_qemu_st_i64: 2973 tcg_out_qemu_st(s, args, true); 2974 break; 2975 2976 case INDEX_op_ext8s_i32: 2977 case INDEX_op_ext8s_i64: 2978 tcg_out_ext8s(s, args[0], args[1]); 2979 break; 2980 case INDEX_op_ext16s_i32: 2981 case INDEX_op_ext16s_i64: 2982 tcg_out_ext16s(s, args[0], args[1]); 2983 break; 2984 case INDEX_op_ext_i32_i64: 2985 case INDEX_op_ext32s_i64: 2986 tcg_out_ext32s(s, args[0], args[1]); 2987 break; 2988 case INDEX_op_extu_i32_i64: 2989 tcg_out_ext32u(s, args[0], args[1]); 2990 break; 2991 2992 case INDEX_op_setcond_i32: 2993 tcg_out_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1], args[2], 2994 const_args[2]); 2995 break; 2996 case INDEX_op_setcond_i64: 2997 tcg_out_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1], args[2], 2998 const_args[2]); 2999 break; 3000 case INDEX_op_setcond2_i32: 3001 tcg_out_setcond2(s, args, const_args); 3002 break; 3003 3004 case INDEX_op_bswap16_i32: 3005 case INDEX_op_bswap16_i64: 3006 tcg_out_bswap16(s, args[0], args[1], args[2]); 3007 break; 3008 case INDEX_op_bswap32_i32: 3009 tcg_out_bswap32(s, args[0], args[1], 0); 3010 break; 3011 case INDEX_op_bswap32_i64: 3012 tcg_out_bswap32(s, args[0], args[1], args[2]); 3013 break; 3014 case INDEX_op_bswap64_i64: 3015 tcg_out_bswap64(s, args[0], args[1]); 3016 break; 3017 3018 case INDEX_op_deposit_i32: 3019 if (const_args[2]) { 3020 uint32_t mask = ((2u << (args[4] - 1)) - 1) << args[3]; 3021 tcg_out_andi32(s, args[0], args[0], ~mask); 3022 } else { 3023 tcg_out_rlw(s, RLWIMI, args[0], args[2], args[3], 3024 32 - args[3] - args[4], 31 - args[3]); 3025 } 3026 break; 3027 case INDEX_op_deposit_i64: 3028 if (const_args[2]) { 3029 uint64_t mask = ((2ull << (args[4] - 1)) - 1) << args[3]; 3030 tcg_out_andi64(s, args[0], args[0], ~mask); 3031 } else { 3032 tcg_out_rld(s, RLDIMI, args[0], args[2], args[3], 3033 64 - args[3] - args[4]); 3034 } 3035 break; 3036 3037 case INDEX_op_extract_i32: 3038 tcg_out_rlw(s, RLWINM, args[0], args[1], 3039 32 - args[2], 32 - args[3], 31); 3040 break; 3041 case INDEX_op_extract_i64: 3042 tcg_out_rld(s, RLDICL, args[0], args[1], 64 - args[2], 64 - args[3]); 3043 break; 3044 3045 case INDEX_op_movcond_i32: 3046 tcg_out_movcond(s, TCG_TYPE_I32, args[5], args[0], args[1], args[2], 3047 args[3], args[4], const_args[2]); 3048 break; 3049 case INDEX_op_movcond_i64: 3050 tcg_out_movcond(s, TCG_TYPE_I64, args[5], args[0], args[1], args[2], 3051 args[3], args[4], const_args[2]); 3052 break; 3053 3054#if TCG_TARGET_REG_BITS == 64 3055 case INDEX_op_add2_i64: 3056#else 3057 case INDEX_op_add2_i32: 3058#endif 3059 /* Note that the CA bit is defined based on the word size of the 3060 environment. So in 64-bit mode it's always carry-out of bit 63. 3061 The fallback code using deposit works just as well for 32-bit. */ 3062 a0 = args[0], a1 = args[1]; 3063 if (a0 == args[3] || (!const_args[5] && a0 == args[5])) { 3064 a0 = TCG_REG_R0; 3065 } 3066 if (const_args[4]) { 3067 tcg_out32(s, ADDIC | TAI(a0, args[2], args[4])); 3068 } else { 3069 tcg_out32(s, ADDC | TAB(a0, args[2], args[4])); 3070 } 3071 if (const_args[5]) { 3072 tcg_out32(s, (args[5] ? ADDME : ADDZE) | RT(a1) | RA(args[3])); 3073 } else { 3074 tcg_out32(s, ADDE | TAB(a1, args[3], args[5])); 3075 } 3076 if (a0 != args[0]) { 3077 tcg_out_mov(s, TCG_TYPE_REG, args[0], a0); 3078 } 3079 break; 3080 3081#if TCG_TARGET_REG_BITS == 64 3082 case INDEX_op_sub2_i64: 3083#else 3084 case INDEX_op_sub2_i32: 3085#endif 3086 a0 = args[0], a1 = args[1]; 3087 if (a0 == args[5] || (!const_args[3] && a0 == args[3])) { 3088 a0 = TCG_REG_R0; 3089 } 3090 if (const_args[2]) { 3091 tcg_out32(s, SUBFIC | TAI(a0, args[4], args[2])); 3092 } else { 3093 tcg_out32(s, SUBFC | TAB(a0, args[4], args[2])); 3094 } 3095 if (const_args[3]) { 3096 tcg_out32(s, (args[3] ? SUBFME : SUBFZE) | RT(a1) | RA(args[5])); 3097 } else { 3098 tcg_out32(s, SUBFE | TAB(a1, args[5], args[3])); 3099 } 3100 if (a0 != args[0]) { 3101 tcg_out_mov(s, TCG_TYPE_REG, args[0], a0); 3102 } 3103 break; 3104 3105 case INDEX_op_muluh_i32: 3106 tcg_out32(s, MULHWU | TAB(args[0], args[1], args[2])); 3107 break; 3108 case INDEX_op_mulsh_i32: 3109 tcg_out32(s, MULHW | TAB(args[0], args[1], args[2])); 3110 break; 3111 case INDEX_op_muluh_i64: 3112 tcg_out32(s, MULHDU | TAB(args[0], args[1], args[2])); 3113 break; 3114 case INDEX_op_mulsh_i64: 3115 tcg_out32(s, MULHD | TAB(args[0], args[1], args[2])); 3116 break; 3117 3118 case INDEX_op_mb: 3119 tcg_out_mb(s, args[0]); 3120 break; 3121 3122 case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */ 3123 case INDEX_op_mov_i64: 3124 case INDEX_op_call: /* Always emitted via tcg_out_call. */ 3125 case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */ 3126 case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ 3127 default: 3128 tcg_abort(); 3129 } 3130} 3131 3132int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, unsigned vece) 3133{ 3134 switch (opc) { 3135 case INDEX_op_and_vec: 3136 case INDEX_op_or_vec: 3137 case INDEX_op_xor_vec: 3138 case INDEX_op_andc_vec: 3139 case INDEX_op_not_vec: 3140 case INDEX_op_nor_vec: 3141 case INDEX_op_eqv_vec: 3142 case INDEX_op_nand_vec: 3143 return 1; 3144 case INDEX_op_orc_vec: 3145 return have_isa_2_07; 3146 case INDEX_op_add_vec: 3147 case INDEX_op_sub_vec: 3148 case INDEX_op_smax_vec: 3149 case INDEX_op_smin_vec: 3150 case INDEX_op_umax_vec: 3151 case INDEX_op_umin_vec: 3152 case INDEX_op_shlv_vec: 3153 case INDEX_op_shrv_vec: 3154 case INDEX_op_sarv_vec: 3155 case INDEX_op_rotlv_vec: 3156 return vece <= MO_32 || have_isa_2_07; 3157 case INDEX_op_ssadd_vec: 3158 case INDEX_op_sssub_vec: 3159 case INDEX_op_usadd_vec: 3160 case INDEX_op_ussub_vec: 3161 return vece <= MO_32; 3162 case INDEX_op_cmp_vec: 3163 case INDEX_op_shli_vec: 3164 case INDEX_op_shri_vec: 3165 case INDEX_op_sari_vec: 3166 case INDEX_op_rotli_vec: 3167 return vece <= MO_32 || have_isa_2_07 ? -1 : 0; 3168 case INDEX_op_neg_vec: 3169 return vece >= MO_32 && have_isa_3_00; 3170 case INDEX_op_mul_vec: 3171 switch (vece) { 3172 case MO_8: 3173 case MO_16: 3174 return -1; 3175 case MO_32: 3176 return have_isa_2_07 ? 1 : -1; 3177 case MO_64: 3178 return have_isa_3_10; 3179 } 3180 return 0; 3181 case INDEX_op_bitsel_vec: 3182 return have_vsx; 3183 case INDEX_op_rotrv_vec: 3184 return -1; 3185 default: 3186 return 0; 3187 } 3188} 3189 3190static bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece, 3191 TCGReg dst, TCGReg src) 3192{ 3193 tcg_debug_assert(dst >= TCG_REG_V0); 3194 3195 /* Splat from integer reg allowed via constraints for v3.00. */ 3196 if (src < TCG_REG_V0) { 3197 tcg_debug_assert(have_isa_3_00); 3198 switch (vece) { 3199 case MO_64: 3200 tcg_out32(s, MTVSRDD | VRT(dst) | RA(src) | RB(src)); 3201 return true; 3202 case MO_32: 3203 tcg_out32(s, MTVSRWS | VRT(dst) | RA(src)); 3204 return true; 3205 default: 3206 /* Fail, so that we fall back on either dupm or mov+dup. */ 3207 return false; 3208 } 3209 } 3210 3211 /* 3212 * Recall we use (or emulate) VSX integer loads, so the integer is 3213 * right justified within the left (zero-index) double-word. 3214 */ 3215 switch (vece) { 3216 case MO_8: 3217 tcg_out32(s, VSPLTB | VRT(dst) | VRB(src) | (7 << 16)); 3218 break; 3219 case MO_16: 3220 tcg_out32(s, VSPLTH | VRT(dst) | VRB(src) | (3 << 16)); 3221 break; 3222 case MO_32: 3223 tcg_out32(s, VSPLTW | VRT(dst) | VRB(src) | (1 << 16)); 3224 break; 3225 case MO_64: 3226 if (have_vsx) { 3227 tcg_out32(s, XXPERMDI | VRT(dst) | VRA(src) | VRB(src)); 3228 break; 3229 } 3230 tcg_out_vsldoi(s, TCG_VEC_TMP1, src, src, 8); 3231 tcg_out_vsldoi(s, dst, TCG_VEC_TMP1, src, 8); 3232 break; 3233 default: 3234 g_assert_not_reached(); 3235 } 3236 return true; 3237} 3238 3239static bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece, 3240 TCGReg out, TCGReg base, intptr_t offset) 3241{ 3242 int elt; 3243 3244 tcg_debug_assert(out >= TCG_REG_V0); 3245 switch (vece) { 3246 case MO_8: 3247 if (have_isa_3_00) { 3248 tcg_out_mem_long(s, LXV, LVX, out, base, offset & -16); 3249 } else { 3250 tcg_out_mem_long(s, 0, LVEBX, out, base, offset); 3251 } 3252 elt = extract32(offset, 0, 4); 3253#if !HOST_BIG_ENDIAN 3254 elt ^= 15; 3255#endif 3256 tcg_out32(s, VSPLTB | VRT(out) | VRB(out) | (elt << 16)); 3257 break; 3258 case MO_16: 3259 tcg_debug_assert((offset & 1) == 0); 3260 if (have_isa_3_00) { 3261 tcg_out_mem_long(s, LXV | 8, LVX, out, base, offset & -16); 3262 } else { 3263 tcg_out_mem_long(s, 0, LVEHX, out, base, offset); 3264 } 3265 elt = extract32(offset, 1, 3); 3266#if !HOST_BIG_ENDIAN 3267 elt ^= 7; 3268#endif 3269 tcg_out32(s, VSPLTH | VRT(out) | VRB(out) | (elt << 16)); 3270 break; 3271 case MO_32: 3272 if (have_isa_3_00) { 3273 tcg_out_mem_long(s, 0, LXVWSX, out, base, offset); 3274 break; 3275 } 3276 tcg_debug_assert((offset & 3) == 0); 3277 tcg_out_mem_long(s, 0, LVEWX, out, base, offset); 3278 elt = extract32(offset, 2, 2); 3279#if !HOST_BIG_ENDIAN 3280 elt ^= 3; 3281#endif 3282 tcg_out32(s, VSPLTW | VRT(out) | VRB(out) | (elt << 16)); 3283 break; 3284 case MO_64: 3285 if (have_vsx) { 3286 tcg_out_mem_long(s, 0, LXVDSX, out, base, offset); 3287 break; 3288 } 3289 tcg_debug_assert((offset & 7) == 0); 3290 tcg_out_mem_long(s, 0, LVX, out, base, offset & -16); 3291 tcg_out_vsldoi(s, TCG_VEC_TMP1, out, out, 8); 3292 elt = extract32(offset, 3, 1); 3293#if !HOST_BIG_ENDIAN 3294 elt = !elt; 3295#endif 3296 if (elt) { 3297 tcg_out_vsldoi(s, out, out, TCG_VEC_TMP1, 8); 3298 } else { 3299 tcg_out_vsldoi(s, out, TCG_VEC_TMP1, out, 8); 3300 } 3301 break; 3302 default: 3303 g_assert_not_reached(); 3304 } 3305 return true; 3306} 3307 3308static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc, 3309 unsigned vecl, unsigned vece, 3310 const TCGArg args[TCG_MAX_OP_ARGS], 3311 const int const_args[TCG_MAX_OP_ARGS]) 3312{ 3313 static const uint32_t 3314 add_op[4] = { VADDUBM, VADDUHM, VADDUWM, VADDUDM }, 3315 sub_op[4] = { VSUBUBM, VSUBUHM, VSUBUWM, VSUBUDM }, 3316 mul_op[4] = { 0, 0, VMULUWM, VMULLD }, 3317 neg_op[4] = { 0, 0, VNEGW, VNEGD }, 3318 eq_op[4] = { VCMPEQUB, VCMPEQUH, VCMPEQUW, VCMPEQUD }, 3319 ne_op[4] = { VCMPNEB, VCMPNEH, VCMPNEW, 0 }, 3320 gts_op[4] = { VCMPGTSB, VCMPGTSH, VCMPGTSW, VCMPGTSD }, 3321 gtu_op[4] = { VCMPGTUB, VCMPGTUH, VCMPGTUW, VCMPGTUD }, 3322 ssadd_op[4] = { VADDSBS, VADDSHS, VADDSWS, 0 }, 3323 usadd_op[4] = { VADDUBS, VADDUHS, VADDUWS, 0 }, 3324 sssub_op[4] = { VSUBSBS, VSUBSHS, VSUBSWS, 0 }, 3325 ussub_op[4] = { VSUBUBS, VSUBUHS, VSUBUWS, 0 }, 3326 umin_op[4] = { VMINUB, VMINUH, VMINUW, VMINUD }, 3327 smin_op[4] = { VMINSB, VMINSH, VMINSW, VMINSD }, 3328 umax_op[4] = { VMAXUB, VMAXUH, VMAXUW, VMAXUD }, 3329 smax_op[4] = { VMAXSB, VMAXSH, VMAXSW, VMAXSD }, 3330 shlv_op[4] = { VSLB, VSLH, VSLW, VSLD }, 3331 shrv_op[4] = { VSRB, VSRH, VSRW, VSRD }, 3332 sarv_op[4] = { VSRAB, VSRAH, VSRAW, VSRAD }, 3333 mrgh_op[4] = { VMRGHB, VMRGHH, VMRGHW, 0 }, 3334 mrgl_op[4] = { VMRGLB, VMRGLH, VMRGLW, 0 }, 3335 muleu_op[4] = { VMULEUB, VMULEUH, VMULEUW, 0 }, 3336 mulou_op[4] = { VMULOUB, VMULOUH, VMULOUW, 0 }, 3337 pkum_op[4] = { VPKUHUM, VPKUWUM, 0, 0 }, 3338 rotl_op[4] = { VRLB, VRLH, VRLW, VRLD }; 3339 3340 TCGType type = vecl + TCG_TYPE_V64; 3341 TCGArg a0 = args[0], a1 = args[1], a2 = args[2]; 3342 uint32_t insn; 3343 3344 switch (opc) { 3345 case INDEX_op_ld_vec: 3346 tcg_out_ld(s, type, a0, a1, a2); 3347 return; 3348 case INDEX_op_st_vec: 3349 tcg_out_st(s, type, a0, a1, a2); 3350 return; 3351 case INDEX_op_dupm_vec: 3352 tcg_out_dupm_vec(s, type, vece, a0, a1, a2); 3353 return; 3354 3355 case INDEX_op_add_vec: 3356 insn = add_op[vece]; 3357 break; 3358 case INDEX_op_sub_vec: 3359 insn = sub_op[vece]; 3360 break; 3361 case INDEX_op_neg_vec: 3362 insn = neg_op[vece]; 3363 a2 = a1; 3364 a1 = 0; 3365 break; 3366 case INDEX_op_mul_vec: 3367 insn = mul_op[vece]; 3368 break; 3369 case INDEX_op_ssadd_vec: 3370 insn = ssadd_op[vece]; 3371 break; 3372 case INDEX_op_sssub_vec: 3373 insn = sssub_op[vece]; 3374 break; 3375 case INDEX_op_usadd_vec: 3376 insn = usadd_op[vece]; 3377 break; 3378 case INDEX_op_ussub_vec: 3379 insn = ussub_op[vece]; 3380 break; 3381 case INDEX_op_smin_vec: 3382 insn = smin_op[vece]; 3383 break; 3384 case INDEX_op_umin_vec: 3385 insn = umin_op[vece]; 3386 break; 3387 case INDEX_op_smax_vec: 3388 insn = smax_op[vece]; 3389 break; 3390 case INDEX_op_umax_vec: 3391 insn = umax_op[vece]; 3392 break; 3393 case INDEX_op_shlv_vec: 3394 insn = shlv_op[vece]; 3395 break; 3396 case INDEX_op_shrv_vec: 3397 insn = shrv_op[vece]; 3398 break; 3399 case INDEX_op_sarv_vec: 3400 insn = sarv_op[vece]; 3401 break; 3402 case INDEX_op_and_vec: 3403 insn = VAND; 3404 break; 3405 case INDEX_op_or_vec: 3406 insn = VOR; 3407 break; 3408 case INDEX_op_xor_vec: 3409 insn = VXOR; 3410 break; 3411 case INDEX_op_andc_vec: 3412 insn = VANDC; 3413 break; 3414 case INDEX_op_not_vec: 3415 insn = VNOR; 3416 a2 = a1; 3417 break; 3418 case INDEX_op_orc_vec: 3419 insn = VORC; 3420 break; 3421 case INDEX_op_nand_vec: 3422 insn = VNAND; 3423 break; 3424 case INDEX_op_nor_vec: 3425 insn = VNOR; 3426 break; 3427 case INDEX_op_eqv_vec: 3428 insn = VEQV; 3429 break; 3430 3431 case INDEX_op_cmp_vec: 3432 switch (args[3]) { 3433 case TCG_COND_EQ: 3434 insn = eq_op[vece]; 3435 break; 3436 case TCG_COND_NE: 3437 insn = ne_op[vece]; 3438 break; 3439 case TCG_COND_GT: 3440 insn = gts_op[vece]; 3441 break; 3442 case TCG_COND_GTU: 3443 insn = gtu_op[vece]; 3444 break; 3445 default: 3446 g_assert_not_reached(); 3447 } 3448 break; 3449 3450 case INDEX_op_bitsel_vec: 3451 tcg_out32(s, XXSEL | VRT(a0) | VRC(a1) | VRB(a2) | VRA(args[3])); 3452 return; 3453 3454 case INDEX_op_dup2_vec: 3455 assert(TCG_TARGET_REG_BITS == 32); 3456 /* With inputs a1 = xLxx, a2 = xHxx */ 3457 tcg_out32(s, VMRGHW | VRT(a0) | VRA(a2) | VRB(a1)); /* a0 = xxHL */ 3458 tcg_out_vsldoi(s, TCG_VEC_TMP1, a0, a0, 8); /* tmp = HLxx */ 3459 tcg_out_vsldoi(s, a0, a0, TCG_VEC_TMP1, 8); /* a0 = HLHL */ 3460 return; 3461 3462 case INDEX_op_ppc_mrgh_vec: 3463 insn = mrgh_op[vece]; 3464 break; 3465 case INDEX_op_ppc_mrgl_vec: 3466 insn = mrgl_op[vece]; 3467 break; 3468 case INDEX_op_ppc_muleu_vec: 3469 insn = muleu_op[vece]; 3470 break; 3471 case INDEX_op_ppc_mulou_vec: 3472 insn = mulou_op[vece]; 3473 break; 3474 case INDEX_op_ppc_pkum_vec: 3475 insn = pkum_op[vece]; 3476 break; 3477 case INDEX_op_rotlv_vec: 3478 insn = rotl_op[vece]; 3479 break; 3480 case INDEX_op_ppc_msum_vec: 3481 tcg_debug_assert(vece == MO_16); 3482 tcg_out32(s, VMSUMUHM | VRT(a0) | VRA(a1) | VRB(a2) | VRC(args[3])); 3483 return; 3484 3485 case INDEX_op_mov_vec: /* Always emitted via tcg_out_mov. */ 3486 case INDEX_op_dup_vec: /* Always emitted via tcg_out_dup_vec. */ 3487 default: 3488 g_assert_not_reached(); 3489 } 3490 3491 tcg_debug_assert(insn != 0); 3492 tcg_out32(s, insn | VRT(a0) | VRA(a1) | VRB(a2)); 3493} 3494 3495static void expand_vec_shi(TCGType type, unsigned vece, TCGv_vec v0, 3496 TCGv_vec v1, TCGArg imm, TCGOpcode opci) 3497{ 3498 TCGv_vec t1; 3499 3500 if (vece == MO_32) { 3501 /* 3502 * Only 5 bits are significant, and VSPLTISB can represent -16..15. 3503 * So using negative numbers gets us the 4th bit easily. 3504 */ 3505 imm = sextract32(imm, 0, 5); 3506 } else { 3507 imm &= (8 << vece) - 1; 3508 } 3509 3510 /* Splat w/bytes for xxspltib when 2.07 allows MO_64. */ 3511 t1 = tcg_constant_vec(type, MO_8, imm); 3512 vec_gen_3(opci, type, vece, tcgv_vec_arg(v0), 3513 tcgv_vec_arg(v1), tcgv_vec_arg(t1)); 3514} 3515 3516static void expand_vec_cmp(TCGType type, unsigned vece, TCGv_vec v0, 3517 TCGv_vec v1, TCGv_vec v2, TCGCond cond) 3518{ 3519 bool need_swap = false, need_inv = false; 3520 3521 tcg_debug_assert(vece <= MO_32 || have_isa_2_07); 3522 3523 switch (cond) { 3524 case TCG_COND_EQ: 3525 case TCG_COND_GT: 3526 case TCG_COND_GTU: 3527 break; 3528 case TCG_COND_NE: 3529 if (have_isa_3_00 && vece <= MO_32) { 3530 break; 3531 } 3532 /* fall through */ 3533 case TCG_COND_LE: 3534 case TCG_COND_LEU: 3535 need_inv = true; 3536 break; 3537 case TCG_COND_LT: 3538 case TCG_COND_LTU: 3539 need_swap = true; 3540 break; 3541 case TCG_COND_GE: 3542 case TCG_COND_GEU: 3543 need_swap = need_inv = true; 3544 break; 3545 default: 3546 g_assert_not_reached(); 3547 } 3548 3549 if (need_inv) { 3550 cond = tcg_invert_cond(cond); 3551 } 3552 if (need_swap) { 3553 TCGv_vec t1; 3554 t1 = v1, v1 = v2, v2 = t1; 3555 cond = tcg_swap_cond(cond); 3556 } 3557 3558 vec_gen_4(INDEX_op_cmp_vec, type, vece, tcgv_vec_arg(v0), 3559 tcgv_vec_arg(v1), tcgv_vec_arg(v2), cond); 3560 3561 if (need_inv) { 3562 tcg_gen_not_vec(vece, v0, v0); 3563 } 3564} 3565 3566static void expand_vec_mul(TCGType type, unsigned vece, TCGv_vec v0, 3567 TCGv_vec v1, TCGv_vec v2) 3568{ 3569 TCGv_vec t1 = tcg_temp_new_vec(type); 3570 TCGv_vec t2 = tcg_temp_new_vec(type); 3571 TCGv_vec c0, c16; 3572 3573 switch (vece) { 3574 case MO_8: 3575 case MO_16: 3576 vec_gen_3(INDEX_op_ppc_muleu_vec, type, vece, tcgv_vec_arg(t1), 3577 tcgv_vec_arg(v1), tcgv_vec_arg(v2)); 3578 vec_gen_3(INDEX_op_ppc_mulou_vec, type, vece, tcgv_vec_arg(t2), 3579 tcgv_vec_arg(v1), tcgv_vec_arg(v2)); 3580 vec_gen_3(INDEX_op_ppc_mrgh_vec, type, vece + 1, tcgv_vec_arg(v0), 3581 tcgv_vec_arg(t1), tcgv_vec_arg(t2)); 3582 vec_gen_3(INDEX_op_ppc_mrgl_vec, type, vece + 1, tcgv_vec_arg(t1), 3583 tcgv_vec_arg(t1), tcgv_vec_arg(t2)); 3584 vec_gen_3(INDEX_op_ppc_pkum_vec, type, vece, tcgv_vec_arg(v0), 3585 tcgv_vec_arg(v0), tcgv_vec_arg(t1)); 3586 break; 3587 3588 case MO_32: 3589 tcg_debug_assert(!have_isa_2_07); 3590 /* 3591 * Only 5 bits are significant, and VSPLTISB can represent -16..15. 3592 * So using -16 is a quick way to represent 16. 3593 */ 3594 c16 = tcg_constant_vec(type, MO_8, -16); 3595 c0 = tcg_constant_vec(type, MO_8, 0); 3596 3597 vec_gen_3(INDEX_op_rotlv_vec, type, MO_32, tcgv_vec_arg(t1), 3598 tcgv_vec_arg(v2), tcgv_vec_arg(c16)); 3599 vec_gen_3(INDEX_op_ppc_mulou_vec, type, MO_16, tcgv_vec_arg(t2), 3600 tcgv_vec_arg(v1), tcgv_vec_arg(v2)); 3601 vec_gen_4(INDEX_op_ppc_msum_vec, type, MO_16, tcgv_vec_arg(t1), 3602 tcgv_vec_arg(v1), tcgv_vec_arg(t1), tcgv_vec_arg(c0)); 3603 vec_gen_3(INDEX_op_shlv_vec, type, MO_32, tcgv_vec_arg(t1), 3604 tcgv_vec_arg(t1), tcgv_vec_arg(c16)); 3605 tcg_gen_add_vec(MO_32, v0, t1, t2); 3606 break; 3607 3608 default: 3609 g_assert_not_reached(); 3610 } 3611 tcg_temp_free_vec(t1); 3612 tcg_temp_free_vec(t2); 3613} 3614 3615void tcg_expand_vec_op(TCGOpcode opc, TCGType type, unsigned vece, 3616 TCGArg a0, ...) 3617{ 3618 va_list va; 3619 TCGv_vec v0, v1, v2, t0; 3620 TCGArg a2; 3621 3622 va_start(va, a0); 3623 v0 = temp_tcgv_vec(arg_temp(a0)); 3624 v1 = temp_tcgv_vec(arg_temp(va_arg(va, TCGArg))); 3625 a2 = va_arg(va, TCGArg); 3626 3627 switch (opc) { 3628 case INDEX_op_shli_vec: 3629 expand_vec_shi(type, vece, v0, v1, a2, INDEX_op_shlv_vec); 3630 break; 3631 case INDEX_op_shri_vec: 3632 expand_vec_shi(type, vece, v0, v1, a2, INDEX_op_shrv_vec); 3633 break; 3634 case INDEX_op_sari_vec: 3635 expand_vec_shi(type, vece, v0, v1, a2, INDEX_op_sarv_vec); 3636 break; 3637 case INDEX_op_rotli_vec: 3638 expand_vec_shi(type, vece, v0, v1, a2, INDEX_op_rotlv_vec); 3639 break; 3640 case INDEX_op_cmp_vec: 3641 v2 = temp_tcgv_vec(arg_temp(a2)); 3642 expand_vec_cmp(type, vece, v0, v1, v2, va_arg(va, TCGArg)); 3643 break; 3644 case INDEX_op_mul_vec: 3645 v2 = temp_tcgv_vec(arg_temp(a2)); 3646 expand_vec_mul(type, vece, v0, v1, v2); 3647 break; 3648 case INDEX_op_rotlv_vec: 3649 v2 = temp_tcgv_vec(arg_temp(a2)); 3650 t0 = tcg_temp_new_vec(type); 3651 tcg_gen_neg_vec(vece, t0, v2); 3652 tcg_gen_rotlv_vec(vece, v0, v1, t0); 3653 tcg_temp_free_vec(t0); 3654 break; 3655 default: 3656 g_assert_not_reached(); 3657 } 3658 va_end(va); 3659} 3660 3661static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op) 3662{ 3663 switch (op) { 3664 case INDEX_op_goto_ptr: 3665 return C_O0_I1(r); 3666 3667 case INDEX_op_ld8u_i32: 3668 case INDEX_op_ld8s_i32: 3669 case INDEX_op_ld16u_i32: 3670 case INDEX_op_ld16s_i32: 3671 case INDEX_op_ld_i32: 3672 case INDEX_op_ctpop_i32: 3673 case INDEX_op_neg_i32: 3674 case INDEX_op_not_i32: 3675 case INDEX_op_ext8s_i32: 3676 case INDEX_op_ext16s_i32: 3677 case INDEX_op_bswap16_i32: 3678 case INDEX_op_bswap32_i32: 3679 case INDEX_op_extract_i32: 3680 case INDEX_op_ld8u_i64: 3681 case INDEX_op_ld8s_i64: 3682 case INDEX_op_ld16u_i64: 3683 case INDEX_op_ld16s_i64: 3684 case INDEX_op_ld32u_i64: 3685 case INDEX_op_ld32s_i64: 3686 case INDEX_op_ld_i64: 3687 case INDEX_op_ctpop_i64: 3688 case INDEX_op_neg_i64: 3689 case INDEX_op_not_i64: 3690 case INDEX_op_ext8s_i64: 3691 case INDEX_op_ext16s_i64: 3692 case INDEX_op_ext32s_i64: 3693 case INDEX_op_ext_i32_i64: 3694 case INDEX_op_extu_i32_i64: 3695 case INDEX_op_bswap16_i64: 3696 case INDEX_op_bswap32_i64: 3697 case INDEX_op_bswap64_i64: 3698 case INDEX_op_extract_i64: 3699 return C_O1_I1(r, r); 3700 3701 case INDEX_op_st8_i32: 3702 case INDEX_op_st16_i32: 3703 case INDEX_op_st_i32: 3704 case INDEX_op_st8_i64: 3705 case INDEX_op_st16_i64: 3706 case INDEX_op_st32_i64: 3707 case INDEX_op_st_i64: 3708 return C_O0_I2(r, r); 3709 3710 case INDEX_op_add_i32: 3711 case INDEX_op_and_i32: 3712 case INDEX_op_or_i32: 3713 case INDEX_op_xor_i32: 3714 case INDEX_op_andc_i32: 3715 case INDEX_op_orc_i32: 3716 case INDEX_op_eqv_i32: 3717 case INDEX_op_shl_i32: 3718 case INDEX_op_shr_i32: 3719 case INDEX_op_sar_i32: 3720 case INDEX_op_rotl_i32: 3721 case INDEX_op_rotr_i32: 3722 case INDEX_op_setcond_i32: 3723 case INDEX_op_and_i64: 3724 case INDEX_op_andc_i64: 3725 case INDEX_op_shl_i64: 3726 case INDEX_op_shr_i64: 3727 case INDEX_op_sar_i64: 3728 case INDEX_op_rotl_i64: 3729 case INDEX_op_rotr_i64: 3730 case INDEX_op_setcond_i64: 3731 return C_O1_I2(r, r, ri); 3732 3733 case INDEX_op_mul_i32: 3734 case INDEX_op_mul_i64: 3735 return C_O1_I2(r, r, rI); 3736 3737 case INDEX_op_div_i32: 3738 case INDEX_op_divu_i32: 3739 case INDEX_op_rem_i32: 3740 case INDEX_op_remu_i32: 3741 case INDEX_op_nand_i32: 3742 case INDEX_op_nor_i32: 3743 case INDEX_op_muluh_i32: 3744 case INDEX_op_mulsh_i32: 3745 case INDEX_op_orc_i64: 3746 case INDEX_op_eqv_i64: 3747 case INDEX_op_nand_i64: 3748 case INDEX_op_nor_i64: 3749 case INDEX_op_div_i64: 3750 case INDEX_op_divu_i64: 3751 case INDEX_op_rem_i64: 3752 case INDEX_op_remu_i64: 3753 case INDEX_op_mulsh_i64: 3754 case INDEX_op_muluh_i64: 3755 return C_O1_I2(r, r, r); 3756 3757 case INDEX_op_sub_i32: 3758 return C_O1_I2(r, rI, ri); 3759 case INDEX_op_add_i64: 3760 return C_O1_I2(r, r, rT); 3761 case INDEX_op_or_i64: 3762 case INDEX_op_xor_i64: 3763 return C_O1_I2(r, r, rU); 3764 case INDEX_op_sub_i64: 3765 return C_O1_I2(r, rI, rT); 3766 case INDEX_op_clz_i32: 3767 case INDEX_op_ctz_i32: 3768 case INDEX_op_clz_i64: 3769 case INDEX_op_ctz_i64: 3770 return C_O1_I2(r, r, rZW); 3771 3772 case INDEX_op_brcond_i32: 3773 case INDEX_op_brcond_i64: 3774 return C_O0_I2(r, ri); 3775 3776 case INDEX_op_movcond_i32: 3777 case INDEX_op_movcond_i64: 3778 return C_O1_I4(r, r, ri, rZ, rZ); 3779 case INDEX_op_deposit_i32: 3780 case INDEX_op_deposit_i64: 3781 return C_O1_I2(r, 0, rZ); 3782 case INDEX_op_brcond2_i32: 3783 return C_O0_I4(r, r, ri, ri); 3784 case INDEX_op_setcond2_i32: 3785 return C_O1_I4(r, r, r, ri, ri); 3786 case INDEX_op_add2_i64: 3787 case INDEX_op_add2_i32: 3788 return C_O2_I4(r, r, r, r, rI, rZM); 3789 case INDEX_op_sub2_i64: 3790 case INDEX_op_sub2_i32: 3791 return C_O2_I4(r, r, rI, rZM, r, r); 3792 3793 case INDEX_op_qemu_ld_i32: 3794 return (TCG_TARGET_REG_BITS == 64 || TARGET_LONG_BITS == 32 3795 ? C_O1_I1(r, L) 3796 : C_O1_I2(r, L, L)); 3797 3798 case INDEX_op_qemu_st_i32: 3799 return (TCG_TARGET_REG_BITS == 64 || TARGET_LONG_BITS == 32 3800 ? C_O0_I2(S, S) 3801 : C_O0_I3(S, S, S)); 3802 3803 case INDEX_op_qemu_ld_i64: 3804 return (TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, L) 3805 : TARGET_LONG_BITS == 32 ? C_O2_I1(L, L, L) 3806 : C_O2_I2(L, L, L, L)); 3807 3808 case INDEX_op_qemu_st_i64: 3809 return (TCG_TARGET_REG_BITS == 64 ? C_O0_I2(S, S) 3810 : TARGET_LONG_BITS == 32 ? C_O0_I3(S, S, S) 3811 : C_O0_I4(S, S, S, S)); 3812 3813 case INDEX_op_add_vec: 3814 case INDEX_op_sub_vec: 3815 case INDEX_op_mul_vec: 3816 case INDEX_op_and_vec: 3817 case INDEX_op_or_vec: 3818 case INDEX_op_xor_vec: 3819 case INDEX_op_andc_vec: 3820 case INDEX_op_orc_vec: 3821 case INDEX_op_nor_vec: 3822 case INDEX_op_eqv_vec: 3823 case INDEX_op_nand_vec: 3824 case INDEX_op_cmp_vec: 3825 case INDEX_op_ssadd_vec: 3826 case INDEX_op_sssub_vec: 3827 case INDEX_op_usadd_vec: 3828 case INDEX_op_ussub_vec: 3829 case INDEX_op_smax_vec: 3830 case INDEX_op_smin_vec: 3831 case INDEX_op_umax_vec: 3832 case INDEX_op_umin_vec: 3833 case INDEX_op_shlv_vec: 3834 case INDEX_op_shrv_vec: 3835 case INDEX_op_sarv_vec: 3836 case INDEX_op_rotlv_vec: 3837 case INDEX_op_rotrv_vec: 3838 case INDEX_op_ppc_mrgh_vec: 3839 case INDEX_op_ppc_mrgl_vec: 3840 case INDEX_op_ppc_muleu_vec: 3841 case INDEX_op_ppc_mulou_vec: 3842 case INDEX_op_ppc_pkum_vec: 3843 case INDEX_op_dup2_vec: 3844 return C_O1_I2(v, v, v); 3845 3846 case INDEX_op_not_vec: 3847 case INDEX_op_neg_vec: 3848 return C_O1_I1(v, v); 3849 3850 case INDEX_op_dup_vec: 3851 return have_isa_3_00 ? C_O1_I1(v, vr) : C_O1_I1(v, v); 3852 3853 case INDEX_op_ld_vec: 3854 case INDEX_op_dupm_vec: 3855 return C_O1_I1(v, r); 3856 3857 case INDEX_op_st_vec: 3858 return C_O0_I2(v, r); 3859 3860 case INDEX_op_bitsel_vec: 3861 case INDEX_op_ppc_msum_vec: 3862 return C_O1_I3(v, v, v, v); 3863 3864 default: 3865 g_assert_not_reached(); 3866 } 3867} 3868 3869static void tcg_target_init(TCGContext *s) 3870{ 3871 unsigned long hwcap = qemu_getauxval(AT_HWCAP); 3872 unsigned long hwcap2 = qemu_getauxval(AT_HWCAP2); 3873 3874 have_isa = tcg_isa_base; 3875 if (hwcap & PPC_FEATURE_ARCH_2_06) { 3876 have_isa = tcg_isa_2_06; 3877 } 3878#ifdef PPC_FEATURE2_ARCH_2_07 3879 if (hwcap2 & PPC_FEATURE2_ARCH_2_07) { 3880 have_isa = tcg_isa_2_07; 3881 } 3882#endif 3883#ifdef PPC_FEATURE2_ARCH_3_00 3884 if (hwcap2 & PPC_FEATURE2_ARCH_3_00) { 3885 have_isa = tcg_isa_3_00; 3886 } 3887#endif 3888#ifdef PPC_FEATURE2_ARCH_3_10 3889 if (hwcap2 & PPC_FEATURE2_ARCH_3_10) { 3890 have_isa = tcg_isa_3_10; 3891 } 3892#endif 3893 3894#ifdef PPC_FEATURE2_HAS_ISEL 3895 /* Prefer explicit instruction from the kernel. */ 3896 have_isel = (hwcap2 & PPC_FEATURE2_HAS_ISEL) != 0; 3897#else 3898 /* Fall back to knowing Power7 (2.06) has ISEL. */ 3899 have_isel = have_isa_2_06; 3900#endif 3901 3902 if (hwcap & PPC_FEATURE_HAS_ALTIVEC) { 3903 have_altivec = true; 3904 /* We only care about the portion of VSX that overlaps Altivec. */ 3905 if (hwcap & PPC_FEATURE_HAS_VSX) { 3906 have_vsx = true; 3907 } 3908 } 3909 3910 tcg_target_available_regs[TCG_TYPE_I32] = 0xffffffff; 3911 tcg_target_available_regs[TCG_TYPE_I64] = 0xffffffff; 3912 if (have_altivec) { 3913 tcg_target_available_regs[TCG_TYPE_V64] = 0xffffffff00000000ull; 3914 tcg_target_available_regs[TCG_TYPE_V128] = 0xffffffff00000000ull; 3915 } 3916 3917 tcg_target_call_clobber_regs = 0; 3918 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R0); 3919 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R2); 3920 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R3); 3921 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R4); 3922 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R5); 3923 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R6); 3924 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R7); 3925 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R8); 3926 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R9); 3927 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R10); 3928 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R11); 3929 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R12); 3930 3931 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V0); 3932 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V1); 3933 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V2); 3934 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V3); 3935 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V4); 3936 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V5); 3937 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V6); 3938 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V7); 3939 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V8); 3940 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V9); 3941 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V10); 3942 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V11); 3943 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V12); 3944 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V13); 3945 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V14); 3946 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V15); 3947 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V16); 3948 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V17); 3949 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V18); 3950 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V19); 3951 3952 s->reserved_regs = 0; 3953 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0); /* tcg temp */ 3954 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R1); /* stack pointer */ 3955#if defined(_CALL_SYSV) 3956 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R2); /* toc pointer */ 3957#endif 3958#if defined(_CALL_SYSV) || TCG_TARGET_REG_BITS == 64 3959 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R13); /* thread pointer */ 3960#endif 3961 tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP1); /* mem temp */ 3962 tcg_regset_set_reg(s->reserved_regs, TCG_VEC_TMP1); 3963 tcg_regset_set_reg(s->reserved_regs, TCG_VEC_TMP2); 3964 if (USE_REG_TB) { 3965 tcg_regset_set_reg(s->reserved_regs, TCG_REG_TB); /* tb->tc_ptr */ 3966 } 3967} 3968 3969#ifdef __ELF__ 3970typedef struct { 3971 DebugFrameCIE cie; 3972 DebugFrameFDEHeader fde; 3973 uint8_t fde_def_cfa[4]; 3974 uint8_t fde_reg_ofs[ARRAY_SIZE(tcg_target_callee_save_regs) * 2 + 3]; 3975} DebugFrame; 3976 3977/* We're expecting a 2 byte uleb128 encoded value. */ 3978QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14)); 3979 3980#if TCG_TARGET_REG_BITS == 64 3981# define ELF_HOST_MACHINE EM_PPC64 3982#else 3983# define ELF_HOST_MACHINE EM_PPC 3984#endif 3985 3986static DebugFrame debug_frame = { 3987 .cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */ 3988 .cie.id = -1, 3989 .cie.version = 1, 3990 .cie.code_align = 1, 3991 .cie.data_align = (-SZR & 0x7f), /* sleb128 -SZR */ 3992 .cie.return_column = 65, 3993 3994 /* Total FDE size does not include the "len" member. */ 3995 .fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, fde.cie_offset), 3996 3997 .fde_def_cfa = { 3998 12, TCG_REG_R1, /* DW_CFA_def_cfa r1, ... */ 3999 (FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */ 4000 (FRAME_SIZE >> 7) 4001 }, 4002 .fde_reg_ofs = { 4003 /* DW_CFA_offset_extended_sf, lr, LR_OFFSET */ 4004 0x11, 65, (LR_OFFSET / -SZR) & 0x7f, 4005 } 4006}; 4007 4008void tcg_register_jit(const void *buf, size_t buf_size) 4009{ 4010 uint8_t *p = &debug_frame.fde_reg_ofs[3]; 4011 int i; 4012 4013 for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); ++i, p += 2) { 4014 p[0] = 0x80 + tcg_target_callee_save_regs[i]; 4015 p[1] = (FRAME_SIZE - (REG_SAVE_BOT + i * SZR)) / SZR; 4016 } 4017 4018 debug_frame.fde.func_start = (uintptr_t)buf; 4019 debug_frame.fde.func_len = buf_size; 4020 4021 tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame)); 4022} 4023#endif /* __ELF__ */ 4024#undef VMULEUB 4025#undef VMULEUH 4026#undef VMULEUW 4027#undef VMULOUB 4028#undef VMULOUH 4029#undef VMULOUW 4030#undef VMSUMUHM 4031