Annotation of qemu/tcg/sparc/tcg-target.c, revision 1.1.1.6

1.1       root        1: /*
                      2:  * Tiny Code Generator for QEMU
                      3:  *
                      4:  * Copyright (c) 2008 Fabrice Bellard
                      5:  *
                      6:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                      7:  * of this software and associated documentation files (the "Software"), to deal
                      8:  * in the Software without restriction, including without limitation the rights
                      9:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     10:  * copies of the Software, and to permit persons to whom the Software is
                     11:  * furnished to do so, subject to the following conditions:
                     12:  *
                     13:  * The above copyright notice and this permission notice shall be included in
                     14:  * all copies or substantial portions of the Software.
                     15:  *
                     16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     17:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
                     19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     21:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     22:  * THE SOFTWARE.
                     23:  */
                     24: 
                     25: #ifndef NDEBUG
                     26: static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
                     27:     "%g0",
                     28:     "%g1",
                     29:     "%g2",
                     30:     "%g3",
                     31:     "%g4",
                     32:     "%g5",
                     33:     "%g6",
                     34:     "%g7",
                     35:     "%o0",
                     36:     "%o1",
                     37:     "%o2",
                     38:     "%o3",
                     39:     "%o4",
                     40:     "%o5",
                     41:     "%o6",
                     42:     "%o7",
                     43:     "%l0",
                     44:     "%l1",
                     45:     "%l2",
                     46:     "%l3",
                     47:     "%l4",
                     48:     "%l5",
                     49:     "%l6",
                     50:     "%l7",
                     51:     "%i0",
                     52:     "%i1",
                     53:     "%i2",
                     54:     "%i3",
                     55:     "%i4",
                     56:     "%i5",
                     57:     "%i6",
                     58:     "%i7",
                     59: };
                     60: #endif
                     61: 
1.1.1.6 ! root       62: #ifdef CONFIG_TCG_PASS_AREG0
        !            63: #define ARG_OFFSET 1
        !            64: #else
        !            65: #define ARG_OFFSET 0
        !            66: #endif
        !            67: 
1.1       root       68: static const int tcg_target_reg_alloc_order[] = {
                     69:     TCG_REG_L0,
                     70:     TCG_REG_L1,
                     71:     TCG_REG_L2,
                     72:     TCG_REG_L3,
                     73:     TCG_REG_L4,
                     74:     TCG_REG_L5,
                     75:     TCG_REG_L6,
                     76:     TCG_REG_L7,
                     77:     TCG_REG_I0,
                     78:     TCG_REG_I1,
                     79:     TCG_REG_I2,
                     80:     TCG_REG_I3,
                     81:     TCG_REG_I4,
                     82: };
                     83: 
                     84: static const int tcg_target_call_iarg_regs[6] = {
                     85:     TCG_REG_O0,
                     86:     TCG_REG_O1,
                     87:     TCG_REG_O2,
                     88:     TCG_REG_O3,
                     89:     TCG_REG_O4,
                     90:     TCG_REG_O5,
                     91: };
                     92: 
1.1.1.5   root       93: static const int tcg_target_call_oarg_regs[] = {
1.1       root       94:     TCG_REG_O0,
1.1.1.6 ! root       95:     TCG_REG_O1,
        !            96:     TCG_REG_O2,
        !            97:     TCG_REG_O3,
1.1       root       98: };
                     99: 
                    100: static inline int check_fit_tl(tcg_target_long val, unsigned int bits)
                    101: {
                    102:     return (val << ((sizeof(tcg_target_long) * 8 - bits))
                    103:             >> (sizeof(tcg_target_long) * 8 - bits)) == val;
                    104: }
                    105: 
                    106: static inline int check_fit_i32(uint32_t val, unsigned int bits)
                    107: {
                    108:     return ((val << (32 - bits)) >> (32 - bits)) == val;
                    109: }
                    110: 
                    111: static void patch_reloc(uint8_t *code_ptr, int type,
                    112:                         tcg_target_long value, tcg_target_long addend)
                    113: {
                    114:     value += addend;
                    115:     switch (type) {
                    116:     case R_SPARC_32:
                    117:         if (value != (uint32_t)value)
                    118:             tcg_abort();
                    119:         *(uint32_t *)code_ptr = value;
                    120:         break;
                    121:     case R_SPARC_WDISP22:
                    122:         value -= (long)code_ptr;
                    123:         value >>= 2;
                    124:         if (!check_fit_tl(value, 22))
                    125:             tcg_abort();
                    126:         *(uint32_t *)code_ptr = ((*(uint32_t *)code_ptr) & ~0x3fffff) | value;
                    127:         break;
1.1.1.2   root      128:     case R_SPARC_WDISP19:
                    129:         value -= (long)code_ptr;
                    130:         value >>= 2;
                    131:         if (!check_fit_tl(value, 19))
                    132:             tcg_abort();
                    133:         *(uint32_t *)code_ptr = ((*(uint32_t *)code_ptr) & ~0x7ffff) | value;
                    134:         break;
1.1       root      135:     default:
                    136:         tcg_abort();
                    137:     }
                    138: }
                    139: 
                    140: /* maximum number of register used for input function arguments */
                    141: static inline int tcg_target_get_call_iarg_regs_count(int flags)
                    142: {
                    143:     return 6;
                    144: }
                    145: 
                    146: /* parse target specific constraints */
                    147: static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
                    148: {
                    149:     const char *ct_str;
                    150: 
                    151:     ct_str = *pct_str;
                    152:     switch (ct_str[0]) {
                    153:     case 'r':
1.1.1.3   root      154:         ct->ct |= TCG_CT_REG;
                    155:         tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
                    156:         break;
1.1       root      157:     case 'L': /* qemu_ld/st constraint */
                    158:         ct->ct |= TCG_CT_REG;
                    159:         tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
                    160:         // Helper args
                    161:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_O0);
                    162:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_O1);
                    163:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_O2);
1.1.1.6 ! root      164: #ifdef CONFIG_TCG_PASS_AREG0
        !           165:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_O3);
        !           166: #endif
1.1       root      167:         break;
                    168:     case 'I':
                    169:         ct->ct |= TCG_CT_CONST_S11;
                    170:         break;
                    171:     case 'J':
                    172:         ct->ct |= TCG_CT_CONST_S13;
                    173:         break;
                    174:     default:
                    175:         return -1;
                    176:     }
                    177:     ct_str++;
                    178:     *pct_str = ct_str;
                    179:     return 0;
                    180: }
                    181: 
                    182: /* test if a constant matches the constraint */
                    183: static inline int tcg_target_const_match(tcg_target_long val,
                    184:                                          const TCGArgConstraint *arg_ct)
                    185: {
                    186:     int ct;
                    187: 
                    188:     ct = arg_ct->ct;
                    189:     if (ct & TCG_CT_CONST)
                    190:         return 1;
                    191:     else if ((ct & TCG_CT_CONST_S11) && check_fit_tl(val, 11))
                    192:         return 1;
                    193:     else if ((ct & TCG_CT_CONST_S13) && check_fit_tl(val, 13))
                    194:         return 1;
                    195:     else
                    196:         return 0;
                    197: }
                    198: 
                    199: #define INSN_OP(x)  ((x) << 30)
                    200: #define INSN_OP2(x) ((x) << 22)
                    201: #define INSN_OP3(x) ((x) << 19)
                    202: #define INSN_OPF(x) ((x) << 5)
                    203: #define INSN_RD(x)  ((x) << 25)
                    204: #define INSN_RS1(x) ((x) << 14)
                    205: #define INSN_RS2(x) (x)
                    206: #define INSN_ASI(x) ((x) << 5)
                    207: 
1.1.1.3   root      208: #define INSN_IMM11(x) ((1 << 13) | ((x) & 0x7ff))
1.1       root      209: #define INSN_IMM13(x) ((1 << 13) | ((x) & 0x1fff))
1.1.1.2   root      210: #define INSN_OFF19(x) (((x) >> 2) & 0x07ffff)
1.1       root      211: #define INSN_OFF22(x) (((x) >> 2) & 0x3fffff)
                    212: 
                    213: #define INSN_COND(x, a) (((x) << 25) | ((a) << 29))
                    214: #define COND_N     0x0
                    215: #define COND_E     0x1
                    216: #define COND_LE    0x2
                    217: #define COND_L     0x3
                    218: #define COND_LEU   0x4
                    219: #define COND_CS    0x5
                    220: #define COND_NEG   0x6
                    221: #define COND_VS    0x7
                    222: #define COND_A     0x8
                    223: #define COND_NE    0x9
                    224: #define COND_G     0xa
                    225: #define COND_GE    0xb
                    226: #define COND_GU    0xc
                    227: #define COND_CC    0xd
                    228: #define COND_POS   0xe
                    229: #define COND_VC    0xf
                    230: #define BA         (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2))
                    231: 
1.1.1.3   root      232: #define MOVCC_ICC  (1 << 18)
                    233: #define MOVCC_XCC  (1 << 18 | 1 << 12)
                    234: 
1.1       root      235: #define ARITH_ADD  (INSN_OP(2) | INSN_OP3(0x00))
1.1.1.3   root      236: #define ARITH_ADDCC (INSN_OP(2) | INSN_OP3(0x10))
1.1       root      237: #define ARITH_AND  (INSN_OP(2) | INSN_OP3(0x01))
1.1.1.3   root      238: #define ARITH_ANDN (INSN_OP(2) | INSN_OP3(0x05))
1.1       root      239: #define ARITH_OR   (INSN_OP(2) | INSN_OP3(0x02))
                    240: #define ARITH_ORCC (INSN_OP(2) | INSN_OP3(0x12))
1.1.1.3   root      241: #define ARITH_ORN  (INSN_OP(2) | INSN_OP3(0x06))
1.1       root      242: #define ARITH_XOR  (INSN_OP(2) | INSN_OP3(0x03))
                    243: #define ARITH_SUB  (INSN_OP(2) | INSN_OP3(0x04))
                    244: #define ARITH_SUBCC (INSN_OP(2) | INSN_OP3(0x14))
                    245: #define ARITH_ADDX (INSN_OP(2) | INSN_OP3(0x10))
                    246: #define ARITH_SUBX (INSN_OP(2) | INSN_OP3(0x0c))
                    247: #define ARITH_UMUL (INSN_OP(2) | INSN_OP3(0x0a))
                    248: #define ARITH_UDIV (INSN_OP(2) | INSN_OP3(0x0e))
                    249: #define ARITH_SDIV (INSN_OP(2) | INSN_OP3(0x0f))
                    250: #define ARITH_MULX (INSN_OP(2) | INSN_OP3(0x09))
                    251: #define ARITH_UDIVX (INSN_OP(2) | INSN_OP3(0x0d))
                    252: #define ARITH_SDIVX (INSN_OP(2) | INSN_OP3(0x2d))
1.1.1.3   root      253: #define ARITH_MOVCC (INSN_OP(2) | INSN_OP3(0x2c))
1.1       root      254: 
                    255: #define SHIFT_SLL  (INSN_OP(2) | INSN_OP3(0x25))
                    256: #define SHIFT_SRL  (INSN_OP(2) | INSN_OP3(0x26))
                    257: #define SHIFT_SRA  (INSN_OP(2) | INSN_OP3(0x27))
                    258: 
                    259: #define SHIFT_SLLX (INSN_OP(2) | INSN_OP3(0x25) | (1 << 12))
                    260: #define SHIFT_SRLX (INSN_OP(2) | INSN_OP3(0x26) | (1 << 12))
                    261: #define SHIFT_SRAX (INSN_OP(2) | INSN_OP3(0x27) | (1 << 12))
                    262: 
1.1.1.3   root      263: #define RDY        (INSN_OP(2) | INSN_OP3(0x28) | INSN_RS1(0))
                    264: #define WRY        (INSN_OP(2) | INSN_OP3(0x30) | INSN_RD(0))
1.1       root      265: #define JMPL       (INSN_OP(2) | INSN_OP3(0x38))
                    266: #define SAVE       (INSN_OP(2) | INSN_OP3(0x3c))
                    267: #define RESTORE    (INSN_OP(2) | INSN_OP3(0x3d))
                    268: #define SETHI      (INSN_OP(0) | INSN_OP2(0x4))
                    269: #define CALL       INSN_OP(1)
                    270: #define LDUB       (INSN_OP(3) | INSN_OP3(0x01))
                    271: #define LDSB       (INSN_OP(3) | INSN_OP3(0x09))
                    272: #define LDUH       (INSN_OP(3) | INSN_OP3(0x02))
                    273: #define LDSH       (INSN_OP(3) | INSN_OP3(0x0a))
                    274: #define LDUW       (INSN_OP(3) | INSN_OP3(0x00))
                    275: #define LDSW       (INSN_OP(3) | INSN_OP3(0x08))
                    276: #define LDX        (INSN_OP(3) | INSN_OP3(0x0b))
                    277: #define STB        (INSN_OP(3) | INSN_OP3(0x05))
                    278: #define STH        (INSN_OP(3) | INSN_OP3(0x06))
                    279: #define STW        (INSN_OP(3) | INSN_OP3(0x04))
                    280: #define STX        (INSN_OP(3) | INSN_OP3(0x0e))
                    281: #define LDUBA      (INSN_OP(3) | INSN_OP3(0x11))
                    282: #define LDSBA      (INSN_OP(3) | INSN_OP3(0x19))
                    283: #define LDUHA      (INSN_OP(3) | INSN_OP3(0x12))
                    284: #define LDSHA      (INSN_OP(3) | INSN_OP3(0x1a))
                    285: #define LDUWA      (INSN_OP(3) | INSN_OP3(0x10))
                    286: #define LDSWA      (INSN_OP(3) | INSN_OP3(0x18))
                    287: #define LDXA       (INSN_OP(3) | INSN_OP3(0x1b))
                    288: #define STBA       (INSN_OP(3) | INSN_OP3(0x15))
                    289: #define STHA       (INSN_OP(3) | INSN_OP3(0x16))
                    290: #define STWA       (INSN_OP(3) | INSN_OP3(0x14))
                    291: #define STXA       (INSN_OP(3) | INSN_OP3(0x1e))
                    292: 
                    293: #ifndef ASI_PRIMARY_LITTLE
                    294: #define ASI_PRIMARY_LITTLE 0x88
                    295: #endif
                    296: 
                    297: static inline void tcg_out_arith(TCGContext *s, int rd, int rs1, int rs2,
                    298:                                  int op)
                    299: {
                    300:     tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1) |
                    301:               INSN_RS2(rs2));
                    302: }
                    303: 
                    304: static inline void tcg_out_arithi(TCGContext *s, int rd, int rs1,
                    305:                                   uint32_t offset, int op)
                    306: {
                    307:     tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1) |
                    308:               INSN_IMM13(offset));
                    309: }
                    310: 
1.1.1.3   root      311: static void tcg_out_arithc(TCGContext *s, int rd, int rs1,
                    312:                           int val2, int val2const, int op)
                    313: {
                    314:     tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1)
                    315:               | (val2const ? INSN_IMM13(val2) : INSN_RS2(val2)));
                    316: }
                    317: 
1.1.1.5   root      318: static inline void tcg_out_mov(TCGContext *s, TCGType type,
                    319:                                TCGReg ret, TCGReg arg)
1.1       root      320: {
                    321:     tcg_out_arith(s, ret, arg, TCG_REG_G0, ARITH_OR);
                    322: }
                    323: 
                    324: static inline void tcg_out_sethi(TCGContext *s, int ret, uint32_t arg)
                    325: {
                    326:     tcg_out32(s, SETHI | INSN_RD(ret) | ((arg & 0xfffffc00) >> 10));
                    327: }
                    328: 
                    329: static inline void tcg_out_movi_imm13(TCGContext *s, int ret, uint32_t arg)
                    330: {
                    331:     tcg_out_arithi(s, ret, TCG_REG_G0, arg, ARITH_OR);
                    332: }
                    333: 
                    334: static inline void tcg_out_movi_imm32(TCGContext *s, int ret, uint32_t arg)
                    335: {
1.1.1.3   root      336:     if (check_fit_tl(arg, 13))
1.1       root      337:         tcg_out_movi_imm13(s, ret, arg);
                    338:     else {
                    339:         tcg_out_sethi(s, ret, arg);
                    340:         if (arg & 0x3ff)
                    341:             tcg_out_arithi(s, ret, ret, arg & 0x3ff, ARITH_OR);
                    342:     }
                    343: }
                    344: 
                    345: static inline void tcg_out_movi(TCGContext *s, TCGType type,
1.1.1.5   root      346:                                 TCGReg ret, tcg_target_long arg)
1.1       root      347: {
1.1.1.3   root      348:     /* All 32-bit constants, as well as 64-bit constants with
                    349:        no high bits set go through movi_imm32.  */
                    350:     if (TCG_TARGET_REG_BITS == 32
                    351:         || type == TCG_TYPE_I32
                    352:         || (arg & ~(tcg_target_long)0xffffffff) == 0) {
                    353:         tcg_out_movi_imm32(s, ret, arg);
                    354:     } else if (check_fit_tl(arg, 13)) {
                    355:         /* A 13-bit constant sign-extended to 64-bits.  */
                    356:         tcg_out_movi_imm13(s, ret, arg);
                    357:     } else if (check_fit_tl(arg, 32)) {
                    358:         /* A 32-bit constant sign-extended to 64-bits.  */
                    359:         tcg_out_sethi(s, ret, ~arg);
                    360:         tcg_out_arithi(s, ret, ret, (arg & 0x3ff) | -0x400, ARITH_XOR);
                    361:     } else {
                    362:         tcg_out_movi_imm32(s, TCG_REG_I4, arg >> (TCG_TARGET_REG_BITS / 2));
1.1       root      363:         tcg_out_arithi(s, TCG_REG_I4, TCG_REG_I4, 32, SHIFT_SLLX);
                    364:         tcg_out_movi_imm32(s, ret, arg);
                    365:         tcg_out_arith(s, ret, ret, TCG_REG_I4, ARITH_OR);
                    366:     }
                    367: }
                    368: 
                    369: static inline void tcg_out_ld_raw(TCGContext *s, int ret,
                    370:                                   tcg_target_long arg)
                    371: {
                    372:     tcg_out_sethi(s, ret, arg);
                    373:     tcg_out32(s, LDUW | INSN_RD(ret) | INSN_RS1(ret) |
                    374:               INSN_IMM13(arg & 0x3ff));
                    375: }
                    376: 
                    377: static inline void tcg_out_ld_ptr(TCGContext *s, int ret,
                    378:                                   tcg_target_long arg)
                    379: {
                    380:     if (!check_fit_tl(arg, 10))
                    381:         tcg_out_movi(s, TCG_TYPE_PTR, ret, arg & ~0x3ffULL);
1.1.1.3   root      382:     if (TCG_TARGET_REG_BITS == 64) {
                    383:         tcg_out32(s, LDX | INSN_RD(ret) | INSN_RS1(ret) |
                    384:                   INSN_IMM13(arg & 0x3ff));
                    385:     } else {
                    386:         tcg_out32(s, LDUW | INSN_RD(ret) | INSN_RS1(ret) |
                    387:                   INSN_IMM13(arg & 0x3ff));
                    388:     }
1.1       root      389: }
                    390: 
                    391: static inline void tcg_out_ldst(TCGContext *s, int ret, int addr, int offset, int op)
                    392: {
                    393:     if (check_fit_tl(offset, 13))
                    394:         tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(addr) |
                    395:                   INSN_IMM13(offset));
                    396:     else {
                    397:         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, offset);
                    398:         tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(TCG_REG_I5) |
                    399:                   INSN_RS2(addr));
                    400:     }
                    401: }
                    402: 
                    403: static inline void tcg_out_ldst_asi(TCGContext *s, int ret, int addr,
                    404:                                     int offset, int op, int asi)
                    405: {
                    406:     tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, offset);
                    407:     tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(TCG_REG_I5) |
                    408:               INSN_ASI(asi) | INSN_RS2(addr));
                    409: }
                    410: 
1.1.1.5   root      411: static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret,
                    412:                               TCGReg arg1, tcg_target_long arg2)
1.1       root      413: {
                    414:     if (type == TCG_TYPE_I32)
                    415:         tcg_out_ldst(s, ret, arg1, arg2, LDUW);
                    416:     else
                    417:         tcg_out_ldst(s, ret, arg1, arg2, LDX);
                    418: }
                    419: 
1.1.1.5   root      420: static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
                    421:                               TCGReg arg1, tcg_target_long arg2)
1.1       root      422: {
                    423:     if (type == TCG_TYPE_I32)
                    424:         tcg_out_ldst(s, arg, arg1, arg2, STW);
                    425:     else
                    426:         tcg_out_ldst(s, arg, arg1, arg2, STX);
                    427: }
                    428: 
1.1.1.3   root      429: static inline void tcg_out_sety(TCGContext *s, int rs)
1.1       root      430: {
1.1.1.3   root      431:     tcg_out32(s, WRY | INSN_RS1(TCG_REG_G0) | INSN_RS2(rs));
                    432: }
                    433: 
                    434: static inline void tcg_out_rdy(TCGContext *s, int rd)
                    435: {
                    436:     tcg_out32(s, RDY | INSN_RD(rd));
1.1       root      437: }
                    438: 
                    439: static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
                    440: {
                    441:     if (val != 0) {
                    442:         if (check_fit_tl(val, 13))
                    443:             tcg_out_arithi(s, reg, reg, val, ARITH_ADD);
                    444:         else {
                    445:             tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, val);
                    446:             tcg_out_arith(s, reg, reg, TCG_REG_I5, ARITH_ADD);
                    447:         }
                    448:     }
                    449: }
                    450: 
                    451: static inline void tcg_out_andi(TCGContext *s, int reg, tcg_target_long val)
                    452: {
                    453:     if (val != 0) {
                    454:         if (check_fit_tl(val, 13))
                    455:             tcg_out_arithi(s, reg, reg, val, ARITH_AND);
                    456:         else {
                    457:             tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_I5, val);
                    458:             tcg_out_arith(s, reg, reg, TCG_REG_I5, ARITH_AND);
                    459:         }
                    460:     }
                    461: }
                    462: 
1.1.1.3   root      463: static void tcg_out_div32(TCGContext *s, int rd, int rs1,
                    464:                           int val2, int val2const, int uns)
                    465: {
                    466:     /* Load Y with the sign/zero extension of RS1 to 64-bits.  */
                    467:     if (uns) {
                    468:         tcg_out_sety(s, TCG_REG_G0);
                    469:     } else {
                    470:         tcg_out_arithi(s, TCG_REG_I5, rs1, 31, SHIFT_SRA);
                    471:         tcg_out_sety(s, TCG_REG_I5);
                    472:     }
                    473: 
                    474:     tcg_out_arithc(s, rd, rs1, val2, val2const,
                    475:                    uns ? ARITH_UDIV : ARITH_SDIV);
                    476: }
                    477: 
1.1       root      478: static inline void tcg_out_nop(TCGContext *s)
                    479: {
                    480:     tcg_out_sethi(s, TCG_REG_G0, 0);
                    481: }
                    482: 
1.1.1.2   root      483: static void tcg_out_branch_i32(TCGContext *s, int opc, int label_index)
1.1       root      484: {
                    485:     TCGLabel *l = &s->labels[label_index];
                    486: 
                    487:     if (l->has_value) {
                    488:         tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x2)
                    489:                       | INSN_OFF22(l->u.value - (unsigned long)s->code_ptr)));
                    490:     } else {
                    491:         tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP22, label_index, 0);
                    492:         tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x2) | 0));
                    493:     }
                    494: }
                    495: 
1.1.1.3   root      496: #if TCG_TARGET_REG_BITS == 64
1.1.1.2   root      497: static void tcg_out_branch_i64(TCGContext *s, int opc, int label_index)
                    498: {
                    499:     TCGLabel *l = &s->labels[label_index];
                    500: 
                    501:     if (l->has_value) {
                    502:         tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x1) |
                    503:                       (0x5 << 19) |
                    504:                       INSN_OFF19(l->u.value - (unsigned long)s->code_ptr)));
                    505:     } else {
                    506:         tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP19, label_index, 0);
                    507:         tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x1) |
                    508:                       (0x5 << 19) | 0));
                    509:     }
                    510: }
                    511: #endif
                    512: 
1.1       root      513: static const uint8_t tcg_cond_to_bcond[10] = {
                    514:     [TCG_COND_EQ] = COND_E,
                    515:     [TCG_COND_NE] = COND_NE,
                    516:     [TCG_COND_LT] = COND_L,
                    517:     [TCG_COND_GE] = COND_GE,
                    518:     [TCG_COND_LE] = COND_LE,
                    519:     [TCG_COND_GT] = COND_G,
                    520:     [TCG_COND_LTU] = COND_CS,
                    521:     [TCG_COND_GEU] = COND_CC,
                    522:     [TCG_COND_LEU] = COND_LEU,
                    523:     [TCG_COND_GTU] = COND_GU,
                    524: };
                    525: 
1.1.1.3   root      526: static void tcg_out_cmp(TCGContext *s, TCGArg c1, TCGArg c2, int c2const)
                    527: {
                    528:     tcg_out_arithc(s, TCG_REG_G0, c1, c2, c2const, ARITH_SUBCC);
                    529: }
                    530: 
                    531: static void tcg_out_brcond_i32(TCGContext *s, TCGCond cond,
1.1.1.2   root      532:                                TCGArg arg1, TCGArg arg2, int const_arg2,
                    533:                                int label_index)
                    534: {
1.1.1.3   root      535:     tcg_out_cmp(s, arg1, arg2, const_arg2);
1.1.1.2   root      536:     tcg_out_branch_i32(s, tcg_cond_to_bcond[cond], label_index);
                    537:     tcg_out_nop(s);
                    538: }
                    539: 
1.1.1.3   root      540: #if TCG_TARGET_REG_BITS == 64
                    541: static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond,
1.1.1.2   root      542:                                TCGArg arg1, TCGArg arg2, int const_arg2,
                    543:                                int label_index)
1.1       root      544: {
1.1.1.3   root      545:     tcg_out_cmp(s, arg1, arg2, const_arg2);
1.1.1.2   root      546:     tcg_out_branch_i64(s, tcg_cond_to_bcond[cond], label_index);
1.1       root      547:     tcg_out_nop(s);
                    548: }
1.1.1.3   root      549: #else
                    550: static void tcg_out_brcond2_i32(TCGContext *s, TCGCond cond,
                    551:                                 TCGArg al, TCGArg ah,
                    552:                                 TCGArg bl, int blconst,
                    553:                                 TCGArg bh, int bhconst, int label_dest)
                    554: {
                    555:     int cc, label_next = gen_new_label();
                    556: 
                    557:     tcg_out_cmp(s, ah, bh, bhconst);
                    558: 
                    559:     /* Note that we fill one of the delay slots with the second compare.  */
                    560:     switch (cond) {
                    561:     case TCG_COND_EQ:
                    562:         cc = INSN_COND(tcg_cond_to_bcond[TCG_COND_NE], 0);
                    563:         tcg_out_branch_i32(s, cc, label_next);
                    564:         tcg_out_cmp(s, al, bl, blconst);
                    565:         cc = INSN_COND(tcg_cond_to_bcond[TCG_COND_EQ], 0);
                    566:         tcg_out_branch_i32(s, cc, label_dest);
                    567:         break;
                    568: 
                    569:     case TCG_COND_NE:
                    570:         cc = INSN_COND(tcg_cond_to_bcond[TCG_COND_NE], 0);
                    571:         tcg_out_branch_i32(s, cc, label_dest);
                    572:         tcg_out_cmp(s, al, bl, blconst);
                    573:         tcg_out_branch_i32(s, cc, label_dest);
                    574:         break;
                    575: 
                    576:     default:
                    577:         /* ??? One could fairly easily special-case 64-bit unsigned
                    578:            compares against 32-bit zero-extended constants.  For instance,
                    579:            we know that (unsigned)AH < 0 is false and need not emit it.
                    580:            Similarly, (unsigned)AH > 0 being true implies AH != 0, so the
                    581:            second branch will never be taken.  */
                    582:         cc = INSN_COND(tcg_cond_to_bcond[cond], 0);
                    583:         tcg_out_branch_i32(s, cc, label_dest);
                    584:         tcg_out_nop(s);
                    585:         cc = INSN_COND(tcg_cond_to_bcond[TCG_COND_NE], 0);
                    586:         tcg_out_branch_i32(s, cc, label_next);
                    587:         tcg_out_cmp(s, al, bl, blconst);
                    588:         cc = INSN_COND(tcg_cond_to_bcond[tcg_unsigned_cond(cond)], 0);
                    589:         tcg_out_branch_i32(s, cc, label_dest);
                    590:         break;
                    591:     }
                    592:     tcg_out_nop(s);
                    593: 
1.1.1.6 ! root      594:     tcg_out_label(s, label_next, s->code_ptr);
1.1.1.3   root      595: }
                    596: #endif
                    597: 
                    598: static void tcg_out_setcond_i32(TCGContext *s, TCGCond cond, TCGArg ret,
                    599:                                 TCGArg c1, TCGArg c2, int c2const)
                    600: {
                    601:     TCGArg t;
                    602: 
                    603:     /* For 32-bit comparisons, we can play games with ADDX/SUBX.  */
                    604:     switch (cond) {
                    605:     case TCG_COND_EQ:
                    606:     case TCG_COND_NE:
                    607:         if (c2 != 0) {
                    608:             tcg_out_arithc(s, ret, c1, c2, c2const, ARITH_XOR);
                    609:         }
                    610:         c1 = TCG_REG_G0, c2 = ret, c2const = 0;
                    611:         cond = (cond == TCG_COND_EQ ? TCG_COND_LEU : TCG_COND_LTU);
                    612:        break;
                    613: 
                    614:     case TCG_COND_GTU:
                    615:     case TCG_COND_GEU:
                    616:         if (c2const && c2 != 0) {
                    617:             tcg_out_movi_imm13(s, TCG_REG_I5, c2);
                    618:             c2 = TCG_REG_I5;
                    619:         }
                    620:         t = c1, c1 = c2, c2 = t, c2const = 0;
                    621:         cond = tcg_swap_cond(cond);
                    622:         break;
                    623: 
                    624:     case TCG_COND_LTU:
                    625:     case TCG_COND_LEU:
                    626:         break;
                    627: 
                    628:     default:
                    629:         tcg_out_cmp(s, c1, c2, c2const);
                    630: #if defined(__sparc_v9__) || defined(__sparc_v8plus__)
                    631:         tcg_out_movi_imm13(s, ret, 0);
                    632:         tcg_out32 (s, ARITH_MOVCC | INSN_RD(ret)
                    633:                    | INSN_RS1(tcg_cond_to_bcond[cond])
                    634:                    | MOVCC_ICC | INSN_IMM11(1));
                    635: #else
                    636:         t = gen_new_label();
                    637:         tcg_out_branch_i32(s, INSN_COND(tcg_cond_to_bcond[cond], 1), t);
                    638:         tcg_out_movi_imm13(s, ret, 1);
                    639:         tcg_out_movi_imm13(s, ret, 0);
1.1.1.6 ! root      640:         tcg_out_label(s, t, s->code_ptr);
1.1.1.3   root      641: #endif
                    642:         return;
                    643:     }
                    644: 
                    645:     tcg_out_cmp(s, c1, c2, c2const);
                    646:     if (cond == TCG_COND_LTU) {
                    647:         tcg_out_arithi(s, ret, TCG_REG_G0, 0, ARITH_ADDX);
                    648:     } else {
                    649:         tcg_out_arithi(s, ret, TCG_REG_G0, -1, ARITH_SUBX);
                    650:     }
                    651: }
                    652: 
                    653: #if TCG_TARGET_REG_BITS == 64
                    654: static void tcg_out_setcond_i64(TCGContext *s, TCGCond cond, TCGArg ret,
                    655:                                 TCGArg c1, TCGArg c2, int c2const)
                    656: {
                    657:     tcg_out_cmp(s, c1, c2, c2const);
                    658:     tcg_out_movi_imm13(s, ret, 0);
                    659:     tcg_out32 (s, ARITH_MOVCC | INSN_RD(ret)
                    660:                | INSN_RS1(tcg_cond_to_bcond[cond])
                    661:                | MOVCC_XCC | INSN_IMM11(1));
                    662: }
                    663: #else
                    664: static void tcg_out_setcond2_i32(TCGContext *s, TCGCond cond, TCGArg ret,
                    665:                                  TCGArg al, TCGArg ah,
                    666:                                  TCGArg bl, int blconst,
                    667:                                  TCGArg bh, int bhconst)
                    668: {
                    669:     int lab;
                    670: 
                    671:     switch (cond) {
                    672:     case TCG_COND_EQ:
                    673:         tcg_out_setcond_i32(s, TCG_COND_EQ, TCG_REG_I5, al, bl, blconst);
                    674:         tcg_out_setcond_i32(s, TCG_COND_EQ, ret, ah, bh, bhconst);
                    675:         tcg_out_arith(s, ret, ret, TCG_REG_I5, ARITH_AND);
                    676:         break;
                    677: 
                    678:     case TCG_COND_NE:
                    679:         tcg_out_setcond_i32(s, TCG_COND_NE, TCG_REG_I5, al, al, blconst);
                    680:         tcg_out_setcond_i32(s, TCG_COND_NE, ret, ah, bh, bhconst);
                    681:         tcg_out_arith(s, ret, ret, TCG_REG_I5, ARITH_OR);
                    682:         break;
                    683: 
                    684:     default:
                    685:         lab = gen_new_label();
                    686: 
                    687:         tcg_out_cmp(s, ah, bh, bhconst);
                    688:         tcg_out_branch_i32(s, INSN_COND(tcg_cond_to_bcond[cond], 1), lab);
                    689:         tcg_out_movi_imm13(s, ret, 1);
                    690:         tcg_out_branch_i32(s, INSN_COND(COND_NE, 1), lab);
                    691:         tcg_out_movi_imm13(s, ret, 0);
                    692: 
                    693:         tcg_out_setcond_i32(s, tcg_unsigned_cond(cond), ret, al, bl, blconst);
                    694: 
1.1.1.6 ! root      695:         tcg_out_label(s, lab, s->code_ptr);
1.1.1.3   root      696:         break;
                    697:     }
                    698: }
1.1.1.2   root      699: #endif
1.1       root      700: 
                    701: /* Generate global QEMU prologue and epilogue code */
1.1.1.3   root      702: static void tcg_target_qemu_prologue(TCGContext *s)
1.1       root      703: {
1.1.1.4   root      704:     tcg_set_frame(s, TCG_REG_I6, TCG_TARGET_CALL_STACK_OFFSET,
                    705:                   CPU_TEMP_BUF_NLONGS * (int)sizeof(long));
1.1       root      706:     tcg_out32(s, SAVE | INSN_RD(TCG_REG_O6) | INSN_RS1(TCG_REG_O6) |
1.1.1.4   root      707:               INSN_IMM13(-(TCG_TARGET_STACK_MINFRAME +
                    708:                            CPU_TEMP_BUF_NLONGS * (int)sizeof(long))));
                    709:     tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I1) |
1.1       root      710:               INSN_RS2(TCG_REG_G0));
1.1.1.4   root      711:     tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_I0);
1.1       root      712: }
                    713: 
                    714: #if defined(CONFIG_SOFTMMU)
                    715: 
                    716: #include "../../softmmu_defs.h"
                    717: 
1.1.1.6 ! root      718: #ifdef CONFIG_TCG_PASS_AREG0
        !           719: /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
        !           720:    int mmu_idx) */
        !           721: static const void * const qemu_ld_helpers[4] = {
        !           722:     helper_ldb_mmu,
        !           723:     helper_ldw_mmu,
        !           724:     helper_ldl_mmu,
        !           725:     helper_ldq_mmu,
        !           726: };
        !           727: 
        !           728: /* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
        !           729:    uintxx_t val, int mmu_idx) */
        !           730: static const void * const qemu_st_helpers[4] = {
        !           731:     helper_stb_mmu,
        !           732:     helper_stw_mmu,
        !           733:     helper_stl_mmu,
        !           734:     helper_stq_mmu,
        !           735: };
        !           736: #else
        !           737: /* legacy helper signature: __ld_mmu(target_ulong addr, int
        !           738:    mmu_idx) */
1.1       root      739: static const void * const qemu_ld_helpers[4] = {
                    740:     __ldb_mmu,
                    741:     __ldw_mmu,
                    742:     __ldl_mmu,
                    743:     __ldq_mmu,
                    744: };
                    745: 
1.1.1.6 ! root      746: /* legacy helper signature: __st_mmu(target_ulong addr, uintxx_t val,
        !           747:    int mmu_idx) */
1.1       root      748: static const void * const qemu_st_helpers[4] = {
                    749:     __stb_mmu,
                    750:     __stw_mmu,
                    751:     __stl_mmu,
                    752:     __stq_mmu,
                    753: };
                    754: #endif
1.1.1.6 ! root      755: #endif
1.1       root      756: 
                    757: #if TARGET_LONG_BITS == 32
                    758: #define TARGET_LD_OP LDUW
                    759: #else
                    760: #define TARGET_LD_OP LDX
                    761: #endif
                    762: 
1.1.1.3   root      763: #if defined(CONFIG_SOFTMMU)
                    764: #if HOST_LONG_BITS == 32
1.1       root      765: #define TARGET_ADDEND_LD_OP LDUW
                    766: #else
                    767: #define TARGET_ADDEND_LD_OP LDX
                    768: #endif
1.1.1.3   root      769: #endif
1.1       root      770: 
                    771: #ifdef __arch64__
                    772: #define HOST_LD_OP LDX
                    773: #define HOST_ST_OP STX
                    774: #define HOST_SLL_OP SHIFT_SLLX
                    775: #define HOST_SRA_OP SHIFT_SRAX
                    776: #else
                    777: #define HOST_LD_OP LDUW
                    778: #define HOST_ST_OP STW
                    779: #define HOST_SLL_OP SHIFT_SLL
                    780: #define HOST_SRA_OP SHIFT_SRA
                    781: #endif
                    782: 
                    783: static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
                    784:                             int opc)
                    785: {
                    786:     int addr_reg, data_reg, arg0, arg1, arg2, mem_index, s_bits;
                    787: #if defined(CONFIG_SOFTMMU)
                    788:     uint32_t *label1_ptr, *label2_ptr;
                    789: #endif
                    790: 
                    791:     data_reg = *args++;
                    792:     addr_reg = *args++;
                    793:     mem_index = *args;
                    794:     s_bits = opc & 3;
                    795: 
                    796:     arg0 = TCG_REG_O0;
                    797:     arg1 = TCG_REG_O1;
                    798:     arg2 = TCG_REG_O2;
                    799: 
                    800: #if defined(CONFIG_SOFTMMU)
                    801:     /* srl addr_reg, x, arg1 */
                    802:     tcg_out_arithi(s, arg1, addr_reg, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS,
                    803:                    SHIFT_SRL);
                    804:     /* and addr_reg, x, arg0 */
                    805:     tcg_out_arithi(s, arg0, addr_reg, TARGET_PAGE_MASK | ((1 << s_bits) - 1),
                    806:                    ARITH_AND);
                    807: 
                    808:     /* and arg1, x, arg1 */
                    809:     tcg_out_andi(s, arg1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
                    810: 
                    811:     /* add arg1, x, arg1 */
1.1.1.6 ! root      812:     tcg_out_addi(s, arg1, offsetof(CPUArchState,
1.1       root      813:                                    tlb_table[mem_index][0].addr_read));
                    814: 
                    815:     /* add env, arg1, arg1 */
                    816:     tcg_out_arith(s, arg1, TCG_AREG0, arg1, ARITH_ADD);
                    817: 
                    818:     /* ld [arg1], arg2 */
                    819:     tcg_out32(s, TARGET_LD_OP | INSN_RD(arg2) | INSN_RS1(arg1) |
                    820:               INSN_RS2(TCG_REG_G0));
                    821: 
                    822:     /* subcc arg0, arg2, %g0 */
                    823:     tcg_out_arith(s, TCG_REG_G0, arg0, arg2, ARITH_SUBCC);
                    824: 
                    825:     /* will become:
1.1.1.2   root      826:        be label1
                    827:         or
                    828:        be,pt %xcc label1 */
1.1       root      829:     label1_ptr = (uint32_t *)s->code_ptr;
                    830:     tcg_out32(s, 0);
                    831: 
                    832:     /* mov (delay slot) */
1.1.1.3   root      833:     tcg_out_mov(s, TCG_TYPE_PTR, arg0, addr_reg);
1.1       root      834: 
                    835:     /* mov */
                    836:     tcg_out_movi(s, TCG_TYPE_I32, arg1, mem_index);
1.1.1.6 ! root      837: #ifdef CONFIG_TCG_PASS_AREG0
        !           838:     /* XXX/FIXME: suboptimal */
        !           839:     tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
        !           840:                 tcg_target_call_iarg_regs[2]);
        !           841:     tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
        !           842:                 tcg_target_call_iarg_regs[1]);
        !           843:     tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
        !           844:                 tcg_target_call_iarg_regs[0]);
        !           845:     tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
        !           846:                 TCG_AREG0);
        !           847: #endif
1.1       root      848: 
                    849:     /* XXX: move that code at the end of the TB */
                    850:     /* qemu_ld_helper[s_bits](arg0, arg1) */
                    851:     tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_ld_helpers[s_bits]
                    852:                            - (tcg_target_ulong)s->code_ptr) >> 2)
                    853:                          & 0x3fffffff));
                    854:     /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
                    855:        global registers */
                    856:     // delay slot
                    857:     tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
1.1.1.2   root      858:                  TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
                    859:                  sizeof(long), HOST_ST_OP);
1.1       root      860:     tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
1.1.1.2   root      861:                  TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
                    862:                  sizeof(long), HOST_LD_OP);
1.1       root      863: 
                    864:     /* data_reg = sign_extend(arg0) */
                    865:     switch(opc) {
                    866:     case 0 | 4:
                    867:         /* sll arg0, 24/56, data_reg */
                    868:         tcg_out_arithi(s, data_reg, arg0, (int)sizeof(tcg_target_long) * 8 - 8,
                    869:                        HOST_SLL_OP);
                    870:         /* sra data_reg, 24/56, data_reg */
                    871:         tcg_out_arithi(s, data_reg, data_reg,
                    872:                        (int)sizeof(tcg_target_long) * 8 - 8, HOST_SRA_OP);
                    873:         break;
                    874:     case 1 | 4:
                    875:         /* sll arg0, 16/48, data_reg */
                    876:         tcg_out_arithi(s, data_reg, arg0,
                    877:                        (int)sizeof(tcg_target_long) * 8 - 16, HOST_SLL_OP);
                    878:         /* sra data_reg, 16/48, data_reg */
                    879:         tcg_out_arithi(s, data_reg, data_reg,
                    880:                        (int)sizeof(tcg_target_long) * 8 - 16, HOST_SRA_OP);
                    881:         break;
                    882:     case 2 | 4:
                    883:         /* sll arg0, 32, data_reg */
                    884:         tcg_out_arithi(s, data_reg, arg0, 32, HOST_SLL_OP);
                    885:         /* sra data_reg, 32, data_reg */
                    886:         tcg_out_arithi(s, data_reg, data_reg, 32, HOST_SRA_OP);
                    887:         break;
                    888:     case 0:
                    889:     case 1:
                    890:     case 2:
                    891:     case 3:
                    892:     default:
                    893:         /* mov */
1.1.1.3   root      894:         tcg_out_mov(s, TCG_TYPE_REG, data_reg, arg0);
1.1       root      895:         break;
                    896:     }
                    897: 
                    898:     /* will become:
                    899:        ba label2 */
                    900:     label2_ptr = (uint32_t *)s->code_ptr;
                    901:     tcg_out32(s, 0);
                    902: 
                    903:     /* nop (delay slot */
                    904:     tcg_out_nop(s);
                    905: 
                    906:     /* label1: */
1.1.1.2   root      907: #if TARGET_LONG_BITS == 32
                    908:     /* be label1 */
1.1       root      909:     *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x2) |
                    910:                    INSN_OFF22((unsigned long)s->code_ptr -
                    911:                               (unsigned long)label1_ptr));
1.1.1.2   root      912: #else
                    913:     /* be,pt %xcc label1 */
                    914:     *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x1) |
                    915:                    (0x5 << 19) | INSN_OFF19((unsigned long)s->code_ptr -
                    916:                               (unsigned long)label1_ptr));
                    917: #endif
1.1       root      918: 
                    919:     /* ld [arg1 + x], arg1 */
                    920:     tcg_out_ldst(s, arg1, arg1, offsetof(CPUTLBEntry, addend) -
                    921:                  offsetof(CPUTLBEntry, addr_read), TARGET_ADDEND_LD_OP);
                    922: 
                    923: #if TARGET_LONG_BITS == 32
                    924:     /* and addr_reg, x, arg0 */
                    925:     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_I5, 0xffffffff);
                    926:     tcg_out_arith(s, arg0, addr_reg, TCG_REG_I5, ARITH_AND);
                    927:     /* add arg0, arg1, arg0 */
                    928:     tcg_out_arith(s, arg0, arg0, arg1, ARITH_ADD);
                    929: #else
                    930:     /* add addr_reg, arg1, arg0 */
                    931:     tcg_out_arith(s, arg0, addr_reg, arg1, ARITH_ADD);
                    932: #endif
                    933: 
                    934: #else
                    935:     arg0 = addr_reg;
                    936: #endif
                    937: 
                    938:     switch(opc) {
                    939:     case 0:
                    940:         /* ldub [arg0], data_reg */
                    941:         tcg_out_ldst(s, data_reg, arg0, 0, LDUB);
                    942:         break;
                    943:     case 0 | 4:
                    944:         /* ldsb [arg0], data_reg */
                    945:         tcg_out_ldst(s, data_reg, arg0, 0, LDSB);
                    946:         break;
                    947:     case 1:
                    948: #ifdef TARGET_WORDS_BIGENDIAN
                    949:         /* lduh [arg0], data_reg */
                    950:         tcg_out_ldst(s, data_reg, arg0, 0, LDUH);
                    951: #else
                    952:         /* lduha [arg0] ASI_PRIMARY_LITTLE, data_reg */
                    953:         tcg_out_ldst_asi(s, data_reg, arg0, 0, LDUHA, ASI_PRIMARY_LITTLE);
                    954: #endif
                    955:         break;
                    956:     case 1 | 4:
                    957: #ifdef TARGET_WORDS_BIGENDIAN
                    958:         /* ldsh [arg0], data_reg */
                    959:         tcg_out_ldst(s, data_reg, arg0, 0, LDSH);
                    960: #else
                    961:         /* ldsha [arg0] ASI_PRIMARY_LITTLE, data_reg */
                    962:         tcg_out_ldst_asi(s, data_reg, arg0, 0, LDSHA, ASI_PRIMARY_LITTLE);
                    963: #endif
                    964:         break;
                    965:     case 2:
                    966: #ifdef TARGET_WORDS_BIGENDIAN
                    967:         /* lduw [arg0], data_reg */
                    968:         tcg_out_ldst(s, data_reg, arg0, 0, LDUW);
                    969: #else
                    970:         /* lduwa [arg0] ASI_PRIMARY_LITTLE, data_reg */
                    971:         tcg_out_ldst_asi(s, data_reg, arg0, 0, LDUWA, ASI_PRIMARY_LITTLE);
                    972: #endif
                    973:         break;
                    974:     case 2 | 4:
                    975: #ifdef TARGET_WORDS_BIGENDIAN
                    976:         /* ldsw [arg0], data_reg */
                    977:         tcg_out_ldst(s, data_reg, arg0, 0, LDSW);
                    978: #else
                    979:         /* ldswa [arg0] ASI_PRIMARY_LITTLE, data_reg */
                    980:         tcg_out_ldst_asi(s, data_reg, arg0, 0, LDSWA, ASI_PRIMARY_LITTLE);
                    981: #endif
                    982:         break;
                    983:     case 3:
                    984: #ifdef TARGET_WORDS_BIGENDIAN
                    985:         /* ldx [arg0], data_reg */
                    986:         tcg_out_ldst(s, data_reg, arg0, 0, LDX);
                    987: #else
                    988:         /* ldxa [arg0] ASI_PRIMARY_LITTLE, data_reg */
                    989:         tcg_out_ldst_asi(s, data_reg, arg0, 0, LDXA, ASI_PRIMARY_LITTLE);
                    990: #endif
                    991:         break;
                    992:     default:
                    993:         tcg_abort();
                    994:     }
                    995: 
                    996: #if defined(CONFIG_SOFTMMU)
                    997:     /* label2: */
                    998:     *label2_ptr = (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2) |
                    999:                    INSN_OFF22((unsigned long)s->code_ptr -
                   1000:                               (unsigned long)label2_ptr));
                   1001: #endif
                   1002: }
                   1003: 
                   1004: static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
                   1005:                             int opc)
                   1006: {
                   1007:     int addr_reg, data_reg, arg0, arg1, arg2, mem_index, s_bits;
                   1008: #if defined(CONFIG_SOFTMMU)
                   1009:     uint32_t *label1_ptr, *label2_ptr;
                   1010: #endif
                   1011: 
                   1012:     data_reg = *args++;
                   1013:     addr_reg = *args++;
                   1014:     mem_index = *args;
                   1015: 
                   1016:     s_bits = opc;
                   1017: 
                   1018:     arg0 = TCG_REG_O0;
                   1019:     arg1 = TCG_REG_O1;
                   1020:     arg2 = TCG_REG_O2;
                   1021: 
                   1022: #if defined(CONFIG_SOFTMMU)
                   1023:     /* srl addr_reg, x, arg1 */
                   1024:     tcg_out_arithi(s, arg1, addr_reg, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS,
                   1025:                    SHIFT_SRL);
                   1026: 
                   1027:     /* and addr_reg, x, arg0 */
                   1028:     tcg_out_arithi(s, arg0, addr_reg, TARGET_PAGE_MASK | ((1 << s_bits) - 1),
                   1029:                    ARITH_AND);
                   1030: 
                   1031:     /* and arg1, x, arg1 */
                   1032:     tcg_out_andi(s, arg1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
                   1033: 
                   1034:     /* add arg1, x, arg1 */
1.1.1.6 ! root     1035:     tcg_out_addi(s, arg1, offsetof(CPUArchState,
1.1       root     1036:                                    tlb_table[mem_index][0].addr_write));
                   1037: 
                   1038:     /* add env, arg1, arg1 */
                   1039:     tcg_out_arith(s, arg1, TCG_AREG0, arg1, ARITH_ADD);
                   1040: 
                   1041:     /* ld [arg1], arg2 */
                   1042:     tcg_out32(s, TARGET_LD_OP | INSN_RD(arg2) | INSN_RS1(arg1) |
                   1043:               INSN_RS2(TCG_REG_G0));
                   1044: 
                   1045:     /* subcc arg0, arg2, %g0 */
                   1046:     tcg_out_arith(s, TCG_REG_G0, arg0, arg2, ARITH_SUBCC);
                   1047: 
                   1048:     /* will become:
1.1.1.2   root     1049:        be label1
                   1050:         or
                   1051:        be,pt %xcc label1 */
1.1       root     1052:     label1_ptr = (uint32_t *)s->code_ptr;
                   1053:     tcg_out32(s, 0);
                   1054: 
                   1055:     /* mov (delay slot) */
1.1.1.3   root     1056:     tcg_out_mov(s, TCG_TYPE_PTR, arg0, addr_reg);
1.1       root     1057: 
                   1058:     /* mov */
1.1.1.3   root     1059:     tcg_out_mov(s, TCG_TYPE_REG, arg1, data_reg);
1.1       root     1060: 
                   1061:     /* mov */
                   1062:     tcg_out_movi(s, TCG_TYPE_I32, arg2, mem_index);
                   1063: 
1.1.1.6 ! root     1064: #ifdef CONFIG_TCG_PASS_AREG0
        !          1065:     /* XXX/FIXME: suboptimal */
        !          1066:     tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
        !          1067:                 tcg_target_call_iarg_regs[2]);
        !          1068:     tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
        !          1069:                 tcg_target_call_iarg_regs[1]);
        !          1070:     tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
        !          1071:                 tcg_target_call_iarg_regs[0]);
        !          1072:     tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
        !          1073:                 TCG_AREG0);
        !          1074: #endif
1.1       root     1075:     /* XXX: move that code at the end of the TB */
                   1076:     /* qemu_st_helper[s_bits](arg0, arg1, arg2) */
                   1077:     tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_st_helpers[s_bits]
                   1078:                            - (tcg_target_ulong)s->code_ptr) >> 2)
                   1079:                          & 0x3fffffff));
                   1080:     /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
                   1081:        global registers */
                   1082:     // delay slot
                   1083:     tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
1.1.1.2   root     1084:                  TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
                   1085:                  sizeof(long), HOST_ST_OP);
1.1       root     1086:     tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
1.1.1.2   root     1087:                  TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
                   1088:                  sizeof(long), HOST_LD_OP);
1.1       root     1089: 
                   1090:     /* will become:
                   1091:        ba label2 */
                   1092:     label2_ptr = (uint32_t *)s->code_ptr;
                   1093:     tcg_out32(s, 0);
                   1094: 
                   1095:     /* nop (delay slot) */
                   1096:     tcg_out_nop(s);
                   1097: 
1.1.1.2   root     1098: #if TARGET_LONG_BITS == 32
                   1099:     /* be label1 */
1.1       root     1100:     *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x2) |
                   1101:                    INSN_OFF22((unsigned long)s->code_ptr -
                   1102:                               (unsigned long)label1_ptr));
1.1.1.2   root     1103: #else
                   1104:     /* be,pt %xcc label1 */
                   1105:     *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x1) |
                   1106:                    (0x5 << 19) | INSN_OFF19((unsigned long)s->code_ptr -
                   1107:                               (unsigned long)label1_ptr));
                   1108: #endif
1.1       root     1109: 
                   1110:     /* ld [arg1 + x], arg1 */
                   1111:     tcg_out_ldst(s, arg1, arg1, offsetof(CPUTLBEntry, addend) -
                   1112:                  offsetof(CPUTLBEntry, addr_write), TARGET_ADDEND_LD_OP);
                   1113: 
                   1114: #if TARGET_LONG_BITS == 32
                   1115:     /* and addr_reg, x, arg0 */
                   1116:     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_I5, 0xffffffff);
                   1117:     tcg_out_arith(s, arg0, addr_reg, TCG_REG_I5, ARITH_AND);
                   1118:     /* add arg0, arg1, arg0 */
                   1119:     tcg_out_arith(s, arg0, arg0, arg1, ARITH_ADD);
                   1120: #else
                   1121:     /* add addr_reg, arg1, arg0 */
                   1122:     tcg_out_arith(s, arg0, addr_reg, arg1, ARITH_ADD);
                   1123: #endif
                   1124: 
                   1125: #else
                   1126:     arg0 = addr_reg;
                   1127: #endif
                   1128: 
                   1129:     switch(opc) {
                   1130:     case 0:
                   1131:         /* stb data_reg, [arg0] */
                   1132:         tcg_out_ldst(s, data_reg, arg0, 0, STB);
                   1133:         break;
                   1134:     case 1:
                   1135: #ifdef TARGET_WORDS_BIGENDIAN
                   1136:         /* sth data_reg, [arg0] */
                   1137:         tcg_out_ldst(s, data_reg, arg0, 0, STH);
                   1138: #else
                   1139:         /* stha data_reg, [arg0] ASI_PRIMARY_LITTLE */
                   1140:         tcg_out_ldst_asi(s, data_reg, arg0, 0, STHA, ASI_PRIMARY_LITTLE);
                   1141: #endif
                   1142:         break;
                   1143:     case 2:
                   1144: #ifdef TARGET_WORDS_BIGENDIAN
                   1145:         /* stw data_reg, [arg0] */
                   1146:         tcg_out_ldst(s, data_reg, arg0, 0, STW);
                   1147: #else
                   1148:         /* stwa data_reg, [arg0] ASI_PRIMARY_LITTLE */
                   1149:         tcg_out_ldst_asi(s, data_reg, arg0, 0, STWA, ASI_PRIMARY_LITTLE);
                   1150: #endif
                   1151:         break;
                   1152:     case 3:
                   1153: #ifdef TARGET_WORDS_BIGENDIAN
                   1154:         /* stx data_reg, [arg0] */
                   1155:         tcg_out_ldst(s, data_reg, arg0, 0, STX);
                   1156: #else
                   1157:         /* stxa data_reg, [arg0] ASI_PRIMARY_LITTLE */
                   1158:         tcg_out_ldst_asi(s, data_reg, arg0, 0, STXA, ASI_PRIMARY_LITTLE);
                   1159: #endif
                   1160:         break;
                   1161:     default:
                   1162:         tcg_abort();
                   1163:     }
                   1164: 
                   1165: #if defined(CONFIG_SOFTMMU)
                   1166:     /* label2: */
                   1167:     *label2_ptr = (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2) |
                   1168:                    INSN_OFF22((unsigned long)s->code_ptr -
                   1169:                               (unsigned long)label2_ptr));
                   1170: #endif
                   1171: }
                   1172: 
1.1.1.3   root     1173: static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
1.1       root     1174:                               const int *const_args)
                   1175: {
                   1176:     int c;
                   1177: 
                   1178:     switch (opc) {
                   1179:     case INDEX_op_exit_tb:
                   1180:         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I0, args[0]);
                   1181:         tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I7) |
                   1182:                   INSN_IMM13(8));
                   1183:         tcg_out32(s, RESTORE | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_G0) |
                   1184:                       INSN_RS2(TCG_REG_G0));
                   1185:         break;
                   1186:     case INDEX_op_goto_tb:
                   1187:         if (s->tb_jmp_offset) {
                   1188:             /* direct jump method */
                   1189:             tcg_out_sethi(s, TCG_REG_I5, args[0] & 0xffffe000);
                   1190:             tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I5) |
                   1191:                       INSN_IMM13((args[0] & 0x1fff)));
                   1192:             s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
                   1193:         } else {
                   1194:             /* indirect jump method */
                   1195:             tcg_out_ld_ptr(s, TCG_REG_I5, (tcg_target_long)(s->tb_next + args[0]));
                   1196:             tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I5) |
                   1197:                       INSN_RS2(TCG_REG_G0));
                   1198:         }
                   1199:         tcg_out_nop(s);
                   1200:         s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
                   1201:         break;
                   1202:     case INDEX_op_call:
                   1203:         if (const_args[0])
                   1204:             tcg_out32(s, CALL | ((((tcg_target_ulong)args[0]
                   1205:                                    - (tcg_target_ulong)s->code_ptr) >> 2)
                   1206:                                  & 0x3fffffff));
                   1207:         else {
                   1208:             tcg_out_ld_ptr(s, TCG_REG_I5,
                   1209:                            (tcg_target_long)(s->tb_next + args[0]));
                   1210:             tcg_out32(s, JMPL | INSN_RD(TCG_REG_O7) | INSN_RS1(TCG_REG_I5) |
                   1211:                       INSN_RS2(TCG_REG_G0));
                   1212:         }
                   1213:         /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
                   1214:            global registers */
                   1215:         // delay slot
                   1216:         tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
1.1.1.2   root     1217:                      TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
                   1218:                      sizeof(long), HOST_ST_OP);
1.1       root     1219:         tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
1.1.1.2   root     1220:                      TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
                   1221:                      sizeof(long), HOST_LD_OP);
1.1       root     1222:         break;
                   1223:     case INDEX_op_jmp:
                   1224:     case INDEX_op_br:
1.1.1.2   root     1225:         tcg_out_branch_i32(s, COND_A, args[0]);
1.1       root     1226:         tcg_out_nop(s);
                   1227:         break;
                   1228:     case INDEX_op_movi_i32:
                   1229:         tcg_out_movi(s, TCG_TYPE_I32, args[0], (uint32_t)args[1]);
                   1230:         break;
                   1231: 
1.1.1.3   root     1232: #if TCG_TARGET_REG_BITS == 64
1.1       root     1233: #define OP_32_64(x)                             \
1.1.1.3   root     1234:         glue(glue(case INDEX_op_, x), _i32):    \
                   1235:         glue(glue(case INDEX_op_, x), _i64)
1.1       root     1236: #else
                   1237: #define OP_32_64(x)                             \
1.1.1.3   root     1238:         glue(glue(case INDEX_op_, x), _i32)
1.1       root     1239: #endif
1.1.1.3   root     1240:     OP_32_64(ld8u):
1.1       root     1241:         tcg_out_ldst(s, args[0], args[1], args[2], LDUB);
                   1242:         break;
1.1.1.3   root     1243:     OP_32_64(ld8s):
1.1       root     1244:         tcg_out_ldst(s, args[0], args[1], args[2], LDSB);
                   1245:         break;
1.1.1.3   root     1246:     OP_32_64(ld16u):
1.1       root     1247:         tcg_out_ldst(s, args[0], args[1], args[2], LDUH);
                   1248:         break;
1.1.1.3   root     1249:     OP_32_64(ld16s):
1.1       root     1250:         tcg_out_ldst(s, args[0], args[1], args[2], LDSH);
                   1251:         break;
                   1252:     case INDEX_op_ld_i32:
1.1.1.3   root     1253: #if TCG_TARGET_REG_BITS == 64
1.1       root     1254:     case INDEX_op_ld32u_i64:
                   1255: #endif
                   1256:         tcg_out_ldst(s, args[0], args[1], args[2], LDUW);
                   1257:         break;
1.1.1.3   root     1258:     OP_32_64(st8):
1.1       root     1259:         tcg_out_ldst(s, args[0], args[1], args[2], STB);
                   1260:         break;
1.1.1.3   root     1261:     OP_32_64(st16):
1.1       root     1262:         tcg_out_ldst(s, args[0], args[1], args[2], STH);
                   1263:         break;
                   1264:     case INDEX_op_st_i32:
1.1.1.3   root     1265: #if TCG_TARGET_REG_BITS == 64
1.1       root     1266:     case INDEX_op_st32_i64:
                   1267: #endif
                   1268:         tcg_out_ldst(s, args[0], args[1], args[2], STW);
                   1269:         break;
1.1.1.3   root     1270:     OP_32_64(add):
1.1       root     1271:         c = ARITH_ADD;
1.1.1.3   root     1272:         goto gen_arith;
                   1273:     OP_32_64(sub):
1.1       root     1274:         c = ARITH_SUB;
1.1.1.3   root     1275:         goto gen_arith;
                   1276:     OP_32_64(and):
1.1       root     1277:         c = ARITH_AND;
1.1.1.3   root     1278:         goto gen_arith;
                   1279:     OP_32_64(andc):
                   1280:         c = ARITH_ANDN;
                   1281:         goto gen_arith;
                   1282:     OP_32_64(or):
1.1       root     1283:         c = ARITH_OR;
1.1.1.3   root     1284:         goto gen_arith;
                   1285:     OP_32_64(orc):
                   1286:         c = ARITH_ORN;
                   1287:         goto gen_arith;
                   1288:     OP_32_64(xor):
1.1       root     1289:         c = ARITH_XOR;
1.1.1.3   root     1290:         goto gen_arith;
1.1       root     1291:     case INDEX_op_shl_i32:
                   1292:         c = SHIFT_SLL;
1.1.1.3   root     1293:         goto gen_arith;
1.1       root     1294:     case INDEX_op_shr_i32:
                   1295:         c = SHIFT_SRL;
1.1.1.3   root     1296:         goto gen_arith;
1.1       root     1297:     case INDEX_op_sar_i32:
                   1298:         c = SHIFT_SRA;
1.1.1.3   root     1299:         goto gen_arith;
1.1       root     1300:     case INDEX_op_mul_i32:
                   1301:         c = ARITH_UMUL;
1.1.1.3   root     1302:         goto gen_arith;
                   1303: 
                   1304:     OP_32_64(neg):
                   1305:        c = ARITH_SUB;
                   1306:        goto gen_arith1;
                   1307:     OP_32_64(not):
                   1308:        c = ARITH_ORN;
                   1309:        goto gen_arith1;
                   1310: 
                   1311:     case INDEX_op_div_i32:
                   1312:         tcg_out_div32(s, args[0], args[1], args[2], const_args[2], 0);
                   1313:         break;
                   1314:     case INDEX_op_divu_i32:
                   1315:         tcg_out_div32(s, args[0], args[1], args[2], const_args[2], 1);
                   1316:         break;
                   1317: 
                   1318:     case INDEX_op_rem_i32:
                   1319:     case INDEX_op_remu_i32:
                   1320:         tcg_out_div32(s, TCG_REG_I5, args[1], args[2], const_args[2],
                   1321:                       opc == INDEX_op_remu_i32);
                   1322:         tcg_out_arithc(s, TCG_REG_I5, TCG_REG_I5, args[2], const_args[2],
                   1323:                        ARITH_UMUL);
                   1324:         tcg_out_arith(s, args[0], args[1], TCG_REG_I5, ARITH_SUB);
                   1325:         break;
1.1       root     1326: 
                   1327:     case INDEX_op_brcond_i32:
1.1.1.2   root     1328:         tcg_out_brcond_i32(s, args[2], args[0], args[1], const_args[1],
                   1329:                            args[3]);
1.1       root     1330:         break;
1.1.1.3   root     1331:     case INDEX_op_setcond_i32:
                   1332:         tcg_out_setcond_i32(s, args[3], args[0], args[1],
                   1333:                             args[2], const_args[2]);
                   1334:         break;
                   1335: 
                   1336: #if TCG_TARGET_REG_BITS == 32
                   1337:     case INDEX_op_brcond2_i32:
                   1338:         tcg_out_brcond2_i32(s, args[4], args[0], args[1],
                   1339:                             args[2], const_args[2],
                   1340:                             args[3], const_args[3], args[5]);
                   1341:         break;
                   1342:     case INDEX_op_setcond2_i32:
                   1343:         tcg_out_setcond2_i32(s, args[5], args[0], args[1], args[2],
                   1344:                              args[3], const_args[3],
                   1345:                              args[4], const_args[4]);
                   1346:         break;
                   1347:     case INDEX_op_add2_i32:
                   1348:         tcg_out_arithc(s, args[0], args[2], args[4], const_args[4],
                   1349:                        ARITH_ADDCC);
                   1350:         tcg_out_arithc(s, args[1], args[3], args[5], const_args[5],
                   1351:                        ARITH_ADDX);
                   1352:         break;
                   1353:     case INDEX_op_sub2_i32:
                   1354:         tcg_out_arithc(s, args[0], args[2], args[4], const_args[4],
                   1355:                        ARITH_SUBCC);
                   1356:         tcg_out_arithc(s, args[1], args[3], args[5], const_args[5],
                   1357:                        ARITH_SUBX);
                   1358:         break;
                   1359:     case INDEX_op_mulu2_i32:
                   1360:         tcg_out_arithc(s, args[0], args[2], args[3], const_args[3],
                   1361:                        ARITH_UMUL);
                   1362:         tcg_out_rdy(s, args[1]);
                   1363:         break;
                   1364: #endif
1.1       root     1365: 
                   1366:     case INDEX_op_qemu_ld8u:
                   1367:         tcg_out_qemu_ld(s, args, 0);
                   1368:         break;
                   1369:     case INDEX_op_qemu_ld8s:
                   1370:         tcg_out_qemu_ld(s, args, 0 | 4);
                   1371:         break;
                   1372:     case INDEX_op_qemu_ld16u:
                   1373:         tcg_out_qemu_ld(s, args, 1);
                   1374:         break;
                   1375:     case INDEX_op_qemu_ld16s:
                   1376:         tcg_out_qemu_ld(s, args, 1 | 4);
                   1377:         break;
1.1.1.3   root     1378:     case INDEX_op_qemu_ld32:
                   1379: #if TCG_TARGET_REG_BITS == 64
1.1       root     1380:     case INDEX_op_qemu_ld32u:
1.1.1.3   root     1381: #endif
1.1       root     1382:         tcg_out_qemu_ld(s, args, 2);
                   1383:         break;
1.1.1.3   root     1384: #if TCG_TARGET_REG_BITS == 64
1.1       root     1385:     case INDEX_op_qemu_ld32s:
                   1386:         tcg_out_qemu_ld(s, args, 2 | 4);
                   1387:         break;
1.1.1.3   root     1388: #endif
1.1       root     1389:     case INDEX_op_qemu_st8:
                   1390:         tcg_out_qemu_st(s, args, 0);
                   1391:         break;
                   1392:     case INDEX_op_qemu_st16:
                   1393:         tcg_out_qemu_st(s, args, 1);
                   1394:         break;
                   1395:     case INDEX_op_qemu_st32:
                   1396:         tcg_out_qemu_st(s, args, 2);
                   1397:         break;
                   1398: 
1.1.1.3   root     1399: #if TCG_TARGET_REG_BITS == 64
1.1       root     1400:     case INDEX_op_movi_i64:
                   1401:         tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
                   1402:         break;
                   1403:     case INDEX_op_ld32s_i64:
                   1404:         tcg_out_ldst(s, args[0], args[1], args[2], LDSW);
                   1405:         break;
                   1406:     case INDEX_op_ld_i64:
                   1407:         tcg_out_ldst(s, args[0], args[1], args[2], LDX);
                   1408:         break;
                   1409:     case INDEX_op_st_i64:
                   1410:         tcg_out_ldst(s, args[0], args[1], args[2], STX);
                   1411:         break;
                   1412:     case INDEX_op_shl_i64:
                   1413:         c = SHIFT_SLLX;
1.1.1.3   root     1414:         goto gen_arith;
1.1       root     1415:     case INDEX_op_shr_i64:
                   1416:         c = SHIFT_SRLX;
1.1.1.3   root     1417:         goto gen_arith;
1.1       root     1418:     case INDEX_op_sar_i64:
                   1419:         c = SHIFT_SRAX;
1.1.1.3   root     1420:         goto gen_arith;
1.1       root     1421:     case INDEX_op_mul_i64:
                   1422:         c = ARITH_MULX;
1.1.1.3   root     1423:         goto gen_arith;
                   1424:     case INDEX_op_div_i64:
1.1       root     1425:         c = ARITH_SDIVX;
1.1.1.3   root     1426:         goto gen_arith;
                   1427:     case INDEX_op_divu_i64:
1.1       root     1428:         c = ARITH_UDIVX;
1.1.1.3   root     1429:         goto gen_arith;
                   1430:     case INDEX_op_rem_i64:
                   1431:     case INDEX_op_remu_i64:
                   1432:         tcg_out_arithc(s, TCG_REG_I5, args[1], args[2], const_args[2],
                   1433:                        opc == INDEX_op_rem_i64 ? ARITH_SDIVX : ARITH_UDIVX);
                   1434:         tcg_out_arithc(s, TCG_REG_I5, TCG_REG_I5, args[2], const_args[2],
                   1435:                        ARITH_MULX);
                   1436:         tcg_out_arith(s, args[0], args[1], TCG_REG_I5, ARITH_SUB);
                   1437:         break;
                   1438:     case INDEX_op_ext32s_i64:
                   1439:         if (const_args[1]) {
                   1440:             tcg_out_movi(s, TCG_TYPE_I64, args[0], (int32_t)args[1]);
                   1441:         } else {
                   1442:             tcg_out_arithi(s, args[0], args[1], 0, SHIFT_SRA);
                   1443:         }
                   1444:         break;
                   1445:     case INDEX_op_ext32u_i64:
                   1446:         if (const_args[1]) {
                   1447:             tcg_out_movi_imm32(s, args[0], args[1]);
                   1448:         } else {
                   1449:             tcg_out_arithi(s, args[0], args[1], 0, SHIFT_SRL);
                   1450:         }
                   1451:         break;
1.1       root     1452: 
                   1453:     case INDEX_op_brcond_i64:
1.1.1.2   root     1454:         tcg_out_brcond_i64(s, args[2], args[0], args[1], const_args[1],
                   1455:                            args[3]);
1.1       root     1456:         break;
1.1.1.3   root     1457:     case INDEX_op_setcond_i64:
                   1458:         tcg_out_setcond_i64(s, args[3], args[0], args[1],
                   1459:                             args[2], const_args[2]);
                   1460:         break;
                   1461: 
1.1       root     1462:     case INDEX_op_qemu_ld64:
                   1463:         tcg_out_qemu_ld(s, args, 3);
                   1464:         break;
                   1465:     case INDEX_op_qemu_st64:
                   1466:         tcg_out_qemu_st(s, args, 3);
                   1467:         break;
                   1468: 
                   1469: #endif
1.1.1.3   root     1470:     gen_arith:
                   1471:         tcg_out_arithc(s, args[0], args[1], args[2], const_args[2], c);
1.1       root     1472:         break;
                   1473: 
1.1.1.3   root     1474:     gen_arith1:
                   1475:        tcg_out_arithc(s, args[0], TCG_REG_G0, args[1], const_args[1], c);
                   1476:        break;
                   1477: 
1.1       root     1478:     default:
                   1479:         fprintf(stderr, "unknown opcode 0x%x\n", opc);
                   1480:         tcg_abort();
                   1481:     }
                   1482: }
                   1483: 
                   1484: static const TCGTargetOpDef sparc_op_defs[] = {
                   1485:     { INDEX_op_exit_tb, { } },
                   1486:     { INDEX_op_goto_tb, { } },
                   1487:     { INDEX_op_call, { "ri" } },
                   1488:     { INDEX_op_jmp, { "ri" } },
                   1489:     { INDEX_op_br, { } },
                   1490: 
                   1491:     { INDEX_op_mov_i32, { "r", "r" } },
                   1492:     { INDEX_op_movi_i32, { "r" } },
                   1493:     { INDEX_op_ld8u_i32, { "r", "r" } },
                   1494:     { INDEX_op_ld8s_i32, { "r", "r" } },
                   1495:     { INDEX_op_ld16u_i32, { "r", "r" } },
                   1496:     { INDEX_op_ld16s_i32, { "r", "r" } },
                   1497:     { INDEX_op_ld_i32, { "r", "r" } },
                   1498:     { INDEX_op_st8_i32, { "r", "r" } },
                   1499:     { INDEX_op_st16_i32, { "r", "r" } },
                   1500:     { INDEX_op_st_i32, { "r", "r" } },
                   1501: 
                   1502:     { INDEX_op_add_i32, { "r", "r", "rJ" } },
                   1503:     { INDEX_op_mul_i32, { "r", "r", "rJ" } },
1.1.1.3   root     1504:     { INDEX_op_div_i32, { "r", "r", "rJ" } },
                   1505:     { INDEX_op_divu_i32, { "r", "r", "rJ" } },
                   1506:     { INDEX_op_rem_i32, { "r", "r", "rJ" } },
                   1507:     { INDEX_op_remu_i32, { "r", "r", "rJ" } },
1.1       root     1508:     { INDEX_op_sub_i32, { "r", "r", "rJ" } },
                   1509:     { INDEX_op_and_i32, { "r", "r", "rJ" } },
1.1.1.3   root     1510:     { INDEX_op_andc_i32, { "r", "r", "rJ" } },
1.1       root     1511:     { INDEX_op_or_i32, { "r", "r", "rJ" } },
1.1.1.3   root     1512:     { INDEX_op_orc_i32, { "r", "r", "rJ" } },
1.1       root     1513:     { INDEX_op_xor_i32, { "r", "r", "rJ" } },
                   1514: 
                   1515:     { INDEX_op_shl_i32, { "r", "r", "rJ" } },
                   1516:     { INDEX_op_shr_i32, { "r", "r", "rJ" } },
                   1517:     { INDEX_op_sar_i32, { "r", "r", "rJ" } },
                   1518: 
1.1.1.3   root     1519:     { INDEX_op_neg_i32, { "r", "rJ" } },
                   1520:     { INDEX_op_not_i32, { "r", "rJ" } },
                   1521: 
                   1522:     { INDEX_op_brcond_i32, { "r", "rJ" } },
                   1523:     { INDEX_op_setcond_i32, { "r", "r", "rJ" } },
                   1524: 
                   1525: #if TCG_TARGET_REG_BITS == 32
                   1526:     { INDEX_op_brcond2_i32, { "r", "r", "rJ", "rJ" } },
                   1527:     { INDEX_op_setcond2_i32, { "r", "r", "r", "rJ", "rJ" } },
                   1528:     { INDEX_op_add2_i32, { "r", "r", "r", "r", "rJ", "rJ" } },
                   1529:     { INDEX_op_sub2_i32, { "r", "r", "r", "r", "rJ", "rJ" } },
                   1530:     { INDEX_op_mulu2_i32, { "r", "r", "r", "rJ" } },
                   1531: #endif
1.1       root     1532: 
                   1533:     { INDEX_op_qemu_ld8u, { "r", "L" } },
                   1534:     { INDEX_op_qemu_ld8s, { "r", "L" } },
                   1535:     { INDEX_op_qemu_ld16u, { "r", "L" } },
                   1536:     { INDEX_op_qemu_ld16s, { "r", "L" } },
1.1.1.3   root     1537:     { INDEX_op_qemu_ld32, { "r", "L" } },
                   1538: #if TCG_TARGET_REG_BITS == 64
1.1       root     1539:     { INDEX_op_qemu_ld32u, { "r", "L" } },
                   1540:     { INDEX_op_qemu_ld32s, { "r", "L" } },
1.1.1.3   root     1541: #endif
1.1       root     1542: 
                   1543:     { INDEX_op_qemu_st8, { "L", "L" } },
                   1544:     { INDEX_op_qemu_st16, { "L", "L" } },
                   1545:     { INDEX_op_qemu_st32, { "L", "L" } },
                   1546: 
1.1.1.3   root     1547: #if TCG_TARGET_REG_BITS == 64
1.1       root     1548:     { INDEX_op_mov_i64, { "r", "r" } },
                   1549:     { INDEX_op_movi_i64, { "r" } },
                   1550:     { INDEX_op_ld8u_i64, { "r", "r" } },
                   1551:     { INDEX_op_ld8s_i64, { "r", "r" } },
                   1552:     { INDEX_op_ld16u_i64, { "r", "r" } },
                   1553:     { INDEX_op_ld16s_i64, { "r", "r" } },
                   1554:     { INDEX_op_ld32u_i64, { "r", "r" } },
                   1555:     { INDEX_op_ld32s_i64, { "r", "r" } },
                   1556:     { INDEX_op_ld_i64, { "r", "r" } },
                   1557:     { INDEX_op_st8_i64, { "r", "r" } },
                   1558:     { INDEX_op_st16_i64, { "r", "r" } },
                   1559:     { INDEX_op_st32_i64, { "r", "r" } },
                   1560:     { INDEX_op_st_i64, { "r", "r" } },
                   1561:     { INDEX_op_qemu_ld64, { "L", "L" } },
                   1562:     { INDEX_op_qemu_st64, { "L", "L" } },
                   1563: 
                   1564:     { INDEX_op_add_i64, { "r", "r", "rJ" } },
                   1565:     { INDEX_op_mul_i64, { "r", "r", "rJ" } },
1.1.1.3   root     1566:     { INDEX_op_div_i64, { "r", "r", "rJ" } },
                   1567:     { INDEX_op_divu_i64, { "r", "r", "rJ" } },
                   1568:     { INDEX_op_rem_i64, { "r", "r", "rJ" } },
                   1569:     { INDEX_op_remu_i64, { "r", "r", "rJ" } },
1.1       root     1570:     { INDEX_op_sub_i64, { "r", "r", "rJ" } },
                   1571:     { INDEX_op_and_i64, { "r", "r", "rJ" } },
1.1.1.3   root     1572:     { INDEX_op_andc_i64, { "r", "r", "rJ" } },
1.1       root     1573:     { INDEX_op_or_i64, { "r", "r", "rJ" } },
1.1.1.3   root     1574:     { INDEX_op_orc_i64, { "r", "r", "rJ" } },
1.1       root     1575:     { INDEX_op_xor_i64, { "r", "r", "rJ" } },
                   1576: 
                   1577:     { INDEX_op_shl_i64, { "r", "r", "rJ" } },
                   1578:     { INDEX_op_shr_i64, { "r", "r", "rJ" } },
                   1579:     { INDEX_op_sar_i64, { "r", "r", "rJ" } },
                   1580: 
1.1.1.3   root     1581:     { INDEX_op_neg_i64, { "r", "rJ" } },
                   1582:     { INDEX_op_not_i64, { "r", "rJ" } },
                   1583: 
                   1584:     { INDEX_op_ext32s_i64, { "r", "ri" } },
                   1585:     { INDEX_op_ext32u_i64, { "r", "ri" } },
                   1586: 
                   1587:     { INDEX_op_brcond_i64, { "r", "rJ" } },
                   1588:     { INDEX_op_setcond_i64, { "r", "r", "rJ" } },
1.1       root     1589: #endif
                   1590:     { -1 },
                   1591: };
                   1592: 
1.1.1.3   root     1593: static void tcg_target_init(TCGContext *s)
1.1       root     1594: {
                   1595:     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
1.1.1.3   root     1596: #if TCG_TARGET_REG_BITS == 64
1.1       root     1597:     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff);
                   1598: #endif
                   1599:     tcg_regset_set32(tcg_target_call_clobber_regs, 0,
                   1600:                      (1 << TCG_REG_G1) |
                   1601:                      (1 << TCG_REG_G2) |
                   1602:                      (1 << TCG_REG_G3) |
                   1603:                      (1 << TCG_REG_G4) |
                   1604:                      (1 << TCG_REG_G5) |
                   1605:                      (1 << TCG_REG_G6) |
                   1606:                      (1 << TCG_REG_G7) |
                   1607:                      (1 << TCG_REG_O0) |
                   1608:                      (1 << TCG_REG_O1) |
                   1609:                      (1 << TCG_REG_O2) |
                   1610:                      (1 << TCG_REG_O3) |
                   1611:                      (1 << TCG_REG_O4) |
                   1612:                      (1 << TCG_REG_O5) |
                   1613:                      (1 << TCG_REG_O7));
                   1614: 
                   1615:     tcg_regset_clear(s->reserved_regs);
                   1616:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_G0);
1.1.1.3   root     1617: #if TCG_TARGET_REG_BITS == 64
1.1       root     1618:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_I4); // for internal use
                   1619: #endif
                   1620:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_I5); // for internal use
                   1621:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_I6);
                   1622:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_I7);
                   1623:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_O6);
                   1624:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_O7);
                   1625:     tcg_add_target_add_op_defs(sparc_op_defs);
                   1626: }
1.1.1.6 ! root     1627: 
        !          1628: #if TCG_TARGET_REG_BITS == 64
        !          1629: # define ELF_HOST_MACHINE  EM_SPARCV9
        !          1630: #elif defined(__sparc_v8plus__)
        !          1631: # define ELF_HOST_MACHINE  EM_SPARC32PLUS
        !          1632: # define ELF_HOST_FLAGS    EF_SPARC_32PLUS
        !          1633: #else
        !          1634: # define ELF_HOST_MACHINE  EM_SPARC
        !          1635: #endif
        !          1636: 
        !          1637: typedef struct {
        !          1638:     uint32_t len __attribute__((aligned((sizeof(void *)))));
        !          1639:     uint32_t id;
        !          1640:     uint8_t version;
        !          1641:     char augmentation[1];
        !          1642:     uint8_t code_align;
        !          1643:     uint8_t data_align;
        !          1644:     uint8_t return_column;
        !          1645: } DebugFrameCIE;
        !          1646: 
        !          1647: typedef struct {
        !          1648:     uint32_t len __attribute__((aligned((sizeof(void *)))));
        !          1649:     uint32_t cie_offset;
        !          1650:     tcg_target_long func_start __attribute__((packed));
        !          1651:     tcg_target_long func_len __attribute__((packed));
        !          1652:     uint8_t def_cfa[TCG_TARGET_REG_BITS == 64 ? 4 : 2];
        !          1653:     uint8_t win_save;
        !          1654:     uint8_t ret_save[3];
        !          1655: } DebugFrameFDE;
        !          1656: 
        !          1657: typedef struct {
        !          1658:     DebugFrameCIE cie;
        !          1659:     DebugFrameFDE fde;
        !          1660: } DebugFrame;
        !          1661: 
        !          1662: static DebugFrame debug_frame = {
        !          1663:     .cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
        !          1664:     .cie.id = -1,
        !          1665:     .cie.version = 1,
        !          1666:     .cie.code_align = 1,
        !          1667:     .cie.data_align = -sizeof(void *) & 0x7f,
        !          1668:     .cie.return_column = 15,            /* o7 */
        !          1669: 
        !          1670:     .fde.len = sizeof(DebugFrameFDE)-4, /* length after .len member */
        !          1671:     .fde.def_cfa = {
        !          1672: #if TCG_TARGET_REG_BITS == 64
        !          1673:         12, 30,                         /* DW_CFA_def_cfa i6, 2047 */
        !          1674:         (2047 & 0x7f) | 0x80, (2047 >> 7)
        !          1675: #else
        !          1676:         13, 30                          /* DW_CFA_def_cfa_register i6 */
        !          1677: #endif
        !          1678:     },
        !          1679:     .fde.win_save = 0x2d,               /* DW_CFA_GNU_window_save */
        !          1680:     .fde.ret_save = { 9, 15, 31 },      /* DW_CFA_register o7, i7 */
        !          1681: };
        !          1682: 
        !          1683: void tcg_register_jit(void *buf, size_t buf_size)
        !          1684: {
        !          1685:     debug_frame.fde.func_start = (tcg_target_long) buf;
        !          1686:     debug_frame.fde.func_len = buf_size;
        !          1687: 
        !          1688:     tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
        !          1689: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.