symbian-qemu-0.9.1-12/qemu-symbian-svp/tcg/sparc/tcg-target.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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 
       
    62 static const int tcg_target_reg_alloc_order[] = {
       
    63     TCG_REG_L0,
       
    64     TCG_REG_L1,
       
    65     TCG_REG_L2,
       
    66     TCG_REG_L3,
       
    67     TCG_REG_L4,
       
    68     TCG_REG_L5,
       
    69     TCG_REG_L6,
       
    70     TCG_REG_L7,
       
    71     TCG_REG_I0,
       
    72     TCG_REG_I1,
       
    73     TCG_REG_I2,
       
    74     TCG_REG_I3,
       
    75     TCG_REG_I4,
       
    76 };
       
    77 
       
    78 static const int tcg_target_call_iarg_regs[6] = {
       
    79     TCG_REG_O0,
       
    80     TCG_REG_O1,
       
    81     TCG_REG_O2,
       
    82     TCG_REG_O3,
       
    83     TCG_REG_O4,
       
    84     TCG_REG_O5,
       
    85 };
       
    86 
       
    87 static const int tcg_target_call_oarg_regs[2] = {
       
    88     TCG_REG_O0,
       
    89     TCG_REG_O1,
       
    90 };
       
    91 
       
    92 static inline int check_fit_tl(tcg_target_long val, unsigned int bits)
       
    93 {
       
    94     return (val << ((sizeof(tcg_target_long) * 8 - bits))
       
    95             >> (sizeof(tcg_target_long) * 8 - bits)) == val;
       
    96 }
       
    97 
       
    98 static inline int check_fit_i32(uint32_t val, unsigned int bits)
       
    99 {
       
   100     return ((val << (32 - bits)) >> (32 - bits)) == val;
       
   101 }
       
   102 
       
   103 static void patch_reloc(uint8_t *code_ptr, int type,
       
   104                         tcg_target_long value, tcg_target_long addend)
       
   105 {
       
   106     value += addend;
       
   107     switch (type) {
       
   108     case R_SPARC_32:
       
   109         if (value != (uint32_t)value)
       
   110             tcg_abort();
       
   111         *(uint32_t *)code_ptr = value;
       
   112         break;
       
   113     case R_SPARC_WDISP22:
       
   114         value -= (long)code_ptr;
       
   115         value >>= 2;
       
   116         if (!check_fit_tl(value, 22))
       
   117             tcg_abort();
       
   118         *(uint32_t *)code_ptr = ((*(uint32_t *)code_ptr) & ~0x3fffff) | value;
       
   119         break;
       
   120     default:
       
   121         tcg_abort();
       
   122     }
       
   123 }
       
   124 
       
   125 /* maximum number of register used for input function arguments */
       
   126 static inline int tcg_target_get_call_iarg_regs_count(int flags)
       
   127 {
       
   128     return 6;
       
   129 }
       
   130 
       
   131 /* parse target specific constraints */
       
   132 static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
       
   133 {
       
   134     const char *ct_str;
       
   135 
       
   136     ct_str = *pct_str;
       
   137     switch (ct_str[0]) {
       
   138     case 'r':
       
   139     case 'L': /* qemu_ld/st constraint */
       
   140         ct->ct |= TCG_CT_REG;
       
   141         tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
       
   142         // Helper args
       
   143         tcg_regset_reset_reg(ct->u.regs, TCG_REG_O0);
       
   144         tcg_regset_reset_reg(ct->u.regs, TCG_REG_O1);
       
   145         tcg_regset_reset_reg(ct->u.regs, TCG_REG_O2);
       
   146         break;
       
   147     case 'I':
       
   148         ct->ct |= TCG_CT_CONST_S11;
       
   149         break;
       
   150     case 'J':
       
   151         ct->ct |= TCG_CT_CONST_S13;
       
   152         break;
       
   153     default:
       
   154         return -1;
       
   155     }
       
   156     ct_str++;
       
   157     *pct_str = ct_str;
       
   158     return 0;
       
   159 }
       
   160 
       
   161 /* test if a constant matches the constraint */
       
   162 static inline int tcg_target_const_match(tcg_target_long val,
       
   163                                          const TCGArgConstraint *arg_ct)
       
   164 {
       
   165     int ct;
       
   166 
       
   167     ct = arg_ct->ct;
       
   168     if (ct & TCG_CT_CONST)
       
   169         return 1;
       
   170     else if ((ct & TCG_CT_CONST_S11) && check_fit_tl(val, 11))
       
   171         return 1;
       
   172     else if ((ct & TCG_CT_CONST_S13) && check_fit_tl(val, 13))
       
   173         return 1;
       
   174     else
       
   175         return 0;
       
   176 }
       
   177 
       
   178 #define INSN_OP(x)  ((x) << 30)
       
   179 #define INSN_OP2(x) ((x) << 22)
       
   180 #define INSN_OP3(x) ((x) << 19)
       
   181 #define INSN_OPF(x) ((x) << 5)
       
   182 #define INSN_RD(x)  ((x) << 25)
       
   183 #define INSN_RS1(x) ((x) << 14)
       
   184 #define INSN_RS2(x) (x)
       
   185 #define INSN_ASI(x) ((x) << 5)
       
   186 
       
   187 #define INSN_IMM13(x) ((1 << 13) | ((x) & 0x1fff))
       
   188 #define INSN_OFF22(x) (((x) >> 2) & 0x3fffff)
       
   189 
       
   190 #define INSN_COND(x, a) (((x) << 25) | ((a) << 29))
       
   191 #define COND_N     0x0
       
   192 #define COND_E     0x1
       
   193 #define COND_LE    0x2
       
   194 #define COND_L     0x3
       
   195 #define COND_LEU   0x4
       
   196 #define COND_CS    0x5
       
   197 #define COND_NEG   0x6
       
   198 #define COND_VS    0x7
       
   199 #define COND_A     0x8
       
   200 #define COND_NE    0x9
       
   201 #define COND_G     0xa
       
   202 #define COND_GE    0xb
       
   203 #define COND_GU    0xc
       
   204 #define COND_CC    0xd
       
   205 #define COND_POS   0xe
       
   206 #define COND_VC    0xf
       
   207 #define BA         (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2))
       
   208 
       
   209 #define ARITH_ADD  (INSN_OP(2) | INSN_OP3(0x00))
       
   210 #define ARITH_AND  (INSN_OP(2) | INSN_OP3(0x01))
       
   211 #define ARITH_OR   (INSN_OP(2) | INSN_OP3(0x02))
       
   212 #define ARITH_ORCC (INSN_OP(2) | INSN_OP3(0x12))
       
   213 #define ARITH_XOR  (INSN_OP(2) | INSN_OP3(0x03))
       
   214 #define ARITH_SUB  (INSN_OP(2) | INSN_OP3(0x04))
       
   215 #define ARITH_SUBCC (INSN_OP(2) | INSN_OP3(0x14))
       
   216 #define ARITH_ADDX (INSN_OP(2) | INSN_OP3(0x10))
       
   217 #define ARITH_SUBX (INSN_OP(2) | INSN_OP3(0x0c))
       
   218 #define ARITH_UMUL (INSN_OP(2) | INSN_OP3(0x0a))
       
   219 #define ARITH_UDIV (INSN_OP(2) | INSN_OP3(0x0e))
       
   220 #define ARITH_SDIV (INSN_OP(2) | INSN_OP3(0x0f))
       
   221 #define ARITH_MULX (INSN_OP(2) | INSN_OP3(0x09))
       
   222 #define ARITH_UDIVX (INSN_OP(2) | INSN_OP3(0x0d))
       
   223 #define ARITH_SDIVX (INSN_OP(2) | INSN_OP3(0x2d))
       
   224 
       
   225 #define SHIFT_SLL  (INSN_OP(2) | INSN_OP3(0x25))
       
   226 #define SHIFT_SRL  (INSN_OP(2) | INSN_OP3(0x26))
       
   227 #define SHIFT_SRA  (INSN_OP(2) | INSN_OP3(0x27))
       
   228 
       
   229 #define SHIFT_SLLX (INSN_OP(2) | INSN_OP3(0x25) | (1 << 12))
       
   230 #define SHIFT_SRLX (INSN_OP(2) | INSN_OP3(0x26) | (1 << 12))
       
   231 #define SHIFT_SRAX (INSN_OP(2) | INSN_OP3(0x27) | (1 << 12))
       
   232 
       
   233 #define WRY        (INSN_OP(2) | INSN_OP3(0x30))
       
   234 #define JMPL       (INSN_OP(2) | INSN_OP3(0x38))
       
   235 #define SAVE       (INSN_OP(2) | INSN_OP3(0x3c))
       
   236 #define RESTORE    (INSN_OP(2) | INSN_OP3(0x3d))
       
   237 #define SETHI      (INSN_OP(0) | INSN_OP2(0x4))
       
   238 #define CALL       INSN_OP(1)
       
   239 #define LDUB       (INSN_OP(3) | INSN_OP3(0x01))
       
   240 #define LDSB       (INSN_OP(3) | INSN_OP3(0x09))
       
   241 #define LDUH       (INSN_OP(3) | INSN_OP3(0x02))
       
   242 #define LDSH       (INSN_OP(3) | INSN_OP3(0x0a))
       
   243 #define LDUW       (INSN_OP(3) | INSN_OP3(0x00))
       
   244 #define LDSW       (INSN_OP(3) | INSN_OP3(0x08))
       
   245 #define LDX        (INSN_OP(3) | INSN_OP3(0x0b))
       
   246 #define STB        (INSN_OP(3) | INSN_OP3(0x05))
       
   247 #define STH        (INSN_OP(3) | INSN_OP3(0x06))
       
   248 #define STW        (INSN_OP(3) | INSN_OP3(0x04))
       
   249 #define STX        (INSN_OP(3) | INSN_OP3(0x0e))
       
   250 #define LDUBA      (INSN_OP(3) | INSN_OP3(0x11))
       
   251 #define LDSBA      (INSN_OP(3) | INSN_OP3(0x19))
       
   252 #define LDUHA      (INSN_OP(3) | INSN_OP3(0x12))
       
   253 #define LDSHA      (INSN_OP(3) | INSN_OP3(0x1a))
       
   254 #define LDUWA      (INSN_OP(3) | INSN_OP3(0x10))
       
   255 #define LDSWA      (INSN_OP(3) | INSN_OP3(0x18))
       
   256 #define LDXA       (INSN_OP(3) | INSN_OP3(0x1b))
       
   257 #define STBA       (INSN_OP(3) | INSN_OP3(0x15))
       
   258 #define STHA       (INSN_OP(3) | INSN_OP3(0x16))
       
   259 #define STWA       (INSN_OP(3) | INSN_OP3(0x14))
       
   260 #define STXA       (INSN_OP(3) | INSN_OP3(0x1e))
       
   261 
       
   262 #ifndef ASI_PRIMARY_LITTLE
       
   263 #define ASI_PRIMARY_LITTLE 0x88
       
   264 #endif
       
   265 
       
   266 static inline void tcg_out_arith(TCGContext *s, int rd, int rs1, int rs2,
       
   267                                  int op)
       
   268 {
       
   269     tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1) |
       
   270               INSN_RS2(rs2));
       
   271 }
       
   272 
       
   273 static inline void tcg_out_arithi(TCGContext *s, int rd, int rs1,
       
   274                                   uint32_t offset, int op)
       
   275 {
       
   276     tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1) |
       
   277               INSN_IMM13(offset));
       
   278 }
       
   279 
       
   280 static inline void tcg_out_mov(TCGContext *s, int ret, int arg)
       
   281 {
       
   282     tcg_out_arith(s, ret, arg, TCG_REG_G0, ARITH_OR);
       
   283 }
       
   284 
       
   285 static inline void tcg_out_sethi(TCGContext *s, int ret, uint32_t arg)
       
   286 {
       
   287     tcg_out32(s, SETHI | INSN_RD(ret) | ((arg & 0xfffffc00) >> 10));
       
   288 }
       
   289 
       
   290 static inline void tcg_out_movi_imm13(TCGContext *s, int ret, uint32_t arg)
       
   291 {
       
   292     tcg_out_arithi(s, ret, TCG_REG_G0, arg, ARITH_OR);
       
   293 }
       
   294 
       
   295 static inline void tcg_out_movi_imm32(TCGContext *s, int ret, uint32_t arg)
       
   296 {
       
   297     if (check_fit_tl(arg, 12))
       
   298         tcg_out_movi_imm13(s, ret, arg);
       
   299     else {
       
   300         tcg_out_sethi(s, ret, arg);
       
   301         if (arg & 0x3ff)
       
   302             tcg_out_arithi(s, ret, ret, arg & 0x3ff, ARITH_OR);
       
   303     }
       
   304 }
       
   305 
       
   306 static inline void tcg_out_movi(TCGContext *s, TCGType type,
       
   307                                 int ret, tcg_target_long arg)
       
   308 {
       
   309 #if defined(__sparc_v9__) && !defined(__sparc_v8plus__)
       
   310     if (!check_fit_tl(arg, 32) && (arg & ~0xffffffffULL) != 0) {
       
   311         tcg_out_movi_imm32(s, TCG_REG_I4, arg >> 32);
       
   312         tcg_out_arithi(s, TCG_REG_I4, TCG_REG_I4, 32, SHIFT_SLLX);
       
   313         tcg_out_movi_imm32(s, ret, arg);
       
   314         tcg_out_arith(s, ret, ret, TCG_REG_I4, ARITH_OR);
       
   315     } else if (check_fit_tl(arg, 12))
       
   316         tcg_out_movi_imm13(s, ret, arg);
       
   317     else {
       
   318         tcg_out_sethi(s, ret, arg);
       
   319         if (arg & 0x3ff)
       
   320             tcg_out_arithi(s, ret, ret, arg & 0x3ff, ARITH_OR);
       
   321     }
       
   322 #else
       
   323     tcg_out_movi_imm32(s, ret, arg);
       
   324 #endif
       
   325 }
       
   326 
       
   327 static inline void tcg_out_ld_raw(TCGContext *s, int ret,
       
   328                                   tcg_target_long arg)
       
   329 {
       
   330     tcg_out_sethi(s, ret, arg);
       
   331     tcg_out32(s, LDUW | INSN_RD(ret) | INSN_RS1(ret) |
       
   332               INSN_IMM13(arg & 0x3ff));
       
   333 }
       
   334 
       
   335 static inline void tcg_out_ld_ptr(TCGContext *s, int ret,
       
   336                                   tcg_target_long arg)
       
   337 {
       
   338     if (!check_fit_tl(arg, 10))
       
   339         tcg_out_movi(s, TCG_TYPE_PTR, ret, arg & ~0x3ffULL);
       
   340 #if defined(__sparc_v9__) && !defined(__sparc_v8plus__)
       
   341     tcg_out32(s, LDX | INSN_RD(ret) | INSN_RS1(ret) |
       
   342               INSN_IMM13(arg & 0x3ff));
       
   343 #else
       
   344     tcg_out32(s, LDUW | INSN_RD(ret) | INSN_RS1(ret) |
       
   345               INSN_IMM13(arg & 0x3ff));
       
   346 #endif
       
   347 }
       
   348 
       
   349 static inline void tcg_out_ldst(TCGContext *s, int ret, int addr, int offset, int op)
       
   350 {
       
   351     if (check_fit_tl(offset, 13))
       
   352         tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(addr) |
       
   353                   INSN_IMM13(offset));
       
   354     else {
       
   355         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, offset);
       
   356         tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(TCG_REG_I5) |
       
   357                   INSN_RS2(addr));
       
   358     }
       
   359 }
       
   360 
       
   361 static inline void tcg_out_ldst_asi(TCGContext *s, int ret, int addr,
       
   362                                     int offset, int op, int asi)
       
   363 {
       
   364     tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, offset);
       
   365     tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(TCG_REG_I5) |
       
   366               INSN_ASI(asi) | INSN_RS2(addr));
       
   367 }
       
   368 
       
   369 static inline void tcg_out_ld(TCGContext *s, TCGType type, int ret,
       
   370                               int arg1, tcg_target_long arg2)
       
   371 {
       
   372     if (type == TCG_TYPE_I32)
       
   373         tcg_out_ldst(s, ret, arg1, arg2, LDUW);
       
   374     else
       
   375         tcg_out_ldst(s, ret, arg1, arg2, LDX);
       
   376 }
       
   377 
       
   378 static inline void tcg_out_st(TCGContext *s, TCGType type, int arg,
       
   379                               int arg1, tcg_target_long arg2)
       
   380 {
       
   381     if (type == TCG_TYPE_I32)
       
   382         tcg_out_ldst(s, arg, arg1, arg2, STW);
       
   383     else
       
   384         tcg_out_ldst(s, arg, arg1, arg2, STX);
       
   385 }
       
   386 
       
   387 static inline void tcg_out_sety(TCGContext *s, tcg_target_long val)
       
   388 {
       
   389     if (val == 0 || val == -1)
       
   390         tcg_out32(s, WRY | INSN_IMM13(val));
       
   391     else
       
   392         fprintf(stderr, "unimplemented sety %ld\n", (long)val);
       
   393 }
       
   394 
       
   395 static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
       
   396 {
       
   397     if (val != 0) {
       
   398         if (check_fit_tl(val, 13))
       
   399             tcg_out_arithi(s, reg, reg, val, ARITH_ADD);
       
   400         else {
       
   401             tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, val);
       
   402             tcg_out_arith(s, reg, reg, TCG_REG_I5, ARITH_ADD);
       
   403         }
       
   404     }
       
   405 }
       
   406 
       
   407 static inline void tcg_out_andi(TCGContext *s, int reg, tcg_target_long val)
       
   408 {
       
   409     if (val != 0) {
       
   410         if (check_fit_tl(val, 13))
       
   411             tcg_out_arithi(s, reg, reg, val, ARITH_AND);
       
   412         else {
       
   413             tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_I5, val);
       
   414             tcg_out_arith(s, reg, reg, TCG_REG_I5, ARITH_AND);
       
   415         }
       
   416     }
       
   417 }
       
   418 
       
   419 static inline void tcg_out_nop(TCGContext *s)
       
   420 {
       
   421     tcg_out_sethi(s, TCG_REG_G0, 0);
       
   422 }
       
   423 
       
   424 static void tcg_out_branch(TCGContext *s, int opc, int label_index)
       
   425 {
       
   426     int32_t val;
       
   427     TCGLabel *l = &s->labels[label_index];
       
   428 
       
   429     if (l->has_value) {
       
   430         val = l->u.value - (tcg_target_long)s->code_ptr;
       
   431         tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x2)
       
   432                       | INSN_OFF22(l->u.value - (unsigned long)s->code_ptr)));
       
   433     } else {
       
   434         tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP22, label_index, 0);
       
   435         tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x2) | 0));
       
   436     }
       
   437 }
       
   438 
       
   439 static const uint8_t tcg_cond_to_bcond[10] = {
       
   440     [TCG_COND_EQ] = COND_E,
       
   441     [TCG_COND_NE] = COND_NE,
       
   442     [TCG_COND_LT] = COND_L,
       
   443     [TCG_COND_GE] = COND_GE,
       
   444     [TCG_COND_LE] = COND_LE,
       
   445     [TCG_COND_GT] = COND_G,
       
   446     [TCG_COND_LTU] = COND_CS,
       
   447     [TCG_COND_GEU] = COND_CC,
       
   448     [TCG_COND_LEU] = COND_LEU,
       
   449     [TCG_COND_GTU] = COND_GU,
       
   450 };
       
   451 
       
   452 static void tcg_out_brcond(TCGContext *s, int cond,
       
   453                            TCGArg arg1, TCGArg arg2, int const_arg2,
       
   454                            int label_index)
       
   455 {
       
   456     if (const_arg2 && arg2 == 0)
       
   457         /* orcc %g0, r, %g0 */
       
   458         tcg_out_arith(s, TCG_REG_G0, TCG_REG_G0, arg1, ARITH_ORCC);
       
   459     else
       
   460         /* subcc r1, r2, %g0 */
       
   461         tcg_out_arith(s, TCG_REG_G0, arg1, arg2, ARITH_SUBCC);
       
   462     tcg_out_branch(s, tcg_cond_to_bcond[cond], label_index);
       
   463     tcg_out_nop(s);
       
   464 }
       
   465 
       
   466 /* Generate global QEMU prologue and epilogue code */
       
   467 void tcg_target_qemu_prologue(TCGContext *s)
       
   468 {
       
   469     tcg_out32(s, SAVE | INSN_RD(TCG_REG_O6) | INSN_RS1(TCG_REG_O6) |
       
   470               INSN_IMM13(-TCG_TARGET_STACK_MINFRAME));
       
   471     tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I0) |
       
   472               INSN_RS2(TCG_REG_G0));
       
   473     tcg_out_nop(s);
       
   474 }
       
   475 
       
   476 #if defined(CONFIG_SOFTMMU)
       
   477 
       
   478 #include "../../softmmu_defs.h"
       
   479 
       
   480 static const void * const qemu_ld_helpers[4] = {
       
   481     __ldb_mmu,
       
   482     __ldw_mmu,
       
   483     __ldl_mmu,
       
   484     __ldq_mmu,
       
   485 };
       
   486 
       
   487 static const void * const qemu_st_helpers[4] = {
       
   488     __stb_mmu,
       
   489     __stw_mmu,
       
   490     __stl_mmu,
       
   491     __stq_mmu,
       
   492 };
       
   493 #endif
       
   494 
       
   495 #if TARGET_LONG_BITS == 32
       
   496 #define TARGET_LD_OP LDUW
       
   497 #else
       
   498 #define TARGET_LD_OP LDX
       
   499 #endif
       
   500 
       
   501 #if TARGET_PHYS_ADDR_BITS == 32
       
   502 #define TARGET_ADDEND_LD_OP LDUW
       
   503 #else
       
   504 #define TARGET_ADDEND_LD_OP LDX
       
   505 #endif
       
   506 
       
   507 #ifdef __arch64__
       
   508 #define HOST_LD_OP LDX
       
   509 #define HOST_ST_OP STX
       
   510 #define HOST_SLL_OP SHIFT_SLLX
       
   511 #define HOST_SRA_OP SHIFT_SRAX
       
   512 #else
       
   513 #define HOST_LD_OP LDUW
       
   514 #define HOST_ST_OP STW
       
   515 #define HOST_SLL_OP SHIFT_SLL
       
   516 #define HOST_SRA_OP SHIFT_SRA
       
   517 #endif
       
   518 
       
   519 static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
       
   520                             int opc)
       
   521 {
       
   522     int addr_reg, data_reg, arg0, arg1, arg2, mem_index, s_bits;
       
   523 #if defined(CONFIG_SOFTMMU)
       
   524     uint32_t *label1_ptr, *label2_ptr;
       
   525 #endif
       
   526 
       
   527     data_reg = *args++;
       
   528     addr_reg = *args++;
       
   529     mem_index = *args;
       
   530     s_bits = opc & 3;
       
   531 
       
   532     arg0 = TCG_REG_O0;
       
   533     arg1 = TCG_REG_O1;
       
   534     arg2 = TCG_REG_O2;
       
   535 
       
   536 #if defined(CONFIG_SOFTMMU)
       
   537     /* srl addr_reg, x, arg1 */
       
   538     tcg_out_arithi(s, arg1, addr_reg, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS,
       
   539                    SHIFT_SRL);
       
   540     /* and addr_reg, x, arg0 */
       
   541     tcg_out_arithi(s, arg0, addr_reg, TARGET_PAGE_MASK | ((1 << s_bits) - 1),
       
   542                    ARITH_AND);
       
   543 
       
   544     /* and arg1, x, arg1 */
       
   545     tcg_out_andi(s, arg1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
       
   546 
       
   547     /* add arg1, x, arg1 */
       
   548     tcg_out_addi(s, arg1, offsetof(CPUState,
       
   549                                    tlb_table[mem_index][0].addr_read));
       
   550 
       
   551     /* add env, arg1, arg1 */
       
   552     tcg_out_arith(s, arg1, TCG_AREG0, arg1, ARITH_ADD);
       
   553 
       
   554     /* ld [arg1], arg2 */
       
   555     tcg_out32(s, TARGET_LD_OP | INSN_RD(arg2) | INSN_RS1(arg1) |
       
   556               INSN_RS2(TCG_REG_G0));
       
   557 
       
   558     /* subcc arg0, arg2, %g0 */
       
   559     tcg_out_arith(s, TCG_REG_G0, arg0, arg2, ARITH_SUBCC);
       
   560 
       
   561     /* will become:
       
   562        be label1 */
       
   563     label1_ptr = (uint32_t *)s->code_ptr;
       
   564     tcg_out32(s, 0);
       
   565 
       
   566     /* mov (delay slot) */
       
   567     tcg_out_mov(s, arg0, addr_reg);
       
   568 
       
   569     /* mov */
       
   570     tcg_out_movi(s, TCG_TYPE_I32, arg1, mem_index);
       
   571 
       
   572     /* XXX: move that code at the end of the TB */
       
   573     /* qemu_ld_helper[s_bits](arg0, arg1) */
       
   574     tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_ld_helpers[s_bits]
       
   575                            - (tcg_target_ulong)s->code_ptr) >> 2)
       
   576                          & 0x3fffffff));
       
   577     /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
       
   578        global registers */
       
   579     // delay slot
       
   580     tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
       
   581                  TCG_TARGET_CALL_STACK_OFFSET - sizeof(long), HOST_ST_OP);
       
   582     tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
       
   583                  TCG_TARGET_CALL_STACK_OFFSET - sizeof(long), HOST_LD_OP);
       
   584 
       
   585     /* data_reg = sign_extend(arg0) */
       
   586     switch(opc) {
       
   587     case 0 | 4:
       
   588         /* sll arg0, 24/56, data_reg */
       
   589         tcg_out_arithi(s, data_reg, arg0, (int)sizeof(tcg_target_long) * 8 - 8,
       
   590                        HOST_SLL_OP);
       
   591         /* sra data_reg, 24/56, data_reg */
       
   592         tcg_out_arithi(s, data_reg, data_reg,
       
   593                        (int)sizeof(tcg_target_long) * 8 - 8, HOST_SRA_OP);
       
   594         break;
       
   595     case 1 | 4:
       
   596         /* sll arg0, 16/48, data_reg */
       
   597         tcg_out_arithi(s, data_reg, arg0,
       
   598                        (int)sizeof(tcg_target_long) * 8 - 16, HOST_SLL_OP);
       
   599         /* sra data_reg, 16/48, data_reg */
       
   600         tcg_out_arithi(s, data_reg, data_reg,
       
   601                        (int)sizeof(tcg_target_long) * 8 - 16, HOST_SRA_OP);
       
   602         break;
       
   603     case 2 | 4:
       
   604         /* sll arg0, 32, data_reg */
       
   605         tcg_out_arithi(s, data_reg, arg0, 32, HOST_SLL_OP);
       
   606         /* sra data_reg, 32, data_reg */
       
   607         tcg_out_arithi(s, data_reg, data_reg, 32, HOST_SRA_OP);
       
   608         break;
       
   609     case 0:
       
   610     case 1:
       
   611     case 2:
       
   612     case 3:
       
   613     default:
       
   614         /* mov */
       
   615         tcg_out_mov(s, data_reg, arg0);
       
   616         break;
       
   617     }
       
   618 
       
   619     /* will become:
       
   620        ba label2 */
       
   621     label2_ptr = (uint32_t *)s->code_ptr;
       
   622     tcg_out32(s, 0);
       
   623 
       
   624     /* nop (delay slot */
       
   625     tcg_out_nop(s);
       
   626 
       
   627     /* label1: */
       
   628     *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x2) |
       
   629                    INSN_OFF22((unsigned long)s->code_ptr -
       
   630                               (unsigned long)label1_ptr));
       
   631 
       
   632     /* ld [arg1 + x], arg1 */
       
   633     tcg_out_ldst(s, arg1, arg1, offsetof(CPUTLBEntry, addend) -
       
   634                  offsetof(CPUTLBEntry, addr_read), TARGET_ADDEND_LD_OP);
       
   635 
       
   636 #if TARGET_LONG_BITS == 32
       
   637     /* and addr_reg, x, arg0 */
       
   638     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_I5, 0xffffffff);
       
   639     tcg_out_arith(s, arg0, addr_reg, TCG_REG_I5, ARITH_AND);
       
   640     /* add arg0, arg1, arg0 */
       
   641     tcg_out_arith(s, arg0, arg0, arg1, ARITH_ADD);
       
   642 #else
       
   643     /* add addr_reg, arg1, arg0 */
       
   644     tcg_out_arith(s, arg0, addr_reg, arg1, ARITH_ADD);
       
   645 #endif
       
   646 
       
   647 #else
       
   648     arg0 = addr_reg;
       
   649 #endif
       
   650 
       
   651     switch(opc) {
       
   652     case 0:
       
   653         /* ldub [arg0], data_reg */
       
   654         tcg_out_ldst(s, data_reg, arg0, 0, LDUB);
       
   655         break;
       
   656     case 0 | 4:
       
   657         /* ldsb [arg0], data_reg */
       
   658         tcg_out_ldst(s, data_reg, arg0, 0, LDSB);
       
   659         break;
       
   660     case 1:
       
   661 #ifdef TARGET_WORDS_BIGENDIAN
       
   662         /* lduh [arg0], data_reg */
       
   663         tcg_out_ldst(s, data_reg, arg0, 0, LDUH);
       
   664 #else
       
   665         /* lduha [arg0] ASI_PRIMARY_LITTLE, data_reg */
       
   666         tcg_out_ldst_asi(s, data_reg, arg0, 0, LDUHA, ASI_PRIMARY_LITTLE);
       
   667 #endif
       
   668         break;
       
   669     case 1 | 4:
       
   670 #ifdef TARGET_WORDS_BIGENDIAN
       
   671         /* ldsh [arg0], data_reg */
       
   672         tcg_out_ldst(s, data_reg, arg0, 0, LDSH);
       
   673 #else
       
   674         /* ldsha [arg0] ASI_PRIMARY_LITTLE, data_reg */
       
   675         tcg_out_ldst_asi(s, data_reg, arg0, 0, LDSHA, ASI_PRIMARY_LITTLE);
       
   676 #endif
       
   677         break;
       
   678     case 2:
       
   679 #ifdef TARGET_WORDS_BIGENDIAN
       
   680         /* lduw [arg0], data_reg */
       
   681         tcg_out_ldst(s, data_reg, arg0, 0, LDUW);
       
   682 #else
       
   683         /* lduwa [arg0] ASI_PRIMARY_LITTLE, data_reg */
       
   684         tcg_out_ldst_asi(s, data_reg, arg0, 0, LDUWA, ASI_PRIMARY_LITTLE);
       
   685 #endif
       
   686         break;
       
   687     case 2 | 4:
       
   688 #ifdef TARGET_WORDS_BIGENDIAN
       
   689         /* ldsw [arg0], data_reg */
       
   690         tcg_out_ldst(s, data_reg, arg0, 0, LDSW);
       
   691 #else
       
   692         /* ldswa [arg0] ASI_PRIMARY_LITTLE, data_reg */
       
   693         tcg_out_ldst_asi(s, data_reg, arg0, 0, LDSWA, ASI_PRIMARY_LITTLE);
       
   694 #endif
       
   695         break;
       
   696     case 3:
       
   697 #ifdef TARGET_WORDS_BIGENDIAN
       
   698         /* ldx [arg0], data_reg */
       
   699         tcg_out_ldst(s, data_reg, arg0, 0, LDX);
       
   700 #else
       
   701         /* ldxa [arg0] ASI_PRIMARY_LITTLE, data_reg */
       
   702         tcg_out_ldst_asi(s, data_reg, arg0, 0, LDXA, ASI_PRIMARY_LITTLE);
       
   703 #endif
       
   704         break;
       
   705     default:
       
   706         tcg_abort();
       
   707     }
       
   708 
       
   709 #if defined(CONFIG_SOFTMMU)
       
   710     /* label2: */
       
   711     *label2_ptr = (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2) |
       
   712                    INSN_OFF22((unsigned long)s->code_ptr -
       
   713                               (unsigned long)label2_ptr));
       
   714 #endif
       
   715 }
       
   716 
       
   717 static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
       
   718                             int opc)
       
   719 {
       
   720     int addr_reg, data_reg, arg0, arg1, arg2, mem_index, s_bits;
       
   721 #if defined(CONFIG_SOFTMMU)
       
   722     uint32_t *label1_ptr, *label2_ptr;
       
   723 #endif
       
   724 
       
   725     data_reg = *args++;
       
   726     addr_reg = *args++;
       
   727     mem_index = *args;
       
   728 
       
   729     s_bits = opc;
       
   730 
       
   731     arg0 = TCG_REG_O0;
       
   732     arg1 = TCG_REG_O1;
       
   733     arg2 = TCG_REG_O2;
       
   734 
       
   735 #if defined(CONFIG_SOFTMMU)
       
   736     /* srl addr_reg, x, arg1 */
       
   737     tcg_out_arithi(s, arg1, addr_reg, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS,
       
   738                    SHIFT_SRL);
       
   739 
       
   740     /* and addr_reg, x, arg0 */
       
   741     tcg_out_arithi(s, arg0, addr_reg, TARGET_PAGE_MASK | ((1 << s_bits) - 1),
       
   742                    ARITH_AND);
       
   743 
       
   744     /* and arg1, x, arg1 */
       
   745     tcg_out_andi(s, arg1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
       
   746 
       
   747     /* add arg1, x, arg1 */
       
   748     tcg_out_addi(s, arg1, offsetof(CPUState,
       
   749                                    tlb_table[mem_index][0].addr_write));
       
   750 
       
   751     /* add env, arg1, arg1 */
       
   752     tcg_out_arith(s, arg1, TCG_AREG0, arg1, ARITH_ADD);
       
   753 
       
   754     /* ld [arg1], arg2 */
       
   755     tcg_out32(s, TARGET_LD_OP | INSN_RD(arg2) | INSN_RS1(arg1) |
       
   756               INSN_RS2(TCG_REG_G0));
       
   757 
       
   758     /* subcc arg0, arg2, %g0 */
       
   759     tcg_out_arith(s, TCG_REG_G0, arg0, arg2, ARITH_SUBCC);
       
   760 
       
   761     /* will become:
       
   762        be label1 */
       
   763     label1_ptr = (uint32_t *)s->code_ptr;
       
   764     tcg_out32(s, 0);
       
   765 
       
   766     /* mov (delay slot) */
       
   767     tcg_out_mov(s, arg0, addr_reg);
       
   768 
       
   769     /* mov */
       
   770     tcg_out_mov(s, arg1, data_reg);
       
   771 
       
   772     /* mov */
       
   773     tcg_out_movi(s, TCG_TYPE_I32, arg2, mem_index);
       
   774 
       
   775     /* XXX: move that code at the end of the TB */
       
   776     /* qemu_st_helper[s_bits](arg0, arg1, arg2) */
       
   777     tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_st_helpers[s_bits]
       
   778                            - (tcg_target_ulong)s->code_ptr) >> 2)
       
   779                          & 0x3fffffff));
       
   780     /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
       
   781        global registers */
       
   782     // delay slot
       
   783     tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
       
   784                  TCG_TARGET_CALL_STACK_OFFSET - sizeof(long), HOST_ST_OP);
       
   785     tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
       
   786                  TCG_TARGET_CALL_STACK_OFFSET - sizeof(long), HOST_LD_OP);
       
   787 
       
   788     /* will become:
       
   789        ba label2 */
       
   790     label2_ptr = (uint32_t *)s->code_ptr;
       
   791     tcg_out32(s, 0);
       
   792 
       
   793     /* nop (delay slot) */
       
   794     tcg_out_nop(s);
       
   795 
       
   796     /* label1: */
       
   797     *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x2) |
       
   798                    INSN_OFF22((unsigned long)s->code_ptr -
       
   799                               (unsigned long)label1_ptr));
       
   800 
       
   801     /* ld [arg1 + x], arg1 */
       
   802     tcg_out_ldst(s, arg1, arg1, offsetof(CPUTLBEntry, addend) -
       
   803                  offsetof(CPUTLBEntry, addr_write), TARGET_ADDEND_LD_OP);
       
   804 
       
   805 #if TARGET_LONG_BITS == 32
       
   806     /* and addr_reg, x, arg0 */
       
   807     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_I5, 0xffffffff);
       
   808     tcg_out_arith(s, arg0, addr_reg, TCG_REG_I5, ARITH_AND);
       
   809     /* add arg0, arg1, arg0 */
       
   810     tcg_out_arith(s, arg0, arg0, arg1, ARITH_ADD);
       
   811 #else
       
   812     /* add addr_reg, arg1, arg0 */
       
   813     tcg_out_arith(s, arg0, addr_reg, arg1, ARITH_ADD);
       
   814 #endif
       
   815 
       
   816 #else
       
   817     arg0 = addr_reg;
       
   818 #endif
       
   819 
       
   820     switch(opc) {
       
   821     case 0:
       
   822         /* stb data_reg, [arg0] */
       
   823         tcg_out_ldst(s, data_reg, arg0, 0, STB);
       
   824         break;
       
   825     case 1:
       
   826 #ifdef TARGET_WORDS_BIGENDIAN
       
   827         /* sth data_reg, [arg0] */
       
   828         tcg_out_ldst(s, data_reg, arg0, 0, STH);
       
   829 #else
       
   830         /* stha data_reg, [arg0] ASI_PRIMARY_LITTLE */
       
   831         tcg_out_ldst_asi(s, data_reg, arg0, 0, STHA, ASI_PRIMARY_LITTLE);
       
   832 #endif
       
   833         break;
       
   834     case 2:
       
   835 #ifdef TARGET_WORDS_BIGENDIAN
       
   836         /* stw data_reg, [arg0] */
       
   837         tcg_out_ldst(s, data_reg, arg0, 0, STW);
       
   838 #else
       
   839         /* stwa data_reg, [arg0] ASI_PRIMARY_LITTLE */
       
   840         tcg_out_ldst_asi(s, data_reg, arg0, 0, STWA, ASI_PRIMARY_LITTLE);
       
   841 #endif
       
   842         break;
       
   843     case 3:
       
   844 #ifdef TARGET_WORDS_BIGENDIAN
       
   845         /* stx data_reg, [arg0] */
       
   846         tcg_out_ldst(s, data_reg, arg0, 0, STX);
       
   847 #else
       
   848         /* stxa data_reg, [arg0] ASI_PRIMARY_LITTLE */
       
   849         tcg_out_ldst_asi(s, data_reg, arg0, 0, STXA, ASI_PRIMARY_LITTLE);
       
   850 #endif
       
   851         break;
       
   852     default:
       
   853         tcg_abort();
       
   854     }
       
   855 
       
   856 #if defined(CONFIG_SOFTMMU)
       
   857     /* label2: */
       
   858     *label2_ptr = (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2) |
       
   859                    INSN_OFF22((unsigned long)s->code_ptr -
       
   860                               (unsigned long)label2_ptr));
       
   861 #endif
       
   862 }
       
   863 
       
   864 static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
       
   865                               const int *const_args)
       
   866 {
       
   867     int c;
       
   868 
       
   869     switch (opc) {
       
   870     case INDEX_op_exit_tb:
       
   871         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I0, args[0]);
       
   872         tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I7) |
       
   873                   INSN_IMM13(8));
       
   874         tcg_out32(s, RESTORE | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_G0) |
       
   875                       INSN_RS2(TCG_REG_G0));
       
   876         break;
       
   877     case INDEX_op_goto_tb:
       
   878         if (s->tb_jmp_offset) {
       
   879             /* direct jump method */
       
   880             tcg_out_sethi(s, TCG_REG_I5, args[0] & 0xffffe000);
       
   881             tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I5) |
       
   882                       INSN_IMM13((args[0] & 0x1fff)));
       
   883             s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
       
   884         } else {
       
   885             /* indirect jump method */
       
   886             tcg_out_ld_ptr(s, TCG_REG_I5, (tcg_target_long)(s->tb_next + args[0]));
       
   887             tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I5) |
       
   888                       INSN_RS2(TCG_REG_G0));
       
   889         }
       
   890         tcg_out_nop(s);
       
   891         s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
       
   892         break;
       
   893     case INDEX_op_call:
       
   894         if (const_args[0])
       
   895             tcg_out32(s, CALL | ((((tcg_target_ulong)args[0]
       
   896                                    - (tcg_target_ulong)s->code_ptr) >> 2)
       
   897                                  & 0x3fffffff));
       
   898         else {
       
   899             tcg_out_ld_ptr(s, TCG_REG_I5,
       
   900                            (tcg_target_long)(s->tb_next + args[0]));
       
   901             tcg_out32(s, JMPL | INSN_RD(TCG_REG_O7) | INSN_RS1(TCG_REG_I5) |
       
   902                       INSN_RS2(TCG_REG_G0));
       
   903         }
       
   904         /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
       
   905            global registers */
       
   906         // delay slot
       
   907         tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
       
   908                      TCG_TARGET_CALL_STACK_OFFSET - sizeof(long), HOST_ST_OP);
       
   909         tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
       
   910                      TCG_TARGET_CALL_STACK_OFFSET - sizeof(long), HOST_LD_OP);
       
   911         break;
       
   912     case INDEX_op_jmp:
       
   913     case INDEX_op_br:
       
   914         tcg_out_branch(s, COND_A, args[0]);
       
   915         tcg_out_nop(s);
       
   916         break;
       
   917     case INDEX_op_movi_i32:
       
   918         tcg_out_movi(s, TCG_TYPE_I32, args[0], (uint32_t)args[1]);
       
   919         break;
       
   920 
       
   921 #if defined(__sparc_v9__) && !defined(__sparc_v8plus__)
       
   922 #define OP_32_64(x)                             \
       
   923         glue(glue(case INDEX_op_, x), _i32:)    \
       
   924         glue(glue(case INDEX_op_, x), _i64:)
       
   925 #else
       
   926 #define OP_32_64(x)                             \
       
   927         glue(glue(case INDEX_op_, x), _i32:)
       
   928 #endif
       
   929         OP_32_64(ld8u);
       
   930         tcg_out_ldst(s, args[0], args[1], args[2], LDUB);
       
   931         break;
       
   932         OP_32_64(ld8s);
       
   933         tcg_out_ldst(s, args[0], args[1], args[2], LDSB);
       
   934         break;
       
   935         OP_32_64(ld16u);
       
   936         tcg_out_ldst(s, args[0], args[1], args[2], LDUH);
       
   937         break;
       
   938         OP_32_64(ld16s);
       
   939         tcg_out_ldst(s, args[0], args[1], args[2], LDSH);
       
   940         break;
       
   941     case INDEX_op_ld_i32:
       
   942 #if defined(__sparc_v9__) && !defined(__sparc_v8plus__)
       
   943     case INDEX_op_ld32u_i64:
       
   944 #endif
       
   945         tcg_out_ldst(s, args[0], args[1], args[2], LDUW);
       
   946         break;
       
   947         OP_32_64(st8);
       
   948         tcg_out_ldst(s, args[0], args[1], args[2], STB);
       
   949         break;
       
   950         OP_32_64(st16);
       
   951         tcg_out_ldst(s, args[0], args[1], args[2], STH);
       
   952         break;
       
   953     case INDEX_op_st_i32:
       
   954 #if defined(__sparc_v9__) && !defined(__sparc_v8plus__)
       
   955     case INDEX_op_st32_i64:
       
   956 #endif
       
   957         tcg_out_ldst(s, args[0], args[1], args[2], STW);
       
   958         break;
       
   959         OP_32_64(add);
       
   960         c = ARITH_ADD;
       
   961         goto gen_arith32;
       
   962         OP_32_64(sub);
       
   963         c = ARITH_SUB;
       
   964         goto gen_arith32;
       
   965         OP_32_64(and);
       
   966         c = ARITH_AND;
       
   967         goto gen_arith32;
       
   968         OP_32_64(or);
       
   969         c = ARITH_OR;
       
   970         goto gen_arith32;
       
   971         OP_32_64(xor);
       
   972         c = ARITH_XOR;
       
   973         goto gen_arith32;
       
   974     case INDEX_op_shl_i32:
       
   975         c = SHIFT_SLL;
       
   976         goto gen_arith32;
       
   977     case INDEX_op_shr_i32:
       
   978         c = SHIFT_SRL;
       
   979         goto gen_arith32;
       
   980     case INDEX_op_sar_i32:
       
   981         c = SHIFT_SRA;
       
   982         goto gen_arith32;
       
   983     case INDEX_op_mul_i32:
       
   984         c = ARITH_UMUL;
       
   985         goto gen_arith32;
       
   986     case INDEX_op_div2_i32:
       
   987 #if defined(__sparc_v9__) || defined(__sparc_v8plus__)
       
   988         c = ARITH_SDIVX;
       
   989         goto gen_arith32;
       
   990 #else
       
   991         tcg_out_sety(s, 0);
       
   992         c = ARITH_SDIV;
       
   993         goto gen_arith32;
       
   994 #endif
       
   995     case INDEX_op_divu2_i32:
       
   996 #if defined(__sparc_v9__) || defined(__sparc_v8plus__)
       
   997         c = ARITH_UDIVX;
       
   998         goto gen_arith32;
       
   999 #else
       
  1000         tcg_out_sety(s, 0);
       
  1001         c = ARITH_UDIV;
       
  1002         goto gen_arith32;
       
  1003 #endif
       
  1004 
       
  1005     case INDEX_op_brcond_i32:
       
  1006         tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
       
  1007                        args[3]);
       
  1008         break;
       
  1009 
       
  1010     case INDEX_op_qemu_ld8u:
       
  1011         tcg_out_qemu_ld(s, args, 0);
       
  1012         break;
       
  1013     case INDEX_op_qemu_ld8s:
       
  1014         tcg_out_qemu_ld(s, args, 0 | 4);
       
  1015         break;
       
  1016     case INDEX_op_qemu_ld16u:
       
  1017         tcg_out_qemu_ld(s, args, 1);
       
  1018         break;
       
  1019     case INDEX_op_qemu_ld16s:
       
  1020         tcg_out_qemu_ld(s, args, 1 | 4);
       
  1021         break;
       
  1022     case INDEX_op_qemu_ld32u:
       
  1023         tcg_out_qemu_ld(s, args, 2);
       
  1024         break;
       
  1025     case INDEX_op_qemu_ld32s:
       
  1026         tcg_out_qemu_ld(s, args, 2 | 4);
       
  1027         break;
       
  1028     case INDEX_op_qemu_st8:
       
  1029         tcg_out_qemu_st(s, args, 0);
       
  1030         break;
       
  1031     case INDEX_op_qemu_st16:
       
  1032         tcg_out_qemu_st(s, args, 1);
       
  1033         break;
       
  1034     case INDEX_op_qemu_st32:
       
  1035         tcg_out_qemu_st(s, args, 2);
       
  1036         break;
       
  1037 
       
  1038 #if defined(__sparc_v9__) && !defined(__sparc_v8plus__)
       
  1039     case INDEX_op_movi_i64:
       
  1040         tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
       
  1041         break;
       
  1042     case INDEX_op_ld32s_i64:
       
  1043         tcg_out_ldst(s, args[0], args[1], args[2], LDSW);
       
  1044         break;
       
  1045     case INDEX_op_ld_i64:
       
  1046         tcg_out_ldst(s, args[0], args[1], args[2], LDX);
       
  1047         break;
       
  1048     case INDEX_op_st_i64:
       
  1049         tcg_out_ldst(s, args[0], args[1], args[2], STX);
       
  1050         break;
       
  1051     case INDEX_op_shl_i64:
       
  1052         c = SHIFT_SLLX;
       
  1053         goto gen_arith32;
       
  1054     case INDEX_op_shr_i64:
       
  1055         c = SHIFT_SRLX;
       
  1056         goto gen_arith32;
       
  1057     case INDEX_op_sar_i64:
       
  1058         c = SHIFT_SRAX;
       
  1059         goto gen_arith32;
       
  1060     case INDEX_op_mul_i64:
       
  1061         c = ARITH_MULX;
       
  1062         goto gen_arith32;
       
  1063     case INDEX_op_div2_i64:
       
  1064         c = ARITH_SDIVX;
       
  1065         goto gen_arith32;
       
  1066     case INDEX_op_divu2_i64:
       
  1067         c = ARITH_UDIVX;
       
  1068         goto gen_arith32;
       
  1069 
       
  1070     case INDEX_op_brcond_i64:
       
  1071         tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
       
  1072                        args[3]);
       
  1073         break;
       
  1074     case INDEX_op_qemu_ld64:
       
  1075         tcg_out_qemu_ld(s, args, 3);
       
  1076         break;
       
  1077     case INDEX_op_qemu_st64:
       
  1078         tcg_out_qemu_st(s, args, 3);
       
  1079         break;
       
  1080 
       
  1081 #endif
       
  1082     gen_arith32:
       
  1083         if (const_args[2]) {
       
  1084             tcg_out_arithi(s, args[0], args[1], args[2], c);
       
  1085         } else {
       
  1086             tcg_out_arith(s, args[0], args[1], args[2], c);
       
  1087         }
       
  1088         break;
       
  1089 
       
  1090     default:
       
  1091         fprintf(stderr, "unknown opcode 0x%x\n", opc);
       
  1092         tcg_abort();
       
  1093     }
       
  1094 }
       
  1095 
       
  1096 static const TCGTargetOpDef sparc_op_defs[] = {
       
  1097     { INDEX_op_exit_tb, { } },
       
  1098     { INDEX_op_goto_tb, { } },
       
  1099     { INDEX_op_call, { "ri" } },
       
  1100     { INDEX_op_jmp, { "ri" } },
       
  1101     { INDEX_op_br, { } },
       
  1102 
       
  1103     { INDEX_op_mov_i32, { "r", "r" } },
       
  1104     { INDEX_op_movi_i32, { "r" } },
       
  1105     { INDEX_op_ld8u_i32, { "r", "r" } },
       
  1106     { INDEX_op_ld8s_i32, { "r", "r" } },
       
  1107     { INDEX_op_ld16u_i32, { "r", "r" } },
       
  1108     { INDEX_op_ld16s_i32, { "r", "r" } },
       
  1109     { INDEX_op_ld_i32, { "r", "r" } },
       
  1110     { INDEX_op_st8_i32, { "r", "r" } },
       
  1111     { INDEX_op_st16_i32, { "r", "r" } },
       
  1112     { INDEX_op_st_i32, { "r", "r" } },
       
  1113 
       
  1114     { INDEX_op_add_i32, { "r", "r", "rJ" } },
       
  1115     { INDEX_op_mul_i32, { "r", "r", "rJ" } },
       
  1116     { INDEX_op_div2_i32, { "r", "r", "0", "1", "r" } },
       
  1117     { INDEX_op_divu2_i32, { "r", "r", "0", "1", "r" } },
       
  1118     { INDEX_op_sub_i32, { "r", "r", "rJ" } },
       
  1119     { INDEX_op_and_i32, { "r", "r", "rJ" } },
       
  1120     { INDEX_op_or_i32, { "r", "r", "rJ" } },
       
  1121     { INDEX_op_xor_i32, { "r", "r", "rJ" } },
       
  1122 
       
  1123     { INDEX_op_shl_i32, { "r", "r", "rJ" } },
       
  1124     { INDEX_op_shr_i32, { "r", "r", "rJ" } },
       
  1125     { INDEX_op_sar_i32, { "r", "r", "rJ" } },
       
  1126 
       
  1127     { INDEX_op_brcond_i32, { "r", "ri" } },
       
  1128 
       
  1129     { INDEX_op_qemu_ld8u, { "r", "L" } },
       
  1130     { INDEX_op_qemu_ld8s, { "r", "L" } },
       
  1131     { INDEX_op_qemu_ld16u, { "r", "L" } },
       
  1132     { INDEX_op_qemu_ld16s, { "r", "L" } },
       
  1133     { INDEX_op_qemu_ld32u, { "r", "L" } },
       
  1134     { INDEX_op_qemu_ld32s, { "r", "L" } },
       
  1135 
       
  1136     { INDEX_op_qemu_st8, { "L", "L" } },
       
  1137     { INDEX_op_qemu_st16, { "L", "L" } },
       
  1138     { INDEX_op_qemu_st32, { "L", "L" } },
       
  1139 
       
  1140 #if defined(__sparc_v9__) && !defined(__sparc_v8plus__)
       
  1141     { INDEX_op_mov_i64, { "r", "r" } },
       
  1142     { INDEX_op_movi_i64, { "r" } },
       
  1143     { INDEX_op_ld8u_i64, { "r", "r" } },
       
  1144     { INDEX_op_ld8s_i64, { "r", "r" } },
       
  1145     { INDEX_op_ld16u_i64, { "r", "r" } },
       
  1146     { INDEX_op_ld16s_i64, { "r", "r" } },
       
  1147     { INDEX_op_ld32u_i64, { "r", "r" } },
       
  1148     { INDEX_op_ld32s_i64, { "r", "r" } },
       
  1149     { INDEX_op_ld_i64, { "r", "r" } },
       
  1150     { INDEX_op_st8_i64, { "r", "r" } },
       
  1151     { INDEX_op_st16_i64, { "r", "r" } },
       
  1152     { INDEX_op_st32_i64, { "r", "r" } },
       
  1153     { INDEX_op_st_i64, { "r", "r" } },
       
  1154     { INDEX_op_qemu_ld64, { "L", "L" } },
       
  1155     { INDEX_op_qemu_st64, { "L", "L" } },
       
  1156 
       
  1157     { INDEX_op_add_i64, { "r", "r", "rJ" } },
       
  1158     { INDEX_op_mul_i64, { "r", "r", "rJ" } },
       
  1159     { INDEX_op_div2_i64, { "r", "r", "0", "1", "r" } },
       
  1160     { INDEX_op_divu2_i64, { "r", "r", "0", "1", "r" } },
       
  1161     { INDEX_op_sub_i64, { "r", "r", "rJ" } },
       
  1162     { INDEX_op_and_i64, { "r", "r", "rJ" } },
       
  1163     { INDEX_op_or_i64, { "r", "r", "rJ" } },
       
  1164     { INDEX_op_xor_i64, { "r", "r", "rJ" } },
       
  1165 
       
  1166     { INDEX_op_shl_i64, { "r", "r", "rJ" } },
       
  1167     { INDEX_op_shr_i64, { "r", "r", "rJ" } },
       
  1168     { INDEX_op_sar_i64, { "r", "r", "rJ" } },
       
  1169 
       
  1170     { INDEX_op_brcond_i64, { "r", "ri" } },
       
  1171 #endif
       
  1172     { -1 },
       
  1173 };
       
  1174 
       
  1175 void tcg_target_init(TCGContext *s)
       
  1176 {
       
  1177     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
       
  1178 #if defined(__sparc_v9__) && !defined(__sparc_v8plus__)
       
  1179     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff);
       
  1180 #endif
       
  1181     tcg_regset_set32(tcg_target_call_clobber_regs, 0,
       
  1182                      (1 << TCG_REG_G1) |
       
  1183                      (1 << TCG_REG_G2) |
       
  1184                      (1 << TCG_REG_G3) |
       
  1185                      (1 << TCG_REG_G4) |
       
  1186                      (1 << TCG_REG_G5) |
       
  1187                      (1 << TCG_REG_G6) |
       
  1188                      (1 << TCG_REG_G7) |
       
  1189                      (1 << TCG_REG_O0) |
       
  1190                      (1 << TCG_REG_O1) |
       
  1191                      (1 << TCG_REG_O2) |
       
  1192                      (1 << TCG_REG_O3) |
       
  1193                      (1 << TCG_REG_O4) |
       
  1194                      (1 << TCG_REG_O5) |
       
  1195                      (1 << TCG_REG_O7));
       
  1196 
       
  1197     tcg_regset_clear(s->reserved_regs);
       
  1198     tcg_regset_set_reg(s->reserved_regs, TCG_REG_G0);
       
  1199 #if defined(__sparc_v9__) && !defined(__sparc_v8plus__)
       
  1200     tcg_regset_set_reg(s->reserved_regs, TCG_REG_I4); // for internal use
       
  1201 #endif
       
  1202     tcg_regset_set_reg(s->reserved_regs, TCG_REG_I5); // for internal use
       
  1203     tcg_regset_set_reg(s->reserved_regs, TCG_REG_I6);
       
  1204     tcg_regset_set_reg(s->reserved_regs, TCG_REG_I7);
       
  1205     tcg_regset_set_reg(s->reserved_regs, TCG_REG_O6);
       
  1206     tcg_regset_set_reg(s->reserved_regs, TCG_REG_O7);
       
  1207     tcg_add_target_add_op_defs(sparc_op_defs);
       
  1208 }