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 "../tcg-pool.c.inc" 26 27#ifdef CONFIG_DEBUG_TCG 28static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { 29#if TCG_TARGET_REG_BITS == 64 30 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi", 31#else 32 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi", 33#endif 34 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", 35 "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", 36#if TCG_TARGET_REG_BITS == 64 37 "%xmm8", "%xmm9", "%xmm10", "%xmm11", 38 "%xmm12", "%xmm13", "%xmm14", "%xmm15", 39#endif 40}; 41#endif 42 43static const int tcg_target_reg_alloc_order[] = { 44#if TCG_TARGET_REG_BITS == 64 45 TCG_REG_RBP, 46 TCG_REG_RBX, 47 TCG_REG_R12, 48 TCG_REG_R13, 49 TCG_REG_R14, 50 TCG_REG_R15, 51 TCG_REG_R10, 52 TCG_REG_R11, 53 TCG_REG_R9, 54 TCG_REG_R8, 55 TCG_REG_RCX, 56 TCG_REG_RDX, 57 TCG_REG_RSI, 58 TCG_REG_RDI, 59 TCG_REG_RAX, 60#else 61 TCG_REG_EBX, 62 TCG_REG_ESI, 63 TCG_REG_EDI, 64 TCG_REG_EBP, 65 TCG_REG_ECX, 66 TCG_REG_EDX, 67 TCG_REG_EAX, 68#endif 69 TCG_REG_XMM0, 70 TCG_REG_XMM1, 71 TCG_REG_XMM2, 72 TCG_REG_XMM3, 73 TCG_REG_XMM4, 74 TCG_REG_XMM5, 75#ifndef _WIN64 76 /* The Win64 ABI has xmm6-xmm15 as caller-saves, and we do not save 77 any of them. Therefore only allow xmm0-xmm5 to be allocated. */ 78 TCG_REG_XMM6, 79 TCG_REG_XMM7, 80#if TCG_TARGET_REG_BITS == 64 81 TCG_REG_XMM8, 82 TCG_REG_XMM9, 83 TCG_REG_XMM10, 84 TCG_REG_XMM11, 85 TCG_REG_XMM12, 86 TCG_REG_XMM13, 87 TCG_REG_XMM14, 88 TCG_REG_XMM15, 89#endif 90#endif 91}; 92 93static const int tcg_target_call_iarg_regs[] = { 94#if TCG_TARGET_REG_BITS == 64 95#if defined(_WIN64) 96 TCG_REG_RCX, 97 TCG_REG_RDX, 98#else 99 TCG_REG_RDI, 100 TCG_REG_RSI, 101 TCG_REG_RDX, 102 TCG_REG_RCX, 103#endif 104 TCG_REG_R8, 105 TCG_REG_R9, 106#else 107 /* 32 bit mode uses stack based calling convention (GCC default). */ 108#endif 109}; 110 111static const int tcg_target_call_oarg_regs[] = { 112 TCG_REG_EAX, 113#if TCG_TARGET_REG_BITS == 32 114 TCG_REG_EDX 115#endif 116}; 117 118/* Constants we accept. */ 119#define TCG_CT_CONST_S32 0x100 120#define TCG_CT_CONST_U32 0x200 121#define TCG_CT_CONST_I32 0x400 122#define TCG_CT_CONST_WSZ 0x800 123 124/* Registers used with L constraint, which are the first argument 125 registers on x86_64, and two random call clobbered registers on 126 i386. */ 127#if TCG_TARGET_REG_BITS == 64 128# define TCG_REG_L0 tcg_target_call_iarg_regs[0] 129# define TCG_REG_L1 tcg_target_call_iarg_regs[1] 130#else 131# define TCG_REG_L0 TCG_REG_EAX 132# define TCG_REG_L1 TCG_REG_EDX 133#endif 134 135/* The host compiler should supply <cpuid.h> to enable runtime features 136 detection, as we're not going to go so far as our own inline assembly. 137 If not available, default values will be assumed. */ 138#if defined(CONFIG_CPUID_H) 139#include "qemu/cpuid.h" 140#endif 141 142/* For 64-bit, we always know that CMOV is available. */ 143#if TCG_TARGET_REG_BITS == 64 144# define have_cmov 1 145#elif defined(CONFIG_CPUID_H) 146static bool have_cmov; 147#else 148# define have_cmov 0 149#endif 150 151/* We need these symbols in tcg-target.h, and we can't properly conditionalize 152 it there. Therefore we always define the variable. */ 153bool have_bmi1; 154bool have_popcnt; 155bool have_avx1; 156bool have_avx2; 157bool have_movbe; 158 159#ifdef CONFIG_CPUID_H 160static bool have_bmi2; 161static bool have_lzcnt; 162#else 163# define have_bmi2 0 164# define have_lzcnt 0 165#endif 166 167static const tcg_insn_unit *tb_ret_addr; 168 169static bool patch_reloc(tcg_insn_unit *code_ptr, int type, 170 intptr_t value, intptr_t addend) 171{ 172 value += addend; 173 switch(type) { 174 case R_386_PC32: 175 value -= (uintptr_t)tcg_splitwx_to_rx(code_ptr); 176 if (value != (int32_t)value) { 177 return false; 178 } 179 /* FALLTHRU */ 180 case R_386_32: 181 tcg_patch32(code_ptr, value); 182 break; 183 case R_386_PC8: 184 value -= (uintptr_t)tcg_splitwx_to_rx(code_ptr); 185 if (value != (int8_t)value) { 186 return false; 187 } 188 tcg_patch8(code_ptr, value); 189 break; 190 default: 191 tcg_abort(); 192 } 193 return true; 194} 195 196#if TCG_TARGET_REG_BITS == 64 197#define ALL_GENERAL_REGS 0x0000ffffu 198#define ALL_VECTOR_REGS 0xffff0000u 199#else 200#define ALL_GENERAL_REGS 0x000000ffu 201#define ALL_VECTOR_REGS 0x00ff0000u 202#endif 203 204/* parse target specific constraints */ 205static const char *target_parse_constraint(TCGArgConstraint *ct, 206 const char *ct_str, TCGType type) 207{ 208 switch(*ct_str++) { 209 case 'a': 210 tcg_regset_set_reg(ct->regs, TCG_REG_EAX); 211 break; 212 case 'b': 213 tcg_regset_set_reg(ct->regs, TCG_REG_EBX); 214 break; 215 case 'c': 216 tcg_regset_set_reg(ct->regs, TCG_REG_ECX); 217 break; 218 case 'd': 219 tcg_regset_set_reg(ct->regs, TCG_REG_EDX); 220 break; 221 case 'S': 222 tcg_regset_set_reg(ct->regs, TCG_REG_ESI); 223 break; 224 case 'D': 225 tcg_regset_set_reg(ct->regs, TCG_REG_EDI); 226 break; 227 case 'q': 228 /* A register that can be used as a byte operand. */ 229 ct->regs = TCG_TARGET_REG_BITS == 64 ? 0xffff : 0xf; 230 break; 231 case 'Q': 232 /* A register with an addressable second byte (e.g. %ah). */ 233 ct->regs = 0xf; 234 break; 235 case 'r': 236 /* A general register. */ 237 ct->regs |= ALL_GENERAL_REGS; 238 break; 239 case 'W': 240 /* With TZCNT/LZCNT, we can have operand-size as an input. */ 241 ct->ct |= TCG_CT_CONST_WSZ; 242 break; 243 case 'x': 244 /* A vector register. */ 245 ct->regs |= ALL_VECTOR_REGS; 246 break; 247 248 case 'L': 249 /* qemu_ld/st data+address constraint */ 250 ct->regs = TCG_TARGET_REG_BITS == 64 ? 0xffff : 0xff; 251#ifdef CONFIG_SOFTMMU 252 tcg_regset_reset_reg(ct->regs, TCG_REG_L0); 253 tcg_regset_reset_reg(ct->regs, TCG_REG_L1); 254#endif 255 break; 256 case 's': 257 /* qemu_st8_i32 data constraint */ 258 ct->regs = 0xf; 259#ifdef CONFIG_SOFTMMU 260 tcg_regset_reset_reg(ct->regs, TCG_REG_L0); 261 tcg_regset_reset_reg(ct->regs, TCG_REG_L1); 262#endif 263 break; 264 265 case 'e': 266 ct->ct |= (type == TCG_TYPE_I32 ? TCG_CT_CONST : TCG_CT_CONST_S32); 267 break; 268 case 'Z': 269 ct->ct |= (type == TCG_TYPE_I32 ? TCG_CT_CONST : TCG_CT_CONST_U32); 270 break; 271 case 'I': 272 ct->ct |= (type == TCG_TYPE_I32 ? TCG_CT_CONST : TCG_CT_CONST_I32); 273 break; 274 275 default: 276 return NULL; 277 } 278 return ct_str; 279} 280 281/* test if a constant matches the constraint */ 282static inline int tcg_target_const_match(tcg_target_long val, TCGType type, 283 const TCGArgConstraint *arg_ct) 284{ 285 int ct = arg_ct->ct; 286 if (ct & TCG_CT_CONST) { 287 return 1; 288 } 289 if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) { 290 return 1; 291 } 292 if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val) { 293 return 1; 294 } 295 if ((ct & TCG_CT_CONST_I32) && ~val == (int32_t)~val) { 296 return 1; 297 } 298 if ((ct & TCG_CT_CONST_WSZ) && val == (type == TCG_TYPE_I32 ? 32 : 64)) { 299 return 1; 300 } 301 return 0; 302} 303 304# define LOWREGMASK(x) ((x) & 7) 305 306#define P_EXT 0x100 /* 0x0f opcode prefix */ 307#define P_EXT38 0x200 /* 0x0f 0x38 opcode prefix */ 308#define P_DATA16 0x400 /* 0x66 opcode prefix */ 309#if TCG_TARGET_REG_BITS == 64 310# define P_REXW 0x1000 /* Set REX.W = 1 */ 311# define P_REXB_R 0x2000 /* REG field as byte register */ 312# define P_REXB_RM 0x4000 /* R/M field as byte register */ 313# define P_GS 0x8000 /* gs segment override */ 314#else 315# define P_REXW 0 316# define P_REXB_R 0 317# define P_REXB_RM 0 318# define P_GS 0 319#endif 320#define P_EXT3A 0x10000 /* 0x0f 0x3a opcode prefix */ 321#define P_SIMDF3 0x20000 /* 0xf3 opcode prefix */ 322#define P_SIMDF2 0x40000 /* 0xf2 opcode prefix */ 323#define P_VEXL 0x80000 /* Set VEX.L = 1 */ 324 325#define OPC_ARITH_EvIz (0x81) 326#define OPC_ARITH_EvIb (0x83) 327#define OPC_ARITH_GvEv (0x03) /* ... plus (ARITH_FOO << 3) */ 328#define OPC_ANDN (0xf2 | P_EXT38) 329#define OPC_ADD_GvEv (OPC_ARITH_GvEv | (ARITH_ADD << 3)) 330#define OPC_AND_GvEv (OPC_ARITH_GvEv | (ARITH_AND << 3)) 331#define OPC_BLENDPS (0x0c | P_EXT3A | P_DATA16) 332#define OPC_BSF (0xbc | P_EXT) 333#define OPC_BSR (0xbd | P_EXT) 334#define OPC_BSWAP (0xc8 | P_EXT) 335#define OPC_CALL_Jz (0xe8) 336#define OPC_CMOVCC (0x40 | P_EXT) /* ... plus condition code */ 337#define OPC_CMP_GvEv (OPC_ARITH_GvEv | (ARITH_CMP << 3)) 338#define OPC_DEC_r32 (0x48) 339#define OPC_IMUL_GvEv (0xaf | P_EXT) 340#define OPC_IMUL_GvEvIb (0x6b) 341#define OPC_IMUL_GvEvIz (0x69) 342#define OPC_INC_r32 (0x40) 343#define OPC_JCC_long (0x80 | P_EXT) /* ... plus condition code */ 344#define OPC_JCC_short (0x70) /* ... plus condition code */ 345#define OPC_JMP_long (0xe9) 346#define OPC_JMP_short (0xeb) 347#define OPC_LEA (0x8d) 348#define OPC_LZCNT (0xbd | P_EXT | P_SIMDF3) 349#define OPC_MOVB_EvGv (0x88) /* stores, more or less */ 350#define OPC_MOVL_EvGv (0x89) /* stores, more or less */ 351#define OPC_MOVL_GvEv (0x8b) /* loads, more or less */ 352#define OPC_MOVB_EvIz (0xc6) 353#define OPC_MOVL_EvIz (0xc7) 354#define OPC_MOVL_Iv (0xb8) 355#define OPC_MOVBE_GyMy (0xf0 | P_EXT38) 356#define OPC_MOVBE_MyGy (0xf1 | P_EXT38) 357#define OPC_MOVD_VyEy (0x6e | P_EXT | P_DATA16) 358#define OPC_MOVD_EyVy (0x7e | P_EXT | P_DATA16) 359#define OPC_MOVDDUP (0x12 | P_EXT | P_SIMDF2) 360#define OPC_MOVDQA_VxWx (0x6f | P_EXT | P_DATA16) 361#define OPC_MOVDQA_WxVx (0x7f | P_EXT | P_DATA16) 362#define OPC_MOVDQU_VxWx (0x6f | P_EXT | P_SIMDF3) 363#define OPC_MOVDQU_WxVx (0x7f | P_EXT | P_SIMDF3) 364#define OPC_MOVQ_VqWq (0x7e | P_EXT | P_SIMDF3) 365#define OPC_MOVQ_WqVq (0xd6 | P_EXT | P_DATA16) 366#define OPC_MOVSBL (0xbe | P_EXT) 367#define OPC_MOVSWL (0xbf | P_EXT) 368#define OPC_MOVSLQ (0x63 | P_REXW) 369#define OPC_MOVZBL (0xb6 | P_EXT) 370#define OPC_MOVZWL (0xb7 | P_EXT) 371#define OPC_PABSB (0x1c | P_EXT38 | P_DATA16) 372#define OPC_PABSW (0x1d | P_EXT38 | P_DATA16) 373#define OPC_PABSD (0x1e | P_EXT38 | P_DATA16) 374#define OPC_PACKSSDW (0x6b | P_EXT | P_DATA16) 375#define OPC_PACKSSWB (0x63 | P_EXT | P_DATA16) 376#define OPC_PACKUSDW (0x2b | P_EXT38 | P_DATA16) 377#define OPC_PACKUSWB (0x67 | P_EXT | P_DATA16) 378#define OPC_PADDB (0xfc | P_EXT | P_DATA16) 379#define OPC_PADDW (0xfd | P_EXT | P_DATA16) 380#define OPC_PADDD (0xfe | P_EXT | P_DATA16) 381#define OPC_PADDQ (0xd4 | P_EXT | P_DATA16) 382#define OPC_PADDSB (0xec | P_EXT | P_DATA16) 383#define OPC_PADDSW (0xed | P_EXT | P_DATA16) 384#define OPC_PADDUB (0xdc | P_EXT | P_DATA16) 385#define OPC_PADDUW (0xdd | P_EXT | P_DATA16) 386#define OPC_PAND (0xdb | P_EXT | P_DATA16) 387#define OPC_PANDN (0xdf | P_EXT | P_DATA16) 388#define OPC_PBLENDW (0x0e | P_EXT3A | P_DATA16) 389#define OPC_PCMPEQB (0x74 | P_EXT | P_DATA16) 390#define OPC_PCMPEQW (0x75 | P_EXT | P_DATA16) 391#define OPC_PCMPEQD (0x76 | P_EXT | P_DATA16) 392#define OPC_PCMPEQQ (0x29 | P_EXT38 | P_DATA16) 393#define OPC_PCMPGTB (0x64 | P_EXT | P_DATA16) 394#define OPC_PCMPGTW (0x65 | P_EXT | P_DATA16) 395#define OPC_PCMPGTD (0x66 | P_EXT | P_DATA16) 396#define OPC_PCMPGTQ (0x37 | P_EXT38 | P_DATA16) 397#define OPC_PMAXSB (0x3c | P_EXT38 | P_DATA16) 398#define OPC_PMAXSW (0xee | P_EXT | P_DATA16) 399#define OPC_PMAXSD (0x3d | P_EXT38 | P_DATA16) 400#define OPC_PMAXUB (0xde | P_EXT | P_DATA16) 401#define OPC_PMAXUW (0x3e | P_EXT38 | P_DATA16) 402#define OPC_PMAXUD (0x3f | P_EXT38 | P_DATA16) 403#define OPC_PMINSB (0x38 | P_EXT38 | P_DATA16) 404#define OPC_PMINSW (0xea | P_EXT | P_DATA16) 405#define OPC_PMINSD (0x39 | P_EXT38 | P_DATA16) 406#define OPC_PMINUB (0xda | P_EXT | P_DATA16) 407#define OPC_PMINUW (0x3a | P_EXT38 | P_DATA16) 408#define OPC_PMINUD (0x3b | P_EXT38 | P_DATA16) 409#define OPC_PMOVSXBW (0x20 | P_EXT38 | P_DATA16) 410#define OPC_PMOVSXWD (0x23 | P_EXT38 | P_DATA16) 411#define OPC_PMOVSXDQ (0x25 | P_EXT38 | P_DATA16) 412#define OPC_PMOVZXBW (0x30 | P_EXT38 | P_DATA16) 413#define OPC_PMOVZXWD (0x33 | P_EXT38 | P_DATA16) 414#define OPC_PMOVZXDQ (0x35 | P_EXT38 | P_DATA16) 415#define OPC_PMULLW (0xd5 | P_EXT | P_DATA16) 416#define OPC_PMULLD (0x40 | P_EXT38 | P_DATA16) 417#define OPC_POR (0xeb | P_EXT | P_DATA16) 418#define OPC_PSHUFB (0x00 | P_EXT38 | P_DATA16) 419#define OPC_PSHUFD (0x70 | P_EXT | P_DATA16) 420#define OPC_PSHUFLW (0x70 | P_EXT | P_SIMDF2) 421#define OPC_PSHUFHW (0x70 | P_EXT | P_SIMDF3) 422#define OPC_PSHIFTW_Ib (0x71 | P_EXT | P_DATA16) /* /2 /6 /4 */ 423#define OPC_PSHIFTD_Ib (0x72 | P_EXT | P_DATA16) /* /2 /6 /4 */ 424#define OPC_PSHIFTQ_Ib (0x73 | P_EXT | P_DATA16) /* /2 /6 /4 */ 425#define OPC_PSLLW (0xf1 | P_EXT | P_DATA16) 426#define OPC_PSLLD (0xf2 | P_EXT | P_DATA16) 427#define OPC_PSLLQ (0xf3 | P_EXT | P_DATA16) 428#define OPC_PSRAW (0xe1 | P_EXT | P_DATA16) 429#define OPC_PSRAD (0xe2 | P_EXT | P_DATA16) 430#define OPC_PSRLW (0xd1 | P_EXT | P_DATA16) 431#define OPC_PSRLD (0xd2 | P_EXT | P_DATA16) 432#define OPC_PSRLQ (0xd3 | P_EXT | P_DATA16) 433#define OPC_PSUBB (0xf8 | P_EXT | P_DATA16) 434#define OPC_PSUBW (0xf9 | P_EXT | P_DATA16) 435#define OPC_PSUBD (0xfa | P_EXT | P_DATA16) 436#define OPC_PSUBQ (0xfb | P_EXT | P_DATA16) 437#define OPC_PSUBSB (0xe8 | P_EXT | P_DATA16) 438#define OPC_PSUBSW (0xe9 | P_EXT | P_DATA16) 439#define OPC_PSUBUB (0xd8 | P_EXT | P_DATA16) 440#define OPC_PSUBUW (0xd9 | P_EXT | P_DATA16) 441#define OPC_PUNPCKLBW (0x60 | P_EXT | P_DATA16) 442#define OPC_PUNPCKLWD (0x61 | P_EXT | P_DATA16) 443#define OPC_PUNPCKLDQ (0x62 | P_EXT | P_DATA16) 444#define OPC_PUNPCKLQDQ (0x6c | P_EXT | P_DATA16) 445#define OPC_PUNPCKHBW (0x68 | P_EXT | P_DATA16) 446#define OPC_PUNPCKHWD (0x69 | P_EXT | P_DATA16) 447#define OPC_PUNPCKHDQ (0x6a | P_EXT | P_DATA16) 448#define OPC_PUNPCKHQDQ (0x6d | P_EXT | P_DATA16) 449#define OPC_PXOR (0xef | P_EXT | P_DATA16) 450#define OPC_POP_r32 (0x58) 451#define OPC_POPCNT (0xb8 | P_EXT | P_SIMDF3) 452#define OPC_PUSH_r32 (0x50) 453#define OPC_PUSH_Iv (0x68) 454#define OPC_PUSH_Ib (0x6a) 455#define OPC_RET (0xc3) 456#define OPC_SETCC (0x90 | P_EXT | P_REXB_RM) /* ... plus cc */ 457#define OPC_SHIFT_1 (0xd1) 458#define OPC_SHIFT_Ib (0xc1) 459#define OPC_SHIFT_cl (0xd3) 460#define OPC_SARX (0xf7 | P_EXT38 | P_SIMDF3) 461#define OPC_SHUFPS (0xc6 | P_EXT) 462#define OPC_SHLX (0xf7 | P_EXT38 | P_DATA16) 463#define OPC_SHRX (0xf7 | P_EXT38 | P_SIMDF2) 464#define OPC_SHRD_Ib (0xac | P_EXT) 465#define OPC_TESTL (0x85) 466#define OPC_TZCNT (0xbc | P_EXT | P_SIMDF3) 467#define OPC_UD2 (0x0b | P_EXT) 468#define OPC_VPBLENDD (0x02 | P_EXT3A | P_DATA16) 469#define OPC_VPBLENDVB (0x4c | P_EXT3A | P_DATA16) 470#define OPC_VPINSRB (0x20 | P_EXT3A | P_DATA16) 471#define OPC_VPINSRW (0xc4 | P_EXT | P_DATA16) 472#define OPC_VBROADCASTSS (0x18 | P_EXT38 | P_DATA16) 473#define OPC_VBROADCASTSD (0x19 | P_EXT38 | P_DATA16) 474#define OPC_VPBROADCASTB (0x78 | P_EXT38 | P_DATA16) 475#define OPC_VPBROADCASTW (0x79 | P_EXT38 | P_DATA16) 476#define OPC_VPBROADCASTD (0x58 | P_EXT38 | P_DATA16) 477#define OPC_VPBROADCASTQ (0x59 | P_EXT38 | P_DATA16) 478#define OPC_VPERMQ (0x00 | P_EXT3A | P_DATA16 | P_REXW) 479#define OPC_VPERM2I128 (0x46 | P_EXT3A | P_DATA16 | P_VEXL) 480#define OPC_VPSLLVD (0x47 | P_EXT38 | P_DATA16) 481#define OPC_VPSLLVQ (0x47 | P_EXT38 | P_DATA16 | P_REXW) 482#define OPC_VPSRAVD (0x46 | P_EXT38 | P_DATA16) 483#define OPC_VPSRLVD (0x45 | P_EXT38 | P_DATA16) 484#define OPC_VPSRLVQ (0x45 | P_EXT38 | P_DATA16 | P_REXW) 485#define OPC_VZEROUPPER (0x77 | P_EXT) 486#define OPC_XCHG_ax_r32 (0x90) 487 488#define OPC_GRP3_Ev (0xf7) 489#define OPC_GRP5 (0xff) 490#define OPC_GRP14 (0x73 | P_EXT | P_DATA16) 491 492/* Group 1 opcode extensions for 0x80-0x83. 493 These are also used as modifiers for OPC_ARITH. */ 494#define ARITH_ADD 0 495#define ARITH_OR 1 496#define ARITH_ADC 2 497#define ARITH_SBB 3 498#define ARITH_AND 4 499#define ARITH_SUB 5 500#define ARITH_XOR 6 501#define ARITH_CMP 7 502 503/* Group 2 opcode extensions for 0xc0, 0xc1, 0xd0-0xd3. */ 504#define SHIFT_ROL 0 505#define SHIFT_ROR 1 506#define SHIFT_SHL 4 507#define SHIFT_SHR 5 508#define SHIFT_SAR 7 509 510/* Group 3 opcode extensions for 0xf6, 0xf7. To be used with OPC_GRP3. */ 511#define EXT3_NOT 2 512#define EXT3_NEG 3 513#define EXT3_MUL 4 514#define EXT3_IMUL 5 515#define EXT3_DIV 6 516#define EXT3_IDIV 7 517 518/* Group 5 opcode extensions for 0xff. To be used with OPC_GRP5. */ 519#define EXT5_INC_Ev 0 520#define EXT5_DEC_Ev 1 521#define EXT5_CALLN_Ev 2 522#define EXT5_JMPN_Ev 4 523 524/* Condition codes to be added to OPC_JCC_{long,short}. */ 525#define JCC_JMP (-1) 526#define JCC_JO 0x0 527#define JCC_JNO 0x1 528#define JCC_JB 0x2 529#define JCC_JAE 0x3 530#define JCC_JE 0x4 531#define JCC_JNE 0x5 532#define JCC_JBE 0x6 533#define JCC_JA 0x7 534#define JCC_JS 0x8 535#define JCC_JNS 0x9 536#define JCC_JP 0xa 537#define JCC_JNP 0xb 538#define JCC_JL 0xc 539#define JCC_JGE 0xd 540#define JCC_JLE 0xe 541#define JCC_JG 0xf 542 543static const uint8_t tcg_cond_to_jcc[] = { 544 [TCG_COND_EQ] = JCC_JE, 545 [TCG_COND_NE] = JCC_JNE, 546 [TCG_COND_LT] = JCC_JL, 547 [TCG_COND_GE] = JCC_JGE, 548 [TCG_COND_LE] = JCC_JLE, 549 [TCG_COND_GT] = JCC_JG, 550 [TCG_COND_LTU] = JCC_JB, 551 [TCG_COND_GEU] = JCC_JAE, 552 [TCG_COND_LEU] = JCC_JBE, 553 [TCG_COND_GTU] = JCC_JA, 554}; 555 556#if TCG_TARGET_REG_BITS == 64 557static void tcg_out_opc(TCGContext *s, int opc, int r, int rm, int x) 558{ 559 int rex; 560 561 if (opc & P_GS) { 562 tcg_out8(s, 0x65); 563 } 564 if (opc & P_DATA16) { 565 /* We should never be asking for both 16 and 64-bit operation. */ 566 tcg_debug_assert((opc & P_REXW) == 0); 567 tcg_out8(s, 0x66); 568 } 569 if (opc & P_SIMDF3) { 570 tcg_out8(s, 0xf3); 571 } else if (opc & P_SIMDF2) { 572 tcg_out8(s, 0xf2); 573 } 574 575 rex = 0; 576 rex |= (opc & P_REXW) ? 0x8 : 0x0; /* REX.W */ 577 rex |= (r & 8) >> 1; /* REX.R */ 578 rex |= (x & 8) >> 2; /* REX.X */ 579 rex |= (rm & 8) >> 3; /* REX.B */ 580 581 /* P_REXB_{R,RM} indicates that the given register is the low byte. 582 For %[abcd]l we need no REX prefix, but for %{si,di,bp,sp}l we do, 583 as otherwise the encoding indicates %[abcd]h. Note that the values 584 that are ORed in merely indicate that the REX byte must be present; 585 those bits get discarded in output. */ 586 rex |= opc & (r >= 4 ? P_REXB_R : 0); 587 rex |= opc & (rm >= 4 ? P_REXB_RM : 0); 588 589 if (rex) { 590 tcg_out8(s, (uint8_t)(rex | 0x40)); 591 } 592 593 if (opc & (P_EXT | P_EXT38 | P_EXT3A)) { 594 tcg_out8(s, 0x0f); 595 if (opc & P_EXT38) { 596 tcg_out8(s, 0x38); 597 } else if (opc & P_EXT3A) { 598 tcg_out8(s, 0x3a); 599 } 600 } 601 602 tcg_out8(s, opc); 603} 604#else 605static void tcg_out_opc(TCGContext *s, int opc) 606{ 607 if (opc & P_DATA16) { 608 tcg_out8(s, 0x66); 609 } 610 if (opc & P_SIMDF3) { 611 tcg_out8(s, 0xf3); 612 } else if (opc & P_SIMDF2) { 613 tcg_out8(s, 0xf2); 614 } 615 if (opc & (P_EXT | P_EXT38 | P_EXT3A)) { 616 tcg_out8(s, 0x0f); 617 if (opc & P_EXT38) { 618 tcg_out8(s, 0x38); 619 } else if (opc & P_EXT3A) { 620 tcg_out8(s, 0x3a); 621 } 622 } 623 tcg_out8(s, opc); 624} 625/* Discard the register arguments to tcg_out_opc early, so as not to penalize 626 the 32-bit compilation paths. This method works with all versions of gcc, 627 whereas relying on optimization may not be able to exclude them. */ 628#define tcg_out_opc(s, opc, r, rm, x) (tcg_out_opc)(s, opc) 629#endif 630 631static void tcg_out_modrm(TCGContext *s, int opc, int r, int rm) 632{ 633 tcg_out_opc(s, opc, r, rm, 0); 634 tcg_out8(s, 0xc0 | (LOWREGMASK(r) << 3) | LOWREGMASK(rm)); 635} 636 637static void tcg_out_vex_opc(TCGContext *s, int opc, int r, int v, 638 int rm, int index) 639{ 640 int tmp; 641 642 /* Use the two byte form if possible, which cannot encode 643 VEX.W, VEX.B, VEX.X, or an m-mmmm field other than P_EXT. */ 644 if ((opc & (P_EXT | P_EXT38 | P_EXT3A | P_REXW)) == P_EXT 645 && ((rm | index) & 8) == 0) { 646 /* Two byte VEX prefix. */ 647 tcg_out8(s, 0xc5); 648 649 tmp = (r & 8 ? 0 : 0x80); /* VEX.R */ 650 } else { 651 /* Three byte VEX prefix. */ 652 tcg_out8(s, 0xc4); 653 654 /* VEX.m-mmmm */ 655 if (opc & P_EXT3A) { 656 tmp = 3; 657 } else if (opc & P_EXT38) { 658 tmp = 2; 659 } else if (opc & P_EXT) { 660 tmp = 1; 661 } else { 662 g_assert_not_reached(); 663 } 664 tmp |= (r & 8 ? 0 : 0x80); /* VEX.R */ 665 tmp |= (index & 8 ? 0 : 0x40); /* VEX.X */ 666 tmp |= (rm & 8 ? 0 : 0x20); /* VEX.B */ 667 tcg_out8(s, tmp); 668 669 tmp = (opc & P_REXW ? 0x80 : 0); /* VEX.W */ 670 } 671 672 tmp |= (opc & P_VEXL ? 0x04 : 0); /* VEX.L */ 673 /* VEX.pp */ 674 if (opc & P_DATA16) { 675 tmp |= 1; /* 0x66 */ 676 } else if (opc & P_SIMDF3) { 677 tmp |= 2; /* 0xf3 */ 678 } else if (opc & P_SIMDF2) { 679 tmp |= 3; /* 0xf2 */ 680 } 681 tmp |= (~v & 15) << 3; /* VEX.vvvv */ 682 tcg_out8(s, tmp); 683 tcg_out8(s, opc); 684} 685 686static void tcg_out_vex_modrm(TCGContext *s, int opc, int r, int v, int rm) 687{ 688 tcg_out_vex_opc(s, opc, r, v, rm, 0); 689 tcg_out8(s, 0xc0 | (LOWREGMASK(r) << 3) | LOWREGMASK(rm)); 690} 691 692/* Output an opcode with a full "rm + (index<<shift) + offset" address mode. 693 We handle either RM and INDEX missing with a negative value. In 64-bit 694 mode for absolute addresses, ~RM is the size of the immediate operand 695 that will follow the instruction. */ 696 697static void tcg_out_sib_offset(TCGContext *s, int r, int rm, int index, 698 int shift, intptr_t offset) 699{ 700 int mod, len; 701 702 if (index < 0 && rm < 0) { 703 if (TCG_TARGET_REG_BITS == 64) { 704 /* Try for a rip-relative addressing mode. This has replaced 705 the 32-bit-mode absolute addressing encoding. */ 706 intptr_t pc = (intptr_t)s->code_ptr + 5 + ~rm; 707 intptr_t disp = offset - pc; 708 if (disp == (int32_t)disp) { 709 tcg_out8(s, (LOWREGMASK(r) << 3) | 5); 710 tcg_out32(s, disp); 711 return; 712 } 713 714 /* Try for an absolute address encoding. This requires the 715 use of the MODRM+SIB encoding and is therefore larger than 716 rip-relative addressing. */ 717 if (offset == (int32_t)offset) { 718 tcg_out8(s, (LOWREGMASK(r) << 3) | 4); 719 tcg_out8(s, (4 << 3) | 5); 720 tcg_out32(s, offset); 721 return; 722 } 723 724 /* ??? The memory isn't directly addressable. */ 725 g_assert_not_reached(); 726 } else { 727 /* Absolute address. */ 728 tcg_out8(s, (r << 3) | 5); 729 tcg_out32(s, offset); 730 return; 731 } 732 } 733 734 /* Find the length of the immediate addend. Note that the encoding 735 that would be used for (%ebp) indicates absolute addressing. */ 736 if (rm < 0) { 737 mod = 0, len = 4, rm = 5; 738 } else if (offset == 0 && LOWREGMASK(rm) != TCG_REG_EBP) { 739 mod = 0, len = 0; 740 } else if (offset == (int8_t)offset) { 741 mod = 0x40, len = 1; 742 } else { 743 mod = 0x80, len = 4; 744 } 745 746 /* Use a single byte MODRM format if possible. Note that the encoding 747 that would be used for %esp is the escape to the two byte form. */ 748 if (index < 0 && LOWREGMASK(rm) != TCG_REG_ESP) { 749 /* Single byte MODRM format. */ 750 tcg_out8(s, mod | (LOWREGMASK(r) << 3) | LOWREGMASK(rm)); 751 } else { 752 /* Two byte MODRM+SIB format. */ 753 754 /* Note that the encoding that would place %esp into the index 755 field indicates no index register. In 64-bit mode, the REX.X 756 bit counts, so %r12 can be used as the index. */ 757 if (index < 0) { 758 index = 4; 759 } else { 760 tcg_debug_assert(index != TCG_REG_ESP); 761 } 762 763 tcg_out8(s, mod | (LOWREGMASK(r) << 3) | 4); 764 tcg_out8(s, (shift << 6) | (LOWREGMASK(index) << 3) | LOWREGMASK(rm)); 765 } 766 767 if (len == 1) { 768 tcg_out8(s, offset); 769 } else if (len == 4) { 770 tcg_out32(s, offset); 771 } 772} 773 774static void tcg_out_modrm_sib_offset(TCGContext *s, int opc, int r, int rm, 775 int index, int shift, intptr_t offset) 776{ 777 tcg_out_opc(s, opc, r, rm < 0 ? 0 : rm, index < 0 ? 0 : index); 778 tcg_out_sib_offset(s, r, rm, index, shift, offset); 779} 780 781static void tcg_out_vex_modrm_sib_offset(TCGContext *s, int opc, int r, int v, 782 int rm, int index, int shift, 783 intptr_t offset) 784{ 785 tcg_out_vex_opc(s, opc, r, v, rm < 0 ? 0 : rm, index < 0 ? 0 : index); 786 tcg_out_sib_offset(s, r, rm, index, shift, offset); 787} 788 789/* A simplification of the above with no index or shift. */ 790static inline void tcg_out_modrm_offset(TCGContext *s, int opc, int r, 791 int rm, intptr_t offset) 792{ 793 tcg_out_modrm_sib_offset(s, opc, r, rm, -1, 0, offset); 794} 795 796static inline void tcg_out_vex_modrm_offset(TCGContext *s, int opc, int r, 797 int v, int rm, intptr_t offset) 798{ 799 tcg_out_vex_modrm_sib_offset(s, opc, r, v, rm, -1, 0, offset); 800} 801 802/* Output an opcode with an expected reference to the constant pool. */ 803static inline void tcg_out_modrm_pool(TCGContext *s, int opc, int r) 804{ 805 tcg_out_opc(s, opc, r, 0, 0); 806 /* Absolute for 32-bit, pc-relative for 64-bit. */ 807 tcg_out8(s, LOWREGMASK(r) << 3 | 5); 808 tcg_out32(s, 0); 809} 810 811/* Output an opcode with an expected reference to the constant pool. */ 812static inline void tcg_out_vex_modrm_pool(TCGContext *s, int opc, int r) 813{ 814 tcg_out_vex_opc(s, opc, r, 0, 0, 0); 815 /* Absolute for 32-bit, pc-relative for 64-bit. */ 816 tcg_out8(s, LOWREGMASK(r) << 3 | 5); 817 tcg_out32(s, 0); 818} 819 820/* Generate dest op= src. Uses the same ARITH_* codes as tgen_arithi. */ 821static inline void tgen_arithr(TCGContext *s, int subop, int dest, int src) 822{ 823 /* Propagate an opcode prefix, such as P_REXW. */ 824 int ext = subop & ~0x7; 825 subop &= 0x7; 826 827 tcg_out_modrm(s, OPC_ARITH_GvEv + (subop << 3) + ext, dest, src); 828} 829 830static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg) 831{ 832 int rexw = 0; 833 834 if (arg == ret) { 835 return true; 836 } 837 switch (type) { 838 case TCG_TYPE_I64: 839 rexw = P_REXW; 840 /* fallthru */ 841 case TCG_TYPE_I32: 842 if (ret < 16) { 843 if (arg < 16) { 844 tcg_out_modrm(s, OPC_MOVL_GvEv + rexw, ret, arg); 845 } else { 846 tcg_out_vex_modrm(s, OPC_MOVD_EyVy + rexw, arg, 0, ret); 847 } 848 } else { 849 if (arg < 16) { 850 tcg_out_vex_modrm(s, OPC_MOVD_VyEy + rexw, ret, 0, arg); 851 } else { 852 tcg_out_vex_modrm(s, OPC_MOVQ_VqWq, ret, 0, arg); 853 } 854 } 855 break; 856 857 case TCG_TYPE_V64: 858 tcg_debug_assert(ret >= 16 && arg >= 16); 859 tcg_out_vex_modrm(s, OPC_MOVQ_VqWq, ret, 0, arg); 860 break; 861 case TCG_TYPE_V128: 862 tcg_debug_assert(ret >= 16 && arg >= 16); 863 tcg_out_vex_modrm(s, OPC_MOVDQA_VxWx, ret, 0, arg); 864 break; 865 case TCG_TYPE_V256: 866 tcg_debug_assert(ret >= 16 && arg >= 16); 867 tcg_out_vex_modrm(s, OPC_MOVDQA_VxWx | P_VEXL, ret, 0, arg); 868 break; 869 870 default: 871 g_assert_not_reached(); 872 } 873 return true; 874} 875 876static const int avx2_dup_insn[4] = { 877 OPC_VPBROADCASTB, OPC_VPBROADCASTW, 878 OPC_VPBROADCASTD, OPC_VPBROADCASTQ, 879}; 880 881static bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece, 882 TCGReg r, TCGReg a) 883{ 884 if (have_avx2) { 885 int vex_l = (type == TCG_TYPE_V256 ? P_VEXL : 0); 886 tcg_out_vex_modrm(s, avx2_dup_insn[vece] + vex_l, r, 0, a); 887 } else { 888 switch (vece) { 889 case MO_8: 890 /* ??? With zero in a register, use PSHUFB. */ 891 tcg_out_vex_modrm(s, OPC_PUNPCKLBW, r, a, a); 892 a = r; 893 /* FALLTHRU */ 894 case MO_16: 895 tcg_out_vex_modrm(s, OPC_PUNPCKLWD, r, a, a); 896 a = r; 897 /* FALLTHRU */ 898 case MO_32: 899 tcg_out_vex_modrm(s, OPC_PSHUFD, r, 0, a); 900 /* imm8 operand: all output lanes selected from input lane 0. */ 901 tcg_out8(s, 0); 902 break; 903 case MO_64: 904 tcg_out_vex_modrm(s, OPC_PUNPCKLQDQ, r, a, a); 905 break; 906 default: 907 g_assert_not_reached(); 908 } 909 } 910 return true; 911} 912 913static bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece, 914 TCGReg r, TCGReg base, intptr_t offset) 915{ 916 if (have_avx2) { 917 int vex_l = (type == TCG_TYPE_V256 ? P_VEXL : 0); 918 tcg_out_vex_modrm_offset(s, avx2_dup_insn[vece] + vex_l, 919 r, 0, base, offset); 920 } else { 921 switch (vece) { 922 case MO_64: 923 tcg_out_vex_modrm_offset(s, OPC_MOVDDUP, r, 0, base, offset); 924 break; 925 case MO_32: 926 tcg_out_vex_modrm_offset(s, OPC_VBROADCASTSS, r, 0, base, offset); 927 break; 928 case MO_16: 929 tcg_out_vex_modrm_offset(s, OPC_VPINSRW, r, r, base, offset); 930 tcg_out8(s, 0); /* imm8 */ 931 tcg_out_dup_vec(s, type, vece, r, r); 932 break; 933 case MO_8: 934 tcg_out_vex_modrm_offset(s, OPC_VPINSRB, r, r, base, offset); 935 tcg_out8(s, 0); /* imm8 */ 936 tcg_out_dup_vec(s, type, vece, r, r); 937 break; 938 default: 939 g_assert_not_reached(); 940 } 941 } 942 return true; 943} 944 945static void tcg_out_dupi_vec(TCGContext *s, TCGType type, unsigned vece, 946 TCGReg ret, int64_t arg) 947{ 948 int vex_l = (type == TCG_TYPE_V256 ? P_VEXL : 0); 949 950 if (arg == 0) { 951 tcg_out_vex_modrm(s, OPC_PXOR, ret, ret, ret); 952 return; 953 } 954 if (arg == -1) { 955 tcg_out_vex_modrm(s, OPC_PCMPEQB + vex_l, ret, ret, ret); 956 return; 957 } 958 959 if (TCG_TARGET_REG_BITS == 32 && vece < MO_64) { 960 if (have_avx2) { 961 tcg_out_vex_modrm_pool(s, OPC_VPBROADCASTD + vex_l, ret); 962 } else { 963 tcg_out_vex_modrm_pool(s, OPC_VBROADCASTSS, ret); 964 } 965 new_pool_label(s, arg, R_386_32, s->code_ptr - 4, 0); 966 } else { 967 if (type == TCG_TYPE_V64) { 968 tcg_out_vex_modrm_pool(s, OPC_MOVQ_VqWq, ret); 969 } else if (have_avx2) { 970 tcg_out_vex_modrm_pool(s, OPC_VPBROADCASTQ + vex_l, ret); 971 } else { 972 tcg_out_vex_modrm_pool(s, OPC_MOVDDUP, ret); 973 } 974 if (TCG_TARGET_REG_BITS == 64) { 975 new_pool_label(s, arg, R_386_PC32, s->code_ptr - 4, -4); 976 } else { 977 new_pool_l2(s, R_386_32, s->code_ptr - 4, 0, arg, arg >> 32); 978 } 979 } 980} 981 982static void tcg_out_movi_vec(TCGContext *s, TCGType type, 983 TCGReg ret, tcg_target_long arg) 984{ 985 if (arg == 0) { 986 tcg_out_vex_modrm(s, OPC_PXOR, ret, ret, ret); 987 return; 988 } 989 if (arg == -1) { 990 tcg_out_vex_modrm(s, OPC_PCMPEQB, ret, ret, ret); 991 return; 992 } 993 994 int rexw = (type == TCG_TYPE_I32 ? 0 : P_REXW); 995 tcg_out_vex_modrm_pool(s, OPC_MOVD_VyEy + rexw, ret); 996 if (TCG_TARGET_REG_BITS == 64) { 997 new_pool_label(s, arg, R_386_PC32, s->code_ptr - 4, -4); 998 } else { 999 new_pool_label(s, arg, R_386_32, s->code_ptr - 4, 0); 1000 } 1001} 1002 1003static void tcg_out_movi_int(TCGContext *s, TCGType type, 1004 TCGReg ret, tcg_target_long arg) 1005{ 1006 tcg_target_long diff; 1007 1008 if (arg == 0) { 1009 tgen_arithr(s, ARITH_XOR, ret, ret); 1010 return; 1011 } 1012 if (arg == (uint32_t)arg || type == TCG_TYPE_I32) { 1013 tcg_out_opc(s, OPC_MOVL_Iv + LOWREGMASK(ret), 0, ret, 0); 1014 tcg_out32(s, arg); 1015 return; 1016 } 1017 if (arg == (int32_t)arg) { 1018 tcg_out_modrm(s, OPC_MOVL_EvIz + P_REXW, 0, ret); 1019 tcg_out32(s, arg); 1020 return; 1021 } 1022 1023 /* Try a 7 byte pc-relative lea before the 10 byte movq. */ 1024 diff = tcg_pcrel_diff(s, (const void *)arg) - 7; 1025 if (diff == (int32_t)diff) { 1026 tcg_out_opc(s, OPC_LEA | P_REXW, ret, 0, 0); 1027 tcg_out8(s, (LOWREGMASK(ret) << 3) | 5); 1028 tcg_out32(s, diff); 1029 return; 1030 } 1031 1032 tcg_out_opc(s, OPC_MOVL_Iv + P_REXW + LOWREGMASK(ret), 0, ret, 0); 1033 tcg_out64(s, arg); 1034} 1035 1036static void tcg_out_movi(TCGContext *s, TCGType type, 1037 TCGReg ret, tcg_target_long arg) 1038{ 1039 switch (type) { 1040 case TCG_TYPE_I32: 1041#if TCG_TARGET_REG_BITS == 64 1042 case TCG_TYPE_I64: 1043#endif 1044 if (ret < 16) { 1045 tcg_out_movi_int(s, type, ret, arg); 1046 } else { 1047 tcg_out_movi_vec(s, type, ret, arg); 1048 } 1049 break; 1050 default: 1051 g_assert_not_reached(); 1052 } 1053} 1054 1055static inline void tcg_out_pushi(TCGContext *s, tcg_target_long val) 1056{ 1057 if (val == (int8_t)val) { 1058 tcg_out_opc(s, OPC_PUSH_Ib, 0, 0, 0); 1059 tcg_out8(s, val); 1060 } else if (val == (int32_t)val) { 1061 tcg_out_opc(s, OPC_PUSH_Iv, 0, 0, 0); 1062 tcg_out32(s, val); 1063 } else { 1064 tcg_abort(); 1065 } 1066} 1067 1068static inline void tcg_out_mb(TCGContext *s, TCGArg a0) 1069{ 1070 /* Given the strength of x86 memory ordering, we only need care for 1071 store-load ordering. Experimentally, "lock orl $0,0(%esp)" is 1072 faster than "mfence", so don't bother with the sse insn. */ 1073 if (a0 & TCG_MO_ST_LD) { 1074 tcg_out8(s, 0xf0); 1075 tcg_out_modrm_offset(s, OPC_ARITH_EvIb, ARITH_OR, TCG_REG_ESP, 0); 1076 tcg_out8(s, 0); 1077 } 1078} 1079 1080static inline void tcg_out_push(TCGContext *s, int reg) 1081{ 1082 tcg_out_opc(s, OPC_PUSH_r32 + LOWREGMASK(reg), 0, reg, 0); 1083} 1084 1085static inline void tcg_out_pop(TCGContext *s, int reg) 1086{ 1087 tcg_out_opc(s, OPC_POP_r32 + LOWREGMASK(reg), 0, reg, 0); 1088} 1089 1090static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, 1091 TCGReg arg1, intptr_t arg2) 1092{ 1093 switch (type) { 1094 case TCG_TYPE_I32: 1095 if (ret < 16) { 1096 tcg_out_modrm_offset(s, OPC_MOVL_GvEv, ret, arg1, arg2); 1097 } else { 1098 tcg_out_vex_modrm_offset(s, OPC_MOVD_VyEy, ret, 0, arg1, arg2); 1099 } 1100 break; 1101 case TCG_TYPE_I64: 1102 if (ret < 16) { 1103 tcg_out_modrm_offset(s, OPC_MOVL_GvEv | P_REXW, ret, arg1, arg2); 1104 break; 1105 } 1106 /* FALLTHRU */ 1107 case TCG_TYPE_V64: 1108 /* There is no instruction that can validate 8-byte alignment. */ 1109 tcg_debug_assert(ret >= 16); 1110 tcg_out_vex_modrm_offset(s, OPC_MOVQ_VqWq, ret, 0, arg1, arg2); 1111 break; 1112 case TCG_TYPE_V128: 1113 /* 1114 * The gvec infrastructure is asserts that v128 vector loads 1115 * and stores use a 16-byte aligned offset. Validate that the 1116 * final pointer is aligned by using an insn that will SIGSEGV. 1117 */ 1118 tcg_debug_assert(ret >= 16); 1119 tcg_out_vex_modrm_offset(s, OPC_MOVDQA_VxWx, ret, 0, arg1, arg2); 1120 break; 1121 case TCG_TYPE_V256: 1122 /* 1123 * The gvec infrastructure only requires 16-byte alignment, 1124 * so here we must use an unaligned load. 1125 */ 1126 tcg_debug_assert(ret >= 16); 1127 tcg_out_vex_modrm_offset(s, OPC_MOVDQU_VxWx | P_VEXL, 1128 ret, 0, arg1, arg2); 1129 break; 1130 default: 1131 g_assert_not_reached(); 1132 } 1133} 1134 1135static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, 1136 TCGReg arg1, intptr_t arg2) 1137{ 1138 switch (type) { 1139 case TCG_TYPE_I32: 1140 if (arg < 16) { 1141 tcg_out_modrm_offset(s, OPC_MOVL_EvGv, arg, arg1, arg2); 1142 } else { 1143 tcg_out_vex_modrm_offset(s, OPC_MOVD_EyVy, arg, 0, arg1, arg2); 1144 } 1145 break; 1146 case TCG_TYPE_I64: 1147 if (arg < 16) { 1148 tcg_out_modrm_offset(s, OPC_MOVL_EvGv | P_REXW, arg, arg1, arg2); 1149 break; 1150 } 1151 /* FALLTHRU */ 1152 case TCG_TYPE_V64: 1153 /* There is no instruction that can validate 8-byte alignment. */ 1154 tcg_debug_assert(arg >= 16); 1155 tcg_out_vex_modrm_offset(s, OPC_MOVQ_WqVq, arg, 0, arg1, arg2); 1156 break; 1157 case TCG_TYPE_V128: 1158 /* 1159 * The gvec infrastructure is asserts that v128 vector loads 1160 * and stores use a 16-byte aligned offset. Validate that the 1161 * final pointer is aligned by using an insn that will SIGSEGV. 1162 */ 1163 tcg_debug_assert(arg >= 16); 1164 tcg_out_vex_modrm_offset(s, OPC_MOVDQA_WxVx, arg, 0, arg1, arg2); 1165 break; 1166 case TCG_TYPE_V256: 1167 /* 1168 * The gvec infrastructure only requires 16-byte alignment, 1169 * so here we must use an unaligned store. 1170 */ 1171 tcg_debug_assert(arg >= 16); 1172 tcg_out_vex_modrm_offset(s, OPC_MOVDQU_WxVx | P_VEXL, 1173 arg, 0, arg1, arg2); 1174 break; 1175 default: 1176 g_assert_not_reached(); 1177 } 1178} 1179 1180static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val, 1181 TCGReg base, intptr_t ofs) 1182{ 1183 int rexw = 0; 1184 if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I64) { 1185 if (val != (int32_t)val) { 1186 return false; 1187 } 1188 rexw = P_REXW; 1189 } else if (type != TCG_TYPE_I32) { 1190 return false; 1191 } 1192 tcg_out_modrm_offset(s, OPC_MOVL_EvIz | rexw, 0, base, ofs); 1193 tcg_out32(s, val); 1194 return true; 1195} 1196 1197static void tcg_out_shifti(TCGContext *s, int subopc, int reg, int count) 1198{ 1199 /* Propagate an opcode prefix, such as P_DATA16. */ 1200 int ext = subopc & ~0x7; 1201 subopc &= 0x7; 1202 1203 if (count == 1) { 1204 tcg_out_modrm(s, OPC_SHIFT_1 + ext, subopc, reg); 1205 } else { 1206 tcg_out_modrm(s, OPC_SHIFT_Ib + ext, subopc, reg); 1207 tcg_out8(s, count); 1208 } 1209} 1210 1211static inline void tcg_out_bswap32(TCGContext *s, int reg) 1212{ 1213 tcg_out_opc(s, OPC_BSWAP + LOWREGMASK(reg), 0, reg, 0); 1214} 1215 1216static inline void tcg_out_rolw_8(TCGContext *s, int reg) 1217{ 1218 tcg_out_shifti(s, SHIFT_ROL + P_DATA16, reg, 8); 1219} 1220 1221static inline void tcg_out_ext8u(TCGContext *s, int dest, int src) 1222{ 1223 /* movzbl */ 1224 tcg_debug_assert(src < 4 || TCG_TARGET_REG_BITS == 64); 1225 tcg_out_modrm(s, OPC_MOVZBL + P_REXB_RM, dest, src); 1226} 1227 1228static void tcg_out_ext8s(TCGContext *s, int dest, int src, int rexw) 1229{ 1230 /* movsbl */ 1231 tcg_debug_assert(src < 4 || TCG_TARGET_REG_BITS == 64); 1232 tcg_out_modrm(s, OPC_MOVSBL + P_REXB_RM + rexw, dest, src); 1233} 1234 1235static inline void tcg_out_ext16u(TCGContext *s, int dest, int src) 1236{ 1237 /* movzwl */ 1238 tcg_out_modrm(s, OPC_MOVZWL, dest, src); 1239} 1240 1241static inline void tcg_out_ext16s(TCGContext *s, int dest, int src, int rexw) 1242{ 1243 /* movsw[lq] */ 1244 tcg_out_modrm(s, OPC_MOVSWL + rexw, dest, src); 1245} 1246 1247static inline void tcg_out_ext32u(TCGContext *s, int dest, int src) 1248{ 1249 /* 32-bit mov zero extends. */ 1250 tcg_out_modrm(s, OPC_MOVL_GvEv, dest, src); 1251} 1252 1253static inline void tcg_out_ext32s(TCGContext *s, int dest, int src) 1254{ 1255 tcg_out_modrm(s, OPC_MOVSLQ, dest, src); 1256} 1257 1258static inline void tcg_out_bswap64(TCGContext *s, int reg) 1259{ 1260 tcg_out_opc(s, OPC_BSWAP + P_REXW + LOWREGMASK(reg), 0, reg, 0); 1261} 1262 1263static void tgen_arithi(TCGContext *s, int c, int r0, 1264 tcg_target_long val, int cf) 1265{ 1266 int rexw = 0; 1267 1268 if (TCG_TARGET_REG_BITS == 64) { 1269 rexw = c & -8; 1270 c &= 7; 1271 } 1272 1273 /* ??? While INC is 2 bytes shorter than ADDL $1, they also induce 1274 partial flags update stalls on Pentium4 and are not recommended 1275 by current Intel optimization manuals. */ 1276 if (!cf && (c == ARITH_ADD || c == ARITH_SUB) && (val == 1 || val == -1)) { 1277 int is_inc = (c == ARITH_ADD) ^ (val < 0); 1278 if (TCG_TARGET_REG_BITS == 64) { 1279 /* The single-byte increment encodings are re-tasked as the 1280 REX prefixes. Use the MODRM encoding. */ 1281 tcg_out_modrm(s, OPC_GRP5 + rexw, 1282 (is_inc ? EXT5_INC_Ev : EXT5_DEC_Ev), r0); 1283 } else { 1284 tcg_out8(s, (is_inc ? OPC_INC_r32 : OPC_DEC_r32) + r0); 1285 } 1286 return; 1287 } 1288 1289 if (c == ARITH_AND) { 1290 if (TCG_TARGET_REG_BITS == 64) { 1291 if (val == 0xffffffffu) { 1292 tcg_out_ext32u(s, r0, r0); 1293 return; 1294 } 1295 if (val == (uint32_t)val) { 1296 /* AND with no high bits set can use a 32-bit operation. */ 1297 rexw = 0; 1298 } 1299 } 1300 if (val == 0xffu && (r0 < 4 || TCG_TARGET_REG_BITS == 64)) { 1301 tcg_out_ext8u(s, r0, r0); 1302 return; 1303 } 1304 if (val == 0xffffu) { 1305 tcg_out_ext16u(s, r0, r0); 1306 return; 1307 } 1308 } 1309 1310 if (val == (int8_t)val) { 1311 tcg_out_modrm(s, OPC_ARITH_EvIb + rexw, c, r0); 1312 tcg_out8(s, val); 1313 return; 1314 } 1315 if (rexw == 0 || val == (int32_t)val) { 1316 tcg_out_modrm(s, OPC_ARITH_EvIz + rexw, c, r0); 1317 tcg_out32(s, val); 1318 return; 1319 } 1320 1321 tcg_abort(); 1322} 1323 1324static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val) 1325{ 1326 if (val != 0) { 1327 tgen_arithi(s, ARITH_ADD + P_REXW, reg, val, 0); 1328 } 1329} 1330 1331/* Use SMALL != 0 to force a short forward branch. */ 1332static void tcg_out_jxx(TCGContext *s, int opc, TCGLabel *l, int small) 1333{ 1334 int32_t val, val1; 1335 1336 if (l->has_value) { 1337 val = tcg_pcrel_diff(s, l->u.value_ptr); 1338 val1 = val - 2; 1339 if ((int8_t)val1 == val1) { 1340 if (opc == -1) { 1341 tcg_out8(s, OPC_JMP_short); 1342 } else { 1343 tcg_out8(s, OPC_JCC_short + opc); 1344 } 1345 tcg_out8(s, val1); 1346 } else { 1347 if (small) { 1348 tcg_abort(); 1349 } 1350 if (opc == -1) { 1351 tcg_out8(s, OPC_JMP_long); 1352 tcg_out32(s, val - 5); 1353 } else { 1354 tcg_out_opc(s, OPC_JCC_long + opc, 0, 0, 0); 1355 tcg_out32(s, val - 6); 1356 } 1357 } 1358 } else if (small) { 1359 if (opc == -1) { 1360 tcg_out8(s, OPC_JMP_short); 1361 } else { 1362 tcg_out8(s, OPC_JCC_short + opc); 1363 } 1364 tcg_out_reloc(s, s->code_ptr, R_386_PC8, l, -1); 1365 s->code_ptr += 1; 1366 } else { 1367 if (opc == -1) { 1368 tcg_out8(s, OPC_JMP_long); 1369 } else { 1370 tcg_out_opc(s, OPC_JCC_long + opc, 0, 0, 0); 1371 } 1372 tcg_out_reloc(s, s->code_ptr, R_386_PC32, l, -4); 1373 s->code_ptr += 4; 1374 } 1375} 1376 1377static void tcg_out_cmp(TCGContext *s, TCGArg arg1, TCGArg arg2, 1378 int const_arg2, int rexw) 1379{ 1380 if (const_arg2) { 1381 if (arg2 == 0) { 1382 /* test r, r */ 1383 tcg_out_modrm(s, OPC_TESTL + rexw, arg1, arg1); 1384 } else { 1385 tgen_arithi(s, ARITH_CMP + rexw, arg1, arg2, 0); 1386 } 1387 } else { 1388 tgen_arithr(s, ARITH_CMP + rexw, arg1, arg2); 1389 } 1390} 1391 1392static void tcg_out_brcond32(TCGContext *s, TCGCond cond, 1393 TCGArg arg1, TCGArg arg2, int const_arg2, 1394 TCGLabel *label, int small) 1395{ 1396 tcg_out_cmp(s, arg1, arg2, const_arg2, 0); 1397 tcg_out_jxx(s, tcg_cond_to_jcc[cond], label, small); 1398} 1399 1400#if TCG_TARGET_REG_BITS == 64 1401static void tcg_out_brcond64(TCGContext *s, TCGCond cond, 1402 TCGArg arg1, TCGArg arg2, int const_arg2, 1403 TCGLabel *label, int small) 1404{ 1405 tcg_out_cmp(s, arg1, arg2, const_arg2, P_REXW); 1406 tcg_out_jxx(s, tcg_cond_to_jcc[cond], label, small); 1407} 1408#else 1409/* XXX: we implement it at the target level to avoid having to 1410 handle cross basic blocks temporaries */ 1411static void tcg_out_brcond2(TCGContext *s, const TCGArg *args, 1412 const int *const_args, int small) 1413{ 1414 TCGLabel *label_next = gen_new_label(); 1415 TCGLabel *label_this = arg_label(args[5]); 1416 1417 switch(args[4]) { 1418 case TCG_COND_EQ: 1419 tcg_out_brcond32(s, TCG_COND_NE, args[0], args[2], const_args[2], 1420 label_next, 1); 1421 tcg_out_brcond32(s, TCG_COND_EQ, args[1], args[3], const_args[3], 1422 label_this, small); 1423 break; 1424 case TCG_COND_NE: 1425 tcg_out_brcond32(s, TCG_COND_NE, args[0], args[2], const_args[2], 1426 label_this, small); 1427 tcg_out_brcond32(s, TCG_COND_NE, args[1], args[3], const_args[3], 1428 label_this, small); 1429 break; 1430 case TCG_COND_LT: 1431 tcg_out_brcond32(s, TCG_COND_LT, args[1], args[3], const_args[3], 1432 label_this, small); 1433 tcg_out_jxx(s, JCC_JNE, label_next, 1); 1434 tcg_out_brcond32(s, TCG_COND_LTU, args[0], args[2], const_args[2], 1435 label_this, small); 1436 break; 1437 case TCG_COND_LE: 1438 tcg_out_brcond32(s, TCG_COND_LT, args[1], args[3], const_args[3], 1439 label_this, small); 1440 tcg_out_jxx(s, JCC_JNE, label_next, 1); 1441 tcg_out_brcond32(s, TCG_COND_LEU, args[0], args[2], const_args[2], 1442 label_this, small); 1443 break; 1444 case TCG_COND_GT: 1445 tcg_out_brcond32(s, TCG_COND_GT, args[1], args[3], const_args[3], 1446 label_this, small); 1447 tcg_out_jxx(s, JCC_JNE, label_next, 1); 1448 tcg_out_brcond32(s, TCG_COND_GTU, args[0], args[2], const_args[2], 1449 label_this, small); 1450 break; 1451 case TCG_COND_GE: 1452 tcg_out_brcond32(s, TCG_COND_GT, args[1], args[3], const_args[3], 1453 label_this, small); 1454 tcg_out_jxx(s, JCC_JNE, label_next, 1); 1455 tcg_out_brcond32(s, TCG_COND_GEU, args[0], args[2], const_args[2], 1456 label_this, small); 1457 break; 1458 case TCG_COND_LTU: 1459 tcg_out_brcond32(s, TCG_COND_LTU, args[1], args[3], const_args[3], 1460 label_this, small); 1461 tcg_out_jxx(s, JCC_JNE, label_next, 1); 1462 tcg_out_brcond32(s, TCG_COND_LTU, args[0], args[2], const_args[2], 1463 label_this, small); 1464 break; 1465 case TCG_COND_LEU: 1466 tcg_out_brcond32(s, TCG_COND_LTU, args[1], args[3], const_args[3], 1467 label_this, small); 1468 tcg_out_jxx(s, JCC_JNE, label_next, 1); 1469 tcg_out_brcond32(s, TCG_COND_LEU, args[0], args[2], const_args[2], 1470 label_this, small); 1471 break; 1472 case TCG_COND_GTU: 1473 tcg_out_brcond32(s, TCG_COND_GTU, args[1], args[3], const_args[3], 1474 label_this, small); 1475 tcg_out_jxx(s, JCC_JNE, label_next, 1); 1476 tcg_out_brcond32(s, TCG_COND_GTU, args[0], args[2], const_args[2], 1477 label_this, small); 1478 break; 1479 case TCG_COND_GEU: 1480 tcg_out_brcond32(s, TCG_COND_GTU, args[1], args[3], const_args[3], 1481 label_this, small); 1482 tcg_out_jxx(s, JCC_JNE, label_next, 1); 1483 tcg_out_brcond32(s, TCG_COND_GEU, args[0], args[2], const_args[2], 1484 label_this, small); 1485 break; 1486 default: 1487 tcg_abort(); 1488 } 1489 tcg_out_label(s, label_next); 1490} 1491#endif 1492 1493static void tcg_out_setcond32(TCGContext *s, TCGCond cond, TCGArg dest, 1494 TCGArg arg1, TCGArg arg2, int const_arg2) 1495{ 1496 tcg_out_cmp(s, arg1, arg2, const_arg2, 0); 1497 tcg_out_modrm(s, OPC_SETCC | tcg_cond_to_jcc[cond], 0, dest); 1498 tcg_out_ext8u(s, dest, dest); 1499} 1500 1501#if TCG_TARGET_REG_BITS == 64 1502static void tcg_out_setcond64(TCGContext *s, TCGCond cond, TCGArg dest, 1503 TCGArg arg1, TCGArg arg2, int const_arg2) 1504{ 1505 tcg_out_cmp(s, arg1, arg2, const_arg2, P_REXW); 1506 tcg_out_modrm(s, OPC_SETCC | tcg_cond_to_jcc[cond], 0, dest); 1507 tcg_out_ext8u(s, dest, dest); 1508} 1509#else 1510static void tcg_out_setcond2(TCGContext *s, const TCGArg *args, 1511 const int *const_args) 1512{ 1513 TCGArg new_args[6]; 1514 TCGLabel *label_true, *label_over; 1515 1516 memcpy(new_args, args+1, 5*sizeof(TCGArg)); 1517 1518 if (args[0] == args[1] || args[0] == args[2] 1519 || (!const_args[3] && args[0] == args[3]) 1520 || (!const_args[4] && args[0] == args[4])) { 1521 /* When the destination overlaps with one of the argument 1522 registers, don't do anything tricky. */ 1523 label_true = gen_new_label(); 1524 label_over = gen_new_label(); 1525 1526 new_args[5] = label_arg(label_true); 1527 tcg_out_brcond2(s, new_args, const_args+1, 1); 1528 1529 tcg_out_movi(s, TCG_TYPE_I32, args[0], 0); 1530 tcg_out_jxx(s, JCC_JMP, label_over, 1); 1531 tcg_out_label(s, label_true); 1532 1533 tcg_out_movi(s, TCG_TYPE_I32, args[0], 1); 1534 tcg_out_label(s, label_over); 1535 } else { 1536 /* When the destination does not overlap one of the arguments, 1537 clear the destination first, jump if cond false, and emit an 1538 increment in the true case. This results in smaller code. */ 1539 1540 tcg_out_movi(s, TCG_TYPE_I32, args[0], 0); 1541 1542 label_over = gen_new_label(); 1543 new_args[4] = tcg_invert_cond(new_args[4]); 1544 new_args[5] = label_arg(label_over); 1545 tcg_out_brcond2(s, new_args, const_args+1, 1); 1546 1547 tgen_arithi(s, ARITH_ADD, args[0], 1, 0); 1548 tcg_out_label(s, label_over); 1549 } 1550} 1551#endif 1552 1553static void tcg_out_cmov(TCGContext *s, TCGCond cond, int rexw, 1554 TCGReg dest, TCGReg v1) 1555{ 1556 if (have_cmov) { 1557 tcg_out_modrm(s, OPC_CMOVCC | tcg_cond_to_jcc[cond] | rexw, dest, v1); 1558 } else { 1559 TCGLabel *over = gen_new_label(); 1560 tcg_out_jxx(s, tcg_cond_to_jcc[tcg_invert_cond(cond)], over, 1); 1561 tcg_out_mov(s, TCG_TYPE_I32, dest, v1); 1562 tcg_out_label(s, over); 1563 } 1564} 1565 1566static void tcg_out_movcond32(TCGContext *s, TCGCond cond, TCGReg dest, 1567 TCGReg c1, TCGArg c2, int const_c2, 1568 TCGReg v1) 1569{ 1570 tcg_out_cmp(s, c1, c2, const_c2, 0); 1571 tcg_out_cmov(s, cond, 0, dest, v1); 1572} 1573 1574#if TCG_TARGET_REG_BITS == 64 1575static void tcg_out_movcond64(TCGContext *s, TCGCond cond, TCGReg dest, 1576 TCGReg c1, TCGArg c2, int const_c2, 1577 TCGReg v1) 1578{ 1579 tcg_out_cmp(s, c1, c2, const_c2, P_REXW); 1580 tcg_out_cmov(s, cond, P_REXW, dest, v1); 1581} 1582#endif 1583 1584static void tcg_out_ctz(TCGContext *s, int rexw, TCGReg dest, TCGReg arg1, 1585 TCGArg arg2, bool const_a2) 1586{ 1587 if (have_bmi1) { 1588 tcg_out_modrm(s, OPC_TZCNT + rexw, dest, arg1); 1589 if (const_a2) { 1590 tcg_debug_assert(arg2 == (rexw ? 64 : 32)); 1591 } else { 1592 tcg_debug_assert(dest != arg2); 1593 tcg_out_cmov(s, TCG_COND_LTU, rexw, dest, arg2); 1594 } 1595 } else { 1596 tcg_debug_assert(dest != arg2); 1597 tcg_out_modrm(s, OPC_BSF + rexw, dest, arg1); 1598 tcg_out_cmov(s, TCG_COND_EQ, rexw, dest, arg2); 1599 } 1600} 1601 1602static void tcg_out_clz(TCGContext *s, int rexw, TCGReg dest, TCGReg arg1, 1603 TCGArg arg2, bool const_a2) 1604{ 1605 if (have_lzcnt) { 1606 tcg_out_modrm(s, OPC_LZCNT + rexw, dest, arg1); 1607 if (const_a2) { 1608 tcg_debug_assert(arg2 == (rexw ? 64 : 32)); 1609 } else { 1610 tcg_debug_assert(dest != arg2); 1611 tcg_out_cmov(s, TCG_COND_LTU, rexw, dest, arg2); 1612 } 1613 } else { 1614 tcg_debug_assert(!const_a2); 1615 tcg_debug_assert(dest != arg1); 1616 tcg_debug_assert(dest != arg2); 1617 1618 /* Recall that the output of BSR is the index not the count. */ 1619 tcg_out_modrm(s, OPC_BSR + rexw, dest, arg1); 1620 tgen_arithi(s, ARITH_XOR + rexw, dest, rexw ? 63 : 31, 0); 1621 1622 /* Since we have destroyed the flags from BSR, we have to re-test. */ 1623 tcg_out_cmp(s, arg1, 0, 1, rexw); 1624 tcg_out_cmov(s, TCG_COND_EQ, rexw, dest, arg2); 1625 } 1626} 1627 1628static void tcg_out_branch(TCGContext *s, int call, const tcg_insn_unit *dest) 1629{ 1630 intptr_t disp = tcg_pcrel_diff(s, dest) - 5; 1631 1632 if (disp == (int32_t)disp) { 1633 tcg_out_opc(s, call ? OPC_CALL_Jz : OPC_JMP_long, 0, 0, 0); 1634 tcg_out32(s, disp); 1635 } else { 1636 /* rip-relative addressing into the constant pool. 1637 This is 6 + 8 = 14 bytes, as compared to using an 1638 an immediate load 10 + 6 = 16 bytes, plus we may 1639 be able to re-use the pool constant for more calls. */ 1640 tcg_out_opc(s, OPC_GRP5, 0, 0, 0); 1641 tcg_out8(s, (call ? EXT5_CALLN_Ev : EXT5_JMPN_Ev) << 3 | 5); 1642 new_pool_label(s, (uintptr_t)dest, R_386_PC32, s->code_ptr, -4); 1643 tcg_out32(s, 0); 1644 } 1645} 1646 1647static inline void tcg_out_call(TCGContext *s, const tcg_insn_unit *dest) 1648{ 1649 tcg_out_branch(s, 1, dest); 1650} 1651 1652static void tcg_out_jmp(TCGContext *s, const tcg_insn_unit *dest) 1653{ 1654 tcg_out_branch(s, 0, dest); 1655} 1656 1657static void tcg_out_nopn(TCGContext *s, int n) 1658{ 1659 int i; 1660 /* Emit 1 or 2 operand size prefixes for the standard one byte nop, 1661 * "xchg %eax,%eax", forming "xchg %ax,%ax". All cores accept the 1662 * duplicate prefix, and all of the interesting recent cores can 1663 * decode and discard the duplicates in a single cycle. 1664 */ 1665 tcg_debug_assert(n >= 1); 1666 for (i = 1; i < n; ++i) { 1667 tcg_out8(s, 0x66); 1668 } 1669 tcg_out8(s, 0x90); 1670} 1671 1672#if defined(CONFIG_SOFTMMU) 1673#include "../tcg-ldst.c.inc" 1674 1675/* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr, 1676 * int mmu_idx, uintptr_t ra) 1677 */ 1678static void * const qemu_ld_helpers[16] = { 1679 [MO_UB] = helper_ret_ldub_mmu, 1680 [MO_LEUW] = helper_le_lduw_mmu, 1681 [MO_LEUL] = helper_le_ldul_mmu, 1682 [MO_LEQ] = helper_le_ldq_mmu, 1683 [MO_BEUW] = helper_be_lduw_mmu, 1684 [MO_BEUL] = helper_be_ldul_mmu, 1685 [MO_BEQ] = helper_be_ldq_mmu, 1686}; 1687 1688/* helper signature: helper_ret_st_mmu(CPUState *env, target_ulong addr, 1689 * uintxx_t val, int mmu_idx, uintptr_t ra) 1690 */ 1691static void * const qemu_st_helpers[16] = { 1692 [MO_UB] = helper_ret_stb_mmu, 1693 [MO_LEUW] = helper_le_stw_mmu, 1694 [MO_LEUL] = helper_le_stl_mmu, 1695 [MO_LEQ] = helper_le_stq_mmu, 1696 [MO_BEUW] = helper_be_stw_mmu, 1697 [MO_BEUL] = helper_be_stl_mmu, 1698 [MO_BEQ] = helper_be_stq_mmu, 1699}; 1700 1701/* Perform the TLB load and compare. 1702 1703 Inputs: 1704 ADDRLO and ADDRHI contain the low and high part of the address. 1705 1706 MEM_INDEX and S_BITS are the memory context and log2 size of the load. 1707 1708 WHICH is the offset into the CPUTLBEntry structure of the slot to read. 1709 This should be offsetof addr_read or addr_write. 1710 1711 Outputs: 1712 LABEL_PTRS is filled with 1 (32-bit addresses) or 2 (64-bit addresses) 1713 positions of the displacements of forward jumps to the TLB miss case. 1714 1715 Second argument register is loaded with the low part of the address. 1716 In the TLB hit case, it has been adjusted as indicated by the TLB 1717 and so is a host address. In the TLB miss case, it continues to 1718 hold a guest address. 1719 1720 First argument register is clobbered. */ 1721 1722static inline void tcg_out_tlb_load(TCGContext *s, TCGReg addrlo, TCGReg addrhi, 1723 int mem_index, MemOp opc, 1724 tcg_insn_unit **label_ptr, int which) 1725{ 1726 const TCGReg r0 = TCG_REG_L0; 1727 const TCGReg r1 = TCG_REG_L1; 1728 TCGType ttype = TCG_TYPE_I32; 1729 TCGType tlbtype = TCG_TYPE_I32; 1730 int trexw = 0, hrexw = 0, tlbrexw = 0; 1731 unsigned a_bits = get_alignment_bits(opc); 1732 unsigned s_bits = opc & MO_SIZE; 1733 unsigned a_mask = (1 << a_bits) - 1; 1734 unsigned s_mask = (1 << s_bits) - 1; 1735 target_ulong tlb_mask; 1736 1737 if (TCG_TARGET_REG_BITS == 64) { 1738 if (TARGET_LONG_BITS == 64) { 1739 ttype = TCG_TYPE_I64; 1740 trexw = P_REXW; 1741 } 1742 if (TCG_TYPE_PTR == TCG_TYPE_I64) { 1743 hrexw = P_REXW; 1744 if (TARGET_PAGE_BITS + CPU_TLB_DYN_MAX_BITS > 32) { 1745 tlbtype = TCG_TYPE_I64; 1746 tlbrexw = P_REXW; 1747 } 1748 } 1749 } 1750 1751 tcg_out_mov(s, tlbtype, r0, addrlo); 1752 tcg_out_shifti(s, SHIFT_SHR + tlbrexw, r0, 1753 TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); 1754 1755 tcg_out_modrm_offset(s, OPC_AND_GvEv + trexw, r0, TCG_AREG0, 1756 TLB_MASK_TABLE_OFS(mem_index) + 1757 offsetof(CPUTLBDescFast, mask)); 1758 1759 tcg_out_modrm_offset(s, OPC_ADD_GvEv + hrexw, r0, TCG_AREG0, 1760 TLB_MASK_TABLE_OFS(mem_index) + 1761 offsetof(CPUTLBDescFast, table)); 1762 1763 /* If the required alignment is at least as large as the access, simply 1764 copy the address and mask. For lesser alignments, check that we don't 1765 cross pages for the complete access. */ 1766 if (a_bits >= s_bits) { 1767 tcg_out_mov(s, ttype, r1, addrlo); 1768 } else { 1769 tcg_out_modrm_offset(s, OPC_LEA + trexw, r1, addrlo, s_mask - a_mask); 1770 } 1771 tlb_mask = (target_ulong)TARGET_PAGE_MASK | a_mask; 1772 tgen_arithi(s, ARITH_AND + trexw, r1, tlb_mask, 0); 1773 1774 /* cmp 0(r0), r1 */ 1775 tcg_out_modrm_offset(s, OPC_CMP_GvEv + trexw, r1, r0, which); 1776 1777 /* Prepare for both the fast path add of the tlb addend, and the slow 1778 path function argument setup. */ 1779 tcg_out_mov(s, ttype, r1, addrlo); 1780 1781 /* jne slow_path */ 1782 tcg_out_opc(s, OPC_JCC_long + JCC_JNE, 0, 0, 0); 1783 label_ptr[0] = s->code_ptr; 1784 s->code_ptr += 4; 1785 1786 if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) { 1787 /* cmp 4(r0), addrhi */ 1788 tcg_out_modrm_offset(s, OPC_CMP_GvEv, addrhi, r0, which + 4); 1789 1790 /* jne slow_path */ 1791 tcg_out_opc(s, OPC_JCC_long + JCC_JNE, 0, 0, 0); 1792 label_ptr[1] = s->code_ptr; 1793 s->code_ptr += 4; 1794 } 1795 1796 /* TLB Hit. */ 1797 1798 /* add addend(r0), r1 */ 1799 tcg_out_modrm_offset(s, OPC_ADD_GvEv + hrexw, r1, r0, 1800 offsetof(CPUTLBEntry, addend)); 1801} 1802 1803/* 1804 * Record the context of a call to the out of line helper code for the slow path 1805 * for a load or store, so that we can later generate the correct helper code 1806 */ 1807static void add_qemu_ldst_label(TCGContext *s, bool is_ld, bool is_64, 1808 TCGMemOpIdx oi, 1809 TCGReg datalo, TCGReg datahi, 1810 TCGReg addrlo, TCGReg addrhi, 1811 tcg_insn_unit *raddr, 1812 tcg_insn_unit **label_ptr) 1813{ 1814 TCGLabelQemuLdst *label = new_ldst_label(s); 1815 1816 label->is_ld = is_ld; 1817 label->oi = oi; 1818 label->type = is_64 ? TCG_TYPE_I64 : TCG_TYPE_I32; 1819 label->datalo_reg = datalo; 1820 label->datahi_reg = datahi; 1821 label->addrlo_reg = addrlo; 1822 label->addrhi_reg = addrhi; 1823 label->raddr = tcg_splitwx_to_rx(raddr); 1824 label->label_ptr[0] = label_ptr[0]; 1825 if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) { 1826 label->label_ptr[1] = label_ptr[1]; 1827 } 1828} 1829 1830/* 1831 * Generate code for the slow path for a load at the end of block 1832 */ 1833static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) 1834{ 1835 TCGMemOpIdx oi = l->oi; 1836 MemOp opc = get_memop(oi); 1837 TCGReg data_reg; 1838 tcg_insn_unit **label_ptr = &l->label_ptr[0]; 1839 int rexw = (l->type == TCG_TYPE_I64 ? P_REXW : 0); 1840 1841 /* resolve label address */ 1842 tcg_patch32(label_ptr[0], s->code_ptr - label_ptr[0] - 4); 1843 if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) { 1844 tcg_patch32(label_ptr[1], s->code_ptr - label_ptr[1] - 4); 1845 } 1846 1847 if (TCG_TARGET_REG_BITS == 32) { 1848 int ofs = 0; 1849 1850 tcg_out_st(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_ESP, ofs); 1851 ofs += 4; 1852 1853 tcg_out_st(s, TCG_TYPE_I32, l->addrlo_reg, TCG_REG_ESP, ofs); 1854 ofs += 4; 1855 1856 if (TARGET_LONG_BITS == 64) { 1857 tcg_out_st(s, TCG_TYPE_I32, l->addrhi_reg, TCG_REG_ESP, ofs); 1858 ofs += 4; 1859 } 1860 1861 tcg_out_sti(s, TCG_TYPE_I32, oi, TCG_REG_ESP, ofs); 1862 ofs += 4; 1863 1864 tcg_out_sti(s, TCG_TYPE_PTR, (uintptr_t)l->raddr, TCG_REG_ESP, ofs); 1865 } else { 1866 tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0); 1867 /* The second argument is already loaded with addrlo. */ 1868 tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2], oi); 1869 tcg_out_movi(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[3], 1870 (uintptr_t)l->raddr); 1871 } 1872 1873 tcg_out_call(s, qemu_ld_helpers[opc & (MO_BSWAP | MO_SIZE)]); 1874 1875 data_reg = l->datalo_reg; 1876 switch (opc & MO_SSIZE) { 1877 case MO_SB: 1878 tcg_out_ext8s(s, data_reg, TCG_REG_EAX, rexw); 1879 break; 1880 case MO_SW: 1881 tcg_out_ext16s(s, data_reg, TCG_REG_EAX, rexw); 1882 break; 1883#if TCG_TARGET_REG_BITS == 64 1884 case MO_SL: 1885 tcg_out_ext32s(s, data_reg, TCG_REG_EAX); 1886 break; 1887#endif 1888 case MO_UB: 1889 case MO_UW: 1890 /* Note that the helpers have zero-extended to tcg_target_long. */ 1891 case MO_UL: 1892 tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX); 1893 break; 1894 case MO_Q: 1895 if (TCG_TARGET_REG_BITS == 64) { 1896 tcg_out_mov(s, TCG_TYPE_I64, data_reg, TCG_REG_RAX); 1897 } else if (data_reg == TCG_REG_EDX) { 1898 /* xchg %edx, %eax */ 1899 tcg_out_opc(s, OPC_XCHG_ax_r32 + TCG_REG_EDX, 0, 0, 0); 1900 tcg_out_mov(s, TCG_TYPE_I32, l->datahi_reg, TCG_REG_EAX); 1901 } else { 1902 tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX); 1903 tcg_out_mov(s, TCG_TYPE_I32, l->datahi_reg, TCG_REG_EDX); 1904 } 1905 break; 1906 default: 1907 tcg_abort(); 1908 } 1909 1910 /* Jump to the code corresponding to next IR of qemu_st */ 1911 tcg_out_jmp(s, l->raddr); 1912 return true; 1913} 1914 1915/* 1916 * Generate code for the slow path for a store at the end of block 1917 */ 1918static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l) 1919{ 1920 TCGMemOpIdx oi = l->oi; 1921 MemOp opc = get_memop(oi); 1922 MemOp s_bits = opc & MO_SIZE; 1923 tcg_insn_unit **label_ptr = &l->label_ptr[0]; 1924 TCGReg retaddr; 1925 1926 /* resolve label address */ 1927 tcg_patch32(label_ptr[0], s->code_ptr - label_ptr[0] - 4); 1928 if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) { 1929 tcg_patch32(label_ptr[1], s->code_ptr - label_ptr[1] - 4); 1930 } 1931 1932 if (TCG_TARGET_REG_BITS == 32) { 1933 int ofs = 0; 1934 1935 tcg_out_st(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_ESP, ofs); 1936 ofs += 4; 1937 1938 tcg_out_st(s, TCG_TYPE_I32, l->addrlo_reg, TCG_REG_ESP, ofs); 1939 ofs += 4; 1940 1941 if (TARGET_LONG_BITS == 64) { 1942 tcg_out_st(s, TCG_TYPE_I32, l->addrhi_reg, TCG_REG_ESP, ofs); 1943 ofs += 4; 1944 } 1945 1946 tcg_out_st(s, TCG_TYPE_I32, l->datalo_reg, TCG_REG_ESP, ofs); 1947 ofs += 4; 1948 1949 if (s_bits == MO_64) { 1950 tcg_out_st(s, TCG_TYPE_I32, l->datahi_reg, TCG_REG_ESP, ofs); 1951 ofs += 4; 1952 } 1953 1954 tcg_out_sti(s, TCG_TYPE_I32, oi, TCG_REG_ESP, ofs); 1955 ofs += 4; 1956 1957 retaddr = TCG_REG_EAX; 1958 tcg_out_movi(s, TCG_TYPE_PTR, retaddr, (uintptr_t)l->raddr); 1959 tcg_out_st(s, TCG_TYPE_PTR, retaddr, TCG_REG_ESP, ofs); 1960 } else { 1961 tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0); 1962 /* The second argument is already loaded with addrlo. */ 1963 tcg_out_mov(s, (s_bits == MO_64 ? TCG_TYPE_I64 : TCG_TYPE_I32), 1964 tcg_target_call_iarg_regs[2], l->datalo_reg); 1965 tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3], oi); 1966 1967 if (ARRAY_SIZE(tcg_target_call_iarg_regs) > 4) { 1968 retaddr = tcg_target_call_iarg_regs[4]; 1969 tcg_out_movi(s, TCG_TYPE_PTR, retaddr, (uintptr_t)l->raddr); 1970 } else { 1971 retaddr = TCG_REG_RAX; 1972 tcg_out_movi(s, TCG_TYPE_PTR, retaddr, (uintptr_t)l->raddr); 1973 tcg_out_st(s, TCG_TYPE_PTR, retaddr, TCG_REG_ESP, 1974 TCG_TARGET_CALL_STACK_OFFSET); 1975 } 1976 } 1977 1978 /* "Tail call" to the helper, with the return address back inline. */ 1979 tcg_out_push(s, retaddr); 1980 tcg_out_jmp(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]); 1981 return true; 1982} 1983#elif TCG_TARGET_REG_BITS == 32 1984# define x86_guest_base_seg 0 1985# define x86_guest_base_index -1 1986# define x86_guest_base_offset guest_base 1987#else 1988static int x86_guest_base_seg; 1989static int x86_guest_base_index = -1; 1990static int32_t x86_guest_base_offset; 1991# if defined(__x86_64__) && defined(__linux__) 1992# include <asm/prctl.h> 1993# include <sys/prctl.h> 1994int arch_prctl(int code, unsigned long addr); 1995static inline int setup_guest_base_seg(void) 1996{ 1997 if (arch_prctl(ARCH_SET_GS, guest_base) == 0) { 1998 return P_GS; 1999 } 2000 return 0; 2001} 2002# elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__) 2003# include <machine/sysarch.h> 2004static inline int setup_guest_base_seg(void) 2005{ 2006 if (sysarch(AMD64_SET_GSBASE, &guest_base) == 0) { 2007 return P_GS; 2008 } 2009 return 0; 2010} 2011# else 2012static inline int setup_guest_base_seg(void) 2013{ 2014 return 0; 2015} 2016# endif 2017#endif /* SOFTMMU */ 2018 2019static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg datalo, TCGReg datahi, 2020 TCGReg base, int index, intptr_t ofs, 2021 int seg, bool is64, MemOp memop) 2022{ 2023 bool use_movbe = false; 2024 int rexw = is64 * P_REXW; 2025 int movop = OPC_MOVL_GvEv; 2026 2027 /* Do big-endian loads with movbe. */ 2028 if (memop & MO_BSWAP) { 2029 tcg_debug_assert(have_movbe); 2030 use_movbe = true; 2031 movop = OPC_MOVBE_GyMy; 2032 } 2033 2034 switch (memop & MO_SSIZE) { 2035 case MO_UB: 2036 tcg_out_modrm_sib_offset(s, OPC_MOVZBL + seg, datalo, 2037 base, index, 0, ofs); 2038 break; 2039 case MO_SB: 2040 tcg_out_modrm_sib_offset(s, OPC_MOVSBL + rexw + seg, datalo, 2041 base, index, 0, ofs); 2042 break; 2043 case MO_UW: 2044 if (use_movbe) { 2045 /* There is no extending movbe; only low 16-bits are modified. */ 2046 if (datalo != base && datalo != index) { 2047 /* XOR breaks dependency chains. */ 2048 tgen_arithr(s, ARITH_XOR, datalo, datalo); 2049 tcg_out_modrm_sib_offset(s, OPC_MOVBE_GyMy + P_DATA16 + seg, 2050 datalo, base, index, 0, ofs); 2051 } else { 2052 tcg_out_modrm_sib_offset(s, OPC_MOVBE_GyMy + P_DATA16 + seg, 2053 datalo, base, index, 0, ofs); 2054 tcg_out_ext16u(s, datalo, datalo); 2055 } 2056 } else { 2057 tcg_out_modrm_sib_offset(s, OPC_MOVZWL + seg, datalo, 2058 base, index, 0, ofs); 2059 } 2060 break; 2061 case MO_SW: 2062 if (use_movbe) { 2063 tcg_out_modrm_sib_offset(s, OPC_MOVBE_GyMy + P_DATA16 + seg, 2064 datalo, base, index, 0, ofs); 2065 tcg_out_ext16s(s, datalo, datalo, rexw); 2066 } else { 2067 tcg_out_modrm_sib_offset(s, OPC_MOVSWL + rexw + seg, 2068 datalo, base, index, 0, ofs); 2069 } 2070 break; 2071 case MO_UL: 2072 tcg_out_modrm_sib_offset(s, movop + seg, datalo, base, index, 0, ofs); 2073 break; 2074#if TCG_TARGET_REG_BITS == 64 2075 case MO_SL: 2076 if (use_movbe) { 2077 tcg_out_modrm_sib_offset(s, OPC_MOVBE_GyMy + seg, datalo, 2078 base, index, 0, ofs); 2079 tcg_out_ext32s(s, datalo, datalo); 2080 } else { 2081 tcg_out_modrm_sib_offset(s, OPC_MOVSLQ + seg, datalo, 2082 base, index, 0, ofs); 2083 } 2084 break; 2085#endif 2086 case MO_Q: 2087 if (TCG_TARGET_REG_BITS == 64) { 2088 tcg_out_modrm_sib_offset(s, movop + P_REXW + seg, datalo, 2089 base, index, 0, ofs); 2090 } else { 2091 if (use_movbe) { 2092 TCGReg t = datalo; 2093 datalo = datahi; 2094 datahi = t; 2095 } 2096 if (base != datalo) { 2097 tcg_out_modrm_sib_offset(s, movop + seg, datalo, 2098 base, index, 0, ofs); 2099 tcg_out_modrm_sib_offset(s, movop + seg, datahi, 2100 base, index, 0, ofs + 4); 2101 } else { 2102 tcg_out_modrm_sib_offset(s, movop + seg, datahi, 2103 base, index, 0, ofs + 4); 2104 tcg_out_modrm_sib_offset(s, movop + seg, datalo, 2105 base, index, 0, ofs); 2106 } 2107 } 2108 break; 2109 default: 2110 g_assert_not_reached(); 2111 } 2112} 2113 2114/* XXX: qemu_ld and qemu_st could be modified to clobber only EDX and 2115 EAX. It will be useful once fixed registers globals are less 2116 common. */ 2117static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64) 2118{ 2119 TCGReg datalo, datahi, addrlo; 2120 TCGReg addrhi __attribute__((unused)); 2121 TCGMemOpIdx oi; 2122 MemOp opc; 2123#if defined(CONFIG_SOFTMMU) 2124 int mem_index; 2125 tcg_insn_unit *label_ptr[2]; 2126#endif 2127 2128 datalo = *args++; 2129 datahi = (TCG_TARGET_REG_BITS == 32 && is64 ? *args++ : 0); 2130 addrlo = *args++; 2131 addrhi = (TARGET_LONG_BITS > TCG_TARGET_REG_BITS ? *args++ : 0); 2132 oi = *args++; 2133 opc = get_memop(oi); 2134 2135#if defined(CONFIG_SOFTMMU) 2136 mem_index = get_mmuidx(oi); 2137 2138 tcg_out_tlb_load(s, addrlo, addrhi, mem_index, opc, 2139 label_ptr, offsetof(CPUTLBEntry, addr_read)); 2140 2141 /* TLB Hit. */ 2142 tcg_out_qemu_ld_direct(s, datalo, datahi, TCG_REG_L1, -1, 0, 0, is64, opc); 2143 2144 /* Record the current context of a load into ldst label */ 2145 add_qemu_ldst_label(s, true, is64, oi, datalo, datahi, addrlo, addrhi, 2146 s->code_ptr, label_ptr); 2147#else 2148 tcg_out_qemu_ld_direct(s, datalo, datahi, addrlo, x86_guest_base_index, 2149 x86_guest_base_offset, x86_guest_base_seg, 2150 is64, opc); 2151#endif 2152} 2153 2154static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg datalo, TCGReg datahi, 2155 TCGReg base, int index, intptr_t ofs, 2156 int seg, MemOp memop) 2157{ 2158 bool use_movbe = false; 2159 int movop = OPC_MOVL_EvGv; 2160 2161 /* 2162 * Do big-endian stores with movbe or softmmu. 2163 * User-only without movbe will have its swapping done generically. 2164 */ 2165 if (memop & MO_BSWAP) { 2166 tcg_debug_assert(have_movbe); 2167 use_movbe = true; 2168 movop = OPC_MOVBE_MyGy; 2169 } 2170 2171 switch (memop & MO_SIZE) { 2172 case MO_8: 2173 /* This is handled with constraints on INDEX_op_qemu_st8_i32. */ 2174 tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || datalo < 4); 2175 tcg_out_modrm_sib_offset(s, OPC_MOVB_EvGv + P_REXB_R + seg, 2176 datalo, base, index, 0, ofs); 2177 break; 2178 case MO_16: 2179 tcg_out_modrm_sib_offset(s, movop + P_DATA16 + seg, datalo, 2180 base, index, 0, ofs); 2181 break; 2182 case MO_32: 2183 tcg_out_modrm_sib_offset(s, movop + seg, datalo, base, index, 0, ofs); 2184 break; 2185 case MO_64: 2186 if (TCG_TARGET_REG_BITS == 64) { 2187 tcg_out_modrm_sib_offset(s, movop + P_REXW + seg, datalo, 2188 base, index, 0, ofs); 2189 } else { 2190 if (use_movbe) { 2191 TCGReg t = datalo; 2192 datalo = datahi; 2193 datahi = t; 2194 } 2195 tcg_out_modrm_sib_offset(s, movop + seg, datalo, 2196 base, index, 0, ofs); 2197 tcg_out_modrm_sib_offset(s, movop + seg, datahi, 2198 base, index, 0, ofs + 4); 2199 } 2200 break; 2201 default: 2202 g_assert_not_reached(); 2203 } 2204} 2205 2206static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is64) 2207{ 2208 TCGReg datalo, datahi, addrlo; 2209 TCGReg addrhi __attribute__((unused)); 2210 TCGMemOpIdx oi; 2211 MemOp opc; 2212#if defined(CONFIG_SOFTMMU) 2213 int mem_index; 2214 tcg_insn_unit *label_ptr[2]; 2215#endif 2216 2217 datalo = *args++; 2218 datahi = (TCG_TARGET_REG_BITS == 32 && is64 ? *args++ : 0); 2219 addrlo = *args++; 2220 addrhi = (TARGET_LONG_BITS > TCG_TARGET_REG_BITS ? *args++ : 0); 2221 oi = *args++; 2222 opc = get_memop(oi); 2223 2224#if defined(CONFIG_SOFTMMU) 2225 mem_index = get_mmuidx(oi); 2226 2227 tcg_out_tlb_load(s, addrlo, addrhi, mem_index, opc, 2228 label_ptr, offsetof(CPUTLBEntry, addr_write)); 2229 2230 /* TLB Hit. */ 2231 tcg_out_qemu_st_direct(s, datalo, datahi, TCG_REG_L1, -1, 0, 0, opc); 2232 2233 /* Record the current context of a store into ldst label */ 2234 add_qemu_ldst_label(s, false, is64, oi, datalo, datahi, addrlo, addrhi, 2235 s->code_ptr, label_ptr); 2236#else 2237 tcg_out_qemu_st_direct(s, datalo, datahi, addrlo, x86_guest_base_index, 2238 x86_guest_base_offset, x86_guest_base_seg, opc); 2239#endif 2240} 2241 2242static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, 2243 const TCGArg *args, const int *const_args) 2244{ 2245 TCGArg a0, a1, a2; 2246 int c, const_a2, vexop, rexw = 0; 2247 2248#if TCG_TARGET_REG_BITS == 64 2249# define OP_32_64(x) \ 2250 case glue(glue(INDEX_op_, x), _i64): \ 2251 rexw = P_REXW; /* FALLTHRU */ \ 2252 case glue(glue(INDEX_op_, x), _i32) 2253#else 2254# define OP_32_64(x) \ 2255 case glue(glue(INDEX_op_, x), _i32) 2256#endif 2257 2258 /* Hoist the loads of the most common arguments. */ 2259 a0 = args[0]; 2260 a1 = args[1]; 2261 a2 = args[2]; 2262 const_a2 = const_args[2]; 2263 2264 switch (opc) { 2265 case INDEX_op_exit_tb: 2266 /* Reuse the zeroing that exists for goto_ptr. */ 2267 if (a0 == 0) { 2268 tcg_out_jmp(s, tcg_code_gen_epilogue); 2269 } else { 2270 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_EAX, a0); 2271 tcg_out_jmp(s, tb_ret_addr); 2272 } 2273 break; 2274 case INDEX_op_goto_tb: 2275 if (s->tb_jmp_insn_offset) { 2276 /* direct jump method */ 2277 int gap; 2278 /* jump displacement must be aligned for atomic patching; 2279 * see if we need to add extra nops before jump 2280 */ 2281 gap = QEMU_ALIGN_PTR_UP(s->code_ptr + 1, 4) - s->code_ptr; 2282 if (gap != 1) { 2283 tcg_out_nopn(s, gap - 1); 2284 } 2285 tcg_out8(s, OPC_JMP_long); /* jmp im */ 2286 s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s); 2287 tcg_out32(s, 0); 2288 } else { 2289 /* indirect jump method */ 2290 tcg_out_modrm_offset(s, OPC_GRP5, EXT5_JMPN_Ev, -1, 2291 (intptr_t)(s->tb_jmp_target_addr + a0)); 2292 } 2293 set_jmp_reset_offset(s, a0); 2294 break; 2295 case INDEX_op_goto_ptr: 2296 /* jmp to the given host address (could be epilogue) */ 2297 tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, a0); 2298 break; 2299 case INDEX_op_br: 2300 tcg_out_jxx(s, JCC_JMP, arg_label(a0), 0); 2301 break; 2302 OP_32_64(ld8u): 2303 /* Note that we can ignore REXW for the zero-extend to 64-bit. */ 2304 tcg_out_modrm_offset(s, OPC_MOVZBL, a0, a1, a2); 2305 break; 2306 OP_32_64(ld8s): 2307 tcg_out_modrm_offset(s, OPC_MOVSBL + rexw, a0, a1, a2); 2308 break; 2309 OP_32_64(ld16u): 2310 /* Note that we can ignore REXW for the zero-extend to 64-bit. */ 2311 tcg_out_modrm_offset(s, OPC_MOVZWL, a0, a1, a2); 2312 break; 2313 OP_32_64(ld16s): 2314 tcg_out_modrm_offset(s, OPC_MOVSWL + rexw, a0, a1, a2); 2315 break; 2316#if TCG_TARGET_REG_BITS == 64 2317 case INDEX_op_ld32u_i64: 2318#endif 2319 case INDEX_op_ld_i32: 2320 tcg_out_ld(s, TCG_TYPE_I32, a0, a1, a2); 2321 break; 2322 2323 OP_32_64(st8): 2324 if (const_args[0]) { 2325 tcg_out_modrm_offset(s, OPC_MOVB_EvIz, 0, a1, a2); 2326 tcg_out8(s, a0); 2327 } else { 2328 tcg_out_modrm_offset(s, OPC_MOVB_EvGv | P_REXB_R, a0, a1, a2); 2329 } 2330 break; 2331 OP_32_64(st16): 2332 if (const_args[0]) { 2333 tcg_out_modrm_offset(s, OPC_MOVL_EvIz | P_DATA16, 0, a1, a2); 2334 tcg_out16(s, a0); 2335 } else { 2336 tcg_out_modrm_offset(s, OPC_MOVL_EvGv | P_DATA16, a0, a1, a2); 2337 } 2338 break; 2339#if TCG_TARGET_REG_BITS == 64 2340 case INDEX_op_st32_i64: 2341#endif 2342 case INDEX_op_st_i32: 2343 if (const_args[0]) { 2344 tcg_out_modrm_offset(s, OPC_MOVL_EvIz, 0, a1, a2); 2345 tcg_out32(s, a0); 2346 } else { 2347 tcg_out_st(s, TCG_TYPE_I32, a0, a1, a2); 2348 } 2349 break; 2350 2351 OP_32_64(add): 2352 /* For 3-operand addition, use LEA. */ 2353 if (a0 != a1) { 2354 TCGArg c3 = 0; 2355 if (const_a2) { 2356 c3 = a2, a2 = -1; 2357 } else if (a0 == a2) { 2358 /* Watch out for dest = src + dest, since we've removed 2359 the matching constraint on the add. */ 2360 tgen_arithr(s, ARITH_ADD + rexw, a0, a1); 2361 break; 2362 } 2363 2364 tcg_out_modrm_sib_offset(s, OPC_LEA + rexw, a0, a1, a2, 0, c3); 2365 break; 2366 } 2367 c = ARITH_ADD; 2368 goto gen_arith; 2369 OP_32_64(sub): 2370 c = ARITH_SUB; 2371 goto gen_arith; 2372 OP_32_64(and): 2373 c = ARITH_AND; 2374 goto gen_arith; 2375 OP_32_64(or): 2376 c = ARITH_OR; 2377 goto gen_arith; 2378 OP_32_64(xor): 2379 c = ARITH_XOR; 2380 goto gen_arith; 2381 gen_arith: 2382 if (const_a2) { 2383 tgen_arithi(s, c + rexw, a0, a2, 0); 2384 } else { 2385 tgen_arithr(s, c + rexw, a0, a2); 2386 } 2387 break; 2388 2389 OP_32_64(andc): 2390 if (const_a2) { 2391 tcg_out_mov(s, rexw ? TCG_TYPE_I64 : TCG_TYPE_I32, a0, a1); 2392 tgen_arithi(s, ARITH_AND + rexw, a0, ~a2, 0); 2393 } else { 2394 tcg_out_vex_modrm(s, OPC_ANDN + rexw, a0, a2, a1); 2395 } 2396 break; 2397 2398 OP_32_64(mul): 2399 if (const_a2) { 2400 int32_t val; 2401 val = a2; 2402 if (val == (int8_t)val) { 2403 tcg_out_modrm(s, OPC_IMUL_GvEvIb + rexw, a0, a0); 2404 tcg_out8(s, val); 2405 } else { 2406 tcg_out_modrm(s, OPC_IMUL_GvEvIz + rexw, a0, a0); 2407 tcg_out32(s, val); 2408 } 2409 } else { 2410 tcg_out_modrm(s, OPC_IMUL_GvEv + rexw, a0, a2); 2411 } 2412 break; 2413 2414 OP_32_64(div2): 2415 tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_IDIV, args[4]); 2416 break; 2417 OP_32_64(divu2): 2418 tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_DIV, args[4]); 2419 break; 2420 2421 OP_32_64(shl): 2422 /* For small constant 3-operand shift, use LEA. */ 2423 if (const_a2 && a0 != a1 && (a2 - 1) < 3) { 2424 if (a2 - 1 == 0) { 2425 /* shl $1,a1,a0 -> lea (a1,a1),a0 */ 2426 tcg_out_modrm_sib_offset(s, OPC_LEA + rexw, a0, a1, a1, 0, 0); 2427 } else { 2428 /* shl $n,a1,a0 -> lea 0(,a1,n),a0 */ 2429 tcg_out_modrm_sib_offset(s, OPC_LEA + rexw, a0, -1, a1, a2, 0); 2430 } 2431 break; 2432 } 2433 c = SHIFT_SHL; 2434 vexop = OPC_SHLX; 2435 goto gen_shift_maybe_vex; 2436 OP_32_64(shr): 2437 c = SHIFT_SHR; 2438 vexop = OPC_SHRX; 2439 goto gen_shift_maybe_vex; 2440 OP_32_64(sar): 2441 c = SHIFT_SAR; 2442 vexop = OPC_SARX; 2443 goto gen_shift_maybe_vex; 2444 OP_32_64(rotl): 2445 c = SHIFT_ROL; 2446 goto gen_shift; 2447 OP_32_64(rotr): 2448 c = SHIFT_ROR; 2449 goto gen_shift; 2450 gen_shift_maybe_vex: 2451 if (have_bmi2) { 2452 if (!const_a2) { 2453 tcg_out_vex_modrm(s, vexop + rexw, a0, a2, a1); 2454 break; 2455 } 2456 tcg_out_mov(s, rexw ? TCG_TYPE_I64 : TCG_TYPE_I32, a0, a1); 2457 } 2458 /* FALLTHRU */ 2459 gen_shift: 2460 if (const_a2) { 2461 tcg_out_shifti(s, c + rexw, a0, a2); 2462 } else { 2463 tcg_out_modrm(s, OPC_SHIFT_cl + rexw, c, a0); 2464 } 2465 break; 2466 2467 OP_32_64(ctz): 2468 tcg_out_ctz(s, rexw, args[0], args[1], args[2], const_args[2]); 2469 break; 2470 OP_32_64(clz): 2471 tcg_out_clz(s, rexw, args[0], args[1], args[2], const_args[2]); 2472 break; 2473 OP_32_64(ctpop): 2474 tcg_out_modrm(s, OPC_POPCNT + rexw, a0, a1); 2475 break; 2476 2477 case INDEX_op_brcond_i32: 2478 tcg_out_brcond32(s, a2, a0, a1, const_args[1], arg_label(args[3]), 0); 2479 break; 2480 case INDEX_op_setcond_i32: 2481 tcg_out_setcond32(s, args[3], a0, a1, a2, const_a2); 2482 break; 2483 case INDEX_op_movcond_i32: 2484 tcg_out_movcond32(s, args[5], a0, a1, a2, const_a2, args[3]); 2485 break; 2486 2487 OP_32_64(bswap16): 2488 tcg_out_rolw_8(s, a0); 2489 break; 2490 OP_32_64(bswap32): 2491 tcg_out_bswap32(s, a0); 2492 break; 2493 2494 OP_32_64(neg): 2495 tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_NEG, a0); 2496 break; 2497 OP_32_64(not): 2498 tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_NOT, a0); 2499 break; 2500 2501 OP_32_64(ext8s): 2502 tcg_out_ext8s(s, a0, a1, rexw); 2503 break; 2504 OP_32_64(ext16s): 2505 tcg_out_ext16s(s, a0, a1, rexw); 2506 break; 2507 OP_32_64(ext8u): 2508 tcg_out_ext8u(s, a0, a1); 2509 break; 2510 OP_32_64(ext16u): 2511 tcg_out_ext16u(s, a0, a1); 2512 break; 2513 2514 case INDEX_op_qemu_ld_i32: 2515 tcg_out_qemu_ld(s, args, 0); 2516 break; 2517 case INDEX_op_qemu_ld_i64: 2518 tcg_out_qemu_ld(s, args, 1); 2519 break; 2520 case INDEX_op_qemu_st_i32: 2521 case INDEX_op_qemu_st8_i32: 2522 tcg_out_qemu_st(s, args, 0); 2523 break; 2524 case INDEX_op_qemu_st_i64: 2525 tcg_out_qemu_st(s, args, 1); 2526 break; 2527 2528 OP_32_64(mulu2): 2529 tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_MUL, args[3]); 2530 break; 2531 OP_32_64(muls2): 2532 tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_IMUL, args[3]); 2533 break; 2534 OP_32_64(add2): 2535 if (const_args[4]) { 2536 tgen_arithi(s, ARITH_ADD + rexw, a0, args[4], 1); 2537 } else { 2538 tgen_arithr(s, ARITH_ADD + rexw, a0, args[4]); 2539 } 2540 if (const_args[5]) { 2541 tgen_arithi(s, ARITH_ADC + rexw, a1, args[5], 1); 2542 } else { 2543 tgen_arithr(s, ARITH_ADC + rexw, a1, args[5]); 2544 } 2545 break; 2546 OP_32_64(sub2): 2547 if (const_args[4]) { 2548 tgen_arithi(s, ARITH_SUB + rexw, a0, args[4], 1); 2549 } else { 2550 tgen_arithr(s, ARITH_SUB + rexw, a0, args[4]); 2551 } 2552 if (const_args[5]) { 2553 tgen_arithi(s, ARITH_SBB + rexw, a1, args[5], 1); 2554 } else { 2555 tgen_arithr(s, ARITH_SBB + rexw, a1, args[5]); 2556 } 2557 break; 2558 2559#if TCG_TARGET_REG_BITS == 32 2560 case INDEX_op_brcond2_i32: 2561 tcg_out_brcond2(s, args, const_args, 0); 2562 break; 2563 case INDEX_op_setcond2_i32: 2564 tcg_out_setcond2(s, args, const_args); 2565 break; 2566#else /* TCG_TARGET_REG_BITS == 64 */ 2567 case INDEX_op_ld32s_i64: 2568 tcg_out_modrm_offset(s, OPC_MOVSLQ, a0, a1, a2); 2569 break; 2570 case INDEX_op_ld_i64: 2571 tcg_out_ld(s, TCG_TYPE_I64, a0, a1, a2); 2572 break; 2573 case INDEX_op_st_i64: 2574 if (const_args[0]) { 2575 tcg_out_modrm_offset(s, OPC_MOVL_EvIz | P_REXW, 0, a1, a2); 2576 tcg_out32(s, a0); 2577 } else { 2578 tcg_out_st(s, TCG_TYPE_I64, a0, a1, a2); 2579 } 2580 break; 2581 2582 case INDEX_op_brcond_i64: 2583 tcg_out_brcond64(s, a2, a0, a1, const_args[1], arg_label(args[3]), 0); 2584 break; 2585 case INDEX_op_setcond_i64: 2586 tcg_out_setcond64(s, args[3], a0, a1, a2, const_a2); 2587 break; 2588 case INDEX_op_movcond_i64: 2589 tcg_out_movcond64(s, args[5], a0, a1, a2, const_a2, args[3]); 2590 break; 2591 2592 case INDEX_op_bswap64_i64: 2593 tcg_out_bswap64(s, a0); 2594 break; 2595 case INDEX_op_extu_i32_i64: 2596 case INDEX_op_ext32u_i64: 2597 case INDEX_op_extrl_i64_i32: 2598 tcg_out_ext32u(s, a0, a1); 2599 break; 2600 case INDEX_op_ext_i32_i64: 2601 case INDEX_op_ext32s_i64: 2602 tcg_out_ext32s(s, a0, a1); 2603 break; 2604 case INDEX_op_extrh_i64_i32: 2605 tcg_out_shifti(s, SHIFT_SHR + P_REXW, a0, 32); 2606 break; 2607#endif 2608 2609 OP_32_64(deposit): 2610 if (args[3] == 0 && args[4] == 8) { 2611 /* load bits 0..7 */ 2612 tcg_out_modrm(s, OPC_MOVB_EvGv | P_REXB_R | P_REXB_RM, a2, a0); 2613 } else if (args[3] == 8 && args[4] == 8) { 2614 /* load bits 8..15 */ 2615 tcg_out_modrm(s, OPC_MOVB_EvGv, a2, a0 + 4); 2616 } else if (args[3] == 0 && args[4] == 16) { 2617 /* load bits 0..15 */ 2618 tcg_out_modrm(s, OPC_MOVL_EvGv | P_DATA16, a2, a0); 2619 } else { 2620 tcg_abort(); 2621 } 2622 break; 2623 2624 case INDEX_op_extract_i64: 2625 if (a2 + args[3] == 32) { 2626 /* This is a 32-bit zero-extending right shift. */ 2627 tcg_out_mov(s, TCG_TYPE_I32, a0, a1); 2628 tcg_out_shifti(s, SHIFT_SHR, a0, a2); 2629 break; 2630 } 2631 /* FALLTHRU */ 2632 case INDEX_op_extract_i32: 2633 /* On the off-chance that we can use the high-byte registers. 2634 Otherwise we emit the same ext16 + shift pattern that we 2635 would have gotten from the normal tcg-op.c expansion. */ 2636 tcg_debug_assert(a2 == 8 && args[3] == 8); 2637 if (a1 < 4 && a0 < 8) { 2638 tcg_out_modrm(s, OPC_MOVZBL, a0, a1 + 4); 2639 } else { 2640 tcg_out_ext16u(s, a0, a1); 2641 tcg_out_shifti(s, SHIFT_SHR, a0, 8); 2642 } 2643 break; 2644 2645 case INDEX_op_sextract_i32: 2646 /* We don't implement sextract_i64, as we cannot sign-extend to 2647 64-bits without using the REX prefix that explicitly excludes 2648 access to the high-byte registers. */ 2649 tcg_debug_assert(a2 == 8 && args[3] == 8); 2650 if (a1 < 4 && a0 < 8) { 2651 tcg_out_modrm(s, OPC_MOVSBL, a0, a1 + 4); 2652 } else { 2653 tcg_out_ext16s(s, a0, a1, 0); 2654 tcg_out_shifti(s, SHIFT_SAR, a0, 8); 2655 } 2656 break; 2657 2658 OP_32_64(extract2): 2659 /* Note that SHRD outputs to the r/m operand. */ 2660 tcg_out_modrm(s, OPC_SHRD_Ib + rexw, a2, a0); 2661 tcg_out8(s, args[3]); 2662 break; 2663 2664 case INDEX_op_mb: 2665 tcg_out_mb(s, a0); 2666 break; 2667 case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */ 2668 case INDEX_op_mov_i64: 2669 case INDEX_op_call: /* Always emitted via tcg_out_call. */ 2670 default: 2671 tcg_abort(); 2672 } 2673 2674#undef OP_32_64 2675} 2676 2677static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc, 2678 unsigned vecl, unsigned vece, 2679 const TCGArg *args, const int *const_args) 2680{ 2681 static int const add_insn[4] = { 2682 OPC_PADDB, OPC_PADDW, OPC_PADDD, OPC_PADDQ 2683 }; 2684 static int const ssadd_insn[4] = { 2685 OPC_PADDSB, OPC_PADDSW, OPC_UD2, OPC_UD2 2686 }; 2687 static int const usadd_insn[4] = { 2688 OPC_PADDUB, OPC_PADDUW, OPC_UD2, OPC_UD2 2689 }; 2690 static int const sub_insn[4] = { 2691 OPC_PSUBB, OPC_PSUBW, OPC_PSUBD, OPC_PSUBQ 2692 }; 2693 static int const sssub_insn[4] = { 2694 OPC_PSUBSB, OPC_PSUBSW, OPC_UD2, OPC_UD2 2695 }; 2696 static int const ussub_insn[4] = { 2697 OPC_PSUBUB, OPC_PSUBUW, OPC_UD2, OPC_UD2 2698 }; 2699 static int const mul_insn[4] = { 2700 OPC_UD2, OPC_PMULLW, OPC_PMULLD, OPC_UD2 2701 }; 2702 static int const shift_imm_insn[4] = { 2703 OPC_UD2, OPC_PSHIFTW_Ib, OPC_PSHIFTD_Ib, OPC_PSHIFTQ_Ib 2704 }; 2705 static int const cmpeq_insn[4] = { 2706 OPC_PCMPEQB, OPC_PCMPEQW, OPC_PCMPEQD, OPC_PCMPEQQ 2707 }; 2708 static int const cmpgt_insn[4] = { 2709 OPC_PCMPGTB, OPC_PCMPGTW, OPC_PCMPGTD, OPC_PCMPGTQ 2710 }; 2711 static int const punpckl_insn[4] = { 2712 OPC_PUNPCKLBW, OPC_PUNPCKLWD, OPC_PUNPCKLDQ, OPC_PUNPCKLQDQ 2713 }; 2714 static int const punpckh_insn[4] = { 2715 OPC_PUNPCKHBW, OPC_PUNPCKHWD, OPC_PUNPCKHDQ, OPC_PUNPCKHQDQ 2716 }; 2717 static int const packss_insn[4] = { 2718 OPC_PACKSSWB, OPC_PACKSSDW, OPC_UD2, OPC_UD2 2719 }; 2720 static int const packus_insn[4] = { 2721 OPC_PACKUSWB, OPC_PACKUSDW, OPC_UD2, OPC_UD2 2722 }; 2723 static int const smin_insn[4] = { 2724 OPC_PMINSB, OPC_PMINSW, OPC_PMINSD, OPC_UD2 2725 }; 2726 static int const smax_insn[4] = { 2727 OPC_PMAXSB, OPC_PMAXSW, OPC_PMAXSD, OPC_UD2 2728 }; 2729 static int const umin_insn[4] = { 2730 OPC_PMINUB, OPC_PMINUW, OPC_PMINUD, OPC_UD2 2731 }; 2732 static int const umax_insn[4] = { 2733 OPC_PMAXUB, OPC_PMAXUW, OPC_PMAXUD, OPC_UD2 2734 }; 2735 static int const shlv_insn[4] = { 2736 /* TODO: AVX512 adds support for MO_16. */ 2737 OPC_UD2, OPC_UD2, OPC_VPSLLVD, OPC_VPSLLVQ 2738 }; 2739 static int const shrv_insn[4] = { 2740 /* TODO: AVX512 adds support for MO_16. */ 2741 OPC_UD2, OPC_UD2, OPC_VPSRLVD, OPC_VPSRLVQ 2742 }; 2743 static int const sarv_insn[4] = { 2744 /* TODO: AVX512 adds support for MO_16, MO_64. */ 2745 OPC_UD2, OPC_UD2, OPC_VPSRAVD, OPC_UD2 2746 }; 2747 static int const shls_insn[4] = { 2748 OPC_UD2, OPC_PSLLW, OPC_PSLLD, OPC_PSLLQ 2749 }; 2750 static int const shrs_insn[4] = { 2751 OPC_UD2, OPC_PSRLW, OPC_PSRLD, OPC_PSRLQ 2752 }; 2753 static int const sars_insn[4] = { 2754 OPC_UD2, OPC_PSRAW, OPC_PSRAD, OPC_UD2 2755 }; 2756 static int const abs_insn[4] = { 2757 /* TODO: AVX512 adds support for MO_64. */ 2758 OPC_PABSB, OPC_PABSW, OPC_PABSD, OPC_UD2 2759 }; 2760 2761 TCGType type = vecl + TCG_TYPE_V64; 2762 int insn, sub; 2763 TCGArg a0, a1, a2; 2764 2765 a0 = args[0]; 2766 a1 = args[1]; 2767 a2 = args[2]; 2768 2769 switch (opc) { 2770 case INDEX_op_add_vec: 2771 insn = add_insn[vece]; 2772 goto gen_simd; 2773 case INDEX_op_ssadd_vec: 2774 insn = ssadd_insn[vece]; 2775 goto gen_simd; 2776 case INDEX_op_usadd_vec: 2777 insn = usadd_insn[vece]; 2778 goto gen_simd; 2779 case INDEX_op_sub_vec: 2780 insn = sub_insn[vece]; 2781 goto gen_simd; 2782 case INDEX_op_sssub_vec: 2783 insn = sssub_insn[vece]; 2784 goto gen_simd; 2785 case INDEX_op_ussub_vec: 2786 insn = ussub_insn[vece]; 2787 goto gen_simd; 2788 case INDEX_op_mul_vec: 2789 insn = mul_insn[vece]; 2790 goto gen_simd; 2791 case INDEX_op_and_vec: 2792 insn = OPC_PAND; 2793 goto gen_simd; 2794 case INDEX_op_or_vec: 2795 insn = OPC_POR; 2796 goto gen_simd; 2797 case INDEX_op_xor_vec: 2798 insn = OPC_PXOR; 2799 goto gen_simd; 2800 case INDEX_op_smin_vec: 2801 insn = smin_insn[vece]; 2802 goto gen_simd; 2803 case INDEX_op_umin_vec: 2804 insn = umin_insn[vece]; 2805 goto gen_simd; 2806 case INDEX_op_smax_vec: 2807 insn = smax_insn[vece]; 2808 goto gen_simd; 2809 case INDEX_op_umax_vec: 2810 insn = umax_insn[vece]; 2811 goto gen_simd; 2812 case INDEX_op_shlv_vec: 2813 insn = shlv_insn[vece]; 2814 goto gen_simd; 2815 case INDEX_op_shrv_vec: 2816 insn = shrv_insn[vece]; 2817 goto gen_simd; 2818 case INDEX_op_sarv_vec: 2819 insn = sarv_insn[vece]; 2820 goto gen_simd; 2821 case INDEX_op_shls_vec: 2822 insn = shls_insn[vece]; 2823 goto gen_simd; 2824 case INDEX_op_shrs_vec: 2825 insn = shrs_insn[vece]; 2826 goto gen_simd; 2827 case INDEX_op_sars_vec: 2828 insn = sars_insn[vece]; 2829 goto gen_simd; 2830 case INDEX_op_x86_punpckl_vec: 2831 insn = punpckl_insn[vece]; 2832 goto gen_simd; 2833 case INDEX_op_x86_punpckh_vec: 2834 insn = punpckh_insn[vece]; 2835 goto gen_simd; 2836 case INDEX_op_x86_packss_vec: 2837 insn = packss_insn[vece]; 2838 goto gen_simd; 2839 case INDEX_op_x86_packus_vec: 2840 insn = packus_insn[vece]; 2841 goto gen_simd; 2842#if TCG_TARGET_REG_BITS == 32 2843 case INDEX_op_dup2_vec: 2844 /* First merge the two 32-bit inputs to a single 64-bit element. */ 2845 tcg_out_vex_modrm(s, OPC_PUNPCKLDQ, a0, a1, a2); 2846 /* Then replicate the 64-bit elements across the rest of the vector. */ 2847 if (type != TCG_TYPE_V64) { 2848 tcg_out_dup_vec(s, type, MO_64, a0, a0); 2849 } 2850 break; 2851#endif 2852 case INDEX_op_abs_vec: 2853 insn = abs_insn[vece]; 2854 a2 = a1; 2855 a1 = 0; 2856 goto gen_simd; 2857 gen_simd: 2858 tcg_debug_assert(insn != OPC_UD2); 2859 if (type == TCG_TYPE_V256) { 2860 insn |= P_VEXL; 2861 } 2862 tcg_out_vex_modrm(s, insn, a0, a1, a2); 2863 break; 2864 2865 case INDEX_op_cmp_vec: 2866 sub = args[3]; 2867 if (sub == TCG_COND_EQ) { 2868 insn = cmpeq_insn[vece]; 2869 } else if (sub == TCG_COND_GT) { 2870 insn = cmpgt_insn[vece]; 2871 } else { 2872 g_assert_not_reached(); 2873 } 2874 goto gen_simd; 2875 2876 case INDEX_op_andc_vec: 2877 insn = OPC_PANDN; 2878 if (type == TCG_TYPE_V256) { 2879 insn |= P_VEXL; 2880 } 2881 tcg_out_vex_modrm(s, insn, a0, a2, a1); 2882 break; 2883 2884 case INDEX_op_shli_vec: 2885 sub = 6; 2886 goto gen_shift; 2887 case INDEX_op_shri_vec: 2888 sub = 2; 2889 goto gen_shift; 2890 case INDEX_op_sari_vec: 2891 tcg_debug_assert(vece != MO_64); 2892 sub = 4; 2893 gen_shift: 2894 tcg_debug_assert(vece != MO_8); 2895 insn = shift_imm_insn[vece]; 2896 if (type == TCG_TYPE_V256) { 2897 insn |= P_VEXL; 2898 } 2899 tcg_out_vex_modrm(s, insn, sub, a0, a1); 2900 tcg_out8(s, a2); 2901 break; 2902 2903 case INDEX_op_ld_vec: 2904 tcg_out_ld(s, type, a0, a1, a2); 2905 break; 2906 case INDEX_op_st_vec: 2907 tcg_out_st(s, type, a0, a1, a2); 2908 break; 2909 case INDEX_op_dupm_vec: 2910 tcg_out_dupm_vec(s, type, vece, a0, a1, a2); 2911 break; 2912 2913 case INDEX_op_x86_shufps_vec: 2914 insn = OPC_SHUFPS; 2915 sub = args[3]; 2916 goto gen_simd_imm8; 2917 case INDEX_op_x86_blend_vec: 2918 if (vece == MO_16) { 2919 insn = OPC_PBLENDW; 2920 } else if (vece == MO_32) { 2921 insn = (have_avx2 ? OPC_VPBLENDD : OPC_BLENDPS); 2922 } else { 2923 g_assert_not_reached(); 2924 } 2925 sub = args[3]; 2926 goto gen_simd_imm8; 2927 case INDEX_op_x86_vperm2i128_vec: 2928 insn = OPC_VPERM2I128; 2929 sub = args[3]; 2930 goto gen_simd_imm8; 2931 gen_simd_imm8: 2932 if (type == TCG_TYPE_V256) { 2933 insn |= P_VEXL; 2934 } 2935 tcg_out_vex_modrm(s, insn, a0, a1, a2); 2936 tcg_out8(s, sub); 2937 break; 2938 2939 case INDEX_op_x86_vpblendvb_vec: 2940 insn = OPC_VPBLENDVB; 2941 if (type == TCG_TYPE_V256) { 2942 insn |= P_VEXL; 2943 } 2944 tcg_out_vex_modrm(s, insn, a0, a1, a2); 2945 tcg_out8(s, args[3] << 4); 2946 break; 2947 2948 case INDEX_op_x86_psrldq_vec: 2949 tcg_out_vex_modrm(s, OPC_GRP14, 3, a0, a1); 2950 tcg_out8(s, a2); 2951 break; 2952 2953 case INDEX_op_mov_vec: /* Always emitted via tcg_out_mov. */ 2954 case INDEX_op_dup_vec: /* Always emitted via tcg_out_dup_vec. */ 2955 default: 2956 g_assert_not_reached(); 2957 } 2958} 2959 2960static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op) 2961{ 2962 static const TCGTargetOpDef r = { .args_ct_str = { "r" } }; 2963 static const TCGTargetOpDef ri_r = { .args_ct_str = { "ri", "r" } }; 2964 static const TCGTargetOpDef re_r = { .args_ct_str = { "re", "r" } }; 2965 static const TCGTargetOpDef qi_r = { .args_ct_str = { "qi", "r" } }; 2966 static const TCGTargetOpDef r_r = { .args_ct_str = { "r", "r" } }; 2967 static const TCGTargetOpDef r_q = { .args_ct_str = { "r", "q" } }; 2968 static const TCGTargetOpDef r_re = { .args_ct_str = { "r", "re" } }; 2969 static const TCGTargetOpDef r_0 = { .args_ct_str = { "r", "0" } }; 2970 static const TCGTargetOpDef r_r_ri = { .args_ct_str = { "r", "r", "ri" } }; 2971 static const TCGTargetOpDef r_r_re = { .args_ct_str = { "r", "r", "re" } }; 2972 static const TCGTargetOpDef r_0_r = { .args_ct_str = { "r", "0", "r" } }; 2973 static const TCGTargetOpDef r_0_re = { .args_ct_str = { "r", "0", "re" } }; 2974 static const TCGTargetOpDef r_0_ci = { .args_ct_str = { "r", "0", "ci" } }; 2975 static const TCGTargetOpDef r_L = { .args_ct_str = { "r", "L" } }; 2976 static const TCGTargetOpDef L_L = { .args_ct_str = { "L", "L" } }; 2977 static const TCGTargetOpDef s_L = { .args_ct_str = { "s", "L" } }; 2978 static const TCGTargetOpDef r_L_L = { .args_ct_str = { "r", "L", "L" } }; 2979 static const TCGTargetOpDef r_r_L = { .args_ct_str = { "r", "r", "L" } }; 2980 static const TCGTargetOpDef L_L_L = { .args_ct_str = { "L", "L", "L" } }; 2981 static const TCGTargetOpDef s_L_L = { .args_ct_str = { "s", "L", "L" } }; 2982 static const TCGTargetOpDef r_r_L_L 2983 = { .args_ct_str = { "r", "r", "L", "L" } }; 2984 static const TCGTargetOpDef L_L_L_L 2985 = { .args_ct_str = { "L", "L", "L", "L" } }; 2986 static const TCGTargetOpDef x_x = { .args_ct_str = { "x", "x" } }; 2987 static const TCGTargetOpDef x_x_x = { .args_ct_str = { "x", "x", "x" } }; 2988 static const TCGTargetOpDef x_x_x_x 2989 = { .args_ct_str = { "x", "x", "x", "x" } }; 2990 static const TCGTargetOpDef x_r = { .args_ct_str = { "x", "r" } }; 2991 2992 switch (op) { 2993 case INDEX_op_goto_ptr: 2994 return &r; 2995 2996 case INDEX_op_ld8u_i32: 2997 case INDEX_op_ld8u_i64: 2998 case INDEX_op_ld8s_i32: 2999 case INDEX_op_ld8s_i64: 3000 case INDEX_op_ld16u_i32: 3001 case INDEX_op_ld16u_i64: 3002 case INDEX_op_ld16s_i32: 3003 case INDEX_op_ld16s_i64: 3004 case INDEX_op_ld_i32: 3005 case INDEX_op_ld32u_i64: 3006 case INDEX_op_ld32s_i64: 3007 case INDEX_op_ld_i64: 3008 return &r_r; 3009 3010 case INDEX_op_st8_i32: 3011 case INDEX_op_st8_i64: 3012 return &qi_r; 3013 case INDEX_op_st16_i32: 3014 case INDEX_op_st16_i64: 3015 case INDEX_op_st_i32: 3016 case INDEX_op_st32_i64: 3017 return &ri_r; 3018 case INDEX_op_st_i64: 3019 return &re_r; 3020 3021 case INDEX_op_add_i32: 3022 case INDEX_op_add_i64: 3023 return &r_r_re; 3024 case INDEX_op_sub_i32: 3025 case INDEX_op_sub_i64: 3026 case INDEX_op_mul_i32: 3027 case INDEX_op_mul_i64: 3028 case INDEX_op_or_i32: 3029 case INDEX_op_or_i64: 3030 case INDEX_op_xor_i32: 3031 case INDEX_op_xor_i64: 3032 return &r_0_re; 3033 3034 case INDEX_op_and_i32: 3035 case INDEX_op_and_i64: 3036 { 3037 static const TCGTargetOpDef and 3038 = { .args_ct_str = { "r", "0", "reZ" } }; 3039 return ∧ 3040 } 3041 break; 3042 case INDEX_op_andc_i32: 3043 case INDEX_op_andc_i64: 3044 { 3045 static const TCGTargetOpDef andc 3046 = { .args_ct_str = { "r", "r", "rI" } }; 3047 return &andc; 3048 } 3049 break; 3050 3051 case INDEX_op_shl_i32: 3052 case INDEX_op_shl_i64: 3053 case INDEX_op_shr_i32: 3054 case INDEX_op_shr_i64: 3055 case INDEX_op_sar_i32: 3056 case INDEX_op_sar_i64: 3057 return have_bmi2 ? &r_r_ri : &r_0_ci; 3058 case INDEX_op_rotl_i32: 3059 case INDEX_op_rotl_i64: 3060 case INDEX_op_rotr_i32: 3061 case INDEX_op_rotr_i64: 3062 return &r_0_ci; 3063 3064 case INDEX_op_brcond_i32: 3065 case INDEX_op_brcond_i64: 3066 return &r_re; 3067 3068 case INDEX_op_bswap16_i32: 3069 case INDEX_op_bswap16_i64: 3070 case INDEX_op_bswap32_i32: 3071 case INDEX_op_bswap32_i64: 3072 case INDEX_op_bswap64_i64: 3073 case INDEX_op_neg_i32: 3074 case INDEX_op_neg_i64: 3075 case INDEX_op_not_i32: 3076 case INDEX_op_not_i64: 3077 case INDEX_op_extrh_i64_i32: 3078 return &r_0; 3079 3080 case INDEX_op_ext8s_i32: 3081 case INDEX_op_ext8s_i64: 3082 case INDEX_op_ext8u_i32: 3083 case INDEX_op_ext8u_i64: 3084 return &r_q; 3085 case INDEX_op_ext16s_i32: 3086 case INDEX_op_ext16s_i64: 3087 case INDEX_op_ext16u_i32: 3088 case INDEX_op_ext16u_i64: 3089 case INDEX_op_ext32s_i64: 3090 case INDEX_op_ext32u_i64: 3091 case INDEX_op_ext_i32_i64: 3092 case INDEX_op_extu_i32_i64: 3093 case INDEX_op_extrl_i64_i32: 3094 case INDEX_op_extract_i32: 3095 case INDEX_op_extract_i64: 3096 case INDEX_op_sextract_i32: 3097 case INDEX_op_ctpop_i32: 3098 case INDEX_op_ctpop_i64: 3099 return &r_r; 3100 case INDEX_op_extract2_i32: 3101 case INDEX_op_extract2_i64: 3102 return &r_0_r; 3103 3104 case INDEX_op_deposit_i32: 3105 case INDEX_op_deposit_i64: 3106 { 3107 static const TCGTargetOpDef dep 3108 = { .args_ct_str = { "Q", "0", "Q" } }; 3109 return &dep; 3110 } 3111 case INDEX_op_setcond_i32: 3112 case INDEX_op_setcond_i64: 3113 { 3114 static const TCGTargetOpDef setc 3115 = { .args_ct_str = { "q", "r", "re" } }; 3116 return &setc; 3117 } 3118 case INDEX_op_movcond_i32: 3119 case INDEX_op_movcond_i64: 3120 { 3121 static const TCGTargetOpDef movc 3122 = { .args_ct_str = { "r", "r", "re", "r", "0" } }; 3123 return &movc; 3124 } 3125 case INDEX_op_div2_i32: 3126 case INDEX_op_div2_i64: 3127 case INDEX_op_divu2_i32: 3128 case INDEX_op_divu2_i64: 3129 { 3130 static const TCGTargetOpDef div2 3131 = { .args_ct_str = { "a", "d", "0", "1", "r" } }; 3132 return &div2; 3133 } 3134 case INDEX_op_mulu2_i32: 3135 case INDEX_op_mulu2_i64: 3136 case INDEX_op_muls2_i32: 3137 case INDEX_op_muls2_i64: 3138 { 3139 static const TCGTargetOpDef mul2 3140 = { .args_ct_str = { "a", "d", "a", "r" } }; 3141 return &mul2; 3142 } 3143 case INDEX_op_add2_i32: 3144 case INDEX_op_add2_i64: 3145 case INDEX_op_sub2_i32: 3146 case INDEX_op_sub2_i64: 3147 { 3148 static const TCGTargetOpDef arith2 3149 = { .args_ct_str = { "r", "r", "0", "1", "re", "re" } }; 3150 return &arith2; 3151 } 3152 case INDEX_op_ctz_i32: 3153 case INDEX_op_ctz_i64: 3154 { 3155 static const TCGTargetOpDef ctz[2] = { 3156 { .args_ct_str = { "&r", "r", "r" } }, 3157 { .args_ct_str = { "&r", "r", "rW" } }, 3158 }; 3159 return &ctz[have_bmi1]; 3160 } 3161 case INDEX_op_clz_i32: 3162 case INDEX_op_clz_i64: 3163 { 3164 static const TCGTargetOpDef clz[2] = { 3165 { .args_ct_str = { "&r", "r", "r" } }, 3166 { .args_ct_str = { "&r", "r", "rW" } }, 3167 }; 3168 return &clz[have_lzcnt]; 3169 } 3170 3171 case INDEX_op_qemu_ld_i32: 3172 return TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? &r_L : &r_L_L; 3173 case INDEX_op_qemu_st_i32: 3174 return TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? &L_L : &L_L_L; 3175 case INDEX_op_qemu_st8_i32: 3176 return TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? &s_L : &s_L_L; 3177 case INDEX_op_qemu_ld_i64: 3178 return (TCG_TARGET_REG_BITS == 64 ? &r_L 3179 : TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? &r_r_L 3180 : &r_r_L_L); 3181 case INDEX_op_qemu_st_i64: 3182 return (TCG_TARGET_REG_BITS == 64 ? &L_L 3183 : TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? &L_L_L 3184 : &L_L_L_L); 3185 3186 case INDEX_op_brcond2_i32: 3187 { 3188 static const TCGTargetOpDef b2 3189 = { .args_ct_str = { "r", "r", "ri", "ri" } }; 3190 return &b2; 3191 } 3192 case INDEX_op_setcond2_i32: 3193 { 3194 static const TCGTargetOpDef s2 3195 = { .args_ct_str = { "r", "r", "r", "ri", "ri" } }; 3196 return &s2; 3197 } 3198 3199 case INDEX_op_ld_vec: 3200 case INDEX_op_st_vec: 3201 case INDEX_op_dupm_vec: 3202 return &x_r; 3203 3204 case INDEX_op_add_vec: 3205 case INDEX_op_sub_vec: 3206 case INDEX_op_mul_vec: 3207 case INDEX_op_and_vec: 3208 case INDEX_op_or_vec: 3209 case INDEX_op_xor_vec: 3210 case INDEX_op_andc_vec: 3211 case INDEX_op_ssadd_vec: 3212 case INDEX_op_usadd_vec: 3213 case INDEX_op_sssub_vec: 3214 case INDEX_op_ussub_vec: 3215 case INDEX_op_smin_vec: 3216 case INDEX_op_umin_vec: 3217 case INDEX_op_smax_vec: 3218 case INDEX_op_umax_vec: 3219 case INDEX_op_shlv_vec: 3220 case INDEX_op_shrv_vec: 3221 case INDEX_op_sarv_vec: 3222 case INDEX_op_shls_vec: 3223 case INDEX_op_shrs_vec: 3224 case INDEX_op_sars_vec: 3225 case INDEX_op_rotls_vec: 3226 case INDEX_op_cmp_vec: 3227 case INDEX_op_x86_shufps_vec: 3228 case INDEX_op_x86_blend_vec: 3229 case INDEX_op_x86_packss_vec: 3230 case INDEX_op_x86_packus_vec: 3231 case INDEX_op_x86_vperm2i128_vec: 3232 case INDEX_op_x86_punpckl_vec: 3233 case INDEX_op_x86_punpckh_vec: 3234#if TCG_TARGET_REG_BITS == 32 3235 case INDEX_op_dup2_vec: 3236#endif 3237 return &x_x_x; 3238 case INDEX_op_abs_vec: 3239 case INDEX_op_dup_vec: 3240 case INDEX_op_shli_vec: 3241 case INDEX_op_shri_vec: 3242 case INDEX_op_sari_vec: 3243 case INDEX_op_x86_psrldq_vec: 3244 return &x_x; 3245 case INDEX_op_x86_vpblendvb_vec: 3246 return &x_x_x_x; 3247 3248 default: 3249 break; 3250 } 3251 return NULL; 3252} 3253 3254int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, unsigned vece) 3255{ 3256 switch (opc) { 3257 case INDEX_op_add_vec: 3258 case INDEX_op_sub_vec: 3259 case INDEX_op_and_vec: 3260 case INDEX_op_or_vec: 3261 case INDEX_op_xor_vec: 3262 case INDEX_op_andc_vec: 3263 return 1; 3264 case INDEX_op_rotli_vec: 3265 case INDEX_op_cmp_vec: 3266 case INDEX_op_cmpsel_vec: 3267 return -1; 3268 3269 case INDEX_op_shli_vec: 3270 case INDEX_op_shri_vec: 3271 /* We must expand the operation for MO_8. */ 3272 return vece == MO_8 ? -1 : 1; 3273 3274 case INDEX_op_sari_vec: 3275 /* We must expand the operation for MO_8. */ 3276 if (vece == MO_8) { 3277 return -1; 3278 } 3279 /* We can emulate this for MO_64, but it does not pay off 3280 unless we're producing at least 4 values. */ 3281 if (vece == MO_64) { 3282 return type >= TCG_TYPE_V256 ? -1 : 0; 3283 } 3284 return 1; 3285 3286 case INDEX_op_shls_vec: 3287 case INDEX_op_shrs_vec: 3288 return vece >= MO_16; 3289 case INDEX_op_sars_vec: 3290 return vece >= MO_16 && vece <= MO_32; 3291 case INDEX_op_rotls_vec: 3292 return vece >= MO_16 ? -1 : 0; 3293 3294 case INDEX_op_shlv_vec: 3295 case INDEX_op_shrv_vec: 3296 return have_avx2 && vece >= MO_32; 3297 case INDEX_op_sarv_vec: 3298 return have_avx2 && vece == MO_32; 3299 case INDEX_op_rotlv_vec: 3300 case INDEX_op_rotrv_vec: 3301 return have_avx2 && vece >= MO_32 ? -1 : 0; 3302 3303 case INDEX_op_mul_vec: 3304 if (vece == MO_8) { 3305 /* We can expand the operation for MO_8. */ 3306 return -1; 3307 } 3308 if (vece == MO_64) { 3309 return 0; 3310 } 3311 return 1; 3312 3313 case INDEX_op_ssadd_vec: 3314 case INDEX_op_usadd_vec: 3315 case INDEX_op_sssub_vec: 3316 case INDEX_op_ussub_vec: 3317 return vece <= MO_16; 3318 case INDEX_op_smin_vec: 3319 case INDEX_op_smax_vec: 3320 case INDEX_op_umin_vec: 3321 case INDEX_op_umax_vec: 3322 case INDEX_op_abs_vec: 3323 return vece <= MO_32; 3324 3325 default: 3326 return 0; 3327 } 3328} 3329 3330static void expand_vec_shi(TCGType type, unsigned vece, TCGOpcode opc, 3331 TCGv_vec v0, TCGv_vec v1, TCGArg imm) 3332{ 3333 TCGv_vec t1, t2; 3334 3335 tcg_debug_assert(vece == MO_8); 3336 3337 t1 = tcg_temp_new_vec(type); 3338 t2 = tcg_temp_new_vec(type); 3339 3340 /* 3341 * Unpack to W, shift, and repack. Tricky bits: 3342 * (1) Use punpck*bw x,x to produce DDCCBBAA, 3343 * i.e. duplicate in other half of the 16-bit lane. 3344 * (2) For right-shift, add 8 so that the high half of the lane 3345 * becomes zero. For left-shift, and left-rotate, we must 3346 * shift up and down again. 3347 * (3) Step 2 leaves high half zero such that PACKUSWB 3348 * (pack with unsigned saturation) does not modify 3349 * the quantity. 3350 */ 3351 vec_gen_3(INDEX_op_x86_punpckl_vec, type, MO_8, 3352 tcgv_vec_arg(t1), tcgv_vec_arg(v1), tcgv_vec_arg(v1)); 3353 vec_gen_3(INDEX_op_x86_punpckh_vec, type, MO_8, 3354 tcgv_vec_arg(t2), tcgv_vec_arg(v1), tcgv_vec_arg(v1)); 3355 3356 if (opc != INDEX_op_rotli_vec) { 3357 imm += 8; 3358 } 3359 if (opc == INDEX_op_shri_vec) { 3360 tcg_gen_shri_vec(MO_16, t1, t1, imm); 3361 tcg_gen_shri_vec(MO_16, t2, t2, imm); 3362 } else { 3363 tcg_gen_shli_vec(MO_16, t1, t1, imm); 3364 tcg_gen_shli_vec(MO_16, t2, t2, imm); 3365 tcg_gen_shri_vec(MO_16, t1, t1, 8); 3366 tcg_gen_shri_vec(MO_16, t2, t2, 8); 3367 } 3368 3369 vec_gen_3(INDEX_op_x86_packus_vec, type, MO_8, 3370 tcgv_vec_arg(v0), tcgv_vec_arg(t1), tcgv_vec_arg(t2)); 3371 tcg_temp_free_vec(t1); 3372 tcg_temp_free_vec(t2); 3373} 3374 3375static void expand_vec_sari(TCGType type, unsigned vece, 3376 TCGv_vec v0, TCGv_vec v1, TCGArg imm) 3377{ 3378 TCGv_vec t1, t2; 3379 3380 switch (vece) { 3381 case MO_8: 3382 /* Unpack to W, shift, and repack, as in expand_vec_shi. */ 3383 t1 = tcg_temp_new_vec(type); 3384 t2 = tcg_temp_new_vec(type); 3385 vec_gen_3(INDEX_op_x86_punpckl_vec, type, MO_8, 3386 tcgv_vec_arg(t1), tcgv_vec_arg(v1), tcgv_vec_arg(v1)); 3387 vec_gen_3(INDEX_op_x86_punpckh_vec, type, MO_8, 3388 tcgv_vec_arg(t2), tcgv_vec_arg(v1), tcgv_vec_arg(v1)); 3389 tcg_gen_sari_vec(MO_16, t1, t1, imm + 8); 3390 tcg_gen_sari_vec(MO_16, t2, t2, imm + 8); 3391 vec_gen_3(INDEX_op_x86_packss_vec, type, MO_8, 3392 tcgv_vec_arg(v0), tcgv_vec_arg(t1), tcgv_vec_arg(t2)); 3393 tcg_temp_free_vec(t1); 3394 tcg_temp_free_vec(t2); 3395 break; 3396 3397 case MO_64: 3398 if (imm <= 32) { 3399 /* 3400 * We can emulate a small sign extend by performing an arithmetic 3401 * 32-bit shift and overwriting the high half of a 64-bit logical 3402 * shift. Note that the ISA says shift of 32 is valid, but TCG 3403 * does not, so we have to bound the smaller shift -- we get the 3404 * same result in the high half either way. 3405 */ 3406 t1 = tcg_temp_new_vec(type); 3407 tcg_gen_sari_vec(MO_32, t1, v1, MIN(imm, 31)); 3408 tcg_gen_shri_vec(MO_64, v0, v1, imm); 3409 vec_gen_4(INDEX_op_x86_blend_vec, type, MO_32, 3410 tcgv_vec_arg(v0), tcgv_vec_arg(v0), 3411 tcgv_vec_arg(t1), 0xaa); 3412 tcg_temp_free_vec(t1); 3413 } else { 3414 /* Otherwise we will need to use a compare vs 0 to produce 3415 * the sign-extend, shift and merge. 3416 */ 3417 t1 = tcg_const_zeros_vec(type); 3418 tcg_gen_cmp_vec(TCG_COND_GT, MO_64, t1, t1, v1); 3419 tcg_gen_shri_vec(MO_64, v0, v1, imm); 3420 tcg_gen_shli_vec(MO_64, t1, t1, 64 - imm); 3421 tcg_gen_or_vec(MO_64, v0, v0, t1); 3422 tcg_temp_free_vec(t1); 3423 } 3424 break; 3425 3426 default: 3427 g_assert_not_reached(); 3428 } 3429} 3430 3431static void expand_vec_rotli(TCGType type, unsigned vece, 3432 TCGv_vec v0, TCGv_vec v1, TCGArg imm) 3433{ 3434 TCGv_vec t; 3435 3436 if (vece == MO_8) { 3437 expand_vec_shi(type, vece, INDEX_op_rotli_vec, v0, v1, imm); 3438 return; 3439 } 3440 3441 t = tcg_temp_new_vec(type); 3442 tcg_gen_shli_vec(vece, t, v1, imm); 3443 tcg_gen_shri_vec(vece, v0, v1, (8 << vece) - imm); 3444 tcg_gen_or_vec(vece, v0, v0, t); 3445 tcg_temp_free_vec(t); 3446} 3447 3448static void expand_vec_rotls(TCGType type, unsigned vece, 3449 TCGv_vec v0, TCGv_vec v1, TCGv_i32 lsh) 3450{ 3451 TCGv_i32 rsh; 3452 TCGv_vec t; 3453 3454 tcg_debug_assert(vece != MO_8); 3455 3456 t = tcg_temp_new_vec(type); 3457 rsh = tcg_temp_new_i32(); 3458 3459 tcg_gen_neg_i32(rsh, lsh); 3460 tcg_gen_andi_i32(rsh, rsh, (8 << vece) - 1); 3461 tcg_gen_shls_vec(vece, t, v1, lsh); 3462 tcg_gen_shrs_vec(vece, v0, v1, rsh); 3463 tcg_gen_or_vec(vece, v0, v0, t); 3464 tcg_temp_free_vec(t); 3465 tcg_temp_free_i32(rsh); 3466} 3467 3468static void expand_vec_rotv(TCGType type, unsigned vece, TCGv_vec v0, 3469 TCGv_vec v1, TCGv_vec sh, bool right) 3470{ 3471 TCGv_vec t = tcg_temp_new_vec(type); 3472 3473 tcg_gen_dupi_vec(vece, t, 8 << vece); 3474 tcg_gen_sub_vec(vece, t, t, sh); 3475 if (right) { 3476 tcg_gen_shlv_vec(vece, t, v1, t); 3477 tcg_gen_shrv_vec(vece, v0, v1, sh); 3478 } else { 3479 tcg_gen_shrv_vec(vece, t, v1, t); 3480 tcg_gen_shlv_vec(vece, v0, v1, sh); 3481 } 3482 tcg_gen_or_vec(vece, v0, v0, t); 3483 tcg_temp_free_vec(t); 3484} 3485 3486static void expand_vec_mul(TCGType type, unsigned vece, 3487 TCGv_vec v0, TCGv_vec v1, TCGv_vec v2) 3488{ 3489 TCGv_vec t1, t2, t3, t4; 3490 3491 tcg_debug_assert(vece == MO_8); 3492 3493 /* 3494 * Unpack v1 bytes to words, 0 | x. 3495 * Unpack v2 bytes to words, y | 0. 3496 * This leaves the 8-bit result, x * y, with 8 bits of right padding. 3497 * Shift logical right by 8 bits to clear the high 8 bytes before 3498 * using an unsigned saturated pack. 3499 * 3500 * The difference between the V64, V128 and V256 cases is merely how 3501 * we distribute the expansion between temporaries. 3502 */ 3503 switch (type) { 3504 case TCG_TYPE_V64: 3505 t1 = tcg_temp_new_vec(TCG_TYPE_V128); 3506 t2 = tcg_temp_new_vec(TCG_TYPE_V128); 3507 tcg_gen_dup16i_vec(t2, 0); 3508 vec_gen_3(INDEX_op_x86_punpckl_vec, TCG_TYPE_V128, MO_8, 3509 tcgv_vec_arg(t1), tcgv_vec_arg(v1), tcgv_vec_arg(t2)); 3510 vec_gen_3(INDEX_op_x86_punpckl_vec, TCG_TYPE_V128, MO_8, 3511 tcgv_vec_arg(t2), tcgv_vec_arg(t2), tcgv_vec_arg(v2)); 3512 tcg_gen_mul_vec(MO_16, t1, t1, t2); 3513 tcg_gen_shri_vec(MO_16, t1, t1, 8); 3514 vec_gen_3(INDEX_op_x86_packus_vec, TCG_TYPE_V128, MO_8, 3515 tcgv_vec_arg(v0), tcgv_vec_arg(t1), tcgv_vec_arg(t1)); 3516 tcg_temp_free_vec(t1); 3517 tcg_temp_free_vec(t2); 3518 break; 3519 3520 case TCG_TYPE_V128: 3521 case TCG_TYPE_V256: 3522 t1 = tcg_temp_new_vec(type); 3523 t2 = tcg_temp_new_vec(type); 3524 t3 = tcg_temp_new_vec(type); 3525 t4 = tcg_temp_new_vec(type); 3526 tcg_gen_dup16i_vec(t4, 0); 3527 vec_gen_3(INDEX_op_x86_punpckl_vec, type, MO_8, 3528 tcgv_vec_arg(t1), tcgv_vec_arg(v1), tcgv_vec_arg(t4)); 3529 vec_gen_3(INDEX_op_x86_punpckl_vec, type, MO_8, 3530 tcgv_vec_arg(t2), tcgv_vec_arg(t4), tcgv_vec_arg(v2)); 3531 vec_gen_3(INDEX_op_x86_punpckh_vec, type, MO_8, 3532 tcgv_vec_arg(t3), tcgv_vec_arg(v1), tcgv_vec_arg(t4)); 3533 vec_gen_3(INDEX_op_x86_punpckh_vec, type, MO_8, 3534 tcgv_vec_arg(t4), tcgv_vec_arg(t4), tcgv_vec_arg(v2)); 3535 tcg_gen_mul_vec(MO_16, t1, t1, t2); 3536 tcg_gen_mul_vec(MO_16, t3, t3, t4); 3537 tcg_gen_shri_vec(MO_16, t1, t1, 8); 3538 tcg_gen_shri_vec(MO_16, t3, t3, 8); 3539 vec_gen_3(INDEX_op_x86_packus_vec, type, MO_8, 3540 tcgv_vec_arg(v0), tcgv_vec_arg(t1), tcgv_vec_arg(t3)); 3541 tcg_temp_free_vec(t1); 3542 tcg_temp_free_vec(t2); 3543 tcg_temp_free_vec(t3); 3544 tcg_temp_free_vec(t4); 3545 break; 3546 3547 default: 3548 g_assert_not_reached(); 3549 } 3550} 3551 3552static bool expand_vec_cmp_noinv(TCGType type, unsigned vece, TCGv_vec v0, 3553 TCGv_vec v1, TCGv_vec v2, TCGCond cond) 3554{ 3555 enum { 3556 NEED_INV = 1, 3557 NEED_SWAP = 2, 3558 NEED_BIAS = 4, 3559 NEED_UMIN = 8, 3560 NEED_UMAX = 16, 3561 }; 3562 TCGv_vec t1, t2; 3563 uint8_t fixup; 3564 3565 switch (cond) { 3566 case TCG_COND_EQ: 3567 case TCG_COND_GT: 3568 fixup = 0; 3569 break; 3570 case TCG_COND_NE: 3571 case TCG_COND_LE: 3572 fixup = NEED_INV; 3573 break; 3574 case TCG_COND_LT: 3575 fixup = NEED_SWAP; 3576 break; 3577 case TCG_COND_GE: 3578 fixup = NEED_SWAP | NEED_INV; 3579 break; 3580 case TCG_COND_LEU: 3581 if (vece <= MO_32) { 3582 fixup = NEED_UMIN; 3583 } else { 3584 fixup = NEED_BIAS | NEED_INV; 3585 } 3586 break; 3587 case TCG_COND_GTU: 3588 if (vece <= MO_32) { 3589 fixup = NEED_UMIN | NEED_INV; 3590 } else { 3591 fixup = NEED_BIAS; 3592 } 3593 break; 3594 case TCG_COND_GEU: 3595 if (vece <= MO_32) { 3596 fixup = NEED_UMAX; 3597 } else { 3598 fixup = NEED_BIAS | NEED_SWAP | NEED_INV; 3599 } 3600 break; 3601 case TCG_COND_LTU: 3602 if (vece <= MO_32) { 3603 fixup = NEED_UMAX | NEED_INV; 3604 } else { 3605 fixup = NEED_BIAS | NEED_SWAP; 3606 } 3607 break; 3608 default: 3609 g_assert_not_reached(); 3610 } 3611 3612 if (fixup & NEED_INV) { 3613 cond = tcg_invert_cond(cond); 3614 } 3615 if (fixup & NEED_SWAP) { 3616 t1 = v1, v1 = v2, v2 = t1; 3617 cond = tcg_swap_cond(cond); 3618 } 3619 3620 t1 = t2 = NULL; 3621 if (fixup & (NEED_UMIN | NEED_UMAX)) { 3622 t1 = tcg_temp_new_vec(type); 3623 if (fixup & NEED_UMIN) { 3624 tcg_gen_umin_vec(vece, t1, v1, v2); 3625 } else { 3626 tcg_gen_umax_vec(vece, t1, v1, v2); 3627 } 3628 v2 = t1; 3629 cond = TCG_COND_EQ; 3630 } else if (fixup & NEED_BIAS) { 3631 t1 = tcg_temp_new_vec(type); 3632 t2 = tcg_temp_new_vec(type); 3633 tcg_gen_dupi_vec(vece, t2, 1ull << ((8 << vece) - 1)); 3634 tcg_gen_sub_vec(vece, t1, v1, t2); 3635 tcg_gen_sub_vec(vece, t2, v2, t2); 3636 v1 = t1; 3637 v2 = t2; 3638 cond = tcg_signed_cond(cond); 3639 } 3640 3641 tcg_debug_assert(cond == TCG_COND_EQ || cond == TCG_COND_GT); 3642 /* Expand directly; do not recurse. */ 3643 vec_gen_4(INDEX_op_cmp_vec, type, vece, 3644 tcgv_vec_arg(v0), tcgv_vec_arg(v1), tcgv_vec_arg(v2), cond); 3645 3646 if (t1) { 3647 tcg_temp_free_vec(t1); 3648 if (t2) { 3649 tcg_temp_free_vec(t2); 3650 } 3651 } 3652 return fixup & NEED_INV; 3653} 3654 3655static void expand_vec_cmp(TCGType type, unsigned vece, TCGv_vec v0, 3656 TCGv_vec v1, TCGv_vec v2, TCGCond cond) 3657{ 3658 if (expand_vec_cmp_noinv(type, vece, v0, v1, v2, cond)) { 3659 tcg_gen_not_vec(vece, v0, v0); 3660 } 3661} 3662 3663static void expand_vec_cmpsel(TCGType type, unsigned vece, TCGv_vec v0, 3664 TCGv_vec c1, TCGv_vec c2, 3665 TCGv_vec v3, TCGv_vec v4, TCGCond cond) 3666{ 3667 TCGv_vec t = tcg_temp_new_vec(type); 3668 3669 if (expand_vec_cmp_noinv(type, vece, t, c1, c2, cond)) { 3670 /* Invert the sense of the compare by swapping arguments. */ 3671 TCGv_vec x; 3672 x = v3, v3 = v4, v4 = x; 3673 } 3674 vec_gen_4(INDEX_op_x86_vpblendvb_vec, type, vece, 3675 tcgv_vec_arg(v0), tcgv_vec_arg(v4), 3676 tcgv_vec_arg(v3), tcgv_vec_arg(t)); 3677 tcg_temp_free_vec(t); 3678} 3679 3680void tcg_expand_vec_op(TCGOpcode opc, TCGType type, unsigned vece, 3681 TCGArg a0, ...) 3682{ 3683 va_list va; 3684 TCGArg a2; 3685 TCGv_vec v0, v1, v2, v3, v4; 3686 3687 va_start(va, a0); 3688 v0 = temp_tcgv_vec(arg_temp(a0)); 3689 v1 = temp_tcgv_vec(arg_temp(va_arg(va, TCGArg))); 3690 a2 = va_arg(va, TCGArg); 3691 3692 switch (opc) { 3693 case INDEX_op_shli_vec: 3694 case INDEX_op_shri_vec: 3695 expand_vec_shi(type, vece, opc, v0, v1, a2); 3696 break; 3697 3698 case INDEX_op_sari_vec: 3699 expand_vec_sari(type, vece, v0, v1, a2); 3700 break; 3701 3702 case INDEX_op_rotli_vec: 3703 expand_vec_rotli(type, vece, v0, v1, a2); 3704 break; 3705 3706 case INDEX_op_rotls_vec: 3707 expand_vec_rotls(type, vece, v0, v1, temp_tcgv_i32(arg_temp(a2))); 3708 break; 3709 3710 case INDEX_op_rotlv_vec: 3711 v2 = temp_tcgv_vec(arg_temp(a2)); 3712 expand_vec_rotv(type, vece, v0, v1, v2, false); 3713 break; 3714 case INDEX_op_rotrv_vec: 3715 v2 = temp_tcgv_vec(arg_temp(a2)); 3716 expand_vec_rotv(type, vece, v0, v1, v2, true); 3717 break; 3718 3719 case INDEX_op_mul_vec: 3720 v2 = temp_tcgv_vec(arg_temp(a2)); 3721 expand_vec_mul(type, vece, v0, v1, v2); 3722 break; 3723 3724 case INDEX_op_cmp_vec: 3725 v2 = temp_tcgv_vec(arg_temp(a2)); 3726 expand_vec_cmp(type, vece, v0, v1, v2, va_arg(va, TCGArg)); 3727 break; 3728 3729 case INDEX_op_cmpsel_vec: 3730 v2 = temp_tcgv_vec(arg_temp(a2)); 3731 v3 = temp_tcgv_vec(arg_temp(va_arg(va, TCGArg))); 3732 v4 = temp_tcgv_vec(arg_temp(va_arg(va, TCGArg))); 3733 expand_vec_cmpsel(type, vece, v0, v1, v2, v3, v4, va_arg(va, TCGArg)); 3734 break; 3735 3736 default: 3737 break; 3738 } 3739 3740 va_end(va); 3741} 3742 3743static const int tcg_target_callee_save_regs[] = { 3744#if TCG_TARGET_REG_BITS == 64 3745 TCG_REG_RBP, 3746 TCG_REG_RBX, 3747#if defined(_WIN64) 3748 TCG_REG_RDI, 3749 TCG_REG_RSI, 3750#endif 3751 TCG_REG_R12, 3752 TCG_REG_R13, 3753 TCG_REG_R14, /* Currently used for the global env. */ 3754 TCG_REG_R15, 3755#else 3756 TCG_REG_EBP, /* Currently used for the global env. */ 3757 TCG_REG_EBX, 3758 TCG_REG_ESI, 3759 TCG_REG_EDI, 3760#endif 3761}; 3762 3763/* Compute frame size via macros, to share between tcg_target_qemu_prologue 3764 and tcg_register_jit. */ 3765 3766#define PUSH_SIZE \ 3767 ((1 + ARRAY_SIZE(tcg_target_callee_save_regs)) \ 3768 * (TCG_TARGET_REG_BITS / 8)) 3769 3770#define FRAME_SIZE \ 3771 ((PUSH_SIZE \ 3772 + TCG_STATIC_CALL_ARGS_SIZE \ 3773 + CPU_TEMP_BUF_NLONGS * sizeof(long) \ 3774 + TCG_TARGET_STACK_ALIGN - 1) \ 3775 & ~(TCG_TARGET_STACK_ALIGN - 1)) 3776 3777/* Generate global QEMU prologue and epilogue code */ 3778static void tcg_target_qemu_prologue(TCGContext *s) 3779{ 3780 int i, stack_addend; 3781 3782 /* TB prologue */ 3783 3784 /* Reserve some stack space, also for TCG temps. */ 3785 stack_addend = FRAME_SIZE - PUSH_SIZE; 3786 tcg_set_frame(s, TCG_REG_CALL_STACK, TCG_STATIC_CALL_ARGS_SIZE, 3787 CPU_TEMP_BUF_NLONGS * sizeof(long)); 3788 3789 /* Save all callee saved registers. */ 3790 for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) { 3791 tcg_out_push(s, tcg_target_callee_save_regs[i]); 3792 } 3793 3794#if TCG_TARGET_REG_BITS == 32 3795 tcg_out_ld(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_ESP, 3796 (ARRAY_SIZE(tcg_target_callee_save_regs) + 1) * 4); 3797 tcg_out_addi(s, TCG_REG_ESP, -stack_addend); 3798 /* jmp *tb. */ 3799 tcg_out_modrm_offset(s, OPC_GRP5, EXT5_JMPN_Ev, TCG_REG_ESP, 3800 (ARRAY_SIZE(tcg_target_callee_save_regs) + 2) * 4 3801 + stack_addend); 3802#else 3803# if !defined(CONFIG_SOFTMMU) && TCG_TARGET_REG_BITS == 64 3804 if (guest_base) { 3805 int seg = setup_guest_base_seg(); 3806 if (seg != 0) { 3807 x86_guest_base_seg = seg; 3808 } else if (guest_base == (int32_t)guest_base) { 3809 x86_guest_base_offset = guest_base; 3810 } else { 3811 /* Choose R12 because, as a base, it requires a SIB byte. */ 3812 x86_guest_base_index = TCG_REG_R12; 3813 tcg_out_movi(s, TCG_TYPE_PTR, x86_guest_base_index, guest_base); 3814 tcg_regset_set_reg(s->reserved_regs, x86_guest_base_index); 3815 } 3816 } 3817# endif 3818 tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); 3819 tcg_out_addi(s, TCG_REG_ESP, -stack_addend); 3820 /* jmp *tb. */ 3821 tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, tcg_target_call_iarg_regs[1]); 3822#endif 3823 3824 /* 3825 * Return path for goto_ptr. Set return value to 0, a-la exit_tb, 3826 * and fall through to the rest of the epilogue. 3827 */ 3828 tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr); 3829 tcg_out_movi(s, TCG_TYPE_REG, TCG_REG_EAX, 0); 3830 3831 /* TB epilogue */ 3832 tb_ret_addr = tcg_splitwx_to_rx(s->code_ptr); 3833 3834 tcg_out_addi(s, TCG_REG_CALL_STACK, stack_addend); 3835 3836 if (have_avx2) { 3837 tcg_out_vex_opc(s, OPC_VZEROUPPER, 0, 0, 0, 0); 3838 } 3839 for (i = ARRAY_SIZE(tcg_target_callee_save_regs) - 1; i >= 0; i--) { 3840 tcg_out_pop(s, tcg_target_callee_save_regs[i]); 3841 } 3842 tcg_out_opc(s, OPC_RET, 0, 0, 0); 3843} 3844 3845static void tcg_out_nop_fill(tcg_insn_unit *p, int count) 3846{ 3847 memset(p, 0x90, count); 3848} 3849 3850static void tcg_target_init(TCGContext *s) 3851{ 3852#ifdef CONFIG_CPUID_H 3853 unsigned a, b, c, d, b7 = 0; 3854 int max = __get_cpuid_max(0, 0); 3855 3856 if (max >= 7) { 3857 /* BMI1 is available on AMD Piledriver and Intel Haswell CPUs. */ 3858 __cpuid_count(7, 0, a, b7, c, d); 3859 have_bmi1 = (b7 & bit_BMI) != 0; 3860 have_bmi2 = (b7 & bit_BMI2) != 0; 3861 } 3862 3863 if (max >= 1) { 3864 __cpuid(1, a, b, c, d); 3865#ifndef have_cmov 3866 /* For 32-bit, 99% certainty that we're running on hardware that 3867 supports cmov, but we still need to check. In case cmov is not 3868 available, we'll use a small forward branch. */ 3869 have_cmov = (d & bit_CMOV) != 0; 3870#endif 3871 3872 /* MOVBE is only available on Intel Atom and Haswell CPUs, so we 3873 need to probe for it. */ 3874 have_movbe = (c & bit_MOVBE) != 0; 3875 have_popcnt = (c & bit_POPCNT) != 0; 3876 3877 /* There are a number of things we must check before we can be 3878 sure of not hitting invalid opcode. */ 3879 if (c & bit_OSXSAVE) { 3880 unsigned xcrl, xcrh; 3881 /* The xgetbv instruction is not available to older versions of 3882 * the assembler, so we encode the instruction manually. 3883 */ 3884 asm(".byte 0x0f, 0x01, 0xd0" : "=a" (xcrl), "=d" (xcrh) : "c" (0)); 3885 if ((xcrl & 6) == 6) { 3886 have_avx1 = (c & bit_AVX) != 0; 3887 have_avx2 = (b7 & bit_AVX2) != 0; 3888 } 3889 } 3890 } 3891 3892 max = __get_cpuid_max(0x8000000, 0); 3893 if (max >= 1) { 3894 __cpuid(0x80000001, a, b, c, d); 3895 /* LZCNT was introduced with AMD Barcelona and Intel Haswell CPUs. */ 3896 have_lzcnt = (c & bit_LZCNT) != 0; 3897 } 3898#endif /* CONFIG_CPUID_H */ 3899 3900 tcg_target_available_regs[TCG_TYPE_I32] = ALL_GENERAL_REGS; 3901 if (TCG_TARGET_REG_BITS == 64) { 3902 tcg_target_available_regs[TCG_TYPE_I64] = ALL_GENERAL_REGS; 3903 } 3904 if (have_avx1) { 3905 tcg_target_available_regs[TCG_TYPE_V64] = ALL_VECTOR_REGS; 3906 tcg_target_available_regs[TCG_TYPE_V128] = ALL_VECTOR_REGS; 3907 } 3908 if (have_avx2) { 3909 tcg_target_available_regs[TCG_TYPE_V256] = ALL_VECTOR_REGS; 3910 } 3911 3912 tcg_target_call_clobber_regs = ALL_VECTOR_REGS; 3913 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EAX); 3914 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EDX); 3915 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_ECX); 3916 if (TCG_TARGET_REG_BITS == 64) { 3917#if !defined(_WIN64) 3918 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_RDI); 3919 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_RSI); 3920#endif 3921 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R8); 3922 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R9); 3923 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R10); 3924 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R11); 3925 } 3926 3927 s->reserved_regs = 0; 3928 tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK); 3929} 3930 3931typedef struct { 3932 DebugFrameHeader h; 3933 uint8_t fde_def_cfa[4]; 3934 uint8_t fde_reg_ofs[14]; 3935} DebugFrame; 3936 3937/* We're expecting a 2 byte uleb128 encoded value. */ 3938QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14)); 3939 3940#if !defined(__ELF__) 3941 /* Host machine without ELF. */ 3942#elif TCG_TARGET_REG_BITS == 64 3943#define ELF_HOST_MACHINE EM_X86_64 3944static const DebugFrame debug_frame = { 3945 .h.cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */ 3946 .h.cie.id = -1, 3947 .h.cie.version = 1, 3948 .h.cie.code_align = 1, 3949 .h.cie.data_align = 0x78, /* sleb128 -8 */ 3950 .h.cie.return_column = 16, 3951 3952 /* Total FDE size does not include the "len" member. */ 3953 .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset), 3954 3955 .fde_def_cfa = { 3956 12, 7, /* DW_CFA_def_cfa %rsp, ... */ 3957 (FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */ 3958 (FRAME_SIZE >> 7) 3959 }, 3960 .fde_reg_ofs = { 3961 0x90, 1, /* DW_CFA_offset, %rip, -8 */ 3962 /* The following ordering must match tcg_target_callee_save_regs. */ 3963 0x86, 2, /* DW_CFA_offset, %rbp, -16 */ 3964 0x83, 3, /* DW_CFA_offset, %rbx, -24 */ 3965 0x8c, 4, /* DW_CFA_offset, %r12, -32 */ 3966 0x8d, 5, /* DW_CFA_offset, %r13, -40 */ 3967 0x8e, 6, /* DW_CFA_offset, %r14, -48 */ 3968 0x8f, 7, /* DW_CFA_offset, %r15, -56 */ 3969 } 3970}; 3971#else 3972#define ELF_HOST_MACHINE EM_386 3973static const DebugFrame debug_frame = { 3974 .h.cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */ 3975 .h.cie.id = -1, 3976 .h.cie.version = 1, 3977 .h.cie.code_align = 1, 3978 .h.cie.data_align = 0x7c, /* sleb128 -4 */ 3979 .h.cie.return_column = 8, 3980 3981 /* Total FDE size does not include the "len" member. */ 3982 .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset), 3983 3984 .fde_def_cfa = { 3985 12, 4, /* DW_CFA_def_cfa %esp, ... */ 3986 (FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */ 3987 (FRAME_SIZE >> 7) 3988 }, 3989 .fde_reg_ofs = { 3990 0x88, 1, /* DW_CFA_offset, %eip, -4 */ 3991 /* The following ordering must match tcg_target_callee_save_regs. */ 3992 0x85, 2, /* DW_CFA_offset, %ebp, -8 */ 3993 0x83, 3, /* DW_CFA_offset, %ebx, -12 */ 3994 0x86, 4, /* DW_CFA_offset, %esi, -16 */ 3995 0x87, 5, /* DW_CFA_offset, %edi, -20 */ 3996 } 3997}; 3998#endif 3999 4000#if defined(ELF_HOST_MACHINE) 4001void tcg_register_jit(const void *buf, size_t buf_size) 4002{ 4003 tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame)); 4004} 4005#endif 4006