1*139c1837SPaolo Bonzini/* 2*139c1837SPaolo Bonzini * Tiny Code Generator for QEMU 3*139c1837SPaolo Bonzini * 4*139c1837SPaolo Bonzini * Copyright (c) 2018 SiFive, Inc 5*139c1837SPaolo Bonzini * Copyright (c) 2008-2009 Arnaud Patard <arnaud.patard@rtp-net.org> 6*139c1837SPaolo Bonzini * Copyright (c) 2009 Aurelien Jarno <aurelien@aurel32.net> 7*139c1837SPaolo Bonzini * Copyright (c) 2008 Fabrice Bellard 8*139c1837SPaolo Bonzini * 9*139c1837SPaolo Bonzini * Based on i386/tcg-target.c and mips/tcg-target.c 10*139c1837SPaolo Bonzini * 11*139c1837SPaolo Bonzini * Permission is hereby granted, free of charge, to any person obtaining a copy 12*139c1837SPaolo Bonzini * of this software and associated documentation files (the "Software"), to deal 13*139c1837SPaolo Bonzini * in the Software without restriction, including without limitation the rights 14*139c1837SPaolo Bonzini * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15*139c1837SPaolo Bonzini * copies of the Software, and to permit persons to whom the Software is 16*139c1837SPaolo Bonzini * furnished to do so, subject to the following conditions: 17*139c1837SPaolo Bonzini * 18*139c1837SPaolo Bonzini * The above copyright notice and this permission notice shall be included in 19*139c1837SPaolo Bonzini * all copies or substantial portions of the Software. 20*139c1837SPaolo Bonzini * 21*139c1837SPaolo Bonzini * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22*139c1837SPaolo Bonzini * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23*139c1837SPaolo Bonzini * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 24*139c1837SPaolo Bonzini * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25*139c1837SPaolo Bonzini * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26*139c1837SPaolo Bonzini * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27*139c1837SPaolo Bonzini * THE SOFTWARE. 28*139c1837SPaolo Bonzini */ 29*139c1837SPaolo Bonzini 30*139c1837SPaolo Bonzini#include "../tcg-pool.c.inc" 31*139c1837SPaolo Bonzini 32*139c1837SPaolo Bonzini#ifdef CONFIG_DEBUG_TCG 33*139c1837SPaolo Bonzinistatic const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { 34*139c1837SPaolo Bonzini "zero", 35*139c1837SPaolo Bonzini "ra", 36*139c1837SPaolo Bonzini "sp", 37*139c1837SPaolo Bonzini "gp", 38*139c1837SPaolo Bonzini "tp", 39*139c1837SPaolo Bonzini "t0", 40*139c1837SPaolo Bonzini "t1", 41*139c1837SPaolo Bonzini "t2", 42*139c1837SPaolo Bonzini "s0", 43*139c1837SPaolo Bonzini "s1", 44*139c1837SPaolo Bonzini "a0", 45*139c1837SPaolo Bonzini "a1", 46*139c1837SPaolo Bonzini "a2", 47*139c1837SPaolo Bonzini "a3", 48*139c1837SPaolo Bonzini "a4", 49*139c1837SPaolo Bonzini "a5", 50*139c1837SPaolo Bonzini "a6", 51*139c1837SPaolo Bonzini "a7", 52*139c1837SPaolo Bonzini "s2", 53*139c1837SPaolo Bonzini "s3", 54*139c1837SPaolo Bonzini "s4", 55*139c1837SPaolo Bonzini "s5", 56*139c1837SPaolo Bonzini "s6", 57*139c1837SPaolo Bonzini "s7", 58*139c1837SPaolo Bonzini "s8", 59*139c1837SPaolo Bonzini "s9", 60*139c1837SPaolo Bonzini "s10", 61*139c1837SPaolo Bonzini "s11", 62*139c1837SPaolo Bonzini "t3", 63*139c1837SPaolo Bonzini "t4", 64*139c1837SPaolo Bonzini "t5", 65*139c1837SPaolo Bonzini "t6" 66*139c1837SPaolo Bonzini}; 67*139c1837SPaolo Bonzini#endif 68*139c1837SPaolo Bonzini 69*139c1837SPaolo Bonzinistatic const int tcg_target_reg_alloc_order[] = { 70*139c1837SPaolo Bonzini /* Call saved registers */ 71*139c1837SPaolo Bonzini /* TCG_REG_S0 reservered for TCG_AREG0 */ 72*139c1837SPaolo Bonzini TCG_REG_S1, 73*139c1837SPaolo Bonzini TCG_REG_S2, 74*139c1837SPaolo Bonzini TCG_REG_S3, 75*139c1837SPaolo Bonzini TCG_REG_S4, 76*139c1837SPaolo Bonzini TCG_REG_S5, 77*139c1837SPaolo Bonzini TCG_REG_S6, 78*139c1837SPaolo Bonzini TCG_REG_S7, 79*139c1837SPaolo Bonzini TCG_REG_S8, 80*139c1837SPaolo Bonzini TCG_REG_S9, 81*139c1837SPaolo Bonzini TCG_REG_S10, 82*139c1837SPaolo Bonzini TCG_REG_S11, 83*139c1837SPaolo Bonzini 84*139c1837SPaolo Bonzini /* Call clobbered registers */ 85*139c1837SPaolo Bonzini TCG_REG_T0, 86*139c1837SPaolo Bonzini TCG_REG_T1, 87*139c1837SPaolo Bonzini TCG_REG_T2, 88*139c1837SPaolo Bonzini TCG_REG_T3, 89*139c1837SPaolo Bonzini TCG_REG_T4, 90*139c1837SPaolo Bonzini TCG_REG_T5, 91*139c1837SPaolo Bonzini TCG_REG_T6, 92*139c1837SPaolo Bonzini 93*139c1837SPaolo Bonzini /* Argument registers */ 94*139c1837SPaolo Bonzini TCG_REG_A0, 95*139c1837SPaolo Bonzini TCG_REG_A1, 96*139c1837SPaolo Bonzini TCG_REG_A2, 97*139c1837SPaolo Bonzini TCG_REG_A3, 98*139c1837SPaolo Bonzini TCG_REG_A4, 99*139c1837SPaolo Bonzini TCG_REG_A5, 100*139c1837SPaolo Bonzini TCG_REG_A6, 101*139c1837SPaolo Bonzini TCG_REG_A7, 102*139c1837SPaolo Bonzini}; 103*139c1837SPaolo Bonzini 104*139c1837SPaolo Bonzinistatic const int tcg_target_call_iarg_regs[] = { 105*139c1837SPaolo Bonzini TCG_REG_A0, 106*139c1837SPaolo Bonzini TCG_REG_A1, 107*139c1837SPaolo Bonzini TCG_REG_A2, 108*139c1837SPaolo Bonzini TCG_REG_A3, 109*139c1837SPaolo Bonzini TCG_REG_A4, 110*139c1837SPaolo Bonzini TCG_REG_A5, 111*139c1837SPaolo Bonzini TCG_REG_A6, 112*139c1837SPaolo Bonzini TCG_REG_A7, 113*139c1837SPaolo Bonzini}; 114*139c1837SPaolo Bonzini 115*139c1837SPaolo Bonzinistatic const int tcg_target_call_oarg_regs[] = { 116*139c1837SPaolo Bonzini TCG_REG_A0, 117*139c1837SPaolo Bonzini TCG_REG_A1, 118*139c1837SPaolo Bonzini}; 119*139c1837SPaolo Bonzini 120*139c1837SPaolo Bonzini#define TCG_CT_CONST_ZERO 0x100 121*139c1837SPaolo Bonzini#define TCG_CT_CONST_S12 0x200 122*139c1837SPaolo Bonzini#define TCG_CT_CONST_N12 0x400 123*139c1837SPaolo Bonzini#define TCG_CT_CONST_M12 0x800 124*139c1837SPaolo Bonzini 125*139c1837SPaolo Bonzinistatic inline tcg_target_long sextreg(tcg_target_long val, int pos, int len) 126*139c1837SPaolo Bonzini{ 127*139c1837SPaolo Bonzini if (TCG_TARGET_REG_BITS == 32) { 128*139c1837SPaolo Bonzini return sextract32(val, pos, len); 129*139c1837SPaolo Bonzini } else { 130*139c1837SPaolo Bonzini return sextract64(val, pos, len); 131*139c1837SPaolo Bonzini } 132*139c1837SPaolo Bonzini} 133*139c1837SPaolo Bonzini 134*139c1837SPaolo Bonzini/* parse target specific constraints */ 135*139c1837SPaolo Bonzinistatic const char *target_parse_constraint(TCGArgConstraint *ct, 136*139c1837SPaolo Bonzini const char *ct_str, TCGType type) 137*139c1837SPaolo Bonzini{ 138*139c1837SPaolo Bonzini switch (*ct_str++) { 139*139c1837SPaolo Bonzini case 'r': 140*139c1837SPaolo Bonzini ct->ct |= TCG_CT_REG; 141*139c1837SPaolo Bonzini ct->u.regs = 0xffffffff; 142*139c1837SPaolo Bonzini break; 143*139c1837SPaolo Bonzini case 'L': 144*139c1837SPaolo Bonzini /* qemu_ld/qemu_st constraint */ 145*139c1837SPaolo Bonzini ct->ct |= TCG_CT_REG; 146*139c1837SPaolo Bonzini ct->u.regs = 0xffffffff; 147*139c1837SPaolo Bonzini /* qemu_ld/qemu_st uses TCG_REG_TMP0 */ 148*139c1837SPaolo Bonzini#if defined(CONFIG_SOFTMMU) 149*139c1837SPaolo Bonzini tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[0]); 150*139c1837SPaolo Bonzini tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[1]); 151*139c1837SPaolo Bonzini tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[2]); 152*139c1837SPaolo Bonzini tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[3]); 153*139c1837SPaolo Bonzini tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[4]); 154*139c1837SPaolo Bonzini#endif 155*139c1837SPaolo Bonzini break; 156*139c1837SPaolo Bonzini case 'I': 157*139c1837SPaolo Bonzini ct->ct |= TCG_CT_CONST_S12; 158*139c1837SPaolo Bonzini break; 159*139c1837SPaolo Bonzini case 'N': 160*139c1837SPaolo Bonzini ct->ct |= TCG_CT_CONST_N12; 161*139c1837SPaolo Bonzini break; 162*139c1837SPaolo Bonzini case 'M': 163*139c1837SPaolo Bonzini ct->ct |= TCG_CT_CONST_M12; 164*139c1837SPaolo Bonzini break; 165*139c1837SPaolo Bonzini case 'Z': 166*139c1837SPaolo Bonzini /* we can use a zero immediate as a zero register argument. */ 167*139c1837SPaolo Bonzini ct->ct |= TCG_CT_CONST_ZERO; 168*139c1837SPaolo Bonzini break; 169*139c1837SPaolo Bonzini default: 170*139c1837SPaolo Bonzini return NULL; 171*139c1837SPaolo Bonzini } 172*139c1837SPaolo Bonzini return ct_str; 173*139c1837SPaolo Bonzini} 174*139c1837SPaolo Bonzini 175*139c1837SPaolo Bonzini/* test if a constant matches the constraint */ 176*139c1837SPaolo Bonzinistatic int tcg_target_const_match(tcg_target_long val, TCGType type, 177*139c1837SPaolo Bonzini const TCGArgConstraint *arg_ct) 178*139c1837SPaolo Bonzini{ 179*139c1837SPaolo Bonzini int ct = arg_ct->ct; 180*139c1837SPaolo Bonzini if (ct & TCG_CT_CONST) { 181*139c1837SPaolo Bonzini return 1; 182*139c1837SPaolo Bonzini } 183*139c1837SPaolo Bonzini if ((ct & TCG_CT_CONST_ZERO) && val == 0) { 184*139c1837SPaolo Bonzini return 1; 185*139c1837SPaolo Bonzini } 186*139c1837SPaolo Bonzini if ((ct & TCG_CT_CONST_S12) && val == sextreg(val, 0, 12)) { 187*139c1837SPaolo Bonzini return 1; 188*139c1837SPaolo Bonzini } 189*139c1837SPaolo Bonzini if ((ct & TCG_CT_CONST_N12) && -val == sextreg(-val, 0, 12)) { 190*139c1837SPaolo Bonzini return 1; 191*139c1837SPaolo Bonzini } 192*139c1837SPaolo Bonzini if ((ct & TCG_CT_CONST_M12) && val >= -0xfff && val <= 0xfff) { 193*139c1837SPaolo Bonzini return 1; 194*139c1837SPaolo Bonzini } 195*139c1837SPaolo Bonzini return 0; 196*139c1837SPaolo Bonzini} 197*139c1837SPaolo Bonzini 198*139c1837SPaolo Bonzini/* 199*139c1837SPaolo Bonzini * RISC-V Base ISA opcodes (IM) 200*139c1837SPaolo Bonzini */ 201*139c1837SPaolo Bonzini 202*139c1837SPaolo Bonzinitypedef enum { 203*139c1837SPaolo Bonzini OPC_ADD = 0x33, 204*139c1837SPaolo Bonzini OPC_ADDI = 0x13, 205*139c1837SPaolo Bonzini OPC_AND = 0x7033, 206*139c1837SPaolo Bonzini OPC_ANDI = 0x7013, 207*139c1837SPaolo Bonzini OPC_AUIPC = 0x17, 208*139c1837SPaolo Bonzini OPC_BEQ = 0x63, 209*139c1837SPaolo Bonzini OPC_BGE = 0x5063, 210*139c1837SPaolo Bonzini OPC_BGEU = 0x7063, 211*139c1837SPaolo Bonzini OPC_BLT = 0x4063, 212*139c1837SPaolo Bonzini OPC_BLTU = 0x6063, 213*139c1837SPaolo Bonzini OPC_BNE = 0x1063, 214*139c1837SPaolo Bonzini OPC_DIV = 0x2004033, 215*139c1837SPaolo Bonzini OPC_DIVU = 0x2005033, 216*139c1837SPaolo Bonzini OPC_JAL = 0x6f, 217*139c1837SPaolo Bonzini OPC_JALR = 0x67, 218*139c1837SPaolo Bonzini OPC_LB = 0x3, 219*139c1837SPaolo Bonzini OPC_LBU = 0x4003, 220*139c1837SPaolo Bonzini OPC_LD = 0x3003, 221*139c1837SPaolo Bonzini OPC_LH = 0x1003, 222*139c1837SPaolo Bonzini OPC_LHU = 0x5003, 223*139c1837SPaolo Bonzini OPC_LUI = 0x37, 224*139c1837SPaolo Bonzini OPC_LW = 0x2003, 225*139c1837SPaolo Bonzini OPC_LWU = 0x6003, 226*139c1837SPaolo Bonzini OPC_MUL = 0x2000033, 227*139c1837SPaolo Bonzini OPC_MULH = 0x2001033, 228*139c1837SPaolo Bonzini OPC_MULHSU = 0x2002033, 229*139c1837SPaolo Bonzini OPC_MULHU = 0x2003033, 230*139c1837SPaolo Bonzini OPC_OR = 0x6033, 231*139c1837SPaolo Bonzini OPC_ORI = 0x6013, 232*139c1837SPaolo Bonzini OPC_REM = 0x2006033, 233*139c1837SPaolo Bonzini OPC_REMU = 0x2007033, 234*139c1837SPaolo Bonzini OPC_SB = 0x23, 235*139c1837SPaolo Bonzini OPC_SD = 0x3023, 236*139c1837SPaolo Bonzini OPC_SH = 0x1023, 237*139c1837SPaolo Bonzini OPC_SLL = 0x1033, 238*139c1837SPaolo Bonzini OPC_SLLI = 0x1013, 239*139c1837SPaolo Bonzini OPC_SLT = 0x2033, 240*139c1837SPaolo Bonzini OPC_SLTI = 0x2013, 241*139c1837SPaolo Bonzini OPC_SLTIU = 0x3013, 242*139c1837SPaolo Bonzini OPC_SLTU = 0x3033, 243*139c1837SPaolo Bonzini OPC_SRA = 0x40005033, 244*139c1837SPaolo Bonzini OPC_SRAI = 0x40005013, 245*139c1837SPaolo Bonzini OPC_SRL = 0x5033, 246*139c1837SPaolo Bonzini OPC_SRLI = 0x5013, 247*139c1837SPaolo Bonzini OPC_SUB = 0x40000033, 248*139c1837SPaolo Bonzini OPC_SW = 0x2023, 249*139c1837SPaolo Bonzini OPC_XOR = 0x4033, 250*139c1837SPaolo Bonzini OPC_XORI = 0x4013, 251*139c1837SPaolo Bonzini 252*139c1837SPaolo Bonzini#if TCG_TARGET_REG_BITS == 64 253*139c1837SPaolo Bonzini OPC_ADDIW = 0x1b, 254*139c1837SPaolo Bonzini OPC_ADDW = 0x3b, 255*139c1837SPaolo Bonzini OPC_DIVUW = 0x200503b, 256*139c1837SPaolo Bonzini OPC_DIVW = 0x200403b, 257*139c1837SPaolo Bonzini OPC_MULW = 0x200003b, 258*139c1837SPaolo Bonzini OPC_REMUW = 0x200703b, 259*139c1837SPaolo Bonzini OPC_REMW = 0x200603b, 260*139c1837SPaolo Bonzini OPC_SLLIW = 0x101b, 261*139c1837SPaolo Bonzini OPC_SLLW = 0x103b, 262*139c1837SPaolo Bonzini OPC_SRAIW = 0x4000501b, 263*139c1837SPaolo Bonzini OPC_SRAW = 0x4000503b, 264*139c1837SPaolo Bonzini OPC_SRLIW = 0x501b, 265*139c1837SPaolo Bonzini OPC_SRLW = 0x503b, 266*139c1837SPaolo Bonzini OPC_SUBW = 0x4000003b, 267*139c1837SPaolo Bonzini#else 268*139c1837SPaolo Bonzini /* Simplify code throughout by defining aliases for RV32. */ 269*139c1837SPaolo Bonzini OPC_ADDIW = OPC_ADDI, 270*139c1837SPaolo Bonzini OPC_ADDW = OPC_ADD, 271*139c1837SPaolo Bonzini OPC_DIVUW = OPC_DIVU, 272*139c1837SPaolo Bonzini OPC_DIVW = OPC_DIV, 273*139c1837SPaolo Bonzini OPC_MULW = OPC_MUL, 274*139c1837SPaolo Bonzini OPC_REMUW = OPC_REMU, 275*139c1837SPaolo Bonzini OPC_REMW = OPC_REM, 276*139c1837SPaolo Bonzini OPC_SLLIW = OPC_SLLI, 277*139c1837SPaolo Bonzini OPC_SLLW = OPC_SLL, 278*139c1837SPaolo Bonzini OPC_SRAIW = OPC_SRAI, 279*139c1837SPaolo Bonzini OPC_SRAW = OPC_SRA, 280*139c1837SPaolo Bonzini OPC_SRLIW = OPC_SRLI, 281*139c1837SPaolo Bonzini OPC_SRLW = OPC_SRL, 282*139c1837SPaolo Bonzini OPC_SUBW = OPC_SUB, 283*139c1837SPaolo Bonzini#endif 284*139c1837SPaolo Bonzini 285*139c1837SPaolo Bonzini OPC_FENCE = 0x0000000f, 286*139c1837SPaolo Bonzini} RISCVInsn; 287*139c1837SPaolo Bonzini 288*139c1837SPaolo Bonzini/* 289*139c1837SPaolo Bonzini * RISC-V immediate and instruction encoders (excludes 16-bit RVC) 290*139c1837SPaolo Bonzini */ 291*139c1837SPaolo Bonzini 292*139c1837SPaolo Bonzini/* Type-R */ 293*139c1837SPaolo Bonzini 294*139c1837SPaolo Bonzinistatic int32_t encode_r(RISCVInsn opc, TCGReg rd, TCGReg rs1, TCGReg rs2) 295*139c1837SPaolo Bonzini{ 296*139c1837SPaolo Bonzini return opc | (rd & 0x1f) << 7 | (rs1 & 0x1f) << 15 | (rs2 & 0x1f) << 20; 297*139c1837SPaolo Bonzini} 298*139c1837SPaolo Bonzini 299*139c1837SPaolo Bonzini/* Type-I */ 300*139c1837SPaolo Bonzini 301*139c1837SPaolo Bonzinistatic int32_t encode_imm12(uint32_t imm) 302*139c1837SPaolo Bonzini{ 303*139c1837SPaolo Bonzini return (imm & 0xfff) << 20; 304*139c1837SPaolo Bonzini} 305*139c1837SPaolo Bonzini 306*139c1837SPaolo Bonzinistatic int32_t encode_i(RISCVInsn opc, TCGReg rd, TCGReg rs1, uint32_t imm) 307*139c1837SPaolo Bonzini{ 308*139c1837SPaolo Bonzini return opc | (rd & 0x1f) << 7 | (rs1 & 0x1f) << 15 | encode_imm12(imm); 309*139c1837SPaolo Bonzini} 310*139c1837SPaolo Bonzini 311*139c1837SPaolo Bonzini/* Type-S */ 312*139c1837SPaolo Bonzini 313*139c1837SPaolo Bonzinistatic int32_t encode_simm12(uint32_t imm) 314*139c1837SPaolo Bonzini{ 315*139c1837SPaolo Bonzini int32_t ret = 0; 316*139c1837SPaolo Bonzini 317*139c1837SPaolo Bonzini ret |= (imm & 0xFE0) << 20; 318*139c1837SPaolo Bonzini ret |= (imm & 0x1F) << 7; 319*139c1837SPaolo Bonzini 320*139c1837SPaolo Bonzini return ret; 321*139c1837SPaolo Bonzini} 322*139c1837SPaolo Bonzini 323*139c1837SPaolo Bonzinistatic int32_t encode_s(RISCVInsn opc, TCGReg rs1, TCGReg rs2, uint32_t imm) 324*139c1837SPaolo Bonzini{ 325*139c1837SPaolo Bonzini return opc | (rs1 & 0x1f) << 15 | (rs2 & 0x1f) << 20 | encode_simm12(imm); 326*139c1837SPaolo Bonzini} 327*139c1837SPaolo Bonzini 328*139c1837SPaolo Bonzini/* Type-SB */ 329*139c1837SPaolo Bonzini 330*139c1837SPaolo Bonzinistatic int32_t encode_sbimm12(uint32_t imm) 331*139c1837SPaolo Bonzini{ 332*139c1837SPaolo Bonzini int32_t ret = 0; 333*139c1837SPaolo Bonzini 334*139c1837SPaolo Bonzini ret |= (imm & 0x1000) << 19; 335*139c1837SPaolo Bonzini ret |= (imm & 0x7e0) << 20; 336*139c1837SPaolo Bonzini ret |= (imm & 0x1e) << 7; 337*139c1837SPaolo Bonzini ret |= (imm & 0x800) >> 4; 338*139c1837SPaolo Bonzini 339*139c1837SPaolo Bonzini return ret; 340*139c1837SPaolo Bonzini} 341*139c1837SPaolo Bonzini 342*139c1837SPaolo Bonzinistatic int32_t encode_sb(RISCVInsn opc, TCGReg rs1, TCGReg rs2, uint32_t imm) 343*139c1837SPaolo Bonzini{ 344*139c1837SPaolo Bonzini return opc | (rs1 & 0x1f) << 15 | (rs2 & 0x1f) << 20 | encode_sbimm12(imm); 345*139c1837SPaolo Bonzini} 346*139c1837SPaolo Bonzini 347*139c1837SPaolo Bonzini/* Type-U */ 348*139c1837SPaolo Bonzini 349*139c1837SPaolo Bonzinistatic int32_t encode_uimm20(uint32_t imm) 350*139c1837SPaolo Bonzini{ 351*139c1837SPaolo Bonzini return imm & 0xfffff000; 352*139c1837SPaolo Bonzini} 353*139c1837SPaolo Bonzini 354*139c1837SPaolo Bonzinistatic int32_t encode_u(RISCVInsn opc, TCGReg rd, uint32_t imm) 355*139c1837SPaolo Bonzini{ 356*139c1837SPaolo Bonzini return opc | (rd & 0x1f) << 7 | encode_uimm20(imm); 357*139c1837SPaolo Bonzini} 358*139c1837SPaolo Bonzini 359*139c1837SPaolo Bonzini/* Type-UJ */ 360*139c1837SPaolo Bonzini 361*139c1837SPaolo Bonzinistatic int32_t encode_ujimm20(uint32_t imm) 362*139c1837SPaolo Bonzini{ 363*139c1837SPaolo Bonzini int32_t ret = 0; 364*139c1837SPaolo Bonzini 365*139c1837SPaolo Bonzini ret |= (imm & 0x0007fe) << (21 - 1); 366*139c1837SPaolo Bonzini ret |= (imm & 0x000800) << (20 - 11); 367*139c1837SPaolo Bonzini ret |= (imm & 0x0ff000) << (12 - 12); 368*139c1837SPaolo Bonzini ret |= (imm & 0x100000) << (31 - 20); 369*139c1837SPaolo Bonzini 370*139c1837SPaolo Bonzini return ret; 371*139c1837SPaolo Bonzini} 372*139c1837SPaolo Bonzini 373*139c1837SPaolo Bonzinistatic int32_t encode_uj(RISCVInsn opc, TCGReg rd, uint32_t imm) 374*139c1837SPaolo Bonzini{ 375*139c1837SPaolo Bonzini return opc | (rd & 0x1f) << 7 | encode_ujimm20(imm); 376*139c1837SPaolo Bonzini} 377*139c1837SPaolo Bonzini 378*139c1837SPaolo Bonzini/* 379*139c1837SPaolo Bonzini * RISC-V instruction emitters 380*139c1837SPaolo Bonzini */ 381*139c1837SPaolo Bonzini 382*139c1837SPaolo Bonzinistatic void tcg_out_opc_reg(TCGContext *s, RISCVInsn opc, 383*139c1837SPaolo Bonzini TCGReg rd, TCGReg rs1, TCGReg rs2) 384*139c1837SPaolo Bonzini{ 385*139c1837SPaolo Bonzini tcg_out32(s, encode_r(opc, rd, rs1, rs2)); 386*139c1837SPaolo Bonzini} 387*139c1837SPaolo Bonzini 388*139c1837SPaolo Bonzinistatic void tcg_out_opc_imm(TCGContext *s, RISCVInsn opc, 389*139c1837SPaolo Bonzini TCGReg rd, TCGReg rs1, TCGArg imm) 390*139c1837SPaolo Bonzini{ 391*139c1837SPaolo Bonzini tcg_out32(s, encode_i(opc, rd, rs1, imm)); 392*139c1837SPaolo Bonzini} 393*139c1837SPaolo Bonzini 394*139c1837SPaolo Bonzinistatic void tcg_out_opc_store(TCGContext *s, RISCVInsn opc, 395*139c1837SPaolo Bonzini TCGReg rs1, TCGReg rs2, uint32_t imm) 396*139c1837SPaolo Bonzini{ 397*139c1837SPaolo Bonzini tcg_out32(s, encode_s(opc, rs1, rs2, imm)); 398*139c1837SPaolo Bonzini} 399*139c1837SPaolo Bonzini 400*139c1837SPaolo Bonzinistatic void tcg_out_opc_branch(TCGContext *s, RISCVInsn opc, 401*139c1837SPaolo Bonzini TCGReg rs1, TCGReg rs2, uint32_t imm) 402*139c1837SPaolo Bonzini{ 403*139c1837SPaolo Bonzini tcg_out32(s, encode_sb(opc, rs1, rs2, imm)); 404*139c1837SPaolo Bonzini} 405*139c1837SPaolo Bonzini 406*139c1837SPaolo Bonzinistatic void tcg_out_opc_upper(TCGContext *s, RISCVInsn opc, 407*139c1837SPaolo Bonzini TCGReg rd, uint32_t imm) 408*139c1837SPaolo Bonzini{ 409*139c1837SPaolo Bonzini tcg_out32(s, encode_u(opc, rd, imm)); 410*139c1837SPaolo Bonzini} 411*139c1837SPaolo Bonzini 412*139c1837SPaolo Bonzinistatic void tcg_out_opc_jump(TCGContext *s, RISCVInsn opc, 413*139c1837SPaolo Bonzini TCGReg rd, uint32_t imm) 414*139c1837SPaolo Bonzini{ 415*139c1837SPaolo Bonzini tcg_out32(s, encode_uj(opc, rd, imm)); 416*139c1837SPaolo Bonzini} 417*139c1837SPaolo Bonzini 418*139c1837SPaolo Bonzinistatic void tcg_out_nop_fill(tcg_insn_unit *p, int count) 419*139c1837SPaolo Bonzini{ 420*139c1837SPaolo Bonzini int i; 421*139c1837SPaolo Bonzini for (i = 0; i < count; ++i) { 422*139c1837SPaolo Bonzini p[i] = encode_i(OPC_ADDI, TCG_REG_ZERO, TCG_REG_ZERO, 0); 423*139c1837SPaolo Bonzini } 424*139c1837SPaolo Bonzini} 425*139c1837SPaolo Bonzini 426*139c1837SPaolo Bonzini/* 427*139c1837SPaolo Bonzini * Relocations 428*139c1837SPaolo Bonzini */ 429*139c1837SPaolo Bonzini 430*139c1837SPaolo Bonzinistatic bool reloc_sbimm12(tcg_insn_unit *code_ptr, tcg_insn_unit *target) 431*139c1837SPaolo Bonzini{ 432*139c1837SPaolo Bonzini intptr_t offset = (intptr_t)target - (intptr_t)code_ptr; 433*139c1837SPaolo Bonzini 434*139c1837SPaolo Bonzini if (offset == sextreg(offset, 1, 12) << 1) { 435*139c1837SPaolo Bonzini code_ptr[0] |= encode_sbimm12(offset); 436*139c1837SPaolo Bonzini return true; 437*139c1837SPaolo Bonzini } 438*139c1837SPaolo Bonzini 439*139c1837SPaolo Bonzini return false; 440*139c1837SPaolo Bonzini} 441*139c1837SPaolo Bonzini 442*139c1837SPaolo Bonzinistatic bool reloc_jimm20(tcg_insn_unit *code_ptr, tcg_insn_unit *target) 443*139c1837SPaolo Bonzini{ 444*139c1837SPaolo Bonzini intptr_t offset = (intptr_t)target - (intptr_t)code_ptr; 445*139c1837SPaolo Bonzini 446*139c1837SPaolo Bonzini if (offset == sextreg(offset, 1, 20) << 1) { 447*139c1837SPaolo Bonzini code_ptr[0] |= encode_ujimm20(offset); 448*139c1837SPaolo Bonzini return true; 449*139c1837SPaolo Bonzini } 450*139c1837SPaolo Bonzini 451*139c1837SPaolo Bonzini return false; 452*139c1837SPaolo Bonzini} 453*139c1837SPaolo Bonzini 454*139c1837SPaolo Bonzinistatic bool reloc_call(tcg_insn_unit *code_ptr, tcg_insn_unit *target) 455*139c1837SPaolo Bonzini{ 456*139c1837SPaolo Bonzini intptr_t offset = (intptr_t)target - (intptr_t)code_ptr; 457*139c1837SPaolo Bonzini int32_t lo = sextreg(offset, 0, 12); 458*139c1837SPaolo Bonzini int32_t hi = offset - lo; 459*139c1837SPaolo Bonzini 460*139c1837SPaolo Bonzini if (offset == hi + lo) { 461*139c1837SPaolo Bonzini code_ptr[0] |= encode_uimm20(hi); 462*139c1837SPaolo Bonzini code_ptr[1] |= encode_imm12(lo); 463*139c1837SPaolo Bonzini return true; 464*139c1837SPaolo Bonzini } 465*139c1837SPaolo Bonzini 466*139c1837SPaolo Bonzini return false; 467*139c1837SPaolo Bonzini} 468*139c1837SPaolo Bonzini 469*139c1837SPaolo Bonzinistatic bool patch_reloc(tcg_insn_unit *code_ptr, int type, 470*139c1837SPaolo Bonzini intptr_t value, intptr_t addend) 471*139c1837SPaolo Bonzini{ 472*139c1837SPaolo Bonzini uint32_t insn = *code_ptr; 473*139c1837SPaolo Bonzini intptr_t diff; 474*139c1837SPaolo Bonzini bool short_jmp; 475*139c1837SPaolo Bonzini 476*139c1837SPaolo Bonzini tcg_debug_assert(addend == 0); 477*139c1837SPaolo Bonzini 478*139c1837SPaolo Bonzini switch (type) { 479*139c1837SPaolo Bonzini case R_RISCV_BRANCH: 480*139c1837SPaolo Bonzini diff = value - (uintptr_t)code_ptr; 481*139c1837SPaolo Bonzini short_jmp = diff == sextreg(diff, 0, 12); 482*139c1837SPaolo Bonzini if (short_jmp) { 483*139c1837SPaolo Bonzini return reloc_sbimm12(code_ptr, (tcg_insn_unit *)value); 484*139c1837SPaolo Bonzini } else { 485*139c1837SPaolo Bonzini /* Invert the condition */ 486*139c1837SPaolo Bonzini insn = insn ^ (1 << 12); 487*139c1837SPaolo Bonzini /* Clear the offset */ 488*139c1837SPaolo Bonzini insn &= 0x01fff07f; 489*139c1837SPaolo Bonzini /* Set the offset to the PC + 8 */ 490*139c1837SPaolo Bonzini insn |= encode_sbimm12(8); 491*139c1837SPaolo Bonzini 492*139c1837SPaolo Bonzini /* Move forward */ 493*139c1837SPaolo Bonzini code_ptr[0] = insn; 494*139c1837SPaolo Bonzini 495*139c1837SPaolo Bonzini /* Overwrite the NOP with jal x0,value */ 496*139c1837SPaolo Bonzini diff = value - (uintptr_t)(code_ptr + 1); 497*139c1837SPaolo Bonzini insn = encode_uj(OPC_JAL, TCG_REG_ZERO, diff); 498*139c1837SPaolo Bonzini code_ptr[1] = insn; 499*139c1837SPaolo Bonzini 500*139c1837SPaolo Bonzini return true; 501*139c1837SPaolo Bonzini } 502*139c1837SPaolo Bonzini break; 503*139c1837SPaolo Bonzini case R_RISCV_JAL: 504*139c1837SPaolo Bonzini return reloc_jimm20(code_ptr, (tcg_insn_unit *)value); 505*139c1837SPaolo Bonzini case R_RISCV_CALL: 506*139c1837SPaolo Bonzini return reloc_call(code_ptr, (tcg_insn_unit *)value); 507*139c1837SPaolo Bonzini default: 508*139c1837SPaolo Bonzini tcg_abort(); 509*139c1837SPaolo Bonzini } 510*139c1837SPaolo Bonzini} 511*139c1837SPaolo Bonzini 512*139c1837SPaolo Bonzini/* 513*139c1837SPaolo Bonzini * TCG intrinsics 514*139c1837SPaolo Bonzini */ 515*139c1837SPaolo Bonzini 516*139c1837SPaolo Bonzinistatic bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg) 517*139c1837SPaolo Bonzini{ 518*139c1837SPaolo Bonzini if (ret == arg) { 519*139c1837SPaolo Bonzini return true; 520*139c1837SPaolo Bonzini } 521*139c1837SPaolo Bonzini switch (type) { 522*139c1837SPaolo Bonzini case TCG_TYPE_I32: 523*139c1837SPaolo Bonzini case TCG_TYPE_I64: 524*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_ADDI, ret, arg, 0); 525*139c1837SPaolo Bonzini break; 526*139c1837SPaolo Bonzini default: 527*139c1837SPaolo Bonzini g_assert_not_reached(); 528*139c1837SPaolo Bonzini } 529*139c1837SPaolo Bonzini return true; 530*139c1837SPaolo Bonzini} 531*139c1837SPaolo Bonzini 532*139c1837SPaolo Bonzinistatic void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd, 533*139c1837SPaolo Bonzini tcg_target_long val) 534*139c1837SPaolo Bonzini{ 535*139c1837SPaolo Bonzini tcg_target_long lo, hi, tmp; 536*139c1837SPaolo Bonzini int shift, ret; 537*139c1837SPaolo Bonzini 538*139c1837SPaolo Bonzini if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) { 539*139c1837SPaolo Bonzini val = (int32_t)val; 540*139c1837SPaolo Bonzini } 541*139c1837SPaolo Bonzini 542*139c1837SPaolo Bonzini lo = sextreg(val, 0, 12); 543*139c1837SPaolo Bonzini if (val == lo) { 544*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_ADDI, rd, TCG_REG_ZERO, lo); 545*139c1837SPaolo Bonzini return; 546*139c1837SPaolo Bonzini } 547*139c1837SPaolo Bonzini 548*139c1837SPaolo Bonzini hi = val - lo; 549*139c1837SPaolo Bonzini if (TCG_TARGET_REG_BITS == 32 || val == (int32_t)val) { 550*139c1837SPaolo Bonzini tcg_out_opc_upper(s, OPC_LUI, rd, hi); 551*139c1837SPaolo Bonzini if (lo != 0) { 552*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_ADDIW, rd, rd, lo); 553*139c1837SPaolo Bonzini } 554*139c1837SPaolo Bonzini return; 555*139c1837SPaolo Bonzini } 556*139c1837SPaolo Bonzini 557*139c1837SPaolo Bonzini /* We can only be here if TCG_TARGET_REG_BITS != 32 */ 558*139c1837SPaolo Bonzini tmp = tcg_pcrel_diff(s, (void *)val); 559*139c1837SPaolo Bonzini if (tmp == (int32_t)tmp) { 560*139c1837SPaolo Bonzini tcg_out_opc_upper(s, OPC_AUIPC, rd, 0); 561*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_ADDI, rd, rd, 0); 562*139c1837SPaolo Bonzini ret = reloc_call(s->code_ptr - 2, (tcg_insn_unit *)val); 563*139c1837SPaolo Bonzini tcg_debug_assert(ret == true); 564*139c1837SPaolo Bonzini return; 565*139c1837SPaolo Bonzini } 566*139c1837SPaolo Bonzini 567*139c1837SPaolo Bonzini /* Look for a single 20-bit section. */ 568*139c1837SPaolo Bonzini shift = ctz64(val); 569*139c1837SPaolo Bonzini tmp = val >> shift; 570*139c1837SPaolo Bonzini if (tmp == sextreg(tmp, 0, 20)) { 571*139c1837SPaolo Bonzini tcg_out_opc_upper(s, OPC_LUI, rd, tmp << 12); 572*139c1837SPaolo Bonzini if (shift > 12) { 573*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_SLLI, rd, rd, shift - 12); 574*139c1837SPaolo Bonzini } else { 575*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_SRAI, rd, rd, 12 - shift); 576*139c1837SPaolo Bonzini } 577*139c1837SPaolo Bonzini return; 578*139c1837SPaolo Bonzini } 579*139c1837SPaolo Bonzini 580*139c1837SPaolo Bonzini /* Look for a few high zero bits, with lots of bits set in the middle. */ 581*139c1837SPaolo Bonzini shift = clz64(val); 582*139c1837SPaolo Bonzini tmp = val << shift; 583*139c1837SPaolo Bonzini if (tmp == sextreg(tmp, 12, 20) << 12) { 584*139c1837SPaolo Bonzini tcg_out_opc_upper(s, OPC_LUI, rd, tmp); 585*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_SRLI, rd, rd, shift); 586*139c1837SPaolo Bonzini return; 587*139c1837SPaolo Bonzini } else if (tmp == sextreg(tmp, 0, 12)) { 588*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_ADDI, rd, TCG_REG_ZERO, tmp); 589*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_SRLI, rd, rd, shift); 590*139c1837SPaolo Bonzini return; 591*139c1837SPaolo Bonzini } 592*139c1837SPaolo Bonzini 593*139c1837SPaolo Bonzini /* Drop into the constant pool. */ 594*139c1837SPaolo Bonzini new_pool_label(s, val, R_RISCV_CALL, s->code_ptr, 0); 595*139c1837SPaolo Bonzini tcg_out_opc_upper(s, OPC_AUIPC, rd, 0); 596*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_LD, rd, rd, 0); 597*139c1837SPaolo Bonzini} 598*139c1837SPaolo Bonzini 599*139c1837SPaolo Bonzinistatic void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg) 600*139c1837SPaolo Bonzini{ 601*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_ANDI, ret, arg, 0xff); 602*139c1837SPaolo Bonzini} 603*139c1837SPaolo Bonzini 604*139c1837SPaolo Bonzinistatic void tcg_out_ext16u(TCGContext *s, TCGReg ret, TCGReg arg) 605*139c1837SPaolo Bonzini{ 606*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 16); 607*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_SRLIW, ret, ret, 16); 608*139c1837SPaolo Bonzini} 609*139c1837SPaolo Bonzini 610*139c1837SPaolo Bonzinistatic void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg) 611*139c1837SPaolo Bonzini{ 612*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_SLLI, ret, arg, 32); 613*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_SRLI, ret, ret, 32); 614*139c1837SPaolo Bonzini} 615*139c1837SPaolo Bonzini 616*139c1837SPaolo Bonzinistatic void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg) 617*139c1837SPaolo Bonzini{ 618*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 24); 619*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_SRAIW, ret, ret, 24); 620*139c1837SPaolo Bonzini} 621*139c1837SPaolo Bonzini 622*139c1837SPaolo Bonzinistatic void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg) 623*139c1837SPaolo Bonzini{ 624*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 16); 625*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_SRAIW, ret, ret, 16); 626*139c1837SPaolo Bonzini} 627*139c1837SPaolo Bonzini 628*139c1837SPaolo Bonzinistatic void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg) 629*139c1837SPaolo Bonzini{ 630*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_ADDIW, ret, arg, 0); 631*139c1837SPaolo Bonzini} 632*139c1837SPaolo Bonzini 633*139c1837SPaolo Bonzinistatic void tcg_out_ldst(TCGContext *s, RISCVInsn opc, TCGReg data, 634*139c1837SPaolo Bonzini TCGReg addr, intptr_t offset) 635*139c1837SPaolo Bonzini{ 636*139c1837SPaolo Bonzini intptr_t imm12 = sextreg(offset, 0, 12); 637*139c1837SPaolo Bonzini 638*139c1837SPaolo Bonzini if (offset != imm12) { 639*139c1837SPaolo Bonzini intptr_t diff = offset - (uintptr_t)s->code_ptr; 640*139c1837SPaolo Bonzini 641*139c1837SPaolo Bonzini if (addr == TCG_REG_ZERO && diff == (int32_t)diff) { 642*139c1837SPaolo Bonzini imm12 = sextreg(diff, 0, 12); 643*139c1837SPaolo Bonzini tcg_out_opc_upper(s, OPC_AUIPC, TCG_REG_TMP2, diff - imm12); 644*139c1837SPaolo Bonzini } else { 645*139c1837SPaolo Bonzini tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP2, offset - imm12); 646*139c1837SPaolo Bonzini if (addr != TCG_REG_ZERO) { 647*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP2, TCG_REG_TMP2, addr); 648*139c1837SPaolo Bonzini } 649*139c1837SPaolo Bonzini } 650*139c1837SPaolo Bonzini addr = TCG_REG_TMP2; 651*139c1837SPaolo Bonzini } 652*139c1837SPaolo Bonzini 653*139c1837SPaolo Bonzini switch (opc) { 654*139c1837SPaolo Bonzini case OPC_SB: 655*139c1837SPaolo Bonzini case OPC_SH: 656*139c1837SPaolo Bonzini case OPC_SW: 657*139c1837SPaolo Bonzini case OPC_SD: 658*139c1837SPaolo Bonzini tcg_out_opc_store(s, opc, addr, data, imm12); 659*139c1837SPaolo Bonzini break; 660*139c1837SPaolo Bonzini case OPC_LB: 661*139c1837SPaolo Bonzini case OPC_LBU: 662*139c1837SPaolo Bonzini case OPC_LH: 663*139c1837SPaolo Bonzini case OPC_LHU: 664*139c1837SPaolo Bonzini case OPC_LW: 665*139c1837SPaolo Bonzini case OPC_LWU: 666*139c1837SPaolo Bonzini case OPC_LD: 667*139c1837SPaolo Bonzini tcg_out_opc_imm(s, opc, data, addr, imm12); 668*139c1837SPaolo Bonzini break; 669*139c1837SPaolo Bonzini default: 670*139c1837SPaolo Bonzini g_assert_not_reached(); 671*139c1837SPaolo Bonzini } 672*139c1837SPaolo Bonzini} 673*139c1837SPaolo Bonzini 674*139c1837SPaolo Bonzinistatic void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg, 675*139c1837SPaolo Bonzini TCGReg arg1, intptr_t arg2) 676*139c1837SPaolo Bonzini{ 677*139c1837SPaolo Bonzini bool is32bit = (TCG_TARGET_REG_BITS == 32 || type == TCG_TYPE_I32); 678*139c1837SPaolo Bonzini tcg_out_ldst(s, is32bit ? OPC_LW : OPC_LD, arg, arg1, arg2); 679*139c1837SPaolo Bonzini} 680*139c1837SPaolo Bonzini 681*139c1837SPaolo Bonzinistatic void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, 682*139c1837SPaolo Bonzini TCGReg arg1, intptr_t arg2) 683*139c1837SPaolo Bonzini{ 684*139c1837SPaolo Bonzini bool is32bit = (TCG_TARGET_REG_BITS == 32 || type == TCG_TYPE_I32); 685*139c1837SPaolo Bonzini tcg_out_ldst(s, is32bit ? OPC_SW : OPC_SD, arg, arg1, arg2); 686*139c1837SPaolo Bonzini} 687*139c1837SPaolo Bonzini 688*139c1837SPaolo Bonzinistatic bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val, 689*139c1837SPaolo Bonzini TCGReg base, intptr_t ofs) 690*139c1837SPaolo Bonzini{ 691*139c1837SPaolo Bonzini if (val == 0) { 692*139c1837SPaolo Bonzini tcg_out_st(s, type, TCG_REG_ZERO, base, ofs); 693*139c1837SPaolo Bonzini return true; 694*139c1837SPaolo Bonzini } 695*139c1837SPaolo Bonzini return false; 696*139c1837SPaolo Bonzini} 697*139c1837SPaolo Bonzini 698*139c1837SPaolo Bonzinistatic void tcg_out_addsub2(TCGContext *s, 699*139c1837SPaolo Bonzini TCGReg rl, TCGReg rh, 700*139c1837SPaolo Bonzini TCGReg al, TCGReg ah, 701*139c1837SPaolo Bonzini TCGArg bl, TCGArg bh, 702*139c1837SPaolo Bonzini bool cbl, bool cbh, bool is_sub, bool is32bit) 703*139c1837SPaolo Bonzini{ 704*139c1837SPaolo Bonzini const RISCVInsn opc_add = is32bit ? OPC_ADDW : OPC_ADD; 705*139c1837SPaolo Bonzini const RISCVInsn opc_addi = is32bit ? OPC_ADDIW : OPC_ADDI; 706*139c1837SPaolo Bonzini const RISCVInsn opc_sub = is32bit ? OPC_SUBW : OPC_SUB; 707*139c1837SPaolo Bonzini TCGReg th = TCG_REG_TMP1; 708*139c1837SPaolo Bonzini 709*139c1837SPaolo Bonzini /* If we have a negative constant such that negating it would 710*139c1837SPaolo Bonzini make the high part zero, we can (usually) eliminate one insn. */ 711*139c1837SPaolo Bonzini if (cbl && cbh && bh == -1 && bl != 0) { 712*139c1837SPaolo Bonzini bl = -bl; 713*139c1837SPaolo Bonzini bh = 0; 714*139c1837SPaolo Bonzini is_sub = !is_sub; 715*139c1837SPaolo Bonzini } 716*139c1837SPaolo Bonzini 717*139c1837SPaolo Bonzini /* By operating on the high part first, we get to use the final 718*139c1837SPaolo Bonzini carry operation to move back from the temporary. */ 719*139c1837SPaolo Bonzini if (!cbh) { 720*139c1837SPaolo Bonzini tcg_out_opc_reg(s, (is_sub ? opc_sub : opc_add), th, ah, bh); 721*139c1837SPaolo Bonzini } else if (bh != 0 || ah == rl) { 722*139c1837SPaolo Bonzini tcg_out_opc_imm(s, opc_addi, th, ah, (is_sub ? -bh : bh)); 723*139c1837SPaolo Bonzini } else { 724*139c1837SPaolo Bonzini th = ah; 725*139c1837SPaolo Bonzini } 726*139c1837SPaolo Bonzini 727*139c1837SPaolo Bonzini /* Note that tcg optimization should eliminate the bl == 0 case. */ 728*139c1837SPaolo Bonzini if (is_sub) { 729*139c1837SPaolo Bonzini if (cbl) { 730*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_SLTIU, TCG_REG_TMP0, al, bl); 731*139c1837SPaolo Bonzini tcg_out_opc_imm(s, opc_addi, rl, al, -bl); 732*139c1837SPaolo Bonzini } else { 733*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_TMP0, al, bl); 734*139c1837SPaolo Bonzini tcg_out_opc_reg(s, opc_sub, rl, al, bl); 735*139c1837SPaolo Bonzini } 736*139c1837SPaolo Bonzini tcg_out_opc_reg(s, opc_sub, rh, th, TCG_REG_TMP0); 737*139c1837SPaolo Bonzini } else { 738*139c1837SPaolo Bonzini if (cbl) { 739*139c1837SPaolo Bonzini tcg_out_opc_imm(s, opc_addi, rl, al, bl); 740*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_SLTIU, TCG_REG_TMP0, rl, bl); 741*139c1837SPaolo Bonzini } else if (rl == al && rl == bl) { 742*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_SLTI, TCG_REG_TMP0, al, 0); 743*139c1837SPaolo Bonzini tcg_out_opc_reg(s, opc_addi, rl, al, bl); 744*139c1837SPaolo Bonzini } else { 745*139c1837SPaolo Bonzini tcg_out_opc_reg(s, opc_add, rl, al, bl); 746*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_TMP0, 747*139c1837SPaolo Bonzini rl, (rl == bl ? al : bl)); 748*139c1837SPaolo Bonzini } 749*139c1837SPaolo Bonzini tcg_out_opc_reg(s, opc_add, rh, th, TCG_REG_TMP0); 750*139c1837SPaolo Bonzini } 751*139c1837SPaolo Bonzini} 752*139c1837SPaolo Bonzini 753*139c1837SPaolo Bonzinistatic const struct { 754*139c1837SPaolo Bonzini RISCVInsn op; 755*139c1837SPaolo Bonzini bool swap; 756*139c1837SPaolo Bonzini} tcg_brcond_to_riscv[] = { 757*139c1837SPaolo Bonzini [TCG_COND_EQ] = { OPC_BEQ, false }, 758*139c1837SPaolo Bonzini [TCG_COND_NE] = { OPC_BNE, false }, 759*139c1837SPaolo Bonzini [TCG_COND_LT] = { OPC_BLT, false }, 760*139c1837SPaolo Bonzini [TCG_COND_GE] = { OPC_BGE, false }, 761*139c1837SPaolo Bonzini [TCG_COND_LE] = { OPC_BGE, true }, 762*139c1837SPaolo Bonzini [TCG_COND_GT] = { OPC_BLT, true }, 763*139c1837SPaolo Bonzini [TCG_COND_LTU] = { OPC_BLTU, false }, 764*139c1837SPaolo Bonzini [TCG_COND_GEU] = { OPC_BGEU, false }, 765*139c1837SPaolo Bonzini [TCG_COND_LEU] = { OPC_BGEU, true }, 766*139c1837SPaolo Bonzini [TCG_COND_GTU] = { OPC_BLTU, true } 767*139c1837SPaolo Bonzini}; 768*139c1837SPaolo Bonzini 769*139c1837SPaolo Bonzinistatic void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1, 770*139c1837SPaolo Bonzini TCGReg arg2, TCGLabel *l) 771*139c1837SPaolo Bonzini{ 772*139c1837SPaolo Bonzini RISCVInsn op = tcg_brcond_to_riscv[cond].op; 773*139c1837SPaolo Bonzini 774*139c1837SPaolo Bonzini tcg_debug_assert(op != 0); 775*139c1837SPaolo Bonzini 776*139c1837SPaolo Bonzini if (tcg_brcond_to_riscv[cond].swap) { 777*139c1837SPaolo Bonzini TCGReg t = arg1; 778*139c1837SPaolo Bonzini arg1 = arg2; 779*139c1837SPaolo Bonzini arg2 = t; 780*139c1837SPaolo Bonzini } 781*139c1837SPaolo Bonzini 782*139c1837SPaolo Bonzini if (l->has_value) { 783*139c1837SPaolo Bonzini intptr_t diff = tcg_pcrel_diff(s, l->u.value_ptr); 784*139c1837SPaolo Bonzini if (diff == sextreg(diff, 0, 12)) { 785*139c1837SPaolo Bonzini tcg_out_opc_branch(s, op, arg1, arg2, diff); 786*139c1837SPaolo Bonzini } else { 787*139c1837SPaolo Bonzini /* Invert the conditional branch. */ 788*139c1837SPaolo Bonzini tcg_out_opc_branch(s, op ^ (1 << 12), arg1, arg2, 8); 789*139c1837SPaolo Bonzini tcg_out_opc_jump(s, OPC_JAL, TCG_REG_ZERO, diff - 4); 790*139c1837SPaolo Bonzini } 791*139c1837SPaolo Bonzini } else { 792*139c1837SPaolo Bonzini tcg_out_reloc(s, s->code_ptr, R_RISCV_BRANCH, l, 0); 793*139c1837SPaolo Bonzini tcg_out_opc_branch(s, op, arg1, arg2, 0); 794*139c1837SPaolo Bonzini /* NOP to allow patching later */ 795*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_ADDI, TCG_REG_ZERO, TCG_REG_ZERO, 0); 796*139c1837SPaolo Bonzini } 797*139c1837SPaolo Bonzini} 798*139c1837SPaolo Bonzini 799*139c1837SPaolo Bonzinistatic void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret, 800*139c1837SPaolo Bonzini TCGReg arg1, TCGReg arg2) 801*139c1837SPaolo Bonzini{ 802*139c1837SPaolo Bonzini switch (cond) { 803*139c1837SPaolo Bonzini case TCG_COND_EQ: 804*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_SUB, ret, arg1, arg2); 805*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_SLTIU, ret, ret, 1); 806*139c1837SPaolo Bonzini break; 807*139c1837SPaolo Bonzini case TCG_COND_NE: 808*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_SUB, ret, arg1, arg2); 809*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, ret); 810*139c1837SPaolo Bonzini break; 811*139c1837SPaolo Bonzini case TCG_COND_LT: 812*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2); 813*139c1837SPaolo Bonzini break; 814*139c1837SPaolo Bonzini case TCG_COND_GE: 815*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2); 816*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1); 817*139c1837SPaolo Bonzini break; 818*139c1837SPaolo Bonzini case TCG_COND_LE: 819*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1); 820*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1); 821*139c1837SPaolo Bonzini break; 822*139c1837SPaolo Bonzini case TCG_COND_GT: 823*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1); 824*139c1837SPaolo Bonzini break; 825*139c1837SPaolo Bonzini case TCG_COND_LTU: 826*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2); 827*139c1837SPaolo Bonzini break; 828*139c1837SPaolo Bonzini case TCG_COND_GEU: 829*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2); 830*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1); 831*139c1837SPaolo Bonzini break; 832*139c1837SPaolo Bonzini case TCG_COND_LEU: 833*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1); 834*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1); 835*139c1837SPaolo Bonzini break; 836*139c1837SPaolo Bonzini case TCG_COND_GTU: 837*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1); 838*139c1837SPaolo Bonzini break; 839*139c1837SPaolo Bonzini default: 840*139c1837SPaolo Bonzini g_assert_not_reached(); 841*139c1837SPaolo Bonzini break; 842*139c1837SPaolo Bonzini } 843*139c1837SPaolo Bonzini} 844*139c1837SPaolo Bonzini 845*139c1837SPaolo Bonzinistatic void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGReg al, TCGReg ah, 846*139c1837SPaolo Bonzini TCGReg bl, TCGReg bh, TCGLabel *l) 847*139c1837SPaolo Bonzini{ 848*139c1837SPaolo Bonzini /* todo */ 849*139c1837SPaolo Bonzini g_assert_not_reached(); 850*139c1837SPaolo Bonzini} 851*139c1837SPaolo Bonzini 852*139c1837SPaolo Bonzinistatic void tcg_out_setcond2(TCGContext *s, TCGCond cond, TCGReg ret, 853*139c1837SPaolo Bonzini TCGReg al, TCGReg ah, TCGReg bl, TCGReg bh) 854*139c1837SPaolo Bonzini{ 855*139c1837SPaolo Bonzini /* todo */ 856*139c1837SPaolo Bonzini g_assert_not_reached(); 857*139c1837SPaolo Bonzini} 858*139c1837SPaolo Bonzini 859*139c1837SPaolo Bonzinistatic inline void tcg_out_goto(TCGContext *s, tcg_insn_unit *target) 860*139c1837SPaolo Bonzini{ 861*139c1837SPaolo Bonzini ptrdiff_t offset = tcg_pcrel_diff(s, target); 862*139c1837SPaolo Bonzini tcg_debug_assert(offset == sextreg(offset, 1, 20) << 1); 863*139c1837SPaolo Bonzini tcg_out_opc_jump(s, OPC_JAL, TCG_REG_ZERO, offset); 864*139c1837SPaolo Bonzini} 865*139c1837SPaolo Bonzini 866*139c1837SPaolo Bonzinistatic void tcg_out_call_int(TCGContext *s, tcg_insn_unit *arg, bool tail) 867*139c1837SPaolo Bonzini{ 868*139c1837SPaolo Bonzini TCGReg link = tail ? TCG_REG_ZERO : TCG_REG_RA; 869*139c1837SPaolo Bonzini ptrdiff_t offset = tcg_pcrel_diff(s, arg); 870*139c1837SPaolo Bonzini int ret; 871*139c1837SPaolo Bonzini 872*139c1837SPaolo Bonzini if (offset == sextreg(offset, 1, 20) << 1) { 873*139c1837SPaolo Bonzini /* short jump: -2097150 to 2097152 */ 874*139c1837SPaolo Bonzini tcg_out_opc_jump(s, OPC_JAL, link, offset); 875*139c1837SPaolo Bonzini } else if (TCG_TARGET_REG_BITS == 32 || 876*139c1837SPaolo Bonzini offset == sextreg(offset, 1, 31) << 1) { 877*139c1837SPaolo Bonzini /* long jump: -2147483646 to 2147483648 */ 878*139c1837SPaolo Bonzini tcg_out_opc_upper(s, OPC_AUIPC, TCG_REG_TMP0, 0); 879*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_JALR, link, TCG_REG_TMP0, 0); 880*139c1837SPaolo Bonzini ret = reloc_call(s->code_ptr - 2, arg);\ 881*139c1837SPaolo Bonzini tcg_debug_assert(ret == true); 882*139c1837SPaolo Bonzini } else if (TCG_TARGET_REG_BITS == 64) { 883*139c1837SPaolo Bonzini /* far jump: 64-bit */ 884*139c1837SPaolo Bonzini tcg_target_long imm = sextreg((tcg_target_long)arg, 0, 12); 885*139c1837SPaolo Bonzini tcg_target_long base = (tcg_target_long)arg - imm; 886*139c1837SPaolo Bonzini tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP0, base); 887*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_JALR, link, TCG_REG_TMP0, imm); 888*139c1837SPaolo Bonzini } else { 889*139c1837SPaolo Bonzini g_assert_not_reached(); 890*139c1837SPaolo Bonzini } 891*139c1837SPaolo Bonzini} 892*139c1837SPaolo Bonzini 893*139c1837SPaolo Bonzinistatic void tcg_out_call(TCGContext *s, tcg_insn_unit *arg) 894*139c1837SPaolo Bonzini{ 895*139c1837SPaolo Bonzini tcg_out_call_int(s, arg, false); 896*139c1837SPaolo Bonzini} 897*139c1837SPaolo Bonzini 898*139c1837SPaolo Bonzinistatic void tcg_out_mb(TCGContext *s, TCGArg a0) 899*139c1837SPaolo Bonzini{ 900*139c1837SPaolo Bonzini tcg_insn_unit insn = OPC_FENCE; 901*139c1837SPaolo Bonzini 902*139c1837SPaolo Bonzini if (a0 & TCG_MO_LD_LD) { 903*139c1837SPaolo Bonzini insn |= 0x02200000; 904*139c1837SPaolo Bonzini } 905*139c1837SPaolo Bonzini if (a0 & TCG_MO_ST_LD) { 906*139c1837SPaolo Bonzini insn |= 0x01200000; 907*139c1837SPaolo Bonzini } 908*139c1837SPaolo Bonzini if (a0 & TCG_MO_LD_ST) { 909*139c1837SPaolo Bonzini insn |= 0x02100000; 910*139c1837SPaolo Bonzini } 911*139c1837SPaolo Bonzini if (a0 & TCG_MO_ST_ST) { 912*139c1837SPaolo Bonzini insn |= 0x02200000; 913*139c1837SPaolo Bonzini } 914*139c1837SPaolo Bonzini tcg_out32(s, insn); 915*139c1837SPaolo Bonzini} 916*139c1837SPaolo Bonzini 917*139c1837SPaolo Bonzini/* 918*139c1837SPaolo Bonzini * Load/store and TLB 919*139c1837SPaolo Bonzini */ 920*139c1837SPaolo Bonzini 921*139c1837SPaolo Bonzini#if defined(CONFIG_SOFTMMU) 922*139c1837SPaolo Bonzini#include "../tcg-ldst.c.inc" 923*139c1837SPaolo Bonzini 924*139c1837SPaolo Bonzini/* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr, 925*139c1837SPaolo Bonzini * TCGMemOpIdx oi, uintptr_t ra) 926*139c1837SPaolo Bonzini */ 927*139c1837SPaolo Bonzinistatic void * const qemu_ld_helpers[16] = { 928*139c1837SPaolo Bonzini [MO_UB] = helper_ret_ldub_mmu, 929*139c1837SPaolo Bonzini [MO_SB] = helper_ret_ldsb_mmu, 930*139c1837SPaolo Bonzini [MO_LEUW] = helper_le_lduw_mmu, 931*139c1837SPaolo Bonzini [MO_LESW] = helper_le_ldsw_mmu, 932*139c1837SPaolo Bonzini [MO_LEUL] = helper_le_ldul_mmu, 933*139c1837SPaolo Bonzini#if TCG_TARGET_REG_BITS == 64 934*139c1837SPaolo Bonzini [MO_LESL] = helper_le_ldsl_mmu, 935*139c1837SPaolo Bonzini#endif 936*139c1837SPaolo Bonzini [MO_LEQ] = helper_le_ldq_mmu, 937*139c1837SPaolo Bonzini [MO_BEUW] = helper_be_lduw_mmu, 938*139c1837SPaolo Bonzini [MO_BESW] = helper_be_ldsw_mmu, 939*139c1837SPaolo Bonzini [MO_BEUL] = helper_be_ldul_mmu, 940*139c1837SPaolo Bonzini#if TCG_TARGET_REG_BITS == 64 941*139c1837SPaolo Bonzini [MO_BESL] = helper_be_ldsl_mmu, 942*139c1837SPaolo Bonzini#endif 943*139c1837SPaolo Bonzini [MO_BEQ] = helper_be_ldq_mmu, 944*139c1837SPaolo Bonzini}; 945*139c1837SPaolo Bonzini 946*139c1837SPaolo Bonzini/* helper signature: helper_ret_st_mmu(CPUState *env, target_ulong addr, 947*139c1837SPaolo Bonzini * uintxx_t val, TCGMemOpIdx oi, 948*139c1837SPaolo Bonzini * uintptr_t ra) 949*139c1837SPaolo Bonzini */ 950*139c1837SPaolo Bonzinistatic void * const qemu_st_helpers[16] = { 951*139c1837SPaolo Bonzini [MO_UB] = helper_ret_stb_mmu, 952*139c1837SPaolo Bonzini [MO_LEUW] = helper_le_stw_mmu, 953*139c1837SPaolo Bonzini [MO_LEUL] = helper_le_stl_mmu, 954*139c1837SPaolo Bonzini [MO_LEQ] = helper_le_stq_mmu, 955*139c1837SPaolo Bonzini [MO_BEUW] = helper_be_stw_mmu, 956*139c1837SPaolo Bonzini [MO_BEUL] = helper_be_stl_mmu, 957*139c1837SPaolo Bonzini [MO_BEQ] = helper_be_stq_mmu, 958*139c1837SPaolo Bonzini}; 959*139c1837SPaolo Bonzini 960*139c1837SPaolo Bonzini/* We don't support oversize guests */ 961*139c1837SPaolo BonziniQEMU_BUILD_BUG_ON(TCG_TARGET_REG_BITS < TARGET_LONG_BITS); 962*139c1837SPaolo Bonzini 963*139c1837SPaolo Bonzini/* We expect to use a 12-bit negative offset from ENV. */ 964*139c1837SPaolo BonziniQEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0); 965*139c1837SPaolo BonziniQEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -(1 << 11)); 966*139c1837SPaolo Bonzini 967*139c1837SPaolo Bonzinistatic void tcg_out_tlb_load(TCGContext *s, TCGReg addrl, 968*139c1837SPaolo Bonzini TCGReg addrh, TCGMemOpIdx oi, 969*139c1837SPaolo Bonzini tcg_insn_unit **label_ptr, bool is_load) 970*139c1837SPaolo Bonzini{ 971*139c1837SPaolo Bonzini MemOp opc = get_memop(oi); 972*139c1837SPaolo Bonzini unsigned s_bits = opc & MO_SIZE; 973*139c1837SPaolo Bonzini unsigned a_bits = get_alignment_bits(opc); 974*139c1837SPaolo Bonzini tcg_target_long compare_mask; 975*139c1837SPaolo Bonzini int mem_index = get_mmuidx(oi); 976*139c1837SPaolo Bonzini int fast_ofs = TLB_MASK_TABLE_OFS(mem_index); 977*139c1837SPaolo Bonzini int mask_ofs = fast_ofs + offsetof(CPUTLBDescFast, mask); 978*139c1837SPaolo Bonzini int table_ofs = fast_ofs + offsetof(CPUTLBDescFast, table); 979*139c1837SPaolo Bonzini TCGReg mask_base = TCG_AREG0, table_base = TCG_AREG0; 980*139c1837SPaolo Bonzini 981*139c1837SPaolo Bonzini tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, mask_base, mask_ofs); 982*139c1837SPaolo Bonzini tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, table_base, table_ofs); 983*139c1837SPaolo Bonzini 984*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_SRLI, TCG_REG_TMP2, addrl, 985*139c1837SPaolo Bonzini TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); 986*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_AND, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP0); 987*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP1); 988*139c1837SPaolo Bonzini 989*139c1837SPaolo Bonzini /* Load the tlb comparator and the addend. */ 990*139c1837SPaolo Bonzini tcg_out_ld(s, TCG_TYPE_TL, TCG_REG_TMP0, TCG_REG_TMP2, 991*139c1837SPaolo Bonzini is_load ? offsetof(CPUTLBEntry, addr_read) 992*139c1837SPaolo Bonzini : offsetof(CPUTLBEntry, addr_write)); 993*139c1837SPaolo Bonzini tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP2, TCG_REG_TMP2, 994*139c1837SPaolo Bonzini offsetof(CPUTLBEntry, addend)); 995*139c1837SPaolo Bonzini 996*139c1837SPaolo Bonzini /* We don't support unaligned accesses. */ 997*139c1837SPaolo Bonzini if (a_bits < s_bits) { 998*139c1837SPaolo Bonzini a_bits = s_bits; 999*139c1837SPaolo Bonzini } 1000*139c1837SPaolo Bonzini /* Clear the non-page, non-alignment bits from the address. */ 1001*139c1837SPaolo Bonzini compare_mask = (tcg_target_long)TARGET_PAGE_MASK | ((1 << a_bits) - 1); 1002*139c1837SPaolo Bonzini if (compare_mask == sextreg(compare_mask, 0, 12)) { 1003*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_TMP1, addrl, compare_mask); 1004*139c1837SPaolo Bonzini } else { 1005*139c1837SPaolo Bonzini tcg_out_movi(s, TCG_TYPE_TL, TCG_REG_TMP1, compare_mask); 1006*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_AND, TCG_REG_TMP1, TCG_REG_TMP1, addrl); 1007*139c1837SPaolo Bonzini } 1008*139c1837SPaolo Bonzini 1009*139c1837SPaolo Bonzini /* Compare masked address with the TLB entry. */ 1010*139c1837SPaolo Bonzini label_ptr[0] = s->code_ptr; 1011*139c1837SPaolo Bonzini tcg_out_opc_branch(s, OPC_BNE, TCG_REG_TMP0, TCG_REG_TMP1, 0); 1012*139c1837SPaolo Bonzini /* NOP to allow patching later */ 1013*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_ADDI, TCG_REG_ZERO, TCG_REG_ZERO, 0); 1014*139c1837SPaolo Bonzini 1015*139c1837SPaolo Bonzini /* TLB Hit - translate address using addend. */ 1016*139c1837SPaolo Bonzini if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) { 1017*139c1837SPaolo Bonzini tcg_out_ext32u(s, TCG_REG_TMP0, addrl); 1018*139c1837SPaolo Bonzini addrl = TCG_REG_TMP0; 1019*139c1837SPaolo Bonzini } 1020*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, TCG_REG_TMP2, addrl); 1021*139c1837SPaolo Bonzini} 1022*139c1837SPaolo Bonzini 1023*139c1837SPaolo Bonzinistatic void add_qemu_ldst_label(TCGContext *s, int is_ld, TCGMemOpIdx oi, 1024*139c1837SPaolo Bonzini TCGType ext, 1025*139c1837SPaolo Bonzini TCGReg datalo, TCGReg datahi, 1026*139c1837SPaolo Bonzini TCGReg addrlo, TCGReg addrhi, 1027*139c1837SPaolo Bonzini void *raddr, tcg_insn_unit **label_ptr) 1028*139c1837SPaolo Bonzini{ 1029*139c1837SPaolo Bonzini TCGLabelQemuLdst *label = new_ldst_label(s); 1030*139c1837SPaolo Bonzini 1031*139c1837SPaolo Bonzini label->is_ld = is_ld; 1032*139c1837SPaolo Bonzini label->oi = oi; 1033*139c1837SPaolo Bonzini label->type = ext; 1034*139c1837SPaolo Bonzini label->datalo_reg = datalo; 1035*139c1837SPaolo Bonzini label->datahi_reg = datahi; 1036*139c1837SPaolo Bonzini label->addrlo_reg = addrlo; 1037*139c1837SPaolo Bonzini label->addrhi_reg = addrhi; 1038*139c1837SPaolo Bonzini label->raddr = raddr; 1039*139c1837SPaolo Bonzini label->label_ptr[0] = label_ptr[0]; 1040*139c1837SPaolo Bonzini} 1041*139c1837SPaolo Bonzini 1042*139c1837SPaolo Bonzinistatic bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) 1043*139c1837SPaolo Bonzini{ 1044*139c1837SPaolo Bonzini TCGMemOpIdx oi = l->oi; 1045*139c1837SPaolo Bonzini MemOp opc = get_memop(oi); 1046*139c1837SPaolo Bonzini TCGReg a0 = tcg_target_call_iarg_regs[0]; 1047*139c1837SPaolo Bonzini TCGReg a1 = tcg_target_call_iarg_regs[1]; 1048*139c1837SPaolo Bonzini TCGReg a2 = tcg_target_call_iarg_regs[2]; 1049*139c1837SPaolo Bonzini TCGReg a3 = tcg_target_call_iarg_regs[3]; 1050*139c1837SPaolo Bonzini 1051*139c1837SPaolo Bonzini /* We don't support oversize guests */ 1052*139c1837SPaolo Bonzini if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) { 1053*139c1837SPaolo Bonzini g_assert_not_reached(); 1054*139c1837SPaolo Bonzini } 1055*139c1837SPaolo Bonzini 1056*139c1837SPaolo Bonzini /* resolve label address */ 1057*139c1837SPaolo Bonzini if (!patch_reloc(l->label_ptr[0], R_RISCV_BRANCH, 1058*139c1837SPaolo Bonzini (intptr_t) s->code_ptr, 0)) { 1059*139c1837SPaolo Bonzini return false; 1060*139c1837SPaolo Bonzini } 1061*139c1837SPaolo Bonzini 1062*139c1837SPaolo Bonzini /* call load helper */ 1063*139c1837SPaolo Bonzini tcg_out_mov(s, TCG_TYPE_PTR, a0, TCG_AREG0); 1064*139c1837SPaolo Bonzini tcg_out_mov(s, TCG_TYPE_PTR, a1, l->addrlo_reg); 1065*139c1837SPaolo Bonzini tcg_out_movi(s, TCG_TYPE_PTR, a2, oi); 1066*139c1837SPaolo Bonzini tcg_out_movi(s, TCG_TYPE_PTR, a3, (tcg_target_long)l->raddr); 1067*139c1837SPaolo Bonzini 1068*139c1837SPaolo Bonzini tcg_out_call(s, qemu_ld_helpers[opc & (MO_BSWAP | MO_SSIZE)]); 1069*139c1837SPaolo Bonzini tcg_out_mov(s, (opc & MO_SIZE) == MO_64, l->datalo_reg, a0); 1070*139c1837SPaolo Bonzini 1071*139c1837SPaolo Bonzini tcg_out_goto(s, l->raddr); 1072*139c1837SPaolo Bonzini return true; 1073*139c1837SPaolo Bonzini} 1074*139c1837SPaolo Bonzini 1075*139c1837SPaolo Bonzinistatic bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l) 1076*139c1837SPaolo Bonzini{ 1077*139c1837SPaolo Bonzini TCGMemOpIdx oi = l->oi; 1078*139c1837SPaolo Bonzini MemOp opc = get_memop(oi); 1079*139c1837SPaolo Bonzini MemOp s_bits = opc & MO_SIZE; 1080*139c1837SPaolo Bonzini TCGReg a0 = tcg_target_call_iarg_regs[0]; 1081*139c1837SPaolo Bonzini TCGReg a1 = tcg_target_call_iarg_regs[1]; 1082*139c1837SPaolo Bonzini TCGReg a2 = tcg_target_call_iarg_regs[2]; 1083*139c1837SPaolo Bonzini TCGReg a3 = tcg_target_call_iarg_regs[3]; 1084*139c1837SPaolo Bonzini TCGReg a4 = tcg_target_call_iarg_regs[4]; 1085*139c1837SPaolo Bonzini 1086*139c1837SPaolo Bonzini /* We don't support oversize guests */ 1087*139c1837SPaolo Bonzini if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) { 1088*139c1837SPaolo Bonzini g_assert_not_reached(); 1089*139c1837SPaolo Bonzini } 1090*139c1837SPaolo Bonzini 1091*139c1837SPaolo Bonzini /* resolve label address */ 1092*139c1837SPaolo Bonzini if (!patch_reloc(l->label_ptr[0], R_RISCV_BRANCH, 1093*139c1837SPaolo Bonzini (intptr_t) s->code_ptr, 0)) { 1094*139c1837SPaolo Bonzini return false; 1095*139c1837SPaolo Bonzini } 1096*139c1837SPaolo Bonzini 1097*139c1837SPaolo Bonzini /* call store helper */ 1098*139c1837SPaolo Bonzini tcg_out_mov(s, TCG_TYPE_PTR, a0, TCG_AREG0); 1099*139c1837SPaolo Bonzini tcg_out_mov(s, TCG_TYPE_PTR, a1, l->addrlo_reg); 1100*139c1837SPaolo Bonzini tcg_out_mov(s, TCG_TYPE_PTR, a2, l->datalo_reg); 1101*139c1837SPaolo Bonzini switch (s_bits) { 1102*139c1837SPaolo Bonzini case MO_8: 1103*139c1837SPaolo Bonzini tcg_out_ext8u(s, a2, a2); 1104*139c1837SPaolo Bonzini break; 1105*139c1837SPaolo Bonzini case MO_16: 1106*139c1837SPaolo Bonzini tcg_out_ext16u(s, a2, a2); 1107*139c1837SPaolo Bonzini break; 1108*139c1837SPaolo Bonzini default: 1109*139c1837SPaolo Bonzini break; 1110*139c1837SPaolo Bonzini } 1111*139c1837SPaolo Bonzini tcg_out_movi(s, TCG_TYPE_PTR, a3, oi); 1112*139c1837SPaolo Bonzini tcg_out_movi(s, TCG_TYPE_PTR, a4, (tcg_target_long)l->raddr); 1113*139c1837SPaolo Bonzini 1114*139c1837SPaolo Bonzini tcg_out_call(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SSIZE)]); 1115*139c1837SPaolo Bonzini 1116*139c1837SPaolo Bonzini tcg_out_goto(s, l->raddr); 1117*139c1837SPaolo Bonzini return true; 1118*139c1837SPaolo Bonzini} 1119*139c1837SPaolo Bonzini#endif /* CONFIG_SOFTMMU */ 1120*139c1837SPaolo Bonzini 1121*139c1837SPaolo Bonzinistatic void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg lo, TCGReg hi, 1122*139c1837SPaolo Bonzini TCGReg base, MemOp opc, bool is_64) 1123*139c1837SPaolo Bonzini{ 1124*139c1837SPaolo Bonzini const MemOp bswap = opc & MO_BSWAP; 1125*139c1837SPaolo Bonzini 1126*139c1837SPaolo Bonzini /* We don't yet handle byteswapping, assert */ 1127*139c1837SPaolo Bonzini g_assert(!bswap); 1128*139c1837SPaolo Bonzini 1129*139c1837SPaolo Bonzini switch (opc & (MO_SSIZE)) { 1130*139c1837SPaolo Bonzini case MO_UB: 1131*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_LBU, lo, base, 0); 1132*139c1837SPaolo Bonzini break; 1133*139c1837SPaolo Bonzini case MO_SB: 1134*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_LB, lo, base, 0); 1135*139c1837SPaolo Bonzini break; 1136*139c1837SPaolo Bonzini case MO_UW: 1137*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_LHU, lo, base, 0); 1138*139c1837SPaolo Bonzini break; 1139*139c1837SPaolo Bonzini case MO_SW: 1140*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_LH, lo, base, 0); 1141*139c1837SPaolo Bonzini break; 1142*139c1837SPaolo Bonzini case MO_UL: 1143*139c1837SPaolo Bonzini if (TCG_TARGET_REG_BITS == 64 && is_64) { 1144*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_LWU, lo, base, 0); 1145*139c1837SPaolo Bonzini break; 1146*139c1837SPaolo Bonzini } 1147*139c1837SPaolo Bonzini /* FALLTHRU */ 1148*139c1837SPaolo Bonzini case MO_SL: 1149*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_LW, lo, base, 0); 1150*139c1837SPaolo Bonzini break; 1151*139c1837SPaolo Bonzini case MO_Q: 1152*139c1837SPaolo Bonzini /* Prefer to load from offset 0 first, but allow for overlap. */ 1153*139c1837SPaolo Bonzini if (TCG_TARGET_REG_BITS == 64) { 1154*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_LD, lo, base, 0); 1155*139c1837SPaolo Bonzini } else if (lo != base) { 1156*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_LW, lo, base, 0); 1157*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_LW, hi, base, 4); 1158*139c1837SPaolo Bonzini } else { 1159*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_LW, hi, base, 4); 1160*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_LW, lo, base, 0); 1161*139c1837SPaolo Bonzini } 1162*139c1837SPaolo Bonzini break; 1163*139c1837SPaolo Bonzini default: 1164*139c1837SPaolo Bonzini g_assert_not_reached(); 1165*139c1837SPaolo Bonzini } 1166*139c1837SPaolo Bonzini} 1167*139c1837SPaolo Bonzini 1168*139c1837SPaolo Bonzinistatic void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64) 1169*139c1837SPaolo Bonzini{ 1170*139c1837SPaolo Bonzini TCGReg addr_regl, addr_regh __attribute__((unused)); 1171*139c1837SPaolo Bonzini TCGReg data_regl, data_regh; 1172*139c1837SPaolo Bonzini TCGMemOpIdx oi; 1173*139c1837SPaolo Bonzini MemOp opc; 1174*139c1837SPaolo Bonzini#if defined(CONFIG_SOFTMMU) 1175*139c1837SPaolo Bonzini tcg_insn_unit *label_ptr[1]; 1176*139c1837SPaolo Bonzini#endif 1177*139c1837SPaolo Bonzini TCGReg base = TCG_REG_TMP0; 1178*139c1837SPaolo Bonzini 1179*139c1837SPaolo Bonzini data_regl = *args++; 1180*139c1837SPaolo Bonzini data_regh = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0); 1181*139c1837SPaolo Bonzini addr_regl = *args++; 1182*139c1837SPaolo Bonzini addr_regh = (TCG_TARGET_REG_BITS < TARGET_LONG_BITS ? *args++ : 0); 1183*139c1837SPaolo Bonzini oi = *args++; 1184*139c1837SPaolo Bonzini opc = get_memop(oi); 1185*139c1837SPaolo Bonzini 1186*139c1837SPaolo Bonzini#if defined(CONFIG_SOFTMMU) 1187*139c1837SPaolo Bonzini tcg_out_tlb_load(s, addr_regl, addr_regh, oi, label_ptr, 1); 1188*139c1837SPaolo Bonzini tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc, is_64); 1189*139c1837SPaolo Bonzini add_qemu_ldst_label(s, 1, oi, 1190*139c1837SPaolo Bonzini (is_64 ? TCG_TYPE_I64 : TCG_TYPE_I32), 1191*139c1837SPaolo Bonzini data_regl, data_regh, addr_regl, addr_regh, 1192*139c1837SPaolo Bonzini s->code_ptr, label_ptr); 1193*139c1837SPaolo Bonzini#else 1194*139c1837SPaolo Bonzini if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) { 1195*139c1837SPaolo Bonzini tcg_out_ext32u(s, base, addr_regl); 1196*139c1837SPaolo Bonzini addr_regl = base; 1197*139c1837SPaolo Bonzini } 1198*139c1837SPaolo Bonzini 1199*139c1837SPaolo Bonzini if (guest_base == 0) { 1200*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_ADD, base, addr_regl, TCG_REG_ZERO); 1201*139c1837SPaolo Bonzini } else { 1202*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_ADD, base, TCG_GUEST_BASE_REG, addr_regl); 1203*139c1837SPaolo Bonzini } 1204*139c1837SPaolo Bonzini tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc, is_64); 1205*139c1837SPaolo Bonzini#endif 1206*139c1837SPaolo Bonzini} 1207*139c1837SPaolo Bonzini 1208*139c1837SPaolo Bonzinistatic void tcg_out_qemu_st_direct(TCGContext *s, TCGReg lo, TCGReg hi, 1209*139c1837SPaolo Bonzini TCGReg base, MemOp opc) 1210*139c1837SPaolo Bonzini{ 1211*139c1837SPaolo Bonzini const MemOp bswap = opc & MO_BSWAP; 1212*139c1837SPaolo Bonzini 1213*139c1837SPaolo Bonzini /* We don't yet handle byteswapping, assert */ 1214*139c1837SPaolo Bonzini g_assert(!bswap); 1215*139c1837SPaolo Bonzini 1216*139c1837SPaolo Bonzini switch (opc & (MO_SSIZE)) { 1217*139c1837SPaolo Bonzini case MO_8: 1218*139c1837SPaolo Bonzini tcg_out_opc_store(s, OPC_SB, base, lo, 0); 1219*139c1837SPaolo Bonzini break; 1220*139c1837SPaolo Bonzini case MO_16: 1221*139c1837SPaolo Bonzini tcg_out_opc_store(s, OPC_SH, base, lo, 0); 1222*139c1837SPaolo Bonzini break; 1223*139c1837SPaolo Bonzini case MO_32: 1224*139c1837SPaolo Bonzini tcg_out_opc_store(s, OPC_SW, base, lo, 0); 1225*139c1837SPaolo Bonzini break; 1226*139c1837SPaolo Bonzini case MO_64: 1227*139c1837SPaolo Bonzini if (TCG_TARGET_REG_BITS == 64) { 1228*139c1837SPaolo Bonzini tcg_out_opc_store(s, OPC_SD, base, lo, 0); 1229*139c1837SPaolo Bonzini } else { 1230*139c1837SPaolo Bonzini tcg_out_opc_store(s, OPC_SW, base, lo, 0); 1231*139c1837SPaolo Bonzini tcg_out_opc_store(s, OPC_SW, base, hi, 4); 1232*139c1837SPaolo Bonzini } 1233*139c1837SPaolo Bonzini break; 1234*139c1837SPaolo Bonzini default: 1235*139c1837SPaolo Bonzini g_assert_not_reached(); 1236*139c1837SPaolo Bonzini } 1237*139c1837SPaolo Bonzini} 1238*139c1837SPaolo Bonzini 1239*139c1837SPaolo Bonzinistatic void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64) 1240*139c1837SPaolo Bonzini{ 1241*139c1837SPaolo Bonzini TCGReg addr_regl, addr_regh __attribute__((unused)); 1242*139c1837SPaolo Bonzini TCGReg data_regl, data_regh; 1243*139c1837SPaolo Bonzini TCGMemOpIdx oi; 1244*139c1837SPaolo Bonzini MemOp opc; 1245*139c1837SPaolo Bonzini#if defined(CONFIG_SOFTMMU) 1246*139c1837SPaolo Bonzini tcg_insn_unit *label_ptr[1]; 1247*139c1837SPaolo Bonzini#endif 1248*139c1837SPaolo Bonzini TCGReg base = TCG_REG_TMP0; 1249*139c1837SPaolo Bonzini 1250*139c1837SPaolo Bonzini data_regl = *args++; 1251*139c1837SPaolo Bonzini data_regh = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0); 1252*139c1837SPaolo Bonzini addr_regl = *args++; 1253*139c1837SPaolo Bonzini addr_regh = (TCG_TARGET_REG_BITS < TARGET_LONG_BITS ? *args++ : 0); 1254*139c1837SPaolo Bonzini oi = *args++; 1255*139c1837SPaolo Bonzini opc = get_memop(oi); 1256*139c1837SPaolo Bonzini 1257*139c1837SPaolo Bonzini#if defined(CONFIG_SOFTMMU) 1258*139c1837SPaolo Bonzini tcg_out_tlb_load(s, addr_regl, addr_regh, oi, label_ptr, 0); 1259*139c1837SPaolo Bonzini tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc); 1260*139c1837SPaolo Bonzini add_qemu_ldst_label(s, 0, oi, 1261*139c1837SPaolo Bonzini (is_64 ? TCG_TYPE_I64 : TCG_TYPE_I32), 1262*139c1837SPaolo Bonzini data_regl, data_regh, addr_regl, addr_regh, 1263*139c1837SPaolo Bonzini s->code_ptr, label_ptr); 1264*139c1837SPaolo Bonzini#else 1265*139c1837SPaolo Bonzini if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) { 1266*139c1837SPaolo Bonzini tcg_out_ext32u(s, base, addr_regl); 1267*139c1837SPaolo Bonzini addr_regl = base; 1268*139c1837SPaolo Bonzini } 1269*139c1837SPaolo Bonzini 1270*139c1837SPaolo Bonzini if (guest_base == 0) { 1271*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_ADD, base, addr_regl, TCG_REG_ZERO); 1272*139c1837SPaolo Bonzini } else { 1273*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_ADD, base, TCG_GUEST_BASE_REG, addr_regl); 1274*139c1837SPaolo Bonzini } 1275*139c1837SPaolo Bonzini tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc); 1276*139c1837SPaolo Bonzini#endif 1277*139c1837SPaolo Bonzini} 1278*139c1837SPaolo Bonzini 1279*139c1837SPaolo Bonzinistatic tcg_insn_unit *tb_ret_addr; 1280*139c1837SPaolo Bonzini 1281*139c1837SPaolo Bonzinistatic void tcg_out_op(TCGContext *s, TCGOpcode opc, 1282*139c1837SPaolo Bonzini const TCGArg *args, const int *const_args) 1283*139c1837SPaolo Bonzini{ 1284*139c1837SPaolo Bonzini TCGArg a0 = args[0]; 1285*139c1837SPaolo Bonzini TCGArg a1 = args[1]; 1286*139c1837SPaolo Bonzini TCGArg a2 = args[2]; 1287*139c1837SPaolo Bonzini int c2 = const_args[2]; 1288*139c1837SPaolo Bonzini 1289*139c1837SPaolo Bonzini switch (opc) { 1290*139c1837SPaolo Bonzini case INDEX_op_exit_tb: 1291*139c1837SPaolo Bonzini /* Reuse the zeroing that exists for goto_ptr. */ 1292*139c1837SPaolo Bonzini if (a0 == 0) { 1293*139c1837SPaolo Bonzini tcg_out_call_int(s, s->code_gen_epilogue, true); 1294*139c1837SPaolo Bonzini } else { 1295*139c1837SPaolo Bonzini tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A0, a0); 1296*139c1837SPaolo Bonzini tcg_out_call_int(s, tb_ret_addr, true); 1297*139c1837SPaolo Bonzini } 1298*139c1837SPaolo Bonzini break; 1299*139c1837SPaolo Bonzini 1300*139c1837SPaolo Bonzini case INDEX_op_goto_tb: 1301*139c1837SPaolo Bonzini assert(s->tb_jmp_insn_offset == 0); 1302*139c1837SPaolo Bonzini /* indirect jump method */ 1303*139c1837SPaolo Bonzini tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_REG_ZERO, 1304*139c1837SPaolo Bonzini (uintptr_t)(s->tb_jmp_target_addr + a0)); 1305*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_JALR, TCG_REG_ZERO, TCG_REG_TMP0, 0); 1306*139c1837SPaolo Bonzini set_jmp_reset_offset(s, a0); 1307*139c1837SPaolo Bonzini break; 1308*139c1837SPaolo Bonzini 1309*139c1837SPaolo Bonzini case INDEX_op_goto_ptr: 1310*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_JALR, TCG_REG_ZERO, a0, 0); 1311*139c1837SPaolo Bonzini break; 1312*139c1837SPaolo Bonzini 1313*139c1837SPaolo Bonzini case INDEX_op_br: 1314*139c1837SPaolo Bonzini tcg_out_reloc(s, s->code_ptr, R_RISCV_JAL, arg_label(a0), 0); 1315*139c1837SPaolo Bonzini tcg_out_opc_jump(s, OPC_JAL, TCG_REG_ZERO, 0); 1316*139c1837SPaolo Bonzini break; 1317*139c1837SPaolo Bonzini 1318*139c1837SPaolo Bonzini case INDEX_op_ld8u_i32: 1319*139c1837SPaolo Bonzini case INDEX_op_ld8u_i64: 1320*139c1837SPaolo Bonzini tcg_out_ldst(s, OPC_LBU, a0, a1, a2); 1321*139c1837SPaolo Bonzini break; 1322*139c1837SPaolo Bonzini case INDEX_op_ld8s_i32: 1323*139c1837SPaolo Bonzini case INDEX_op_ld8s_i64: 1324*139c1837SPaolo Bonzini tcg_out_ldst(s, OPC_LB, a0, a1, a2); 1325*139c1837SPaolo Bonzini break; 1326*139c1837SPaolo Bonzini case INDEX_op_ld16u_i32: 1327*139c1837SPaolo Bonzini case INDEX_op_ld16u_i64: 1328*139c1837SPaolo Bonzini tcg_out_ldst(s, OPC_LHU, a0, a1, a2); 1329*139c1837SPaolo Bonzini break; 1330*139c1837SPaolo Bonzini case INDEX_op_ld16s_i32: 1331*139c1837SPaolo Bonzini case INDEX_op_ld16s_i64: 1332*139c1837SPaolo Bonzini tcg_out_ldst(s, OPC_LH, a0, a1, a2); 1333*139c1837SPaolo Bonzini break; 1334*139c1837SPaolo Bonzini case INDEX_op_ld32u_i64: 1335*139c1837SPaolo Bonzini tcg_out_ldst(s, OPC_LWU, a0, a1, a2); 1336*139c1837SPaolo Bonzini break; 1337*139c1837SPaolo Bonzini case INDEX_op_ld_i32: 1338*139c1837SPaolo Bonzini case INDEX_op_ld32s_i64: 1339*139c1837SPaolo Bonzini tcg_out_ldst(s, OPC_LW, a0, a1, a2); 1340*139c1837SPaolo Bonzini break; 1341*139c1837SPaolo Bonzini case INDEX_op_ld_i64: 1342*139c1837SPaolo Bonzini tcg_out_ldst(s, OPC_LD, a0, a1, a2); 1343*139c1837SPaolo Bonzini break; 1344*139c1837SPaolo Bonzini 1345*139c1837SPaolo Bonzini case INDEX_op_st8_i32: 1346*139c1837SPaolo Bonzini case INDEX_op_st8_i64: 1347*139c1837SPaolo Bonzini tcg_out_ldst(s, OPC_SB, a0, a1, a2); 1348*139c1837SPaolo Bonzini break; 1349*139c1837SPaolo Bonzini case INDEX_op_st16_i32: 1350*139c1837SPaolo Bonzini case INDEX_op_st16_i64: 1351*139c1837SPaolo Bonzini tcg_out_ldst(s, OPC_SH, a0, a1, a2); 1352*139c1837SPaolo Bonzini break; 1353*139c1837SPaolo Bonzini case INDEX_op_st_i32: 1354*139c1837SPaolo Bonzini case INDEX_op_st32_i64: 1355*139c1837SPaolo Bonzini tcg_out_ldst(s, OPC_SW, a0, a1, a2); 1356*139c1837SPaolo Bonzini break; 1357*139c1837SPaolo Bonzini case INDEX_op_st_i64: 1358*139c1837SPaolo Bonzini tcg_out_ldst(s, OPC_SD, a0, a1, a2); 1359*139c1837SPaolo Bonzini break; 1360*139c1837SPaolo Bonzini 1361*139c1837SPaolo Bonzini case INDEX_op_add_i32: 1362*139c1837SPaolo Bonzini if (c2) { 1363*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_ADDIW, a0, a1, a2); 1364*139c1837SPaolo Bonzini } else { 1365*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_ADDW, a0, a1, a2); 1366*139c1837SPaolo Bonzini } 1367*139c1837SPaolo Bonzini break; 1368*139c1837SPaolo Bonzini case INDEX_op_add_i64: 1369*139c1837SPaolo Bonzini if (c2) { 1370*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_ADDI, a0, a1, a2); 1371*139c1837SPaolo Bonzini } else { 1372*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_ADD, a0, a1, a2); 1373*139c1837SPaolo Bonzini } 1374*139c1837SPaolo Bonzini break; 1375*139c1837SPaolo Bonzini 1376*139c1837SPaolo Bonzini case INDEX_op_sub_i32: 1377*139c1837SPaolo Bonzini if (c2) { 1378*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_ADDIW, a0, a1, -a2); 1379*139c1837SPaolo Bonzini } else { 1380*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_SUBW, a0, a1, a2); 1381*139c1837SPaolo Bonzini } 1382*139c1837SPaolo Bonzini break; 1383*139c1837SPaolo Bonzini case INDEX_op_sub_i64: 1384*139c1837SPaolo Bonzini if (c2) { 1385*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_ADDI, a0, a1, -a2); 1386*139c1837SPaolo Bonzini } else { 1387*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_SUB, a0, a1, a2); 1388*139c1837SPaolo Bonzini } 1389*139c1837SPaolo Bonzini break; 1390*139c1837SPaolo Bonzini 1391*139c1837SPaolo Bonzini case INDEX_op_and_i32: 1392*139c1837SPaolo Bonzini case INDEX_op_and_i64: 1393*139c1837SPaolo Bonzini if (c2) { 1394*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_ANDI, a0, a1, a2); 1395*139c1837SPaolo Bonzini } else { 1396*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_AND, a0, a1, a2); 1397*139c1837SPaolo Bonzini } 1398*139c1837SPaolo Bonzini break; 1399*139c1837SPaolo Bonzini 1400*139c1837SPaolo Bonzini case INDEX_op_or_i32: 1401*139c1837SPaolo Bonzini case INDEX_op_or_i64: 1402*139c1837SPaolo Bonzini if (c2) { 1403*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_ORI, a0, a1, a2); 1404*139c1837SPaolo Bonzini } else { 1405*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_OR, a0, a1, a2); 1406*139c1837SPaolo Bonzini } 1407*139c1837SPaolo Bonzini break; 1408*139c1837SPaolo Bonzini 1409*139c1837SPaolo Bonzini case INDEX_op_xor_i32: 1410*139c1837SPaolo Bonzini case INDEX_op_xor_i64: 1411*139c1837SPaolo Bonzini if (c2) { 1412*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_XORI, a0, a1, a2); 1413*139c1837SPaolo Bonzini } else { 1414*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_XOR, a0, a1, a2); 1415*139c1837SPaolo Bonzini } 1416*139c1837SPaolo Bonzini break; 1417*139c1837SPaolo Bonzini 1418*139c1837SPaolo Bonzini case INDEX_op_not_i32: 1419*139c1837SPaolo Bonzini case INDEX_op_not_i64: 1420*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_XORI, a0, a1, -1); 1421*139c1837SPaolo Bonzini break; 1422*139c1837SPaolo Bonzini 1423*139c1837SPaolo Bonzini case INDEX_op_neg_i32: 1424*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_SUBW, a0, TCG_REG_ZERO, a1); 1425*139c1837SPaolo Bonzini break; 1426*139c1837SPaolo Bonzini case INDEX_op_neg_i64: 1427*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_SUB, a0, TCG_REG_ZERO, a1); 1428*139c1837SPaolo Bonzini break; 1429*139c1837SPaolo Bonzini 1430*139c1837SPaolo Bonzini case INDEX_op_mul_i32: 1431*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_MULW, a0, a1, a2); 1432*139c1837SPaolo Bonzini break; 1433*139c1837SPaolo Bonzini case INDEX_op_mul_i64: 1434*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_MUL, a0, a1, a2); 1435*139c1837SPaolo Bonzini break; 1436*139c1837SPaolo Bonzini 1437*139c1837SPaolo Bonzini case INDEX_op_div_i32: 1438*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_DIVW, a0, a1, a2); 1439*139c1837SPaolo Bonzini break; 1440*139c1837SPaolo Bonzini case INDEX_op_div_i64: 1441*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_DIV, a0, a1, a2); 1442*139c1837SPaolo Bonzini break; 1443*139c1837SPaolo Bonzini 1444*139c1837SPaolo Bonzini case INDEX_op_divu_i32: 1445*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_DIVUW, a0, a1, a2); 1446*139c1837SPaolo Bonzini break; 1447*139c1837SPaolo Bonzini case INDEX_op_divu_i64: 1448*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_DIVU, a0, a1, a2); 1449*139c1837SPaolo Bonzini break; 1450*139c1837SPaolo Bonzini 1451*139c1837SPaolo Bonzini case INDEX_op_rem_i32: 1452*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_REMW, a0, a1, a2); 1453*139c1837SPaolo Bonzini break; 1454*139c1837SPaolo Bonzini case INDEX_op_rem_i64: 1455*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_REM, a0, a1, a2); 1456*139c1837SPaolo Bonzini break; 1457*139c1837SPaolo Bonzini 1458*139c1837SPaolo Bonzini case INDEX_op_remu_i32: 1459*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_REMUW, a0, a1, a2); 1460*139c1837SPaolo Bonzini break; 1461*139c1837SPaolo Bonzini case INDEX_op_remu_i64: 1462*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_REMU, a0, a1, a2); 1463*139c1837SPaolo Bonzini break; 1464*139c1837SPaolo Bonzini 1465*139c1837SPaolo Bonzini case INDEX_op_shl_i32: 1466*139c1837SPaolo Bonzini if (c2) { 1467*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_SLLIW, a0, a1, a2); 1468*139c1837SPaolo Bonzini } else { 1469*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_SLLW, a0, a1, a2); 1470*139c1837SPaolo Bonzini } 1471*139c1837SPaolo Bonzini break; 1472*139c1837SPaolo Bonzini case INDEX_op_shl_i64: 1473*139c1837SPaolo Bonzini if (c2) { 1474*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_SLLI, a0, a1, a2); 1475*139c1837SPaolo Bonzini } else { 1476*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_SLL, a0, a1, a2); 1477*139c1837SPaolo Bonzini } 1478*139c1837SPaolo Bonzini break; 1479*139c1837SPaolo Bonzini 1480*139c1837SPaolo Bonzini case INDEX_op_shr_i32: 1481*139c1837SPaolo Bonzini if (c2) { 1482*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_SRLIW, a0, a1, a2); 1483*139c1837SPaolo Bonzini } else { 1484*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_SRLW, a0, a1, a2); 1485*139c1837SPaolo Bonzini } 1486*139c1837SPaolo Bonzini break; 1487*139c1837SPaolo Bonzini case INDEX_op_shr_i64: 1488*139c1837SPaolo Bonzini if (c2) { 1489*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_SRLI, a0, a1, a2); 1490*139c1837SPaolo Bonzini } else { 1491*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_SRL, a0, a1, a2); 1492*139c1837SPaolo Bonzini } 1493*139c1837SPaolo Bonzini break; 1494*139c1837SPaolo Bonzini 1495*139c1837SPaolo Bonzini case INDEX_op_sar_i32: 1496*139c1837SPaolo Bonzini if (c2) { 1497*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_SRAIW, a0, a1, a2); 1498*139c1837SPaolo Bonzini } else { 1499*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_SRAW, a0, a1, a2); 1500*139c1837SPaolo Bonzini } 1501*139c1837SPaolo Bonzini break; 1502*139c1837SPaolo Bonzini case INDEX_op_sar_i64: 1503*139c1837SPaolo Bonzini if (c2) { 1504*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_SRAI, a0, a1, a2); 1505*139c1837SPaolo Bonzini } else { 1506*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_SRA, a0, a1, a2); 1507*139c1837SPaolo Bonzini } 1508*139c1837SPaolo Bonzini break; 1509*139c1837SPaolo Bonzini 1510*139c1837SPaolo Bonzini case INDEX_op_add2_i32: 1511*139c1837SPaolo Bonzini tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5], 1512*139c1837SPaolo Bonzini const_args[4], const_args[5], false, true); 1513*139c1837SPaolo Bonzini break; 1514*139c1837SPaolo Bonzini case INDEX_op_add2_i64: 1515*139c1837SPaolo Bonzini tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5], 1516*139c1837SPaolo Bonzini const_args[4], const_args[5], false, false); 1517*139c1837SPaolo Bonzini break; 1518*139c1837SPaolo Bonzini case INDEX_op_sub2_i32: 1519*139c1837SPaolo Bonzini tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5], 1520*139c1837SPaolo Bonzini const_args[4], const_args[5], true, true); 1521*139c1837SPaolo Bonzini break; 1522*139c1837SPaolo Bonzini case INDEX_op_sub2_i64: 1523*139c1837SPaolo Bonzini tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5], 1524*139c1837SPaolo Bonzini const_args[4], const_args[5], true, false); 1525*139c1837SPaolo Bonzini break; 1526*139c1837SPaolo Bonzini 1527*139c1837SPaolo Bonzini case INDEX_op_brcond_i32: 1528*139c1837SPaolo Bonzini case INDEX_op_brcond_i64: 1529*139c1837SPaolo Bonzini tcg_out_brcond(s, a2, a0, a1, arg_label(args[3])); 1530*139c1837SPaolo Bonzini break; 1531*139c1837SPaolo Bonzini case INDEX_op_brcond2_i32: 1532*139c1837SPaolo Bonzini tcg_out_brcond2(s, args[4], a0, a1, a2, args[3], arg_label(args[5])); 1533*139c1837SPaolo Bonzini break; 1534*139c1837SPaolo Bonzini 1535*139c1837SPaolo Bonzini case INDEX_op_setcond_i32: 1536*139c1837SPaolo Bonzini case INDEX_op_setcond_i64: 1537*139c1837SPaolo Bonzini tcg_out_setcond(s, args[3], a0, a1, a2); 1538*139c1837SPaolo Bonzini break; 1539*139c1837SPaolo Bonzini case INDEX_op_setcond2_i32: 1540*139c1837SPaolo Bonzini tcg_out_setcond2(s, args[5], a0, a1, a2, args[3], args[4]); 1541*139c1837SPaolo Bonzini break; 1542*139c1837SPaolo Bonzini 1543*139c1837SPaolo Bonzini case INDEX_op_qemu_ld_i32: 1544*139c1837SPaolo Bonzini tcg_out_qemu_ld(s, args, false); 1545*139c1837SPaolo Bonzini break; 1546*139c1837SPaolo Bonzini case INDEX_op_qemu_ld_i64: 1547*139c1837SPaolo Bonzini tcg_out_qemu_ld(s, args, true); 1548*139c1837SPaolo Bonzini break; 1549*139c1837SPaolo Bonzini case INDEX_op_qemu_st_i32: 1550*139c1837SPaolo Bonzini tcg_out_qemu_st(s, args, false); 1551*139c1837SPaolo Bonzini break; 1552*139c1837SPaolo Bonzini case INDEX_op_qemu_st_i64: 1553*139c1837SPaolo Bonzini tcg_out_qemu_st(s, args, true); 1554*139c1837SPaolo Bonzini break; 1555*139c1837SPaolo Bonzini 1556*139c1837SPaolo Bonzini case INDEX_op_ext8u_i32: 1557*139c1837SPaolo Bonzini case INDEX_op_ext8u_i64: 1558*139c1837SPaolo Bonzini tcg_out_ext8u(s, a0, a1); 1559*139c1837SPaolo Bonzini break; 1560*139c1837SPaolo Bonzini 1561*139c1837SPaolo Bonzini case INDEX_op_ext16u_i32: 1562*139c1837SPaolo Bonzini case INDEX_op_ext16u_i64: 1563*139c1837SPaolo Bonzini tcg_out_ext16u(s, a0, a1); 1564*139c1837SPaolo Bonzini break; 1565*139c1837SPaolo Bonzini 1566*139c1837SPaolo Bonzini case INDEX_op_ext32u_i64: 1567*139c1837SPaolo Bonzini case INDEX_op_extu_i32_i64: 1568*139c1837SPaolo Bonzini tcg_out_ext32u(s, a0, a1); 1569*139c1837SPaolo Bonzini break; 1570*139c1837SPaolo Bonzini 1571*139c1837SPaolo Bonzini case INDEX_op_ext8s_i32: 1572*139c1837SPaolo Bonzini case INDEX_op_ext8s_i64: 1573*139c1837SPaolo Bonzini tcg_out_ext8s(s, a0, a1); 1574*139c1837SPaolo Bonzini break; 1575*139c1837SPaolo Bonzini 1576*139c1837SPaolo Bonzini case INDEX_op_ext16s_i32: 1577*139c1837SPaolo Bonzini case INDEX_op_ext16s_i64: 1578*139c1837SPaolo Bonzini tcg_out_ext16s(s, a0, a1); 1579*139c1837SPaolo Bonzini break; 1580*139c1837SPaolo Bonzini 1581*139c1837SPaolo Bonzini case INDEX_op_ext32s_i64: 1582*139c1837SPaolo Bonzini case INDEX_op_extrl_i64_i32: 1583*139c1837SPaolo Bonzini case INDEX_op_ext_i32_i64: 1584*139c1837SPaolo Bonzini tcg_out_ext32s(s, a0, a1); 1585*139c1837SPaolo Bonzini break; 1586*139c1837SPaolo Bonzini 1587*139c1837SPaolo Bonzini case INDEX_op_extrh_i64_i32: 1588*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_SRAI, a0, a1, 32); 1589*139c1837SPaolo Bonzini break; 1590*139c1837SPaolo Bonzini 1591*139c1837SPaolo Bonzini case INDEX_op_mulsh_i32: 1592*139c1837SPaolo Bonzini case INDEX_op_mulsh_i64: 1593*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_MULH, a0, a1, a2); 1594*139c1837SPaolo Bonzini break; 1595*139c1837SPaolo Bonzini 1596*139c1837SPaolo Bonzini case INDEX_op_muluh_i32: 1597*139c1837SPaolo Bonzini case INDEX_op_muluh_i64: 1598*139c1837SPaolo Bonzini tcg_out_opc_reg(s, OPC_MULHU, a0, a1, a2); 1599*139c1837SPaolo Bonzini break; 1600*139c1837SPaolo Bonzini 1601*139c1837SPaolo Bonzini case INDEX_op_mb: 1602*139c1837SPaolo Bonzini tcg_out_mb(s, a0); 1603*139c1837SPaolo Bonzini break; 1604*139c1837SPaolo Bonzini 1605*139c1837SPaolo Bonzini case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */ 1606*139c1837SPaolo Bonzini case INDEX_op_mov_i64: 1607*139c1837SPaolo Bonzini case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi. */ 1608*139c1837SPaolo Bonzini case INDEX_op_movi_i64: 1609*139c1837SPaolo Bonzini case INDEX_op_call: /* Always emitted via tcg_out_call. */ 1610*139c1837SPaolo Bonzini default: 1611*139c1837SPaolo Bonzini g_assert_not_reached(); 1612*139c1837SPaolo Bonzini } 1613*139c1837SPaolo Bonzini} 1614*139c1837SPaolo Bonzini 1615*139c1837SPaolo Bonzinistatic const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op) 1616*139c1837SPaolo Bonzini{ 1617*139c1837SPaolo Bonzini static const TCGTargetOpDef r 1618*139c1837SPaolo Bonzini = { .args_ct_str = { "r" } }; 1619*139c1837SPaolo Bonzini static const TCGTargetOpDef r_r 1620*139c1837SPaolo Bonzini = { .args_ct_str = { "r", "r" } }; 1621*139c1837SPaolo Bonzini static const TCGTargetOpDef rZ_r 1622*139c1837SPaolo Bonzini = { .args_ct_str = { "rZ", "r" } }; 1623*139c1837SPaolo Bonzini static const TCGTargetOpDef rZ_rZ 1624*139c1837SPaolo Bonzini = { .args_ct_str = { "rZ", "rZ" } }; 1625*139c1837SPaolo Bonzini static const TCGTargetOpDef rZ_rZ_rZ_rZ 1626*139c1837SPaolo Bonzini = { .args_ct_str = { "rZ", "rZ", "rZ", "rZ" } }; 1627*139c1837SPaolo Bonzini static const TCGTargetOpDef r_r_ri 1628*139c1837SPaolo Bonzini = { .args_ct_str = { "r", "r", "ri" } }; 1629*139c1837SPaolo Bonzini static const TCGTargetOpDef r_r_rI 1630*139c1837SPaolo Bonzini = { .args_ct_str = { "r", "r", "rI" } }; 1631*139c1837SPaolo Bonzini static const TCGTargetOpDef r_rZ_rN 1632*139c1837SPaolo Bonzini = { .args_ct_str = { "r", "rZ", "rN" } }; 1633*139c1837SPaolo Bonzini static const TCGTargetOpDef r_rZ_rZ 1634*139c1837SPaolo Bonzini = { .args_ct_str = { "r", "rZ", "rZ" } }; 1635*139c1837SPaolo Bonzini static const TCGTargetOpDef r_rZ_rZ_rZ_rZ 1636*139c1837SPaolo Bonzini = { .args_ct_str = { "r", "rZ", "rZ", "rZ", "rZ" } }; 1637*139c1837SPaolo Bonzini static const TCGTargetOpDef r_L 1638*139c1837SPaolo Bonzini = { .args_ct_str = { "r", "L" } }; 1639*139c1837SPaolo Bonzini static const TCGTargetOpDef r_r_L 1640*139c1837SPaolo Bonzini = { .args_ct_str = { "r", "r", "L" } }; 1641*139c1837SPaolo Bonzini static const TCGTargetOpDef r_L_L 1642*139c1837SPaolo Bonzini = { .args_ct_str = { "r", "L", "L" } }; 1643*139c1837SPaolo Bonzini static const TCGTargetOpDef r_r_L_L 1644*139c1837SPaolo Bonzini = { .args_ct_str = { "r", "r", "L", "L" } }; 1645*139c1837SPaolo Bonzini static const TCGTargetOpDef LZ_L 1646*139c1837SPaolo Bonzini = { .args_ct_str = { "LZ", "L" } }; 1647*139c1837SPaolo Bonzini static const TCGTargetOpDef LZ_L_L 1648*139c1837SPaolo Bonzini = { .args_ct_str = { "LZ", "L", "L" } }; 1649*139c1837SPaolo Bonzini static const TCGTargetOpDef LZ_LZ_L 1650*139c1837SPaolo Bonzini = { .args_ct_str = { "LZ", "LZ", "L" } }; 1651*139c1837SPaolo Bonzini static const TCGTargetOpDef LZ_LZ_L_L 1652*139c1837SPaolo Bonzini = { .args_ct_str = { "LZ", "LZ", "L", "L" } }; 1653*139c1837SPaolo Bonzini static const TCGTargetOpDef r_r_rZ_rZ_rM_rM 1654*139c1837SPaolo Bonzini = { .args_ct_str = { "r", "r", "rZ", "rZ", "rM", "rM" } }; 1655*139c1837SPaolo Bonzini 1656*139c1837SPaolo Bonzini switch (op) { 1657*139c1837SPaolo Bonzini case INDEX_op_goto_ptr: 1658*139c1837SPaolo Bonzini return &r; 1659*139c1837SPaolo Bonzini 1660*139c1837SPaolo Bonzini case INDEX_op_ld8u_i32: 1661*139c1837SPaolo Bonzini case INDEX_op_ld8s_i32: 1662*139c1837SPaolo Bonzini case INDEX_op_ld16u_i32: 1663*139c1837SPaolo Bonzini case INDEX_op_ld16s_i32: 1664*139c1837SPaolo Bonzini case INDEX_op_ld_i32: 1665*139c1837SPaolo Bonzini case INDEX_op_not_i32: 1666*139c1837SPaolo Bonzini case INDEX_op_neg_i32: 1667*139c1837SPaolo Bonzini case INDEX_op_ld8u_i64: 1668*139c1837SPaolo Bonzini case INDEX_op_ld8s_i64: 1669*139c1837SPaolo Bonzini case INDEX_op_ld16u_i64: 1670*139c1837SPaolo Bonzini case INDEX_op_ld16s_i64: 1671*139c1837SPaolo Bonzini case INDEX_op_ld32s_i64: 1672*139c1837SPaolo Bonzini case INDEX_op_ld32u_i64: 1673*139c1837SPaolo Bonzini case INDEX_op_ld_i64: 1674*139c1837SPaolo Bonzini case INDEX_op_not_i64: 1675*139c1837SPaolo Bonzini case INDEX_op_neg_i64: 1676*139c1837SPaolo Bonzini case INDEX_op_ext8u_i32: 1677*139c1837SPaolo Bonzini case INDEX_op_ext8u_i64: 1678*139c1837SPaolo Bonzini case INDEX_op_ext16u_i32: 1679*139c1837SPaolo Bonzini case INDEX_op_ext16u_i64: 1680*139c1837SPaolo Bonzini case INDEX_op_ext32u_i64: 1681*139c1837SPaolo Bonzini case INDEX_op_extu_i32_i64: 1682*139c1837SPaolo Bonzini case INDEX_op_ext8s_i32: 1683*139c1837SPaolo Bonzini case INDEX_op_ext8s_i64: 1684*139c1837SPaolo Bonzini case INDEX_op_ext16s_i32: 1685*139c1837SPaolo Bonzini case INDEX_op_ext16s_i64: 1686*139c1837SPaolo Bonzini case INDEX_op_ext32s_i64: 1687*139c1837SPaolo Bonzini case INDEX_op_extrl_i64_i32: 1688*139c1837SPaolo Bonzini case INDEX_op_extrh_i64_i32: 1689*139c1837SPaolo Bonzini case INDEX_op_ext_i32_i64: 1690*139c1837SPaolo Bonzini return &r_r; 1691*139c1837SPaolo Bonzini 1692*139c1837SPaolo Bonzini case INDEX_op_st8_i32: 1693*139c1837SPaolo Bonzini case INDEX_op_st16_i32: 1694*139c1837SPaolo Bonzini case INDEX_op_st_i32: 1695*139c1837SPaolo Bonzini case INDEX_op_st8_i64: 1696*139c1837SPaolo Bonzini case INDEX_op_st16_i64: 1697*139c1837SPaolo Bonzini case INDEX_op_st32_i64: 1698*139c1837SPaolo Bonzini case INDEX_op_st_i64: 1699*139c1837SPaolo Bonzini return &rZ_r; 1700*139c1837SPaolo Bonzini 1701*139c1837SPaolo Bonzini case INDEX_op_add_i32: 1702*139c1837SPaolo Bonzini case INDEX_op_and_i32: 1703*139c1837SPaolo Bonzini case INDEX_op_or_i32: 1704*139c1837SPaolo Bonzini case INDEX_op_xor_i32: 1705*139c1837SPaolo Bonzini case INDEX_op_add_i64: 1706*139c1837SPaolo Bonzini case INDEX_op_and_i64: 1707*139c1837SPaolo Bonzini case INDEX_op_or_i64: 1708*139c1837SPaolo Bonzini case INDEX_op_xor_i64: 1709*139c1837SPaolo Bonzini return &r_r_rI; 1710*139c1837SPaolo Bonzini 1711*139c1837SPaolo Bonzini case INDEX_op_sub_i32: 1712*139c1837SPaolo Bonzini case INDEX_op_sub_i64: 1713*139c1837SPaolo Bonzini return &r_rZ_rN; 1714*139c1837SPaolo Bonzini 1715*139c1837SPaolo Bonzini case INDEX_op_mul_i32: 1716*139c1837SPaolo Bonzini case INDEX_op_mulsh_i32: 1717*139c1837SPaolo Bonzini case INDEX_op_muluh_i32: 1718*139c1837SPaolo Bonzini case INDEX_op_div_i32: 1719*139c1837SPaolo Bonzini case INDEX_op_divu_i32: 1720*139c1837SPaolo Bonzini case INDEX_op_rem_i32: 1721*139c1837SPaolo Bonzini case INDEX_op_remu_i32: 1722*139c1837SPaolo Bonzini case INDEX_op_setcond_i32: 1723*139c1837SPaolo Bonzini case INDEX_op_mul_i64: 1724*139c1837SPaolo Bonzini case INDEX_op_mulsh_i64: 1725*139c1837SPaolo Bonzini case INDEX_op_muluh_i64: 1726*139c1837SPaolo Bonzini case INDEX_op_div_i64: 1727*139c1837SPaolo Bonzini case INDEX_op_divu_i64: 1728*139c1837SPaolo Bonzini case INDEX_op_rem_i64: 1729*139c1837SPaolo Bonzini case INDEX_op_remu_i64: 1730*139c1837SPaolo Bonzini case INDEX_op_setcond_i64: 1731*139c1837SPaolo Bonzini return &r_rZ_rZ; 1732*139c1837SPaolo Bonzini 1733*139c1837SPaolo Bonzini case INDEX_op_shl_i32: 1734*139c1837SPaolo Bonzini case INDEX_op_shr_i32: 1735*139c1837SPaolo Bonzini case INDEX_op_sar_i32: 1736*139c1837SPaolo Bonzini case INDEX_op_shl_i64: 1737*139c1837SPaolo Bonzini case INDEX_op_shr_i64: 1738*139c1837SPaolo Bonzini case INDEX_op_sar_i64: 1739*139c1837SPaolo Bonzini return &r_r_ri; 1740*139c1837SPaolo Bonzini 1741*139c1837SPaolo Bonzini case INDEX_op_brcond_i32: 1742*139c1837SPaolo Bonzini case INDEX_op_brcond_i64: 1743*139c1837SPaolo Bonzini return &rZ_rZ; 1744*139c1837SPaolo Bonzini 1745*139c1837SPaolo Bonzini case INDEX_op_add2_i32: 1746*139c1837SPaolo Bonzini case INDEX_op_add2_i64: 1747*139c1837SPaolo Bonzini case INDEX_op_sub2_i32: 1748*139c1837SPaolo Bonzini case INDEX_op_sub2_i64: 1749*139c1837SPaolo Bonzini return &r_r_rZ_rZ_rM_rM; 1750*139c1837SPaolo Bonzini 1751*139c1837SPaolo Bonzini case INDEX_op_brcond2_i32: 1752*139c1837SPaolo Bonzini return &rZ_rZ_rZ_rZ; 1753*139c1837SPaolo Bonzini 1754*139c1837SPaolo Bonzini case INDEX_op_setcond2_i32: 1755*139c1837SPaolo Bonzini return &r_rZ_rZ_rZ_rZ; 1756*139c1837SPaolo Bonzini 1757*139c1837SPaolo Bonzini case INDEX_op_qemu_ld_i32: 1758*139c1837SPaolo Bonzini return TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? &r_L : &r_L_L; 1759*139c1837SPaolo Bonzini case INDEX_op_qemu_st_i32: 1760*139c1837SPaolo Bonzini return TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? &LZ_L : &LZ_L_L; 1761*139c1837SPaolo Bonzini case INDEX_op_qemu_ld_i64: 1762*139c1837SPaolo Bonzini return TCG_TARGET_REG_BITS == 64 ? &r_L 1763*139c1837SPaolo Bonzini : TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? &r_r_L 1764*139c1837SPaolo Bonzini : &r_r_L_L; 1765*139c1837SPaolo Bonzini case INDEX_op_qemu_st_i64: 1766*139c1837SPaolo Bonzini return TCG_TARGET_REG_BITS == 64 ? &LZ_L 1767*139c1837SPaolo Bonzini : TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? &LZ_LZ_L 1768*139c1837SPaolo Bonzini : &LZ_LZ_L_L; 1769*139c1837SPaolo Bonzini 1770*139c1837SPaolo Bonzini default: 1771*139c1837SPaolo Bonzini return NULL; 1772*139c1837SPaolo Bonzini } 1773*139c1837SPaolo Bonzini} 1774*139c1837SPaolo Bonzini 1775*139c1837SPaolo Bonzinistatic const int tcg_target_callee_save_regs[] = { 1776*139c1837SPaolo Bonzini TCG_REG_S0, /* used for the global env (TCG_AREG0) */ 1777*139c1837SPaolo Bonzini TCG_REG_S1, 1778*139c1837SPaolo Bonzini TCG_REG_S2, 1779*139c1837SPaolo Bonzini TCG_REG_S3, 1780*139c1837SPaolo Bonzini TCG_REG_S4, 1781*139c1837SPaolo Bonzini TCG_REG_S5, 1782*139c1837SPaolo Bonzini TCG_REG_S6, 1783*139c1837SPaolo Bonzini TCG_REG_S7, 1784*139c1837SPaolo Bonzini TCG_REG_S8, 1785*139c1837SPaolo Bonzini TCG_REG_S9, 1786*139c1837SPaolo Bonzini TCG_REG_S10, 1787*139c1837SPaolo Bonzini TCG_REG_S11, 1788*139c1837SPaolo Bonzini TCG_REG_RA, /* should be last for ABI compliance */ 1789*139c1837SPaolo Bonzini}; 1790*139c1837SPaolo Bonzini 1791*139c1837SPaolo Bonzini/* Stack frame parameters. */ 1792*139c1837SPaolo Bonzini#define REG_SIZE (TCG_TARGET_REG_BITS / 8) 1793*139c1837SPaolo Bonzini#define SAVE_SIZE ((int)ARRAY_SIZE(tcg_target_callee_save_regs) * REG_SIZE) 1794*139c1837SPaolo Bonzini#define TEMP_SIZE (CPU_TEMP_BUF_NLONGS * (int)sizeof(long)) 1795*139c1837SPaolo Bonzini#define FRAME_SIZE ((TCG_STATIC_CALL_ARGS_SIZE + TEMP_SIZE + SAVE_SIZE \ 1796*139c1837SPaolo Bonzini + TCG_TARGET_STACK_ALIGN - 1) \ 1797*139c1837SPaolo Bonzini & -TCG_TARGET_STACK_ALIGN) 1798*139c1837SPaolo Bonzini#define SAVE_OFS (TCG_STATIC_CALL_ARGS_SIZE + TEMP_SIZE) 1799*139c1837SPaolo Bonzini 1800*139c1837SPaolo Bonzini/* We're expecting to be able to use an immediate for frame allocation. */ 1801*139c1837SPaolo BonziniQEMU_BUILD_BUG_ON(FRAME_SIZE > 0x7ff); 1802*139c1837SPaolo Bonzini 1803*139c1837SPaolo Bonzini/* Generate global QEMU prologue and epilogue code */ 1804*139c1837SPaolo Bonzinistatic void tcg_target_qemu_prologue(TCGContext *s) 1805*139c1837SPaolo Bonzini{ 1806*139c1837SPaolo Bonzini int i; 1807*139c1837SPaolo Bonzini 1808*139c1837SPaolo Bonzini tcg_set_frame(s, TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE, TEMP_SIZE); 1809*139c1837SPaolo Bonzini 1810*139c1837SPaolo Bonzini /* TB prologue */ 1811*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_ADDI, TCG_REG_SP, TCG_REG_SP, -FRAME_SIZE); 1812*139c1837SPaolo Bonzini for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) { 1813*139c1837SPaolo Bonzini tcg_out_st(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i], 1814*139c1837SPaolo Bonzini TCG_REG_SP, SAVE_OFS + i * REG_SIZE); 1815*139c1837SPaolo Bonzini } 1816*139c1837SPaolo Bonzini 1817*139c1837SPaolo Bonzini#if !defined(CONFIG_SOFTMMU) 1818*139c1837SPaolo Bonzini tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base); 1819*139c1837SPaolo Bonzini tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG); 1820*139c1837SPaolo Bonzini#endif 1821*139c1837SPaolo Bonzini 1822*139c1837SPaolo Bonzini /* Call generated code */ 1823*139c1837SPaolo Bonzini tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); 1824*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_JALR, TCG_REG_ZERO, tcg_target_call_iarg_regs[1], 0); 1825*139c1837SPaolo Bonzini 1826*139c1837SPaolo Bonzini /* Return path for goto_ptr. Set return value to 0 */ 1827*139c1837SPaolo Bonzini s->code_gen_epilogue = s->code_ptr; 1828*139c1837SPaolo Bonzini tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_A0, TCG_REG_ZERO); 1829*139c1837SPaolo Bonzini 1830*139c1837SPaolo Bonzini /* TB epilogue */ 1831*139c1837SPaolo Bonzini tb_ret_addr = s->code_ptr; 1832*139c1837SPaolo Bonzini for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) { 1833*139c1837SPaolo Bonzini tcg_out_ld(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i], 1834*139c1837SPaolo Bonzini TCG_REG_SP, SAVE_OFS + i * REG_SIZE); 1835*139c1837SPaolo Bonzini } 1836*139c1837SPaolo Bonzini 1837*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_ADDI, TCG_REG_SP, TCG_REG_SP, FRAME_SIZE); 1838*139c1837SPaolo Bonzini tcg_out_opc_imm(s, OPC_JALR, TCG_REG_ZERO, TCG_REG_RA, 0); 1839*139c1837SPaolo Bonzini} 1840*139c1837SPaolo Bonzini 1841*139c1837SPaolo Bonzinistatic void tcg_target_init(TCGContext *s) 1842*139c1837SPaolo Bonzini{ 1843*139c1837SPaolo Bonzini tcg_target_available_regs[TCG_TYPE_I32] = 0xffffffff; 1844*139c1837SPaolo Bonzini if (TCG_TARGET_REG_BITS == 64) { 1845*139c1837SPaolo Bonzini tcg_target_available_regs[TCG_TYPE_I64] = 0xffffffff; 1846*139c1837SPaolo Bonzini } 1847*139c1837SPaolo Bonzini 1848*139c1837SPaolo Bonzini tcg_target_call_clobber_regs = -1u; 1849*139c1837SPaolo Bonzini tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S0); 1850*139c1837SPaolo Bonzini tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S1); 1851*139c1837SPaolo Bonzini tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S2); 1852*139c1837SPaolo Bonzini tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S3); 1853*139c1837SPaolo Bonzini tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S4); 1854*139c1837SPaolo Bonzini tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S5); 1855*139c1837SPaolo Bonzini tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S6); 1856*139c1837SPaolo Bonzini tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S7); 1857*139c1837SPaolo Bonzini tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S8); 1858*139c1837SPaolo Bonzini tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S9); 1859*139c1837SPaolo Bonzini tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S10); 1860*139c1837SPaolo Bonzini tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S11); 1861*139c1837SPaolo Bonzini 1862*139c1837SPaolo Bonzini s->reserved_regs = 0; 1863*139c1837SPaolo Bonzini tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO); 1864*139c1837SPaolo Bonzini tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP0); 1865*139c1837SPaolo Bonzini tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP1); 1866*139c1837SPaolo Bonzini tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP2); 1867*139c1837SPaolo Bonzini tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP); 1868*139c1837SPaolo Bonzini tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP); 1869*139c1837SPaolo Bonzini tcg_regset_set_reg(s->reserved_regs, TCG_REG_TP); 1870*139c1837SPaolo Bonzini} 1871*139c1837SPaolo Bonzini 1872*139c1837SPaolo Bonzinitypedef struct { 1873*139c1837SPaolo Bonzini DebugFrameHeader h; 1874*139c1837SPaolo Bonzini uint8_t fde_def_cfa[4]; 1875*139c1837SPaolo Bonzini uint8_t fde_reg_ofs[ARRAY_SIZE(tcg_target_callee_save_regs) * 2]; 1876*139c1837SPaolo Bonzini} DebugFrame; 1877*139c1837SPaolo Bonzini 1878*139c1837SPaolo Bonzini#define ELF_HOST_MACHINE EM_RISCV 1879*139c1837SPaolo Bonzini 1880*139c1837SPaolo Bonzinistatic const DebugFrame debug_frame = { 1881*139c1837SPaolo Bonzini .h.cie.len = sizeof(DebugFrameCIE) - 4, /* length after .len member */ 1882*139c1837SPaolo Bonzini .h.cie.id = -1, 1883*139c1837SPaolo Bonzini .h.cie.version = 1, 1884*139c1837SPaolo Bonzini .h.cie.code_align = 1, 1885*139c1837SPaolo Bonzini .h.cie.data_align = -(TCG_TARGET_REG_BITS / 8) & 0x7f, /* sleb128 */ 1886*139c1837SPaolo Bonzini .h.cie.return_column = TCG_REG_RA, 1887*139c1837SPaolo Bonzini 1888*139c1837SPaolo Bonzini /* Total FDE size does not include the "len" member. */ 1889*139c1837SPaolo Bonzini .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset), 1890*139c1837SPaolo Bonzini 1891*139c1837SPaolo Bonzini .fde_def_cfa = { 1892*139c1837SPaolo Bonzini 12, TCG_REG_SP, /* DW_CFA_def_cfa sp, ... */ 1893*139c1837SPaolo Bonzini (FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */ 1894*139c1837SPaolo Bonzini (FRAME_SIZE >> 7) 1895*139c1837SPaolo Bonzini }, 1896*139c1837SPaolo Bonzini .fde_reg_ofs = { 1897*139c1837SPaolo Bonzini 0x80 + 9, 12, /* DW_CFA_offset, s1, -96 */ 1898*139c1837SPaolo Bonzini 0x80 + 18, 11, /* DW_CFA_offset, s2, -88 */ 1899*139c1837SPaolo Bonzini 0x80 + 19, 10, /* DW_CFA_offset, s3, -80 */ 1900*139c1837SPaolo Bonzini 0x80 + 20, 9, /* DW_CFA_offset, s4, -72 */ 1901*139c1837SPaolo Bonzini 0x80 + 21, 8, /* DW_CFA_offset, s5, -64 */ 1902*139c1837SPaolo Bonzini 0x80 + 22, 7, /* DW_CFA_offset, s6, -56 */ 1903*139c1837SPaolo Bonzini 0x80 + 23, 6, /* DW_CFA_offset, s7, -48 */ 1904*139c1837SPaolo Bonzini 0x80 + 24, 5, /* DW_CFA_offset, s8, -40 */ 1905*139c1837SPaolo Bonzini 0x80 + 25, 4, /* DW_CFA_offset, s9, -32 */ 1906*139c1837SPaolo Bonzini 0x80 + 26, 3, /* DW_CFA_offset, s10, -24 */ 1907*139c1837SPaolo Bonzini 0x80 + 27, 2, /* DW_CFA_offset, s11, -16 */ 1908*139c1837SPaolo Bonzini 0x80 + 1 , 1, /* DW_CFA_offset, ra, -8 */ 1909*139c1837SPaolo Bonzini } 1910*139c1837SPaolo Bonzini}; 1911*139c1837SPaolo Bonzini 1912*139c1837SPaolo Bonzinivoid tcg_register_jit(void *buf, size_t buf_size) 1913*139c1837SPaolo Bonzini{ 1914*139c1837SPaolo Bonzini tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame)); 1915*139c1837SPaolo Bonzini} 1916