Annotation of qemu/target-sparc/translate.c, revision 1.1.1.3

1.1       root        1: /*
                      2:    SPARC translation
                      3: 
                      4:    Copyright (C) 2003 Thomas M. Ogrisegg <[email protected]>
                      5:    Copyright (C) 2003-2005 Fabrice Bellard
                      6: 
                      7:    This library is free software; you can redistribute it and/or
                      8:    modify it under the terms of the GNU Lesser General Public
                      9:    License as published by the Free Software Foundation; either
                     10:    version 2 of the License, or (at your option) any later version.
                     11: 
                     12:    This library is distributed in the hope that it will be useful,
                     13:    but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     15:    Lesser General Public License for more details.
                     16: 
                     17:    You should have received a copy of the GNU Lesser General Public
                     18:    License along with this library; if not, write to the Free Software
                     19:    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     20:  */
                     21: 
                     22: /*
                     23:    TODO-list:
                     24: 
                     25:    Rest of V9 instructions, VIS instructions
                     26:    NPC/PC static optimisations (use JUMP_TB when possible)
                     27:    Optimize synthetic instructions
                     28:    Optional alignment check
                     29:    128-bit float
                     30:    Tagged add/sub
                     31: */
                     32: 
                     33: #include <stdarg.h>
                     34: #include <stdlib.h>
                     35: #include <stdio.h>
                     36: #include <string.h>
                     37: #include <inttypes.h>
                     38: 
                     39: #include "cpu.h"
                     40: #include "exec-all.h"
                     41: #include "disas.h"
                     42: 
                     43: #define DEBUG_DISAS
                     44: 
                     45: #define DYNAMIC_PC  1 /* dynamic pc value */
                     46: #define JUMP_PC     2 /* dynamic pc value which takes only two values
                     47:                          according to jump_pc[T2] */
                     48: 
                     49: typedef struct DisasContext {
                     50:     target_ulong pc;   /* current Program Counter: integer or DYNAMIC_PC */
                     51:     target_ulong npc;  /* next PC: integer or DYNAMIC_PC or JUMP_PC */
                     52:     target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */
                     53:     int is_br;
                     54:     int mem_idx;
1.1.1.3 ! root       55:     int fpu_enabled;
1.1       root       56:     struct TranslationBlock *tb;
                     57: } DisasContext;
                     58: 
                     59: static uint16_t *gen_opc_ptr;
                     60: static uint32_t *gen_opparam_ptr;
                     61: extern FILE *logfile;
                     62: extern int loglevel;
                     63: 
                     64: enum {
                     65: #define DEF(s,n,copy_size) INDEX_op_ ## s,
                     66: #include "opc.h"
                     67: #undef DEF
                     68:     NB_OPS
                     69: };
                     70: 
                     71: #include "gen-op.h"
                     72: 
                     73: // This function uses non-native bit order
                     74: #define GET_FIELD(X, FROM, TO) \
                     75:   ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
                     76: 
                     77: // This function uses the order in the manuals, i.e. bit 0 is 2^0
                     78: #define GET_FIELD_SP(X, FROM, TO) \
                     79:     GET_FIELD(X, 31 - (TO), 31 - (FROM))
                     80: 
                     81: #define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
                     82: #define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), 32 - ((b) - (a) + 1))
                     83: 
                     84: #ifdef TARGET_SPARC64
                     85: #define DFPREG(r) (((r & 1) << 6) | (r & 0x1e))
                     86: #else
                     87: #define DFPREG(r) (r)
                     88: #endif
                     89: 
                     90: #ifdef USE_DIRECT_JUMP
                     91: #define TBPARAM(x)
                     92: #else
                     93: #define TBPARAM(x) (long)(x)
                     94: #endif
                     95: 
                     96: static int sign_extend(int x, int len)
                     97: {
                     98:     len = 32 - len;
                     99:     return (x << len) >> len;
                    100: }
                    101: 
                    102: #define IS_IMM (insn & (1<<13))
                    103: 
                    104: static void disas_sparc_insn(DisasContext * dc);
                    105: 
                    106: static GenOpFunc *gen_op_movl_TN_reg[2][32] = {
                    107:     {
                    108:      gen_op_movl_g0_T0,
                    109:      gen_op_movl_g1_T0,
                    110:      gen_op_movl_g2_T0,
                    111:      gen_op_movl_g3_T0,
                    112:      gen_op_movl_g4_T0,
                    113:      gen_op_movl_g5_T0,
                    114:      gen_op_movl_g6_T0,
                    115:      gen_op_movl_g7_T0,
                    116:      gen_op_movl_o0_T0,
                    117:      gen_op_movl_o1_T0,
                    118:      gen_op_movl_o2_T0,
                    119:      gen_op_movl_o3_T0,
                    120:      gen_op_movl_o4_T0,
                    121:      gen_op_movl_o5_T0,
                    122:      gen_op_movl_o6_T0,
                    123:      gen_op_movl_o7_T0,
                    124:      gen_op_movl_l0_T0,
                    125:      gen_op_movl_l1_T0,
                    126:      gen_op_movl_l2_T0,
                    127:      gen_op_movl_l3_T0,
                    128:      gen_op_movl_l4_T0,
                    129:      gen_op_movl_l5_T0,
                    130:      gen_op_movl_l6_T0,
                    131:      gen_op_movl_l7_T0,
                    132:      gen_op_movl_i0_T0,
                    133:      gen_op_movl_i1_T0,
                    134:      gen_op_movl_i2_T0,
                    135:      gen_op_movl_i3_T0,
                    136:      gen_op_movl_i4_T0,
                    137:      gen_op_movl_i5_T0,
                    138:      gen_op_movl_i6_T0,
                    139:      gen_op_movl_i7_T0,
                    140:      },
                    141:     {
                    142:      gen_op_movl_g0_T1,
                    143:      gen_op_movl_g1_T1,
                    144:      gen_op_movl_g2_T1,
                    145:      gen_op_movl_g3_T1,
                    146:      gen_op_movl_g4_T1,
                    147:      gen_op_movl_g5_T1,
                    148:      gen_op_movl_g6_T1,
                    149:      gen_op_movl_g7_T1,
                    150:      gen_op_movl_o0_T1,
                    151:      gen_op_movl_o1_T1,
                    152:      gen_op_movl_o2_T1,
                    153:      gen_op_movl_o3_T1,
                    154:      gen_op_movl_o4_T1,
                    155:      gen_op_movl_o5_T1,
                    156:      gen_op_movl_o6_T1,
                    157:      gen_op_movl_o7_T1,
                    158:      gen_op_movl_l0_T1,
                    159:      gen_op_movl_l1_T1,
                    160:      gen_op_movl_l2_T1,
                    161:      gen_op_movl_l3_T1,
                    162:      gen_op_movl_l4_T1,
                    163:      gen_op_movl_l5_T1,
                    164:      gen_op_movl_l6_T1,
                    165:      gen_op_movl_l7_T1,
                    166:      gen_op_movl_i0_T1,
                    167:      gen_op_movl_i1_T1,
                    168:      gen_op_movl_i2_T1,
                    169:      gen_op_movl_i3_T1,
                    170:      gen_op_movl_i4_T1,
                    171:      gen_op_movl_i5_T1,
                    172:      gen_op_movl_i6_T1,
                    173:      gen_op_movl_i7_T1,
                    174:      }
                    175: };
                    176: 
                    177: static GenOpFunc *gen_op_movl_reg_TN[3][32] = {
                    178:     {
                    179:      gen_op_movl_T0_g0,
                    180:      gen_op_movl_T0_g1,
                    181:      gen_op_movl_T0_g2,
                    182:      gen_op_movl_T0_g3,
                    183:      gen_op_movl_T0_g4,
                    184:      gen_op_movl_T0_g5,
                    185:      gen_op_movl_T0_g6,
                    186:      gen_op_movl_T0_g7,
                    187:      gen_op_movl_T0_o0,
                    188:      gen_op_movl_T0_o1,
                    189:      gen_op_movl_T0_o2,
                    190:      gen_op_movl_T0_o3,
                    191:      gen_op_movl_T0_o4,
                    192:      gen_op_movl_T0_o5,
                    193:      gen_op_movl_T0_o6,
                    194:      gen_op_movl_T0_o7,
                    195:      gen_op_movl_T0_l0,
                    196:      gen_op_movl_T0_l1,
                    197:      gen_op_movl_T0_l2,
                    198:      gen_op_movl_T0_l3,
                    199:      gen_op_movl_T0_l4,
                    200:      gen_op_movl_T0_l5,
                    201:      gen_op_movl_T0_l6,
                    202:      gen_op_movl_T0_l7,
                    203:      gen_op_movl_T0_i0,
                    204:      gen_op_movl_T0_i1,
                    205:      gen_op_movl_T0_i2,
                    206:      gen_op_movl_T0_i3,
                    207:      gen_op_movl_T0_i4,
                    208:      gen_op_movl_T0_i5,
                    209:      gen_op_movl_T0_i6,
                    210:      gen_op_movl_T0_i7,
                    211:      },
                    212:     {
                    213:      gen_op_movl_T1_g0,
                    214:      gen_op_movl_T1_g1,
                    215:      gen_op_movl_T1_g2,
                    216:      gen_op_movl_T1_g3,
                    217:      gen_op_movl_T1_g4,
                    218:      gen_op_movl_T1_g5,
                    219:      gen_op_movl_T1_g6,
                    220:      gen_op_movl_T1_g7,
                    221:      gen_op_movl_T1_o0,
                    222:      gen_op_movl_T1_o1,
                    223:      gen_op_movl_T1_o2,
                    224:      gen_op_movl_T1_o3,
                    225:      gen_op_movl_T1_o4,
                    226:      gen_op_movl_T1_o5,
                    227:      gen_op_movl_T1_o6,
                    228:      gen_op_movl_T1_o7,
                    229:      gen_op_movl_T1_l0,
                    230:      gen_op_movl_T1_l1,
                    231:      gen_op_movl_T1_l2,
                    232:      gen_op_movl_T1_l3,
                    233:      gen_op_movl_T1_l4,
                    234:      gen_op_movl_T1_l5,
                    235:      gen_op_movl_T1_l6,
                    236:      gen_op_movl_T1_l7,
                    237:      gen_op_movl_T1_i0,
                    238:      gen_op_movl_T1_i1,
                    239:      gen_op_movl_T1_i2,
                    240:      gen_op_movl_T1_i3,
                    241:      gen_op_movl_T1_i4,
                    242:      gen_op_movl_T1_i5,
                    243:      gen_op_movl_T1_i6,
                    244:      gen_op_movl_T1_i7,
                    245:      },
                    246:     {
                    247:      gen_op_movl_T2_g0,
                    248:      gen_op_movl_T2_g1,
                    249:      gen_op_movl_T2_g2,
                    250:      gen_op_movl_T2_g3,
                    251:      gen_op_movl_T2_g4,
                    252:      gen_op_movl_T2_g5,
                    253:      gen_op_movl_T2_g6,
                    254:      gen_op_movl_T2_g7,
                    255:      gen_op_movl_T2_o0,
                    256:      gen_op_movl_T2_o1,
                    257:      gen_op_movl_T2_o2,
                    258:      gen_op_movl_T2_o3,
                    259:      gen_op_movl_T2_o4,
                    260:      gen_op_movl_T2_o5,
                    261:      gen_op_movl_T2_o6,
                    262:      gen_op_movl_T2_o7,
                    263:      gen_op_movl_T2_l0,
                    264:      gen_op_movl_T2_l1,
                    265:      gen_op_movl_T2_l2,
                    266:      gen_op_movl_T2_l3,
                    267:      gen_op_movl_T2_l4,
                    268:      gen_op_movl_T2_l5,
                    269:      gen_op_movl_T2_l6,
                    270:      gen_op_movl_T2_l7,
                    271:      gen_op_movl_T2_i0,
                    272:      gen_op_movl_T2_i1,
                    273:      gen_op_movl_T2_i2,
                    274:      gen_op_movl_T2_i3,
                    275:      gen_op_movl_T2_i4,
                    276:      gen_op_movl_T2_i5,
                    277:      gen_op_movl_T2_i6,
                    278:      gen_op_movl_T2_i7,
                    279:      }
                    280: };
                    281: 
                    282: static GenOpFunc1 *gen_op_movl_TN_im[3] = {
                    283:     gen_op_movl_T0_im,
                    284:     gen_op_movl_T1_im,
                    285:     gen_op_movl_T2_im
                    286: };
                    287: 
                    288: // Sign extending version
                    289: static GenOpFunc1 * const gen_op_movl_TN_sim[3] = {
                    290:     gen_op_movl_T0_sim,
                    291:     gen_op_movl_T1_sim,
                    292:     gen_op_movl_T2_sim
                    293: };
                    294: 
                    295: #ifdef TARGET_SPARC64
                    296: #define GEN32(func, NAME) \
                    297: static GenOpFunc *NAME ## _table [64] = {                                     \
                    298: NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
                    299: NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
                    300: NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
                    301: NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
                    302: NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
                    303: NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
                    304: NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
                    305: NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
                    306: NAME ## 32, 0, NAME ## 34, 0, NAME ## 36, 0, NAME ## 38, 0,                   \
                    307: NAME ## 40, 0, NAME ## 42, 0, NAME ## 44, 0, NAME ## 46, 0,                   \
                    308: NAME ## 48, 0, NAME ## 50, 0, NAME ## 52, 0, NAME ## 54, 0,                   \
                    309: NAME ## 56, 0, NAME ## 58, 0, NAME ## 60, 0, NAME ## 62, 0,                   \
                    310: };                                                                            \
                    311: static inline void func(int n)                                                \
                    312: {                                                                             \
                    313:     NAME ## _table[n]();                                                      \
                    314: }
                    315: #else
                    316: #define GEN32(func, NAME) \
                    317: static GenOpFunc *NAME ## _table [32] = {                                     \
                    318: NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
                    319: NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
                    320: NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
                    321: NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
                    322: NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
                    323: NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
                    324: NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
                    325: NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
                    326: };                                                                            \
                    327: static inline void func(int n)                                                \
                    328: {                                                                             \
                    329:     NAME ## _table[n]();                                                      \
                    330: }
                    331: #endif
                    332: 
                    333: /* floating point registers moves */
                    334: GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fprf);
                    335: GEN32(gen_op_load_fpr_FT1, gen_op_load_fpr_FT1_fprf);
                    336: GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fprf);
                    337: GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fprf);
                    338: 
                    339: GEN32(gen_op_load_fpr_DT0, gen_op_load_fpr_DT0_fprf);
                    340: GEN32(gen_op_load_fpr_DT1, gen_op_load_fpr_DT1_fprf);
                    341: GEN32(gen_op_store_DT0_fpr, gen_op_store_DT0_fpr_fprf);
                    342: GEN32(gen_op_store_DT1_fpr, gen_op_store_DT1_fpr_fprf);
                    343: 
                    344: #ifdef TARGET_SPARC64
                    345: // 'a' versions allowed to user depending on asi
                    346: #if defined(CONFIG_USER_ONLY)
                    347: #define supervisor(dc) 0
                    348: #define gen_op_ldst(name)        gen_op_##name##_raw()
                    349: #define OP_LD_TABLE(width)                                             \
                    350:     static void gen_op_##width##a(int insn, int is_ld, int size, int sign) \
                    351:     {                                                                  \
                    352:        int asi, offset;                                                \
                    353:                                                                        \
                    354:        if (IS_IMM) {                                                   \
                    355:            offset = GET_FIELD(insn, 25, 31);                           \
                    356:            if (is_ld)                                                  \
                    357:                gen_op_ld_asi_reg(offset, size, sign);                  \
                    358:            else                                                        \
                    359:                gen_op_st_asi_reg(offset, size, sign);                  \
                    360:            return;                                                     \
                    361:        }                                                               \
                    362:        asi = GET_FIELD(insn, 19, 26);                                  \
                    363:        switch (asi) {                                                  \
                    364:        case 0x80: /* Primary address space */                          \
                    365:            gen_op_##width##_raw();                                     \
                    366:            break;                                                      \
1.1.1.3 ! root      367:        case 0x82: /* Primary address space, non-faulting load */       \
        !           368:            gen_op_##width##_raw();                                     \
        !           369:            break;                                                      \
1.1       root      370:        default:                                                        \
                    371:             break;                                                     \
                    372:        }                                                               \
                    373:     }
                    374: 
                    375: #else
                    376: #define gen_op_ldst(name)        (*gen_op_##name[dc->mem_idx])()
                    377: #define OP_LD_TABLE(width)                                             \
                    378:     static GenOpFunc *gen_op_##width[] = {                             \
                    379:        &gen_op_##width##_user,                                         \
                    380:        &gen_op_##width##_kernel,                                       \
                    381:     };                                                                 \
                    382:                                                                        \
                    383:     static void gen_op_##width##a(int insn, int is_ld, int size, int sign) \
                    384:     {                                                                  \
                    385:        int asi, offset;                                                \
                    386:                                                                        \
                    387:        if (IS_IMM) {                                                   \
                    388:            offset = GET_FIELD(insn, 25, 31);                           \
                    389:            if (is_ld)                                                  \
                    390:                gen_op_ld_asi_reg(offset, size, sign);                  \
                    391:            else                                                        \
                    392:                gen_op_st_asi_reg(offset, size, sign);                  \
                    393:            return;                                                     \
                    394:        }                                                               \
                    395:        asi = GET_FIELD(insn, 19, 26);                                  \
                    396:        if (is_ld)                                                      \
                    397:            gen_op_ld_asi(asi, size, sign);                             \
                    398:        else                                                            \
                    399:            gen_op_st_asi(asi, size, sign);                             \
                    400:     }
                    401: 
                    402: #define supervisor(dc) (dc->mem_idx == 1)
                    403: #endif
                    404: #else
                    405: #if defined(CONFIG_USER_ONLY)
                    406: #define gen_op_ldst(name)        gen_op_##name##_raw()
                    407: #define OP_LD_TABLE(width)
                    408: #define supervisor(dc) 0
                    409: #else
                    410: #define gen_op_ldst(name)        (*gen_op_##name[dc->mem_idx])()
                    411: #define OP_LD_TABLE(width)                                                   \
                    412: static GenOpFunc *gen_op_##width[] = {                                        \
                    413:     &gen_op_##width##_user,                                                   \
                    414:     &gen_op_##width##_kernel,                                                 \
                    415: };                                                                            \
                    416:                                                                               \
                    417: static void gen_op_##width##a(int insn, int is_ld, int size, int sign)        \
                    418: {                                                                             \
                    419:     int asi;                                                                  \
                    420:                                                                               \
                    421:     asi = GET_FIELD(insn, 19, 26);                                            \
                    422:     switch (asi) {                                                            \
                    423:        case 10: /* User data access */                                       \
                    424:            gen_op_##width##_user();                                          \
                    425:            break;                                                            \
                    426:        case 11: /* Supervisor data access */                                 \
                    427:            gen_op_##width##_kernel();                                        \
                    428:            break;                                                            \
                    429:         case 0x20 ... 0x2f: /* MMU passthrough */                            \
                    430:            if (is_ld)                                                        \
                    431:                gen_op_ld_asi(asi, size, sign);                               \
                    432:            else                                                              \
                    433:                gen_op_st_asi(asi, size, sign);                               \
                    434:            break;                                                            \
                    435:        default:                                                              \
                    436:            if (is_ld)                                                        \
                    437:                gen_op_ld_asi(asi, size, sign);                               \
                    438:            else                                                              \
                    439:                gen_op_st_asi(asi, size, sign);                               \
                    440:             break;                                                            \
                    441:     }                                                                         \
                    442: }
                    443: 
                    444: #define supervisor(dc) (dc->mem_idx == 1)
                    445: #endif
                    446: #endif
                    447: 
                    448: OP_LD_TABLE(ld);
                    449: OP_LD_TABLE(st);
                    450: OP_LD_TABLE(ldub);
                    451: OP_LD_TABLE(lduh);
                    452: OP_LD_TABLE(ldsb);
                    453: OP_LD_TABLE(ldsh);
                    454: OP_LD_TABLE(stb);
                    455: OP_LD_TABLE(sth);
                    456: OP_LD_TABLE(std);
                    457: OP_LD_TABLE(ldstub);
                    458: OP_LD_TABLE(swap);
                    459: OP_LD_TABLE(ldd);
                    460: OP_LD_TABLE(stf);
                    461: OP_LD_TABLE(stdf);
                    462: OP_LD_TABLE(ldf);
                    463: OP_LD_TABLE(lddf);
                    464: 
                    465: #ifdef TARGET_SPARC64
                    466: OP_LD_TABLE(ldsw);
                    467: OP_LD_TABLE(ldx);
                    468: OP_LD_TABLE(stx);
                    469: OP_LD_TABLE(cas);
                    470: OP_LD_TABLE(casx);
                    471: #endif
                    472: 
                    473: static inline void gen_movl_imm_TN(int reg, uint32_t imm)
                    474: {
                    475:     gen_op_movl_TN_im[reg](imm);
                    476: }
                    477: 
                    478: static inline void gen_movl_imm_T1(uint32_t val)
                    479: {
                    480:     gen_movl_imm_TN(1, val);
                    481: }
                    482: 
                    483: static inline void gen_movl_imm_T0(uint32_t val)
                    484: {
                    485:     gen_movl_imm_TN(0, val);
                    486: }
                    487: 
                    488: static inline void gen_movl_simm_TN(int reg, int32_t imm)
                    489: {
                    490:     gen_op_movl_TN_sim[reg](imm);
                    491: }
                    492: 
                    493: static inline void gen_movl_simm_T1(int32_t val)
                    494: {
                    495:     gen_movl_simm_TN(1, val);
                    496: }
                    497: 
                    498: static inline void gen_movl_simm_T0(int32_t val)
                    499: {
                    500:     gen_movl_simm_TN(0, val);
                    501: }
                    502: 
                    503: static inline void gen_movl_reg_TN(int reg, int t)
                    504: {
                    505:     if (reg)
                    506:        gen_op_movl_reg_TN[t][reg] ();
                    507:     else
                    508:        gen_movl_imm_TN(t, 0);
                    509: }
                    510: 
                    511: static inline void gen_movl_reg_T0(int reg)
                    512: {
                    513:     gen_movl_reg_TN(reg, 0);
                    514: }
                    515: 
                    516: static inline void gen_movl_reg_T1(int reg)
                    517: {
                    518:     gen_movl_reg_TN(reg, 1);
                    519: }
                    520: 
                    521: static inline void gen_movl_reg_T2(int reg)
                    522: {
                    523:     gen_movl_reg_TN(reg, 2);
                    524: }
                    525: 
                    526: static inline void gen_movl_TN_reg(int reg, int t)
                    527: {
                    528:     if (reg)
                    529:        gen_op_movl_TN_reg[t][reg] ();
                    530: }
                    531: 
                    532: static inline void gen_movl_T0_reg(int reg)
                    533: {
                    534:     gen_movl_TN_reg(reg, 0);
                    535: }
                    536: 
                    537: static inline void gen_movl_T1_reg(int reg)
                    538: {
                    539:     gen_movl_TN_reg(reg, 1);
                    540: }
                    541: 
                    542: static inline void gen_jmp_im(target_ulong pc)
                    543: {
                    544: #ifdef TARGET_SPARC64
                    545:     if (pc == (uint32_t)pc) {
                    546:         gen_op_jmp_im(pc);
                    547:     } else {
                    548:         gen_op_jmp_im64(pc >> 32, pc);
                    549:     }
                    550: #else
                    551:     gen_op_jmp_im(pc);
                    552: #endif
                    553: }
                    554: 
                    555: static inline void gen_movl_npc_im(target_ulong npc)
                    556: {
                    557: #ifdef TARGET_SPARC64
                    558:     if (npc == (uint32_t)npc) {
                    559:         gen_op_movl_npc_im(npc);
                    560:     } else {
                    561:         gen_op_movq_npc_im64(npc >> 32, npc);
                    562:     }
                    563: #else
                    564:     gen_op_movl_npc_im(npc);
                    565: #endif
                    566: }
                    567: 
1.1.1.2   root      568: static inline void gen_goto_tb(DisasContext *s, int tb_num, 
                    569:                                target_ulong pc, target_ulong npc)
                    570: {
                    571:     TranslationBlock *tb;
                    572: 
                    573:     tb = s->tb;
                    574:     if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
                    575:         (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK))  {
                    576:         /* jump to same page: we can use a direct jump */
                    577:         if (tb_num == 0)
                    578:             gen_op_goto_tb0(TBPARAM(tb));
                    579:         else
                    580:             gen_op_goto_tb1(TBPARAM(tb));
                    581:         gen_jmp_im(pc);
                    582:         gen_movl_npc_im(npc);
                    583:         gen_op_movl_T0_im((long)tb + tb_num);
                    584:         gen_op_exit_tb();
                    585:     } else {
                    586:         /* jump to another page: currently not optimized */
                    587:         gen_jmp_im(pc);
                    588:         gen_movl_npc_im(npc);
                    589:         gen_op_movl_T0_0();
                    590:         gen_op_exit_tb();
                    591:     }
                    592: }
                    593: 
1.1       root      594: static inline void gen_branch2(DisasContext *dc, long tb, target_ulong pc1, target_ulong pc2)
                    595: {
                    596:     int l1;
                    597: 
                    598:     l1 = gen_new_label();
                    599: 
                    600:     gen_op_jz_T2_label(l1);
                    601: 
1.1.1.2   root      602:     gen_goto_tb(dc, 0, pc1, pc1 + 4);
1.1       root      603: 
                    604:     gen_set_label(l1);
1.1.1.2   root      605:     gen_goto_tb(dc, 1, pc2, pc2 + 4);
1.1       root      606: }
                    607: 
                    608: static inline void gen_branch_a(DisasContext *dc, long tb, target_ulong pc1, target_ulong pc2)
                    609: {
                    610:     int l1;
                    611: 
                    612:     l1 = gen_new_label();
                    613: 
                    614:     gen_op_jz_T2_label(l1);
                    615: 
1.1.1.2   root      616:     gen_goto_tb(dc, 0, pc2, pc1);
1.1       root      617: 
                    618:     gen_set_label(l1);
1.1.1.2   root      619:     gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
1.1       root      620: }
                    621: 
                    622: static inline void gen_branch(DisasContext *dc, long tb, target_ulong pc, target_ulong npc)
                    623: {
1.1.1.2   root      624:     gen_goto_tb(dc, 0, pc, npc);
1.1       root      625: }
                    626: 
                    627: static inline void gen_generic_branch(DisasContext *dc, target_ulong npc1, target_ulong npc2)
                    628: {
                    629:     int l1, l2;
                    630: 
                    631:     l1 = gen_new_label();
                    632:     l2 = gen_new_label();
                    633:     gen_op_jz_T2_label(l1);
                    634: 
                    635:     gen_movl_npc_im(npc1);
                    636:     gen_op_jmp_label(l2);
                    637: 
                    638:     gen_set_label(l1);
                    639:     gen_movl_npc_im(npc2);
                    640:     gen_set_label(l2);
                    641: }
                    642: 
                    643: /* call this function before using T2 as it may have been set for a jump */
                    644: static inline void flush_T2(DisasContext * dc)
                    645: {
                    646:     if (dc->npc == JUMP_PC) {
                    647:         gen_generic_branch(dc, dc->jump_pc[0], dc->jump_pc[1]);
                    648:         dc->npc = DYNAMIC_PC;
                    649:     }
                    650: }
                    651: 
                    652: static inline void save_npc(DisasContext * dc)
                    653: {
                    654:     if (dc->npc == JUMP_PC) {
                    655:         gen_generic_branch(dc, dc->jump_pc[0], dc->jump_pc[1]);
                    656:         dc->npc = DYNAMIC_PC;
                    657:     } else if (dc->npc != DYNAMIC_PC) {
                    658:         gen_movl_npc_im(dc->npc);
                    659:     }
                    660: }
                    661: 
                    662: static inline void save_state(DisasContext * dc)
                    663: {
                    664:     gen_jmp_im(dc->pc);
                    665:     save_npc(dc);
                    666: }
                    667: 
                    668: static inline void gen_mov_pc_npc(DisasContext * dc)
                    669: {
                    670:     if (dc->npc == JUMP_PC) {
                    671:         gen_generic_branch(dc, dc->jump_pc[0], dc->jump_pc[1]);
                    672:         gen_op_mov_pc_npc();
                    673:         dc->pc = DYNAMIC_PC;
                    674:     } else if (dc->npc == DYNAMIC_PC) {
                    675:         gen_op_mov_pc_npc();
                    676:         dc->pc = DYNAMIC_PC;
                    677:     } else {
                    678:         dc->pc = dc->npc;
                    679:     }
                    680: }
                    681: 
                    682: static GenOpFunc * const gen_cond[2][16] = {
                    683:     {
                    684:        gen_op_eval_ba,
                    685:        gen_op_eval_be,
                    686:        gen_op_eval_ble,
                    687:        gen_op_eval_bl,
                    688:        gen_op_eval_bleu,
                    689:        gen_op_eval_bcs,
                    690:        gen_op_eval_bneg,
                    691:        gen_op_eval_bvs,
                    692:        gen_op_eval_bn,
                    693:        gen_op_eval_bne,
                    694:        gen_op_eval_bg,
                    695:        gen_op_eval_bge,
                    696:        gen_op_eval_bgu,
                    697:        gen_op_eval_bcc,
                    698:        gen_op_eval_bpos,
                    699:        gen_op_eval_bvc,
                    700:     },
                    701:     {
                    702: #ifdef TARGET_SPARC64
                    703:        gen_op_eval_ba,
                    704:        gen_op_eval_xbe,
                    705:        gen_op_eval_xble,
                    706:        gen_op_eval_xbl,
                    707:        gen_op_eval_xbleu,
                    708:        gen_op_eval_xbcs,
                    709:        gen_op_eval_xbneg,
                    710:        gen_op_eval_xbvs,
                    711:        gen_op_eval_bn,
                    712:        gen_op_eval_xbne,
                    713:        gen_op_eval_xbg,
                    714:        gen_op_eval_xbge,
                    715:        gen_op_eval_xbgu,
                    716:        gen_op_eval_xbcc,
                    717:        gen_op_eval_xbpos,
                    718:        gen_op_eval_xbvc,
                    719: #endif
                    720:     },
                    721: };
                    722: 
                    723: static GenOpFunc * const gen_fcond[4][16] = {
                    724:     {
                    725:        gen_op_eval_ba,
                    726:        gen_op_eval_fbne,
                    727:        gen_op_eval_fblg,
                    728:        gen_op_eval_fbul,
                    729:        gen_op_eval_fbl,
                    730:        gen_op_eval_fbug,
                    731:        gen_op_eval_fbg,
                    732:        gen_op_eval_fbu,
                    733:        gen_op_eval_bn,
                    734:        gen_op_eval_fbe,
                    735:        gen_op_eval_fbue,
                    736:        gen_op_eval_fbge,
                    737:        gen_op_eval_fbuge,
                    738:        gen_op_eval_fble,
                    739:        gen_op_eval_fbule,
                    740:        gen_op_eval_fbo,
                    741:     },
                    742: #ifdef TARGET_SPARC64
                    743:     {
                    744:        gen_op_eval_ba,
                    745:        gen_op_eval_fbne_fcc1,
                    746:        gen_op_eval_fblg_fcc1,
                    747:        gen_op_eval_fbul_fcc1,
                    748:        gen_op_eval_fbl_fcc1,
                    749:        gen_op_eval_fbug_fcc1,
                    750:        gen_op_eval_fbg_fcc1,
                    751:        gen_op_eval_fbu_fcc1,
                    752:        gen_op_eval_bn,
                    753:        gen_op_eval_fbe_fcc1,
                    754:        gen_op_eval_fbue_fcc1,
                    755:        gen_op_eval_fbge_fcc1,
                    756:        gen_op_eval_fbuge_fcc1,
                    757:        gen_op_eval_fble_fcc1,
                    758:        gen_op_eval_fbule_fcc1,
                    759:        gen_op_eval_fbo_fcc1,
                    760:     },
                    761:     {
                    762:        gen_op_eval_ba,
                    763:        gen_op_eval_fbne_fcc2,
                    764:        gen_op_eval_fblg_fcc2,
                    765:        gen_op_eval_fbul_fcc2,
                    766:        gen_op_eval_fbl_fcc2,
                    767:        gen_op_eval_fbug_fcc2,
                    768:        gen_op_eval_fbg_fcc2,
                    769:        gen_op_eval_fbu_fcc2,
                    770:        gen_op_eval_bn,
                    771:        gen_op_eval_fbe_fcc2,
                    772:        gen_op_eval_fbue_fcc2,
                    773:        gen_op_eval_fbge_fcc2,
                    774:        gen_op_eval_fbuge_fcc2,
                    775:        gen_op_eval_fble_fcc2,
                    776:        gen_op_eval_fbule_fcc2,
                    777:        gen_op_eval_fbo_fcc2,
                    778:     },
                    779:     {
                    780:        gen_op_eval_ba,
                    781:        gen_op_eval_fbne_fcc3,
                    782:        gen_op_eval_fblg_fcc3,
                    783:        gen_op_eval_fbul_fcc3,
                    784:        gen_op_eval_fbl_fcc3,
                    785:        gen_op_eval_fbug_fcc3,
                    786:        gen_op_eval_fbg_fcc3,
                    787:        gen_op_eval_fbu_fcc3,
                    788:        gen_op_eval_bn,
                    789:        gen_op_eval_fbe_fcc3,
                    790:        gen_op_eval_fbue_fcc3,
                    791:        gen_op_eval_fbge_fcc3,
                    792:        gen_op_eval_fbuge_fcc3,
                    793:        gen_op_eval_fble_fcc3,
                    794:        gen_op_eval_fbule_fcc3,
                    795:        gen_op_eval_fbo_fcc3,
                    796:     },
                    797: #else
                    798:     {}, {}, {},
                    799: #endif
                    800: };
                    801: 
                    802: #ifdef TARGET_SPARC64
                    803: static void gen_cond_reg(int cond)
                    804: {
                    805:        switch (cond) {
                    806:        case 0x1:
                    807:            gen_op_eval_brz();
                    808:            break;
                    809:        case 0x2:
                    810:            gen_op_eval_brlez();
                    811:            break;
                    812:        case 0x3:
                    813:            gen_op_eval_brlz();
                    814:            break;
                    815:        case 0x5:
                    816:            gen_op_eval_brnz();
                    817:            break;
                    818:        case 0x6:
                    819:            gen_op_eval_brgz();
                    820:            break;
                    821:         default:
                    822:        case 0x7:
                    823:            gen_op_eval_brgez();
                    824:            break;
                    825:        }
                    826: }
                    827: #endif
                    828: 
                    829: /* XXX: potentially incorrect if dynamic npc */
                    830: static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
                    831: {
                    832:     unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
                    833:     target_ulong target = dc->pc + offset;
                    834:        
                    835:     if (cond == 0x0) {
                    836:        /* unconditional not taken */
                    837:        if (a) {
                    838:            dc->pc = dc->npc + 4; 
                    839:            dc->npc = dc->pc + 4;
                    840:        } else {
                    841:            dc->pc = dc->npc;
                    842:            dc->npc = dc->pc + 4;
                    843:        }
                    844:     } else if (cond == 0x8) {
                    845:        /* unconditional taken */
                    846:        if (a) {
                    847:            dc->pc = target;
                    848:            dc->npc = dc->pc + 4;
                    849:        } else {
                    850:            dc->pc = dc->npc;
                    851:            dc->npc = target;
                    852:        }
                    853:     } else {
                    854:         flush_T2(dc);
                    855:         gen_cond[cc][cond]();
                    856:        if (a) {
                    857:            gen_branch_a(dc, (long)dc->tb, target, dc->npc);
                    858:             dc->is_br = 1;
                    859:        } else {
                    860:             dc->pc = dc->npc;
                    861:             dc->jump_pc[0] = target;
                    862:             dc->jump_pc[1] = dc->npc + 4;
                    863:             dc->npc = JUMP_PC;
                    864:        }
                    865:     }
                    866: }
                    867: 
                    868: /* XXX: potentially incorrect if dynamic npc */
                    869: static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
                    870: {
                    871:     unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
                    872:     target_ulong target = dc->pc + offset;
                    873: 
                    874:     if (cond == 0x0) {
                    875:        /* unconditional not taken */
                    876:        if (a) {
                    877:            dc->pc = dc->npc + 4;
                    878:            dc->npc = dc->pc + 4;
                    879:        } else {
                    880:            dc->pc = dc->npc;
                    881:            dc->npc = dc->pc + 4;
                    882:        }
                    883:     } else if (cond == 0x8) {
                    884:        /* unconditional taken */
                    885:        if (a) {
                    886:            dc->pc = target;
                    887:            dc->npc = dc->pc + 4;
                    888:        } else {
                    889:            dc->pc = dc->npc;
                    890:            dc->npc = target;
                    891:        }
                    892:     } else {
                    893:         flush_T2(dc);
                    894:         gen_fcond[cc][cond]();
                    895:        if (a) {
                    896:            gen_branch_a(dc, (long)dc->tb, target, dc->npc);
                    897:             dc->is_br = 1;
                    898:        } else {
                    899:             dc->pc = dc->npc;
                    900:             dc->jump_pc[0] = target;
                    901:             dc->jump_pc[1] = dc->npc + 4;
                    902:             dc->npc = JUMP_PC;
                    903:        }
                    904:     }
                    905: }
                    906: 
                    907: #ifdef TARGET_SPARC64
                    908: /* XXX: potentially incorrect if dynamic npc */
                    909: static void do_branch_reg(DisasContext * dc, int32_t offset, uint32_t insn)
                    910: {
                    911:     unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
                    912:     target_ulong target = dc->pc + offset;
                    913: 
                    914:     flush_T2(dc);
                    915:     gen_cond_reg(cond);
                    916:     if (a) {
                    917:        gen_branch_a(dc, (long)dc->tb, target, dc->npc);
                    918:        dc->is_br = 1;
                    919:     } else {
                    920:        dc->pc = dc->npc;
                    921:        dc->jump_pc[0] = target;
                    922:        dc->jump_pc[1] = dc->npc + 4;
                    923:        dc->npc = JUMP_PC;
                    924:     }
                    925: }
                    926: 
                    927: static GenOpFunc * const gen_fcmps[4] = {
                    928:     gen_op_fcmps,
                    929:     gen_op_fcmps_fcc1,
                    930:     gen_op_fcmps_fcc2,
                    931:     gen_op_fcmps_fcc3,
                    932: };
                    933: 
                    934: static GenOpFunc * const gen_fcmpd[4] = {
                    935:     gen_op_fcmpd,
                    936:     gen_op_fcmpd_fcc1,
                    937:     gen_op_fcmpd_fcc2,
                    938:     gen_op_fcmpd_fcc3,
                    939: };
                    940: #endif
                    941: 
1.1.1.3 ! root      942: static int gen_trap_ifnofpu(DisasContext * dc)
        !           943: {
        !           944: #if !defined(CONFIG_USER_ONLY)
        !           945:     if (!dc->fpu_enabled) {
        !           946:         save_state(dc);
        !           947:         gen_op_exception(TT_NFPU_INSN);
        !           948:         dc->is_br = 1;
        !           949:         return 1;
        !           950:     }
        !           951: #endif
        !           952:     return 0;
        !           953: }
        !           954: 
1.1       root      955: /* before an instruction, dc->pc must be static */
                    956: static void disas_sparc_insn(DisasContext * dc)
                    957: {
                    958:     unsigned int insn, opc, rs1, rs2, rd;
                    959: 
                    960:     insn = ldl_code(dc->pc);
                    961:     opc = GET_FIELD(insn, 0, 1);
                    962: 
                    963:     rd = GET_FIELD(insn, 2, 6);
                    964:     switch (opc) {
                    965:     case 0:                    /* branches/sethi */
                    966:        {
                    967:            unsigned int xop = GET_FIELD(insn, 7, 9);
                    968:            int32_t target;
                    969:            switch (xop) {
                    970: #ifdef TARGET_SPARC64
                    971:            case 0x1:           /* V9 BPcc */
                    972:                {
                    973:                    int cc;
                    974: 
                    975:                    target = GET_FIELD_SP(insn, 0, 18);
                    976:                    target = sign_extend(target, 18);
1.1.1.3 ! root      977:                    target <<= 2;
1.1       root      978:                    cc = GET_FIELD_SP(insn, 20, 21);
                    979:                    if (cc == 0)
                    980:                        do_branch(dc, target, insn, 0);
                    981:                    else if (cc == 2)
                    982:                        do_branch(dc, target, insn, 1);
                    983:                    else
                    984:                        goto illegal_insn;
                    985:                    goto jmp_insn;
                    986:                }
                    987:            case 0x3:           /* V9 BPr */
                    988:                {
                    989:                    target = GET_FIELD_SP(insn, 0, 13) | 
1.1.1.3 ! root      990:                         (GET_FIELD_SP(insn, 20, 21) << 14);
1.1       root      991:                    target = sign_extend(target, 16);
1.1.1.3 ! root      992:                    target <<= 2;
1.1       root      993:                    rs1 = GET_FIELD(insn, 13, 17);
                    994:                    gen_movl_reg_T0(rs1);
                    995:                    do_branch_reg(dc, target, insn);
                    996:                    goto jmp_insn;
                    997:                }
                    998:            case 0x5:           /* V9 FBPcc */
                    999:                {
                   1000:                    int cc = GET_FIELD_SP(insn, 20, 21);
1.1.1.3 ! root     1001:                     if (gen_trap_ifnofpu(dc))
        !          1002:                         goto jmp_insn;
1.1       root     1003:                    target = GET_FIELD_SP(insn, 0, 18);
                   1004:                    target = sign_extend(target, 19);
1.1.1.3 ! root     1005:                    target <<= 2;
1.1       root     1006:                    do_fbranch(dc, target, insn, cc);
                   1007:                    goto jmp_insn;
                   1008:                }
                   1009: #endif
                   1010:            case 0x2:           /* BN+x */
                   1011:                {
                   1012:                    target = GET_FIELD(insn, 10, 31);
                   1013:                    target = sign_extend(target, 22);
1.1.1.3 ! root     1014:                    target <<= 2;
1.1       root     1015:                    do_branch(dc, target, insn, 0);
                   1016:                    goto jmp_insn;
                   1017:                }
                   1018:            case 0x6:           /* FBN+x */
                   1019:                {
1.1.1.3 ! root     1020:                     if (gen_trap_ifnofpu(dc))
        !          1021:                         goto jmp_insn;
1.1       root     1022:                    target = GET_FIELD(insn, 10, 31);
                   1023:                    target = sign_extend(target, 22);
1.1.1.3 ! root     1024:                    target <<= 2;
1.1       root     1025:                    do_fbranch(dc, target, insn, 0);
                   1026:                    goto jmp_insn;
                   1027:                }
                   1028:            case 0x4:           /* SETHI */
                   1029: #define OPTIM
                   1030: #if defined(OPTIM)
                   1031:                if (rd) { // nop
                   1032: #endif
                   1033:                    uint32_t value = GET_FIELD(insn, 10, 31);
                   1034:                    gen_movl_imm_T0(value << 10);
                   1035:                    gen_movl_T0_reg(rd);
                   1036: #if defined(OPTIM)
                   1037:                }
                   1038: #endif
                   1039:                break;
                   1040:            case 0x0:           /* UNIMPL */
                   1041:            default:
                   1042:                 goto illegal_insn;
                   1043:            }
                   1044:            break;
                   1045:        }
                   1046:        break;
                   1047:     case 1:
                   1048:        /*CALL*/ {
                   1049:            target_long target = GET_FIELDs(insn, 2, 31) << 2;
                   1050: 
                   1051: #ifdef TARGET_SPARC64
                   1052:            if (dc->pc == (uint32_t)dc->pc) {
                   1053:                gen_op_movl_T0_im(dc->pc);
                   1054:            } else {
                   1055:                gen_op_movq_T0_im64(dc->pc >> 32, dc->pc);
                   1056:            }
                   1057: #else
                   1058:            gen_op_movl_T0_im(dc->pc);
                   1059: #endif
                   1060:            gen_movl_T0_reg(15);
                   1061:            target += dc->pc;
                   1062:             gen_mov_pc_npc(dc);
                   1063:            dc->npc = target;
                   1064:        }
                   1065:        goto jmp_insn;
                   1066:     case 2:                    /* FPU & Logical Operations */
                   1067:        {
                   1068:            unsigned int xop = GET_FIELD(insn, 7, 12);
                   1069:            if (xop == 0x3a) {  /* generate trap */
                   1070:                 int cond;
                   1071: 
                   1072:                 rs1 = GET_FIELD(insn, 13, 17);
                   1073:                 gen_movl_reg_T0(rs1);
                   1074:                if (IS_IMM) {
                   1075:                    rs2 = GET_FIELD(insn, 25, 31);
                   1076: #if defined(OPTIM)
                   1077:                    if (rs2 != 0) {
                   1078: #endif
                   1079:                        gen_movl_simm_T1(rs2);
                   1080:                        gen_op_add_T1_T0();
                   1081: #if defined(OPTIM)
                   1082:                    }
                   1083: #endif
                   1084:                 } else {
                   1085:                     rs2 = GET_FIELD(insn, 27, 31);
                   1086: #if defined(OPTIM)
                   1087:                    if (rs2 != 0) {
                   1088: #endif
                   1089:                        gen_movl_reg_T1(rs2);
                   1090:                        gen_op_add_T1_T0();
                   1091: #if defined(OPTIM)
                   1092:                    }
                   1093: #endif
                   1094:                 }
                   1095:                 cond = GET_FIELD(insn, 3, 6);
                   1096:                 if (cond == 0x8) {
1.1.1.3 ! root     1097:                     save_state(dc);
1.1       root     1098:                     gen_op_trap_T0();
                   1099:                 } else if (cond != 0) {
                   1100: #ifdef TARGET_SPARC64
                   1101:                    /* V9 icc/xcc */
                   1102:                    int cc = GET_FIELD_SP(insn, 11, 12);
1.1.1.3 ! root     1103:                    flush_T2(dc);
        !          1104:                     save_state(dc);
1.1       root     1105:                    if (cc == 0)
                   1106:                        gen_cond[0][cond]();
                   1107:                    else if (cc == 2)
                   1108:                        gen_cond[1][cond]();
                   1109:                    else
                   1110:                        goto illegal_insn;
                   1111: #else
1.1.1.3 ! root     1112:                    flush_T2(dc);
        !          1113:                     save_state(dc);
1.1       root     1114:                    gen_cond[0][cond]();
                   1115: #endif
                   1116:                     gen_op_trapcc_T0();
                   1117:                 }
1.1.1.3 ! root     1118:                 gen_op_next_insn();
        !          1119:                 gen_op_movl_T0_0();
        !          1120:                 gen_op_exit_tb();
        !          1121:                 dc->is_br = 1;
        !          1122:                 goto jmp_insn;
1.1       root     1123:             } else if (xop == 0x28) {
                   1124:                 rs1 = GET_FIELD(insn, 13, 17);
                   1125:                 switch(rs1) {
                   1126:                 case 0: /* rdy */
                   1127:                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, y));
                   1128:                     gen_movl_T0_reg(rd);
                   1129:                     break;
                   1130:                 case 15: /* stbar / V9 membar */
                   1131:                    break; /* no effect? */
                   1132: #ifdef TARGET_SPARC64
                   1133:                case 0x2: /* V9 rdccr */
                   1134:                     gen_op_rdccr();
                   1135:                     gen_movl_T0_reg(rd);
                   1136:                     break;
                   1137:                case 0x3: /* V9 rdasi */
                   1138:                    gen_op_movl_T0_env(offsetof(CPUSPARCState, asi));
                   1139:                     gen_movl_T0_reg(rd);
                   1140:                     break;
                   1141:                case 0x4: /* V9 rdtick */
                   1142:                     gen_op_rdtick();
                   1143:                     gen_movl_T0_reg(rd);
                   1144:                     break;
                   1145:                case 0x5: /* V9 rdpc */
1.1.1.3 ! root     1146:                    if (dc->pc == (uint32_t)dc->pc) {
        !          1147:                        gen_op_movl_T0_im(dc->pc);
        !          1148:                    } else {
        !          1149:                        gen_op_movq_T0_im64(dc->pc >> 32, dc->pc);
        !          1150:                    }
1.1       root     1151:                    gen_movl_T0_reg(rd);
                   1152:                    break;
                   1153:                case 0x6: /* V9 rdfprs */
                   1154:                    gen_op_movl_T0_env(offsetof(CPUSPARCState, fprs));
                   1155:                     gen_movl_T0_reg(rd);
                   1156:                     break;
1.1.1.3 ! root     1157:                case 0x13: /* Graphics Status */
        !          1158:                     if (gen_trap_ifnofpu(dc))
        !          1159:                         goto jmp_insn;
        !          1160:                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, gsr));
        !          1161:                     gen_movl_T0_reg(rd);
        !          1162:                     break;
1.1       root     1163:                case 0x17: /* Tick compare */
                   1164:                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, tick_cmpr));
                   1165:                     gen_movl_T0_reg(rd);
                   1166:                     break;
                   1167:                case 0x18: /* System tick */
                   1168:                     gen_op_rdtick(); // XXX
                   1169:                     gen_movl_T0_reg(rd);
                   1170:                     break;
                   1171:                case 0x19: /* System tick compare */
                   1172:                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, stick_cmpr));
                   1173:                     gen_movl_T0_reg(rd);
                   1174:                     break;
                   1175:                case 0x10: /* Performance Control */
                   1176:                case 0x11: /* Performance Instrumentation Counter */
                   1177:                case 0x12: /* Dispatch Control */
                   1178:                case 0x14: /* Softint set, WO */
                   1179:                case 0x15: /* Softint clear, WO */
                   1180:                case 0x16: /* Softint write */
                   1181: #endif
                   1182:                 default:
                   1183:                     goto illegal_insn;
                   1184:                 }
                   1185: #if !defined(CONFIG_USER_ONLY)
                   1186: #ifndef TARGET_SPARC64
                   1187:             } else if (xop == 0x29) { /* rdpsr / V9 unimp */
                   1188:                if (!supervisor(dc))
                   1189:                    goto priv_insn;
                   1190:                 gen_op_rdpsr();
                   1191:                 gen_movl_T0_reg(rd);
                   1192:                 break;
                   1193: #endif
                   1194:             } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
                   1195:                if (!supervisor(dc))
                   1196:                    goto priv_insn;
                   1197: #ifdef TARGET_SPARC64
                   1198:                 rs1 = GET_FIELD(insn, 13, 17);
                   1199:                switch (rs1) {
                   1200:                case 0: // tpc
                   1201:                    gen_op_rdtpc();
                   1202:                    break;
                   1203:                case 1: // tnpc
                   1204:                    gen_op_rdtnpc();
                   1205:                    break;
                   1206:                case 2: // tstate
                   1207:                    gen_op_rdtstate();
                   1208:                    break;
                   1209:                case 3: // tt
                   1210:                    gen_op_rdtt();
                   1211:                    break;
                   1212:                case 4: // tick
                   1213:                    gen_op_rdtick();
                   1214:                    break;
                   1215:                case 5: // tba
                   1216:                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr));
                   1217:                    break;
                   1218:                case 6: // pstate
                   1219:                    gen_op_rdpstate();
                   1220:                    break;
                   1221:                case 7: // tl
                   1222:                    gen_op_movl_T0_env(offsetof(CPUSPARCState, tl));
                   1223:                    break;
                   1224:                case 8: // pil
                   1225:                    gen_op_movl_T0_env(offsetof(CPUSPARCState, psrpil));
                   1226:                    break;
                   1227:                case 9: // cwp
                   1228:                    gen_op_rdcwp();
                   1229:                    break;
                   1230:                case 10: // cansave
                   1231:                    gen_op_movl_T0_env(offsetof(CPUSPARCState, cansave));
                   1232:                    break;
                   1233:                case 11: // canrestore
                   1234:                    gen_op_movl_T0_env(offsetof(CPUSPARCState, canrestore));
                   1235:                    break;
                   1236:                case 12: // cleanwin
                   1237:                    gen_op_movl_T0_env(offsetof(CPUSPARCState, cleanwin));
                   1238:                    break;
                   1239:                case 13: // otherwin
                   1240:                    gen_op_movl_T0_env(offsetof(CPUSPARCState, otherwin));
                   1241:                    break;
                   1242:                case 14: // wstate
                   1243:                    gen_op_movl_T0_env(offsetof(CPUSPARCState, wstate));
                   1244:                    break;
                   1245:                case 31: // ver
                   1246:                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, version));
                   1247:                    break;
                   1248:                case 15: // fq
                   1249:                default:
                   1250:                    goto illegal_insn;
                   1251:                }
                   1252: #else
                   1253:                gen_op_movl_T0_env(offsetof(CPUSPARCState, wim));
                   1254: #endif
                   1255:                 gen_movl_T0_reg(rd);
                   1256:                 break;
                   1257:             } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
                   1258: #ifdef TARGET_SPARC64
                   1259:                gen_op_flushw();
                   1260: #else
                   1261:                if (!supervisor(dc))
                   1262:                    goto priv_insn;
                   1263:                gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr));
                   1264:                 gen_movl_T0_reg(rd);
                   1265: #endif
                   1266:                 break;
                   1267: #endif
                   1268:            } else if (xop == 0x34) {   /* FPU Operations */
1.1.1.3 ! root     1269:                 if (gen_trap_ifnofpu(dc))
        !          1270:                     goto jmp_insn;
1.1       root     1271:                 rs1 = GET_FIELD(insn, 13, 17);
                   1272:                rs2 = GET_FIELD(insn, 27, 31);
                   1273:                xop = GET_FIELD(insn, 18, 26);
                   1274:                switch (xop) {
                   1275:                    case 0x1: /* fmovs */
                   1276:                        gen_op_load_fpr_FT0(rs2);
                   1277:                        gen_op_store_FT0_fpr(rd);
                   1278:                        break;
                   1279:                    case 0x5: /* fnegs */
                   1280:                        gen_op_load_fpr_FT1(rs2);
                   1281:                        gen_op_fnegs();
                   1282:                        gen_op_store_FT0_fpr(rd);
                   1283:                        break;
                   1284:                    case 0x9: /* fabss */
                   1285:                        gen_op_load_fpr_FT1(rs2);
                   1286:                        gen_op_fabss();
                   1287:                        gen_op_store_FT0_fpr(rd);
                   1288:                        break;
                   1289:                    case 0x29: /* fsqrts */
                   1290:                        gen_op_load_fpr_FT1(rs2);
                   1291:                        gen_op_fsqrts();
                   1292:                        gen_op_store_FT0_fpr(rd);
                   1293:                        break;
                   1294:                    case 0x2a: /* fsqrtd */
                   1295:                        gen_op_load_fpr_DT1(DFPREG(rs2));
                   1296:                        gen_op_fsqrtd();
                   1297:                        gen_op_store_DT0_fpr(DFPREG(rd));
                   1298:                        break;
                   1299:                    case 0x2b: /* fsqrtq */
                   1300:                        goto nfpu_insn;
                   1301:                    case 0x41:
                   1302:                        gen_op_load_fpr_FT0(rs1);
                   1303:                        gen_op_load_fpr_FT1(rs2);
                   1304:                        gen_op_fadds();
                   1305:                        gen_op_store_FT0_fpr(rd);
                   1306:                        break;
                   1307:                    case 0x42:
                   1308:                        gen_op_load_fpr_DT0(DFPREG(rs1));
                   1309:                        gen_op_load_fpr_DT1(DFPREG(rs2));
                   1310:                        gen_op_faddd();
                   1311:                        gen_op_store_DT0_fpr(DFPREG(rd));
                   1312:                        break;
                   1313:                    case 0x43: /* faddq */
                   1314:                        goto nfpu_insn;
                   1315:                    case 0x45:
                   1316:                        gen_op_load_fpr_FT0(rs1);
                   1317:                        gen_op_load_fpr_FT1(rs2);
                   1318:                        gen_op_fsubs();
                   1319:                        gen_op_store_FT0_fpr(rd);
                   1320:                        break;
                   1321:                    case 0x46:
                   1322:                        gen_op_load_fpr_DT0(DFPREG(rs1));
                   1323:                        gen_op_load_fpr_DT1(DFPREG(rs2));
                   1324:                        gen_op_fsubd();
                   1325:                        gen_op_store_DT0_fpr(DFPREG(rd));
                   1326:                        break;
                   1327:                    case 0x47: /* fsubq */
                   1328:                        goto nfpu_insn;
                   1329:                    case 0x49:
                   1330:                        gen_op_load_fpr_FT0(rs1);
                   1331:                        gen_op_load_fpr_FT1(rs2);
                   1332:                        gen_op_fmuls();
                   1333:                        gen_op_store_FT0_fpr(rd);
                   1334:                        break;
                   1335:                    case 0x4a:
                   1336:                        gen_op_load_fpr_DT0(DFPREG(rs1));
                   1337:                        gen_op_load_fpr_DT1(DFPREG(rs2));
                   1338:                        gen_op_fmuld();
                   1339:                        gen_op_store_DT0_fpr(rd);
                   1340:                        break;
                   1341:                    case 0x4b: /* fmulq */
                   1342:                        goto nfpu_insn;
                   1343:                    case 0x4d:
                   1344:                        gen_op_load_fpr_FT0(rs1);
                   1345:                        gen_op_load_fpr_FT1(rs2);
                   1346:                        gen_op_fdivs();
                   1347:                        gen_op_store_FT0_fpr(rd);
                   1348:                        break;
                   1349:                    case 0x4e:
                   1350:                        gen_op_load_fpr_DT0(DFPREG(rs1));
                   1351:                        gen_op_load_fpr_DT1(DFPREG(rs2));
                   1352:                        gen_op_fdivd();
                   1353:                        gen_op_store_DT0_fpr(DFPREG(rd));
                   1354:                        break;
                   1355:                    case 0x4f: /* fdivq */
                   1356:                        goto nfpu_insn;
                   1357:                    case 0x69:
                   1358:                        gen_op_load_fpr_FT0(rs1);
                   1359:                        gen_op_load_fpr_FT1(rs2);
                   1360:                        gen_op_fsmuld();
                   1361:                        gen_op_store_DT0_fpr(DFPREG(rd));
                   1362:                        break;
                   1363:                    case 0x6e: /* fdmulq */
                   1364:                        goto nfpu_insn;
                   1365:                    case 0xc4:
                   1366:                        gen_op_load_fpr_FT1(rs2);
                   1367:                        gen_op_fitos();
                   1368:                        gen_op_store_FT0_fpr(rd);
                   1369:                        break;
                   1370:                    case 0xc6:
                   1371:                        gen_op_load_fpr_DT1(DFPREG(rs2));
                   1372:                        gen_op_fdtos();
                   1373:                        gen_op_store_FT0_fpr(rd);
                   1374:                        break;
                   1375:                    case 0xc7: /* fqtos */
                   1376:                        goto nfpu_insn;
                   1377:                    case 0xc8:
                   1378:                        gen_op_load_fpr_FT1(rs2);
                   1379:                        gen_op_fitod();
                   1380:                        gen_op_store_DT0_fpr(DFPREG(rd));
                   1381:                        break;
                   1382:                    case 0xc9:
                   1383:                        gen_op_load_fpr_FT1(rs2);
                   1384:                        gen_op_fstod();
                   1385:                        gen_op_store_DT0_fpr(DFPREG(rd));
                   1386:                        break;
                   1387:                    case 0xcb: /* fqtod */
                   1388:                        goto nfpu_insn;
                   1389:                    case 0xcc: /* fitoq */
                   1390:                        goto nfpu_insn;
                   1391:                    case 0xcd: /* fstoq */
                   1392:                        goto nfpu_insn;
                   1393:                    case 0xce: /* fdtoq */
                   1394:                        goto nfpu_insn;
                   1395:                    case 0xd1:
                   1396:                        gen_op_load_fpr_FT1(rs2);
                   1397:                        gen_op_fstoi();
                   1398:                        gen_op_store_FT0_fpr(rd);
                   1399:                        break;
                   1400:                    case 0xd2:
                   1401:                        gen_op_load_fpr_DT1(rs2);
                   1402:                        gen_op_fdtoi();
                   1403:                        gen_op_store_FT0_fpr(rd);
                   1404:                        break;
                   1405:                    case 0xd3: /* fqtoi */
                   1406:                        goto nfpu_insn;
                   1407: #ifdef TARGET_SPARC64
                   1408:                    case 0x2: /* V9 fmovd */
                   1409:                        gen_op_load_fpr_DT0(DFPREG(rs2));
                   1410:                        gen_op_store_DT0_fpr(DFPREG(rd));
                   1411:                        break;
                   1412:                    case 0x6: /* V9 fnegd */
                   1413:                        gen_op_load_fpr_DT1(DFPREG(rs2));
                   1414:                        gen_op_fnegd();
                   1415:                        gen_op_store_DT0_fpr(DFPREG(rd));
                   1416:                        break;
                   1417:                    case 0xa: /* V9 fabsd */
                   1418:                        gen_op_load_fpr_DT1(DFPREG(rs2));
                   1419:                        gen_op_fabsd();
                   1420:                        gen_op_store_DT0_fpr(DFPREG(rd));
                   1421:                        break;
                   1422:                    case 0x81: /* V9 fstox */
                   1423:                        gen_op_load_fpr_FT1(rs2);
                   1424:                        gen_op_fstox();
                   1425:                        gen_op_store_DT0_fpr(DFPREG(rd));
                   1426:                        break;
                   1427:                    case 0x82: /* V9 fdtox */
                   1428:                        gen_op_load_fpr_DT1(DFPREG(rs2));
                   1429:                        gen_op_fdtox();
                   1430:                        gen_op_store_DT0_fpr(DFPREG(rd));
                   1431:                        break;
                   1432:                    case 0x84: /* V9 fxtos */
                   1433:                        gen_op_load_fpr_DT1(DFPREG(rs2));
                   1434:                        gen_op_fxtos();
                   1435:                        gen_op_store_FT0_fpr(rd);
                   1436:                        break;
                   1437:                    case 0x88: /* V9 fxtod */
                   1438:                        gen_op_load_fpr_DT1(DFPREG(rs2));
                   1439:                        gen_op_fxtod();
                   1440:                        gen_op_store_DT0_fpr(DFPREG(rd));
                   1441:                        break;
                   1442:                    case 0x3: /* V9 fmovq */
                   1443:                    case 0x7: /* V9 fnegq */
                   1444:                    case 0xb: /* V9 fabsq */
                   1445:                    case 0x83: /* V9 fqtox */
                   1446:                    case 0x8c: /* V9 fxtoq */
                   1447:                        goto nfpu_insn;
                   1448: #endif
                   1449:                    default:
                   1450:                        goto illegal_insn;
                   1451:                }
                   1452:            } else if (xop == 0x35) {   /* FPU Operations */
                   1453: #ifdef TARGET_SPARC64
                   1454:                int cond;
                   1455: #endif
1.1.1.3 ! root     1456:                 if (gen_trap_ifnofpu(dc))
        !          1457:                     goto jmp_insn;
1.1       root     1458:                 rs1 = GET_FIELD(insn, 13, 17);
                   1459:                rs2 = GET_FIELD(insn, 27, 31);
                   1460:                xop = GET_FIELD(insn, 18, 26);
                   1461: #ifdef TARGET_SPARC64
                   1462:                if ((xop & 0x11f) == 0x005) { // V9 fmovsr
                   1463:                    cond = GET_FIELD_SP(insn, 14, 17);
                   1464:                    gen_op_load_fpr_FT0(rd);
                   1465:                    gen_op_load_fpr_FT1(rs2);
                   1466:                    rs1 = GET_FIELD(insn, 13, 17);
                   1467:                    gen_movl_reg_T0(rs1);
                   1468:                    flush_T2(dc);
                   1469:                    gen_cond_reg(cond);
                   1470:                    gen_op_fmovs_cc();
                   1471:                    gen_op_store_FT0_fpr(rd);
                   1472:                    break;
                   1473:                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
                   1474:                    cond = GET_FIELD_SP(insn, 14, 17);
                   1475:                    gen_op_load_fpr_DT0(rd);
                   1476:                    gen_op_load_fpr_DT1(rs2);
                   1477:                    flush_T2(dc);
                   1478:                    rs1 = GET_FIELD(insn, 13, 17);
                   1479:                    gen_movl_reg_T0(rs1);
                   1480:                    gen_cond_reg(cond);
                   1481:                    gen_op_fmovs_cc();
                   1482:                    gen_op_store_DT0_fpr(rd);
                   1483:                    break;
                   1484:                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
                   1485:                    goto nfpu_insn;
                   1486:                }
                   1487: #endif
                   1488:                switch (xop) {
                   1489: #ifdef TARGET_SPARC64
                   1490:                    case 0x001: /* V9 fmovscc %fcc0 */
                   1491:                        cond = GET_FIELD_SP(insn, 14, 17);
                   1492:                        gen_op_load_fpr_FT0(rd);
                   1493:                        gen_op_load_fpr_FT1(rs2);
                   1494:                        flush_T2(dc);
                   1495:                        gen_fcond[0][cond]();
                   1496:                        gen_op_fmovs_cc();
                   1497:                        gen_op_store_FT0_fpr(rd);
                   1498:                        break;
                   1499:                    case 0x002: /* V9 fmovdcc %fcc0 */
                   1500:                        cond = GET_FIELD_SP(insn, 14, 17);
                   1501:                        gen_op_load_fpr_DT0(rd);
                   1502:                        gen_op_load_fpr_DT1(rs2);
                   1503:                        flush_T2(dc);
                   1504:                        gen_fcond[0][cond]();
                   1505:                        gen_op_fmovd_cc();
                   1506:                        gen_op_store_DT0_fpr(rd);
                   1507:                        break;
                   1508:                    case 0x003: /* V9 fmovqcc %fcc0 */
                   1509:                        goto nfpu_insn;
                   1510:                    case 0x041: /* V9 fmovscc %fcc1 */
                   1511:                        cond = GET_FIELD_SP(insn, 14, 17);
                   1512:                        gen_op_load_fpr_FT0(rd);
                   1513:                        gen_op_load_fpr_FT1(rs2);
                   1514:                        flush_T2(dc);
                   1515:                        gen_fcond[1][cond]();
                   1516:                        gen_op_fmovs_cc();
                   1517:                        gen_op_store_FT0_fpr(rd);
                   1518:                        break;
                   1519:                    case 0x042: /* V9 fmovdcc %fcc1 */
                   1520:                        cond = GET_FIELD_SP(insn, 14, 17);
                   1521:                        gen_op_load_fpr_DT0(rd);
                   1522:                        gen_op_load_fpr_DT1(rs2);
                   1523:                        flush_T2(dc);
                   1524:                        gen_fcond[1][cond]();
                   1525:                        gen_op_fmovd_cc();
                   1526:                        gen_op_store_DT0_fpr(rd);
                   1527:                        break;
                   1528:                    case 0x043: /* V9 fmovqcc %fcc1 */
                   1529:                        goto nfpu_insn;
                   1530:                    case 0x081: /* V9 fmovscc %fcc2 */
                   1531:                        cond = GET_FIELD_SP(insn, 14, 17);
                   1532:                        gen_op_load_fpr_FT0(rd);
                   1533:                        gen_op_load_fpr_FT1(rs2);
                   1534:                        flush_T2(dc);
                   1535:                        gen_fcond[2][cond]();
                   1536:                        gen_op_fmovs_cc();
                   1537:                        gen_op_store_FT0_fpr(rd);
                   1538:                        break;
                   1539:                    case 0x082: /* V9 fmovdcc %fcc2 */
                   1540:                        cond = GET_FIELD_SP(insn, 14, 17);
                   1541:                        gen_op_load_fpr_DT0(rd);
                   1542:                        gen_op_load_fpr_DT1(rs2);
                   1543:                        flush_T2(dc);
                   1544:                        gen_fcond[2][cond]();
                   1545:                        gen_op_fmovd_cc();
                   1546:                        gen_op_store_DT0_fpr(rd);
                   1547:                        break;
                   1548:                    case 0x083: /* V9 fmovqcc %fcc2 */
                   1549:                        goto nfpu_insn;
                   1550:                    case 0x0c1: /* V9 fmovscc %fcc3 */
                   1551:                        cond = GET_FIELD_SP(insn, 14, 17);
                   1552:                        gen_op_load_fpr_FT0(rd);
                   1553:                        gen_op_load_fpr_FT1(rs2);
                   1554:                        flush_T2(dc);
                   1555:                        gen_fcond[3][cond]();
                   1556:                        gen_op_fmovs_cc();
                   1557:                        gen_op_store_FT0_fpr(rd);
                   1558:                        break;
                   1559:                    case 0x0c2: /* V9 fmovdcc %fcc3 */
                   1560:                        cond = GET_FIELD_SP(insn, 14, 17);
                   1561:                        gen_op_load_fpr_DT0(rd);
                   1562:                        gen_op_load_fpr_DT1(rs2);
                   1563:                        flush_T2(dc);
                   1564:                        gen_fcond[3][cond]();
                   1565:                        gen_op_fmovd_cc();
                   1566:                        gen_op_store_DT0_fpr(rd);
                   1567:                        break;
                   1568:                    case 0x0c3: /* V9 fmovqcc %fcc3 */
                   1569:                        goto nfpu_insn;
                   1570:                    case 0x101: /* V9 fmovscc %icc */
                   1571:                        cond = GET_FIELD_SP(insn, 14, 17);
                   1572:                        gen_op_load_fpr_FT0(rd);
                   1573:                        gen_op_load_fpr_FT1(rs2);
                   1574:                        flush_T2(dc);
                   1575:                        gen_cond[0][cond]();
                   1576:                        gen_op_fmovs_cc();
                   1577:                        gen_op_store_FT0_fpr(rd);
                   1578:                        break;
                   1579:                    case 0x102: /* V9 fmovdcc %icc */
                   1580:                        cond = GET_FIELD_SP(insn, 14, 17);
                   1581:                        gen_op_load_fpr_DT0(rd);
                   1582:                        gen_op_load_fpr_DT1(rs2);
                   1583:                        flush_T2(dc);
                   1584:                        gen_cond[0][cond]();
                   1585:                        gen_op_fmovd_cc();
                   1586:                        gen_op_store_DT0_fpr(rd);
                   1587:                        break;
                   1588:                    case 0x103: /* V9 fmovqcc %icc */
                   1589:                        goto nfpu_insn;
                   1590:                    case 0x181: /* V9 fmovscc %xcc */
                   1591:                        cond = GET_FIELD_SP(insn, 14, 17);
                   1592:                        gen_op_load_fpr_FT0(rd);
                   1593:                        gen_op_load_fpr_FT1(rs2);
                   1594:                        flush_T2(dc);
                   1595:                        gen_cond[1][cond]();
                   1596:                        gen_op_fmovs_cc();
                   1597:                        gen_op_store_FT0_fpr(rd);
                   1598:                        break;
                   1599:                    case 0x182: /* V9 fmovdcc %xcc */
                   1600:                        cond = GET_FIELD_SP(insn, 14, 17);
                   1601:                        gen_op_load_fpr_DT0(rd);
                   1602:                        gen_op_load_fpr_DT1(rs2);
                   1603:                        flush_T2(dc);
                   1604:                        gen_cond[1][cond]();
                   1605:                        gen_op_fmovd_cc();
                   1606:                        gen_op_store_DT0_fpr(rd);
                   1607:                        break;
                   1608:                    case 0x183: /* V9 fmovqcc %xcc */
                   1609:                        goto nfpu_insn;
                   1610: #endif
                   1611:                    case 0x51: /* V9 %fcc */
                   1612:                        gen_op_load_fpr_FT0(rs1);
                   1613:                        gen_op_load_fpr_FT1(rs2);
                   1614: #ifdef TARGET_SPARC64
                   1615:                        gen_fcmps[rd & 3]();
                   1616: #else
                   1617:                        gen_op_fcmps();
                   1618: #endif
                   1619:                        break;
                   1620:                    case 0x52: /* V9 %fcc */
                   1621:                        gen_op_load_fpr_DT0(DFPREG(rs1));
                   1622:                        gen_op_load_fpr_DT1(DFPREG(rs2));
                   1623: #ifdef TARGET_SPARC64
                   1624:                        gen_fcmpd[rd & 3]();
                   1625: #else
                   1626:                        gen_op_fcmpd();
                   1627: #endif
                   1628:                        break;
                   1629:                    case 0x53: /* fcmpq */
                   1630:                        goto nfpu_insn;
                   1631:                    case 0x55: /* fcmpes, V9 %fcc */
                   1632:                        gen_op_load_fpr_FT0(rs1);
                   1633:                        gen_op_load_fpr_FT1(rs2);
                   1634: #ifdef TARGET_SPARC64
                   1635:                        gen_fcmps[rd & 3]();
                   1636: #else
                   1637:                        gen_op_fcmps(); /* XXX should trap if qNaN or sNaN  */
                   1638: #endif
                   1639:                        break;
                   1640:                    case 0x56: /* fcmped, V9 %fcc */
                   1641:                        gen_op_load_fpr_DT0(DFPREG(rs1));
                   1642:                        gen_op_load_fpr_DT1(DFPREG(rs2));
                   1643: #ifdef TARGET_SPARC64
                   1644:                        gen_fcmpd[rd & 3]();
                   1645: #else
                   1646:                        gen_op_fcmpd(); /* XXX should trap if qNaN or sNaN  */
                   1647: #endif
                   1648:                        break;
                   1649:                    case 0x57: /* fcmpeq */
                   1650:                        goto nfpu_insn;
                   1651:                    default:
                   1652:                        goto illegal_insn;
                   1653:                }
                   1654: #if defined(OPTIM)
                   1655:            } else if (xop == 0x2) {
                   1656:                // clr/mov shortcut
                   1657: 
                   1658:                 rs1 = GET_FIELD(insn, 13, 17);
                   1659:                if (rs1 == 0) {
                   1660:                    // or %g0, x, y -> mov T1, x; mov y, T1
                   1661:                    if (IS_IMM) {       /* immediate */
                   1662:                        rs2 = GET_FIELDs(insn, 19, 31);
                   1663:                        gen_movl_simm_T1(rs2);
                   1664:                    } else {            /* register */
                   1665:                        rs2 = GET_FIELD(insn, 27, 31);
                   1666:                        gen_movl_reg_T1(rs2);
                   1667:                    }
                   1668:                    gen_movl_T1_reg(rd);
                   1669:                } else {
                   1670:                    gen_movl_reg_T0(rs1);
                   1671:                    if (IS_IMM) {       /* immediate */
                   1672:                        // or x, #0, y -> mov T1, x; mov y, T1
                   1673:                        rs2 = GET_FIELDs(insn, 19, 31);
                   1674:                        if (rs2 != 0) {
                   1675:                            gen_movl_simm_T1(rs2);
                   1676:                            gen_op_or_T1_T0();
                   1677:                        }
                   1678:                    } else {            /* register */
                   1679:                        // or x, %g0, y -> mov T1, x; mov y, T1
                   1680:                        rs2 = GET_FIELD(insn, 27, 31);
                   1681:                        if (rs2 != 0) {
                   1682:                            gen_movl_reg_T1(rs2);
                   1683:                            gen_op_or_T1_T0();
                   1684:                        }
                   1685:                    }
                   1686:                    gen_movl_T0_reg(rd);
                   1687:                }
                   1688: #endif
                   1689: #ifdef TARGET_SPARC64
                   1690:            } else if (xop == 0x25) { /* sll, V9 sllx ( == sll) */
                   1691:                 rs1 = GET_FIELD(insn, 13, 17);
                   1692:                gen_movl_reg_T0(rs1);
                   1693:                if (IS_IMM) {   /* immediate */
                   1694:                     rs2 = GET_FIELDs(insn, 20, 31);
                   1695:                     gen_movl_simm_T1(rs2);
                   1696:                 } else {               /* register */
                   1697:                     rs2 = GET_FIELD(insn, 27, 31);
                   1698:                     gen_movl_reg_T1(rs2);
                   1699:                 }
                   1700:                gen_op_sll();
                   1701:                gen_movl_T0_reg(rd);
                   1702:            } else if (xop == 0x26) { /* srl, V9 srlx */
                   1703:                 rs1 = GET_FIELD(insn, 13, 17);
                   1704:                gen_movl_reg_T0(rs1);
                   1705:                if (IS_IMM) {   /* immediate */
                   1706:                     rs2 = GET_FIELDs(insn, 20, 31);
                   1707:                     gen_movl_simm_T1(rs2);
                   1708:                 } else {               /* register */
                   1709:                     rs2 = GET_FIELD(insn, 27, 31);
                   1710:                     gen_movl_reg_T1(rs2);
                   1711:                 }
                   1712:                if (insn & (1 << 12))
                   1713:                    gen_op_srlx();
                   1714:                else
                   1715:                    gen_op_srl();
                   1716:                gen_movl_T0_reg(rd);
                   1717:            } else if (xop == 0x27) { /* sra, V9 srax */
                   1718:                 rs1 = GET_FIELD(insn, 13, 17);
                   1719:                gen_movl_reg_T0(rs1);
                   1720:                if (IS_IMM) {   /* immediate */
                   1721:                     rs2 = GET_FIELDs(insn, 20, 31);
                   1722:                     gen_movl_simm_T1(rs2);
                   1723:                 } else {               /* register */
                   1724:                     rs2 = GET_FIELD(insn, 27, 31);
                   1725:                     gen_movl_reg_T1(rs2);
                   1726:                 }
                   1727:                if (insn & (1 << 12))
                   1728:                    gen_op_srax();
                   1729:                else
                   1730:                    gen_op_sra();
                   1731:                gen_movl_T0_reg(rd);
                   1732: #endif
                   1733:            } else if (xop < 0x38) {
                   1734:                 rs1 = GET_FIELD(insn, 13, 17);
                   1735:                gen_movl_reg_T0(rs1);
                   1736:                if (IS_IMM) {   /* immediate */
                   1737:                     rs2 = GET_FIELDs(insn, 19, 31);
                   1738:                     gen_movl_simm_T1(rs2);
                   1739:                 } else {               /* register */
                   1740:                     rs2 = GET_FIELD(insn, 27, 31);
                   1741:                     gen_movl_reg_T1(rs2);
                   1742:                 }
                   1743:                 if (xop < 0x20) {
                   1744:                     switch (xop & ~0x10) {
                   1745:                     case 0x0:
                   1746:                         if (xop & 0x10)
                   1747:                             gen_op_add_T1_T0_cc();
                   1748:                         else
                   1749:                             gen_op_add_T1_T0();
                   1750:                         break;
                   1751:                     case 0x1:
                   1752:                         gen_op_and_T1_T0();
                   1753:                         if (xop & 0x10)
                   1754:                             gen_op_logic_T0_cc();
                   1755:                         break;
                   1756:                     case 0x2:
                   1757:                        gen_op_or_T1_T0();
                   1758:                        if (xop & 0x10)
                   1759:                            gen_op_logic_T0_cc();
                   1760:                        break;
                   1761:                     case 0x3:
                   1762:                         gen_op_xor_T1_T0();
                   1763:                         if (xop & 0x10)
                   1764:                             gen_op_logic_T0_cc();
                   1765:                         break;
                   1766:                     case 0x4:
                   1767:                         if (xop & 0x10)
                   1768:                             gen_op_sub_T1_T0_cc();
                   1769:                         else
                   1770:                             gen_op_sub_T1_T0();
                   1771:                         break;
                   1772:                     case 0x5:
                   1773:                         gen_op_andn_T1_T0();
                   1774:                         if (xop & 0x10)
                   1775:                             gen_op_logic_T0_cc();
                   1776:                         break;
                   1777:                     case 0x6:
                   1778:                         gen_op_orn_T1_T0();
                   1779:                         if (xop & 0x10)
                   1780:                             gen_op_logic_T0_cc();
                   1781:                         break;
                   1782:                     case 0x7:
                   1783:                         gen_op_xnor_T1_T0();
                   1784:                         if (xop & 0x10)
                   1785:                             gen_op_logic_T0_cc();
                   1786:                         break;
                   1787:                     case 0x8:
                   1788:                         if (xop & 0x10)
                   1789:                             gen_op_addx_T1_T0_cc();
                   1790:                         else
                   1791:                             gen_op_addx_T1_T0();
                   1792:                         break;
1.1.1.3 ! root     1793: #ifdef TARGET_SPARC64
        !          1794:                    case 0x9: /* V9 mulx */
        !          1795:                         gen_op_mulx_T1_T0();
        !          1796:                         break;
        !          1797: #endif
1.1       root     1798:                     case 0xa:
                   1799:                         gen_op_umul_T1_T0();
                   1800:                         if (xop & 0x10)
                   1801:                             gen_op_logic_T0_cc();
                   1802:                         break;
                   1803:                     case 0xb:
                   1804:                         gen_op_smul_T1_T0();
                   1805:                         if (xop & 0x10)
                   1806:                             gen_op_logic_T0_cc();
                   1807:                         break;
                   1808:                     case 0xc:
                   1809:                         if (xop & 0x10)
                   1810:                             gen_op_subx_T1_T0_cc();
                   1811:                         else
                   1812:                             gen_op_subx_T1_T0();
                   1813:                         break;
1.1.1.3 ! root     1814: #ifdef TARGET_SPARC64
        !          1815:                    case 0xd: /* V9 udivx */
        !          1816:                         gen_op_udivx_T1_T0();
        !          1817:                         break;
        !          1818: #endif
1.1       root     1819:                     case 0xe:
                   1820:                         gen_op_udiv_T1_T0();
                   1821:                         if (xop & 0x10)
                   1822:                             gen_op_div_cc();
                   1823:                         break;
                   1824:                     case 0xf:
                   1825:                         gen_op_sdiv_T1_T0();
                   1826:                         if (xop & 0x10)
                   1827:                             gen_op_div_cc();
                   1828:                         break;
                   1829:                     default:
                   1830:                         goto illegal_insn;
                   1831:                     }
                   1832:                    gen_movl_T0_reg(rd);
                   1833:                 } else {
                   1834:                     switch (xop) {
                   1835:                    case 0x20: /* taddcc */
                   1836:                    case 0x21: /* tsubcc */
                   1837:                    case 0x22: /* taddcctv */
                   1838:                    case 0x23: /* tsubcctv */
                   1839:                        goto illegal_insn;
                   1840:                     case 0x24: /* mulscc */
                   1841:                         gen_op_mulscc_T1_T0();
                   1842:                         gen_movl_T0_reg(rd);
                   1843:                         break;
                   1844: #ifndef TARGET_SPARC64
                   1845:                     case 0x25: /* sll */
                   1846:                        gen_op_sll();
                   1847:                         gen_movl_T0_reg(rd);
                   1848:                         break;
                   1849:                     case 0x26:  /* srl */
                   1850:                        gen_op_srl();
                   1851:                         gen_movl_T0_reg(rd);
                   1852:                         break;
                   1853:                     case 0x27:  /* sra */
                   1854:                        gen_op_sra();
                   1855:                         gen_movl_T0_reg(rd);
                   1856:                         break;
                   1857: #endif
                   1858:                     case 0x30:
                   1859:                         {
                   1860:                             switch(rd) {
                   1861:                             case 0: /* wry */
                   1862:                                gen_op_xor_T1_T0();
                   1863:                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, y));
                   1864:                                 break;
                   1865: #ifdef TARGET_SPARC64
                   1866:                            case 0x2: /* V9 wrccr */
                   1867:                                 gen_op_wrccr();
                   1868:                                break;
                   1869:                            case 0x3: /* V9 wrasi */
                   1870:                                gen_op_movl_env_T0(offsetof(CPUSPARCState, asi));
                   1871:                                break;
                   1872:                            case 0x6: /* V9 wrfprs */
                   1873:                                gen_op_movl_env_T0(offsetof(CPUSPARCState, fprs));
                   1874:                                break;
                   1875:                            case 0xf: /* V9 sir, nop if user */
                   1876: #if !defined(CONFIG_USER_ONLY)
                   1877:                                if (supervisor(dc))
                   1878:                                    gen_op_sir();
                   1879: #endif
                   1880:                                break;
1.1.1.3 ! root     1881:                            case 0x13: /* Graphics Status */
        !          1882:                                 if (gen_trap_ifnofpu(dc))
        !          1883:                                     goto jmp_insn;
        !          1884:                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, gsr));
        !          1885:                                break;
1.1       root     1886:                            case 0x17: /* Tick compare */
                   1887: #if !defined(CONFIG_USER_ONLY)
                   1888:                                if (!supervisor(dc))
                   1889:                                    goto illegal_insn;
                   1890: #endif
                   1891:                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, tick_cmpr));
                   1892:                                break;
                   1893:                            case 0x18: /* System tick */
                   1894: #if !defined(CONFIG_USER_ONLY)
                   1895:                                if (!supervisor(dc))
                   1896:                                    goto illegal_insn;
                   1897: #endif
                   1898:                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, stick_cmpr));
                   1899:                                break;
                   1900:                            case 0x19: /* System tick compare */
                   1901: #if !defined(CONFIG_USER_ONLY)
                   1902:                                if (!supervisor(dc))
                   1903:                                    goto illegal_insn;
                   1904: #endif
                   1905:                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, stick_cmpr));
                   1906:                                break;
                   1907: 
                   1908:                            case 0x10: /* Performance Control */
                   1909:                            case 0x11: /* Performance Instrumentation Counter */
                   1910:                            case 0x12: /* Dispatch Control */
                   1911:                            case 0x14: /* Softint set */
                   1912:                            case 0x15: /* Softint clear */
                   1913:                            case 0x16: /* Softint write */
                   1914: #endif
                   1915:                             default:
                   1916:                                 goto illegal_insn;
                   1917:                             }
                   1918:                         }
                   1919:                         break;
                   1920: #if !defined(CONFIG_USER_ONLY)
                   1921:                     case 0x31: /* wrpsr, V9 saved, restored */
                   1922:                         {
                   1923:                            if (!supervisor(dc))
                   1924:                                goto priv_insn;
                   1925: #ifdef TARGET_SPARC64
                   1926:                            switch (rd) {
                   1927:                            case 0:
                   1928:                                gen_op_saved();
                   1929:                                break;
                   1930:                            case 1:
                   1931:                                gen_op_restored();
                   1932:                                break;
                   1933:                            default:
                   1934:                                 goto illegal_insn;
                   1935:                             }
                   1936: #else
                   1937:                             gen_op_xor_T1_T0();
                   1938:                             gen_op_wrpsr();
1.1.1.2   root     1939:                             save_state(dc);
                   1940:                             gen_op_next_insn();
                   1941:                            gen_op_movl_T0_0();
                   1942:                            gen_op_exit_tb();
                   1943:                            dc->is_br = 1;
1.1       root     1944: #endif
                   1945:                         }
                   1946:                         break;
                   1947:                     case 0x32: /* wrwim, V9 wrpr */
                   1948:                         {
                   1949:                            if (!supervisor(dc))
                   1950:                                goto priv_insn;
                   1951:                             gen_op_xor_T1_T0();
                   1952: #ifdef TARGET_SPARC64
                   1953:                            switch (rd) {
                   1954:                            case 0: // tpc
                   1955:                                gen_op_wrtpc();
                   1956:                                break;
                   1957:                            case 1: // tnpc
                   1958:                                gen_op_wrtnpc();
                   1959:                                break;
                   1960:                            case 2: // tstate
                   1961:                                gen_op_wrtstate();
                   1962:                                break;
                   1963:                            case 3: // tt
                   1964:                                gen_op_wrtt();
                   1965:                                break;
                   1966:                            case 4: // tick
                   1967:                                gen_op_wrtick();
                   1968:                                break;
                   1969:                            case 5: // tba
                   1970:                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr));
                   1971:                                break;
                   1972:                            case 6: // pstate
                   1973:                                gen_op_wrpstate();
1.1.1.3 ! root     1974:                                 save_state(dc);
        !          1975:                                 gen_op_next_insn();
        !          1976:                                 gen_op_movl_T0_0();
        !          1977:                                 gen_op_exit_tb();
        !          1978:                                 dc->is_br = 1;
1.1       root     1979:                                break;
                   1980:                            case 7: // tl
                   1981:                                gen_op_movl_env_T0(offsetof(CPUSPARCState, tl));
                   1982:                                break;
                   1983:                            case 8: // pil
                   1984:                                gen_op_movl_env_T0(offsetof(CPUSPARCState, psrpil));
                   1985:                                break;
                   1986:                            case 9: // cwp
                   1987:                                gen_op_wrcwp();
                   1988:                                break;
                   1989:                            case 10: // cansave
                   1990:                                gen_op_movl_env_T0(offsetof(CPUSPARCState, cansave));
                   1991:                                break;
                   1992:                            case 11: // canrestore
                   1993:                                gen_op_movl_env_T0(offsetof(CPUSPARCState, canrestore));
                   1994:                                break;
                   1995:                            case 12: // cleanwin
                   1996:                                gen_op_movl_env_T0(offsetof(CPUSPARCState, cleanwin));
                   1997:                                break;
                   1998:                            case 13: // otherwin
                   1999:                                gen_op_movl_env_T0(offsetof(CPUSPARCState, otherwin));
                   2000:                                break;
                   2001:                            case 14: // wstate
                   2002:                                gen_op_movl_env_T0(offsetof(CPUSPARCState, wstate));
                   2003:                                break;
                   2004:                            default:
                   2005:                                goto illegal_insn;
                   2006:                            }
                   2007: #else
                   2008:                            gen_op_movl_env_T0(offsetof(CPUSPARCState, wim));
                   2009: #endif
                   2010:                         }
                   2011:                         break;
                   2012: #ifndef TARGET_SPARC64
                   2013:                     case 0x33: /* wrtbr, V9 unimp */
                   2014:                         {
                   2015:                            if (!supervisor(dc))
                   2016:                                goto priv_insn;
                   2017:                             gen_op_xor_T1_T0();
                   2018:                            gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr));
                   2019:                         }
                   2020:                         break;
                   2021: #endif
                   2022: #endif
                   2023: #ifdef TARGET_SPARC64
                   2024:                    case 0x2c: /* V9 movcc */
                   2025:                        {
                   2026:                            int cc = GET_FIELD_SP(insn, 11, 12);
                   2027:                            int cond = GET_FIELD_SP(insn, 14, 17);
                   2028:                            if (IS_IMM) {       /* immediate */
                   2029:                                rs2 = GET_FIELD_SPs(insn, 0, 10);
                   2030:                                gen_movl_simm_T1(rs2);
                   2031:                            }
                   2032:                            else {
                   2033:                                rs2 = GET_FIELD_SP(insn, 0, 4);
                   2034:                                gen_movl_reg_T1(rs2);
                   2035:                            }
                   2036:                            gen_movl_reg_T0(rd);
                   2037:                            flush_T2(dc);
                   2038:                            if (insn & (1 << 18)) {
                   2039:                                if (cc == 0)
                   2040:                                    gen_cond[0][cond]();
                   2041:                                else if (cc == 2)
                   2042:                                    gen_cond[1][cond]();
                   2043:                                else
                   2044:                                    goto illegal_insn;
                   2045:                            } else {
                   2046:                                gen_fcond[cc][cond]();
                   2047:                            }
                   2048:                            gen_op_mov_cc();
                   2049:                            gen_movl_T0_reg(rd);
                   2050:                            break;
                   2051:                        }
                   2052:                    case 0x2d: /* V9 sdivx */
                   2053:                         gen_op_sdivx_T1_T0();
                   2054:                        gen_movl_T0_reg(rd);
                   2055:                         break;
                   2056:                    case 0x2e: /* V9 popc */
                   2057:                        {
                   2058:                            if (IS_IMM) {       /* immediate */
                   2059:                                rs2 = GET_FIELD_SPs(insn, 0, 12);
                   2060:                                gen_movl_simm_T1(rs2);
                   2061:                                // XXX optimize: popc(constant)
                   2062:                            }
                   2063:                            else {
                   2064:                                rs2 = GET_FIELD_SP(insn, 0, 4);
                   2065:                                gen_movl_reg_T1(rs2);
                   2066:                            }
                   2067:                            gen_op_popc();
                   2068:                            gen_movl_T0_reg(rd);
                   2069:                        }
                   2070:                    case 0x2f: /* V9 movr */
                   2071:                        {
                   2072:                            int cond = GET_FIELD_SP(insn, 10, 12);
                   2073:                            rs1 = GET_FIELD(insn, 13, 17);
                   2074:                            flush_T2(dc);
                   2075:                            gen_movl_reg_T0(rs1);
                   2076:                            gen_cond_reg(cond);
                   2077:                            if (IS_IMM) {       /* immediate */
                   2078:                                rs2 = GET_FIELD_SPs(insn, 0, 10);
                   2079:                                gen_movl_simm_T1(rs2);
                   2080:                            }
                   2081:                            else {
                   2082:                                rs2 = GET_FIELD_SP(insn, 0, 4);
                   2083:                                gen_movl_reg_T1(rs2);
                   2084:                            }
                   2085:                            gen_movl_reg_T0(rd);
                   2086:                            gen_op_mov_cc();
                   2087:                            gen_movl_T0_reg(rd);
                   2088:                            break;
                   2089:                        }
                   2090:                    case 0x36: /* UltraSparc shutdown, VIS */
                   2091:                        {
1.1.1.3 ! root     2092:                            int opf = GET_FIELD_SP(insn, 5, 13);
        !          2093:                             rs1 = GET_FIELD(insn, 13, 17);
        !          2094:                             rs2 = GET_FIELD(insn, 27, 31);
        !          2095: 
        !          2096:                             switch (opf) {
        !          2097:                             case 0x018: /* VIS I alignaddr */
        !          2098:                                 if (gen_trap_ifnofpu(dc))
        !          2099:                                     goto jmp_insn;
        !          2100:                                 gen_movl_reg_T0(rs1);
        !          2101:                                 gen_movl_reg_T1(rs2);
        !          2102:                                 gen_op_alignaddr();
        !          2103:                                 gen_movl_T0_reg(rd);
        !          2104:                                 break;
        !          2105:                             case 0x01a: /* VIS I alignaddrl */
        !          2106:                                 if (gen_trap_ifnofpu(dc))
        !          2107:                                     goto jmp_insn;
        !          2108:                                 // XXX
        !          2109:                                 break;
        !          2110:                             case 0x048: /* VIS I faligndata */
        !          2111:                                 if (gen_trap_ifnofpu(dc))
        !          2112:                                     goto jmp_insn;
        !          2113:                                 gen_op_load_fpr_DT0(rs1);
        !          2114:                                 gen_op_load_fpr_DT1(rs2);
        !          2115:                                 gen_op_faligndata();
        !          2116:                                 gen_op_store_DT0_fpr(rd);
        !          2117:                                 break;
        !          2118:                             default:
        !          2119:                                 goto illegal_insn;
        !          2120:                             }
        !          2121:                             break;
1.1       root     2122:                        }
                   2123: #endif
                   2124:                    default:
                   2125:                        goto illegal_insn;
                   2126:                    }
                   2127:                }
                   2128: #ifdef TARGET_SPARC64
                   2129:            } else if (xop == 0x39) { /* V9 return */
                   2130:                 rs1 = GET_FIELD(insn, 13, 17);
                   2131:                gen_movl_reg_T0(rs1);
                   2132:                 if (IS_IMM) {  /* immediate */
                   2133:                    rs2 = GET_FIELDs(insn, 19, 31);
                   2134: #if defined(OPTIM)
                   2135:                    if (rs2) {
                   2136: #endif
                   2137:                        gen_movl_simm_T1(rs2);
                   2138:                        gen_op_add_T1_T0();
                   2139: #if defined(OPTIM)
                   2140:                    }
                   2141: #endif
                   2142:                 } else {               /* register */
                   2143:                     rs2 = GET_FIELD(insn, 27, 31);
                   2144: #if defined(OPTIM)
                   2145:                    if (rs2) {
                   2146: #endif
                   2147:                        gen_movl_reg_T1(rs2);
                   2148:                        gen_op_add_T1_T0();
                   2149: #if defined(OPTIM)
                   2150:                    }
                   2151: #endif
                   2152:                 }
                   2153:                gen_op_restore();
                   2154:                gen_mov_pc_npc(dc);
                   2155:                gen_op_movl_npc_T0();
                   2156:                dc->npc = DYNAMIC_PC;
                   2157:                goto jmp_insn;
                   2158: #endif
                   2159:            } else {
                   2160:                 rs1 = GET_FIELD(insn, 13, 17);
                   2161:                gen_movl_reg_T0(rs1);
                   2162:                 if (IS_IMM) {  /* immediate */
                   2163:                    rs2 = GET_FIELDs(insn, 19, 31);
                   2164: #if defined(OPTIM)
                   2165:                    if (rs2) {
                   2166: #endif
                   2167:                        gen_movl_simm_T1(rs2);
                   2168:                        gen_op_add_T1_T0();
                   2169: #if defined(OPTIM)
                   2170:                    }
                   2171: #endif
                   2172:                 } else {               /* register */
                   2173:                     rs2 = GET_FIELD(insn, 27, 31);
                   2174: #if defined(OPTIM)
                   2175:                    if (rs2) {
                   2176: #endif
                   2177:                        gen_movl_reg_T1(rs2);
                   2178:                        gen_op_add_T1_T0();
                   2179: #if defined(OPTIM)
                   2180:                    }
                   2181: #endif
                   2182:                 }
                   2183:                switch (xop) {
                   2184:                case 0x38:      /* jmpl */
                   2185:                    {
                   2186:                        if (rd != 0) {
1.1.1.3 ! root     2187: #ifdef TARGET_SPARC64
        !          2188:                             if (dc->pc == (uint32_t)dc->pc) {
        !          2189:                                 gen_op_movl_T1_im(dc->pc);
        !          2190:                             } else {
        !          2191:                                 gen_op_movq_T1_im64(dc->pc >> 32, dc->pc);
        !          2192:                             }
        !          2193: #else
1.1       root     2194:                            gen_op_movl_T1_im(dc->pc);
1.1.1.3 ! root     2195: #endif
1.1       root     2196:                            gen_movl_T1_reg(rd);
                   2197:                        }
                   2198:                         gen_mov_pc_npc(dc);
                   2199:                        gen_op_movl_npc_T0();
                   2200:                        dc->npc = DYNAMIC_PC;
                   2201:                    }
                   2202:                    goto jmp_insn;
                   2203: #if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
                   2204:                case 0x39:      /* rett, V9 return */
                   2205:                    {
                   2206:                        if (!supervisor(dc))
                   2207:                            goto priv_insn;
                   2208:                         gen_mov_pc_npc(dc);
                   2209:                        gen_op_movl_npc_T0();
                   2210:                        dc->npc = DYNAMIC_PC;
                   2211:                        gen_op_rett();
                   2212:                    }
                   2213:                    goto jmp_insn;
                   2214: #endif
                   2215:                case 0x3b: /* flush */
                   2216:                    gen_op_flush_T0();
                   2217:                    break;
                   2218:                case 0x3c:      /* save */
                   2219:                    save_state(dc);
                   2220:                    gen_op_save();
                   2221:                    gen_movl_T0_reg(rd);
                   2222:                    break;
                   2223:                case 0x3d:      /* restore */
                   2224:                    save_state(dc);
                   2225:                    gen_op_restore();
                   2226:                    gen_movl_T0_reg(rd);
                   2227:                    break;
                   2228: #if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
                   2229:                case 0x3e:      /* V9 done/retry */
                   2230:                    {
                   2231:                        switch (rd) {
                   2232:                        case 0:
                   2233:                            if (!supervisor(dc))
                   2234:                                goto priv_insn;
                   2235:                            dc->npc = DYNAMIC_PC;
                   2236:                            dc->pc = DYNAMIC_PC;
                   2237:                            gen_op_done();
                   2238:                            goto jmp_insn;
                   2239:                        case 1:
                   2240:                            if (!supervisor(dc))
                   2241:                                goto priv_insn;
                   2242:                            dc->npc = DYNAMIC_PC;
                   2243:                            dc->pc = DYNAMIC_PC;
                   2244:                            gen_op_retry();
                   2245:                            goto jmp_insn;
                   2246:                        default:
                   2247:                            goto illegal_insn;
                   2248:                        }
                   2249:                    }
                   2250:                    break;
                   2251: #endif
                   2252:                default:
                   2253:                    goto illegal_insn;
                   2254:                }
                   2255:             }
                   2256:            break;
                   2257:        }
                   2258:        break;
                   2259:     case 3:                    /* load/store instructions */
                   2260:        {
                   2261:            unsigned int xop = GET_FIELD(insn, 7, 12);
                   2262:            rs1 = GET_FIELD(insn, 13, 17);
                   2263:            gen_movl_reg_T0(rs1);
                   2264:            if (IS_IMM) {       /* immediate */
                   2265:                rs2 = GET_FIELDs(insn, 19, 31);
                   2266: #if defined(OPTIM)
                   2267:                if (rs2 != 0) {
                   2268: #endif
                   2269:                    gen_movl_simm_T1(rs2);
                   2270:                    gen_op_add_T1_T0();
                   2271: #if defined(OPTIM)
                   2272:                }
                   2273: #endif
                   2274:            } else {            /* register */
                   2275:                rs2 = GET_FIELD(insn, 27, 31);
                   2276: #if defined(OPTIM)
                   2277:                if (rs2 != 0) {
                   2278: #endif
                   2279:                    gen_movl_reg_T1(rs2);
                   2280:                    gen_op_add_T1_T0();
                   2281: #if defined(OPTIM)
                   2282:                }
                   2283: #endif
                   2284:            }
                   2285:            if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) || \
                   2286:                    (xop > 0x17 && xop < 0x1d ) || \
                   2287:                    (xop > 0x2c && xop < 0x33) || xop == 0x1f) {
                   2288:                switch (xop) {
                   2289:                case 0x0:       /* load word */
                   2290:                    gen_op_ldst(ld);
                   2291:                    break;
                   2292:                case 0x1:       /* load unsigned byte */
                   2293:                    gen_op_ldst(ldub);
                   2294:                    break;
                   2295:                case 0x2:       /* load unsigned halfword */
                   2296:                    gen_op_ldst(lduh);
                   2297:                    break;
                   2298:                case 0x3:       /* load double word */
                   2299:                    gen_op_ldst(ldd);
                   2300:                    gen_movl_T0_reg(rd + 1);
                   2301:                    break;
                   2302:                case 0x9:       /* load signed byte */
                   2303:                    gen_op_ldst(ldsb);
                   2304:                    break;
                   2305:                case 0xa:       /* load signed halfword */
                   2306:                    gen_op_ldst(ldsh);
                   2307:                    break;
                   2308:                case 0xd:       /* ldstub -- XXX: should be atomically */
                   2309:                    gen_op_ldst(ldstub);
                   2310:                    break;
                   2311:                case 0x0f:      /* swap register with memory. Also atomically */
                   2312:                    gen_movl_reg_T1(rd);
                   2313:                    gen_op_ldst(swap);
                   2314:                    break;
                   2315: #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
                   2316:                case 0x10:      /* load word alternate */
                   2317: #ifndef TARGET_SPARC64
                   2318:                    if (!supervisor(dc))
                   2319:                        goto priv_insn;
                   2320: #endif
                   2321:                    gen_op_lda(insn, 1, 4, 0);
                   2322:                    break;
                   2323:                case 0x11:      /* load unsigned byte alternate */
                   2324: #ifndef TARGET_SPARC64
                   2325:                    if (!supervisor(dc))
                   2326:                        goto priv_insn;
                   2327: #endif
                   2328:                    gen_op_lduba(insn, 1, 1, 0);
                   2329:                    break;
                   2330:                case 0x12:      /* load unsigned halfword alternate */
                   2331: #ifndef TARGET_SPARC64
                   2332:                    if (!supervisor(dc))
                   2333:                        goto priv_insn;
                   2334: #endif
                   2335:                    gen_op_lduha(insn, 1, 2, 0);
                   2336:                    break;
                   2337:                case 0x13:      /* load double word alternate */
                   2338: #ifndef TARGET_SPARC64
                   2339:                    if (!supervisor(dc))
                   2340:                        goto priv_insn;
                   2341: #endif
                   2342:                    gen_op_ldda(insn, 1, 8, 0);
                   2343:                    gen_movl_T0_reg(rd + 1);
                   2344:                    break;
                   2345:                case 0x19:      /* load signed byte alternate */
                   2346: #ifndef TARGET_SPARC64
                   2347:                    if (!supervisor(dc))
                   2348:                        goto priv_insn;
                   2349: #endif
                   2350:                    gen_op_ldsba(insn, 1, 1, 1);
                   2351:                    break;
                   2352:                case 0x1a:      /* load signed halfword alternate */
                   2353: #ifndef TARGET_SPARC64
                   2354:                    if (!supervisor(dc))
                   2355:                        goto priv_insn;
                   2356: #endif
                   2357:                    gen_op_ldsha(insn, 1, 2 ,1);
                   2358:                    break;
                   2359:                case 0x1d:      /* ldstuba -- XXX: should be atomically */
                   2360: #ifndef TARGET_SPARC64
                   2361:                    if (!supervisor(dc))
                   2362:                        goto priv_insn;
                   2363: #endif
                   2364:                    gen_op_ldstuba(insn, 1, 1, 0);
                   2365:                    break;
                   2366:                case 0x1f:      /* swap reg with alt. memory. Also atomically */
                   2367: #ifndef TARGET_SPARC64
                   2368:                    if (!supervisor(dc))
                   2369:                        goto priv_insn;
                   2370: #endif
                   2371:                    gen_movl_reg_T1(rd);
                   2372:                    gen_op_swapa(insn, 1, 4, 0);
                   2373:                    break;
                   2374: 
                   2375: #ifndef TARGET_SPARC64
                   2376:                     /* avoid warnings */
                   2377:                     (void) &gen_op_stfa;
                   2378:                     (void) &gen_op_stdfa;
                   2379:                     (void) &gen_op_ldfa;
                   2380:                     (void) &gen_op_lddfa;
                   2381: #else
                   2382: #if !defined(CONFIG_USER_ONLY)
                   2383:                    (void) &gen_op_cas;
                   2384:                    (void) &gen_op_casx;
                   2385: #endif
                   2386: #endif
                   2387: #endif
                   2388: #ifdef TARGET_SPARC64
                   2389:                case 0x08: /* V9 ldsw */
                   2390:                    gen_op_ldst(ldsw);
                   2391:                    break;
                   2392:                case 0x0b: /* V9 ldx */
                   2393:                    gen_op_ldst(ldx);
                   2394:                    break;
                   2395:                case 0x18: /* V9 ldswa */
                   2396:                    gen_op_ldswa(insn, 1, 4, 1);
                   2397:                    break;
                   2398:                case 0x1b: /* V9 ldxa */
                   2399:                    gen_op_ldxa(insn, 1, 8, 0);
                   2400:                    break;
                   2401:                case 0x2d: /* V9 prefetch, no effect */
                   2402:                    goto skip_move;
                   2403:                case 0x30: /* V9 ldfa */
                   2404:                    gen_op_ldfa(insn, 1, 8, 0); // XXX
                   2405:                    break;
                   2406:                case 0x33: /* V9 lddfa */
                   2407:                    gen_op_lddfa(insn, 1, 8, 0); // XXX
                   2408: 
                   2409:                    break;
                   2410:                case 0x3d: /* V9 prefetcha, no effect */
                   2411:                    goto skip_move;
                   2412:                case 0x32: /* V9 ldqfa */
                   2413:                    goto nfpu_insn;
                   2414: #endif
                   2415:                default:
                   2416:                    goto illegal_insn;
                   2417:                }
                   2418:                gen_movl_T1_reg(rd);
                   2419: #ifdef TARGET_SPARC64
                   2420:            skip_move: ;
                   2421: #endif
                   2422:            } else if (xop >= 0x20 && xop < 0x24) {
1.1.1.3 ! root     2423:                 if (gen_trap_ifnofpu(dc))
        !          2424:                     goto jmp_insn;
1.1       root     2425:                switch (xop) {
                   2426:                case 0x20:      /* load fpreg */
                   2427:                    gen_op_ldst(ldf);
                   2428:                    gen_op_store_FT0_fpr(rd);
                   2429:                    break;
                   2430:                case 0x21:      /* load fsr */
1.1.1.2   root     2431:                    gen_op_ldst(ldf);
1.1       root     2432:                    gen_op_ldfsr();
                   2433:                    break;
                   2434:                case 0x22:      /* load quad fpreg */
                   2435:                    goto nfpu_insn;
                   2436:                case 0x23:      /* load double fpreg */
                   2437:                    gen_op_ldst(lddf);
                   2438:                    gen_op_store_DT0_fpr(DFPREG(rd));
                   2439:                    break;
                   2440:                default:
                   2441:                    goto illegal_insn;
                   2442:                }
                   2443:            } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) || \
                   2444:                       xop == 0xe || xop == 0x1e) {
                   2445:                gen_movl_reg_T1(rd);
                   2446:                switch (xop) {
                   2447:                case 0x4:
                   2448:                    gen_op_ldst(st);
                   2449:                    break;
                   2450:                case 0x5:
                   2451:                    gen_op_ldst(stb);
                   2452:                    break;
                   2453:                case 0x6:
                   2454:                    gen_op_ldst(sth);
                   2455:                    break;
                   2456:                case 0x7:
                   2457:                     flush_T2(dc);
                   2458:                    gen_movl_reg_T2(rd + 1);
                   2459:                    gen_op_ldst(std);
                   2460:                    break;
                   2461: #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
                   2462:                case 0x14:
                   2463: #ifndef TARGET_SPARC64
                   2464:                    if (!supervisor(dc))
                   2465:                        goto priv_insn;
                   2466: #endif
                   2467:                    gen_op_sta(insn, 0, 4, 0);
                   2468:                     break;
                   2469:                case 0x15:
                   2470: #ifndef TARGET_SPARC64
                   2471:                    if (!supervisor(dc))
                   2472:                        goto priv_insn;
                   2473: #endif
                   2474:                    gen_op_stba(insn, 0, 1, 0);
                   2475:                     break;
                   2476:                case 0x16:
                   2477: #ifndef TARGET_SPARC64
                   2478:                    if (!supervisor(dc))
                   2479:                        goto priv_insn;
                   2480: #endif
                   2481:                    gen_op_stha(insn, 0, 2, 0);
                   2482:                     break;
                   2483:                case 0x17:
                   2484: #ifndef TARGET_SPARC64
                   2485:                    if (!supervisor(dc))
                   2486:                        goto priv_insn;
                   2487: #endif
                   2488:                     flush_T2(dc);
                   2489:                    gen_movl_reg_T2(rd + 1);
                   2490:                    gen_op_stda(insn, 0, 8, 0);
                   2491:                     break;
                   2492: #endif
                   2493: #ifdef TARGET_SPARC64
                   2494:                case 0x0e: /* V9 stx */
                   2495:                    gen_op_ldst(stx);
                   2496:                    break;
                   2497:                case 0x1e: /* V9 stxa */
                   2498:                    gen_op_stxa(insn, 0, 8, 0); // XXX
                   2499:                    break;
                   2500: #endif
                   2501:                default:
                   2502:                    goto illegal_insn;
                   2503:                }
                   2504:            } else if (xop > 0x23 && xop < 0x28) {
1.1.1.3 ! root     2505:                 if (gen_trap_ifnofpu(dc))
        !          2506:                     goto jmp_insn;
1.1       root     2507:                switch (xop) {
                   2508:                case 0x24:
                   2509:                     gen_op_load_fpr_FT0(rd);
                   2510:                    gen_op_ldst(stf);
                   2511:                    break;
                   2512:                case 0x25: /* stfsr, V9 stxfsr */
                   2513:                    gen_op_stfsr();
1.1.1.2   root     2514:                    gen_op_ldst(stf);
1.1       root     2515:                    break;
                   2516:                case 0x26: /* stdfq */
                   2517:                    goto nfpu_insn;
                   2518:                case 0x27:
                   2519:                     gen_op_load_fpr_DT0(DFPREG(rd));
                   2520:                    gen_op_ldst(stdf);
                   2521:                    break;
                   2522:                default:
                   2523:                    goto illegal_insn;
                   2524:                }
                   2525:            } else if (xop > 0x33 && xop < 0x3f) {
                   2526: #ifdef TARGET_SPARC64
                   2527:                switch (xop) {
                   2528:                case 0x34: /* V9 stfa */
                   2529:                    gen_op_stfa(insn, 0, 0, 0); // XXX
                   2530:                    break;
                   2531:                case 0x37: /* V9 stdfa */
                   2532:                    gen_op_stdfa(insn, 0, 0, 0); // XXX
                   2533:                    break;
                   2534:                case 0x3c: /* V9 casa */
                   2535:                    gen_op_casa(insn, 0, 4, 0); // XXX
                   2536:                    break;
                   2537:                case 0x3e: /* V9 casxa */
                   2538:                    gen_op_casxa(insn, 0, 8, 0); // XXX
                   2539:                    break;
                   2540:                case 0x36: /* V9 stqfa */
                   2541:                    goto nfpu_insn;
                   2542:                default:
                   2543:                    goto illegal_insn;
                   2544:                }
                   2545: #else
                   2546:                goto illegal_insn;
                   2547: #endif
                   2548:             }
                   2549:            else
                   2550:                goto illegal_insn;
                   2551:        }
                   2552:        break;
                   2553:     }
                   2554:     /* default case for non jump instructions */
                   2555:     if (dc->npc == DYNAMIC_PC) {
                   2556:        dc->pc = DYNAMIC_PC;
                   2557:        gen_op_next_insn();
                   2558:     } else if (dc->npc == JUMP_PC) {
                   2559:         /* we can do a static jump */
                   2560:         gen_branch2(dc, (long)dc->tb, dc->jump_pc[0], dc->jump_pc[1]);
                   2561:         dc->is_br = 1;
                   2562:     } else {
                   2563:        dc->pc = dc->npc;
                   2564:        dc->npc = dc->npc + 4;
                   2565:     }
                   2566:  jmp_insn:
                   2567:     return;
                   2568:  illegal_insn:
                   2569:     save_state(dc);
                   2570:     gen_op_exception(TT_ILL_INSN);
                   2571:     dc->is_br = 1;
                   2572:     return;
                   2573: #if !defined(CONFIG_USER_ONLY)
                   2574:  priv_insn:
                   2575:     save_state(dc);
                   2576:     gen_op_exception(TT_PRIV_INSN);
                   2577:     dc->is_br = 1;
                   2578:     return;
                   2579: #endif
                   2580:  nfpu_insn:
                   2581:     save_state(dc);
                   2582:     gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
                   2583:     dc->is_br = 1;
                   2584: }
                   2585: 
                   2586: static inline int gen_intermediate_code_internal(TranslationBlock * tb,
                   2587:                                                 int spc, CPUSPARCState *env)
                   2588: {
                   2589:     target_ulong pc_start, last_pc;
                   2590:     uint16_t *gen_opc_end;
                   2591:     DisasContext dc1, *dc = &dc1;
                   2592:     int j, lj = -1;
                   2593: 
                   2594:     memset(dc, 0, sizeof(DisasContext));
                   2595:     dc->tb = tb;
                   2596:     pc_start = tb->pc;
                   2597:     dc->pc = pc_start;
                   2598:     last_pc = dc->pc;
                   2599:     dc->npc = (target_ulong) tb->cs_base;
                   2600: #if defined(CONFIG_USER_ONLY)
                   2601:     dc->mem_idx = 0;
1.1.1.3 ! root     2602:     dc->fpu_enabled = 1;
1.1       root     2603: #else
                   2604:     dc->mem_idx = ((env->psrs) != 0);
1.1.1.3 ! root     2605: #ifdef TARGET_SPARC64
        !          2606:     dc->fpu_enabled = (((env->pstate & PS_PEF) != 0) && ((env->fprs & FPRS_FEF) != 0));
        !          2607: #else
        !          2608:     dc->fpu_enabled = ((env->psref) != 0);
        !          2609: #endif
1.1       root     2610: #endif
                   2611:     gen_opc_ptr = gen_opc_buf;
                   2612:     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
                   2613:     gen_opparam_ptr = gen_opparam_buf;
                   2614:     nb_gen_labels = 0;
                   2615: 
                   2616:     do {
                   2617:         if (env->nb_breakpoints > 0) {
                   2618:             for(j = 0; j < env->nb_breakpoints; j++) {
                   2619:                 if (env->breakpoints[j] == dc->pc) {
                   2620:                    if (dc->pc != pc_start)
                   2621:                        save_state(dc);
                   2622:                     gen_op_debug();
                   2623:                    gen_op_movl_T0_0();
                   2624:                    gen_op_exit_tb();
                   2625:                    dc->is_br = 1;
                   2626:                     goto exit_gen_loop;
                   2627:                 }
                   2628:             }
                   2629:         }
                   2630:         if (spc) {
                   2631:             if (loglevel > 0)
                   2632:                 fprintf(logfile, "Search PC...\n");
                   2633:             j = gen_opc_ptr - gen_opc_buf;
                   2634:             if (lj < j) {
                   2635:                 lj++;
                   2636:                 while (lj < j)
                   2637:                     gen_opc_instr_start[lj++] = 0;
                   2638:                 gen_opc_pc[lj] = dc->pc;
                   2639:                 gen_opc_npc[lj] = dc->npc;
                   2640:                 gen_opc_instr_start[lj] = 1;
                   2641:             }
                   2642:         }
                   2643:        last_pc = dc->pc;
                   2644:        disas_sparc_insn(dc);
                   2645: 
                   2646:        if (dc->is_br)
                   2647:            break;
                   2648:        /* if the next PC is different, we abort now */
                   2649:        if (dc->pc != (last_pc + 4))
                   2650:            break;
                   2651:         /* if we reach a page boundary, we stop generation so that the
                   2652:            PC of a TT_TFAULT exception is always in the right page */
                   2653:         if ((dc->pc & (TARGET_PAGE_SIZE - 1)) == 0)
                   2654:             break;
                   2655:         /* if single step mode, we generate only one instruction and
                   2656:            generate an exception */
                   2657:         if (env->singlestep_enabled) {
                   2658:             gen_jmp_im(dc->pc);
                   2659:             gen_op_movl_T0_0();
                   2660:             gen_op_exit_tb();
                   2661:             break;
                   2662:         }
                   2663:     } while ((gen_opc_ptr < gen_opc_end) &&
                   2664:             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
                   2665: 
                   2666:  exit_gen_loop:
                   2667:     if (!dc->is_br) {
                   2668:         if (dc->pc != DYNAMIC_PC && 
                   2669:             (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
                   2670:             /* static PC and NPC: we can use direct chaining */
                   2671:             gen_branch(dc, (long)tb, dc->pc, dc->npc);
                   2672:         } else {
                   2673:             if (dc->pc != DYNAMIC_PC)
                   2674:                 gen_jmp_im(dc->pc);
                   2675:             save_npc(dc);
                   2676:             gen_op_movl_T0_0();
                   2677:             gen_op_exit_tb();
                   2678:         }
                   2679:     }
                   2680:     *gen_opc_ptr = INDEX_op_end;
                   2681:     if (spc) {
                   2682:         j = gen_opc_ptr - gen_opc_buf;
                   2683:         lj++;
                   2684:         while (lj <= j)
                   2685:             gen_opc_instr_start[lj++] = 0;
                   2686:         tb->size = 0;
                   2687: #if 0
                   2688:         if (loglevel > 0) {
                   2689:             page_dump(logfile);
                   2690:         }
                   2691: #endif
                   2692:         gen_opc_jump_pc[0] = dc->jump_pc[0];
                   2693:         gen_opc_jump_pc[1] = dc->jump_pc[1];
                   2694:     } else {
                   2695:         tb->size = last_pc + 4 - pc_start;
                   2696:     }
                   2697: #ifdef DEBUG_DISAS
                   2698:     if (loglevel & CPU_LOG_TB_IN_ASM) {
                   2699:        fprintf(logfile, "--------------\n");
                   2700:        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
                   2701:        target_disas(logfile, pc_start, last_pc + 4 - pc_start, 0);
                   2702:        fprintf(logfile, "\n");
                   2703:         if (loglevel & CPU_LOG_TB_OP) {
                   2704:             fprintf(logfile, "OP:\n");
                   2705:             dump_ops(gen_opc_buf, gen_opparam_buf);
                   2706:             fprintf(logfile, "\n");
                   2707:         }
                   2708:     }
                   2709: #endif
                   2710:     return 0;
                   2711: }
                   2712: 
                   2713: int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
                   2714: {
                   2715:     return gen_intermediate_code_internal(tb, 0, env);
                   2716: }
                   2717: 
                   2718: int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
                   2719: {
                   2720:     return gen_intermediate_code_internal(tb, 1, env);
                   2721: }
                   2722: 
                   2723: extern int ram_size;
                   2724: 
                   2725: void cpu_reset(CPUSPARCState *env)
                   2726: {
                   2727:     memset(env, 0, sizeof(*env));
                   2728:     tlb_flush(env, 1);
                   2729:     env->cwp = 0;
                   2730:     env->wim = 1;
                   2731:     env->regwptr = env->regbase + (env->cwp * 16);
                   2732: #if defined(CONFIG_USER_ONLY)
                   2733:     env->user_mode_only = 1;
1.1.1.3 ! root     2734: #ifdef TARGET_SPARC64
        !          2735:     env->cleanwin = NWINDOWS - 1;
        !          2736:     env->cansave = NWINDOWS - 1;
        !          2737: #endif
1.1       root     2738: #else
                   2739:     env->psrs = 1;
                   2740:     env->psrps = 1;
                   2741:     env->gregs[1] = ram_size;
                   2742: #ifdef TARGET_SPARC64
                   2743:     env->pstate = PS_PRIV;
                   2744:     env->version = GET_VER(env);
                   2745:     env->pc = 0x1fff0000000ULL;
                   2746: #else
                   2747:     env->mmuregs[0] = (0x04 << 24); /* Impl 0, ver 4, MMU disabled */
                   2748:     env->pc = 0xffd00000;
                   2749: #endif
                   2750:     env->npc = env->pc + 4;
                   2751: #endif
                   2752: }
                   2753: 
                   2754: CPUSPARCState *cpu_sparc_init(void)
                   2755: {
                   2756:     CPUSPARCState *env;
                   2757: 
1.1.1.2   root     2758:     env = qemu_mallocz(sizeof(CPUSPARCState));
                   2759:     if (!env)
                   2760:        return NULL;
                   2761:     cpu_exec_init(env);
1.1       root     2762:     cpu_reset(env);
                   2763:     return (env);
                   2764: }
                   2765: 
                   2766: #define GET_FLAG(a,b) ((env->psr & a)?b:'-')
                   2767: 
                   2768: void cpu_dump_state(CPUState *env, FILE *f, 
                   2769:                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                   2770:                     int flags)
                   2771: {
                   2772:     int i, x;
                   2773: 
                   2774:     cpu_fprintf(f, "pc: " TARGET_FMT_lx "  npc: " TARGET_FMT_lx "\n", env->pc, env->npc);
                   2775:     cpu_fprintf(f, "General Registers:\n");
                   2776:     for (i = 0; i < 4; i++)
                   2777:        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
                   2778:     cpu_fprintf(f, "\n");
                   2779:     for (; i < 8; i++)
                   2780:        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
                   2781:     cpu_fprintf(f, "\nCurrent Register Window:\n");
                   2782:     for (x = 0; x < 3; x++) {
                   2783:        for (i = 0; i < 4; i++)
                   2784:            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
                   2785:                    (x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i,
                   2786:                    env->regwptr[i + x * 8]);
                   2787:        cpu_fprintf(f, "\n");
                   2788:        for (; i < 8; i++)
                   2789:            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
                   2790:                    (x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i,
                   2791:                    env->regwptr[i + x * 8]);
                   2792:        cpu_fprintf(f, "\n");
                   2793:     }
                   2794:     cpu_fprintf(f, "\nFloating Point Registers:\n");
                   2795:     for (i = 0; i < 32; i++) {
                   2796:         if ((i & 3) == 0)
                   2797:             cpu_fprintf(f, "%%f%02d:", i);
                   2798:         cpu_fprintf(f, " %016lf", env->fpr[i]);
                   2799:         if ((i & 3) == 3)
                   2800:             cpu_fprintf(f, "\n");
                   2801:     }
1.1.1.3 ! root     2802: #ifdef TARGET_SPARC64
        !          2803:     cpu_fprintf(f, "pstate: 0x%08x ccr: 0x%02x asi: 0x%02x tl: %d\n",
        !          2804:                env->pstate, GET_CCR(env), env->asi, env->tl);
        !          2805:     cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate %d cleanwin %d cwp %d\n",
        !          2806:                env->cansave, env->canrestore, env->otherwin, env->wstate,
        !          2807:                env->cleanwin, NWINDOWS - 1 - env->cwp);
        !          2808: #else
1.1       root     2809:     cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n", GET_PSR(env),
                   2810:            GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
                   2811:            GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),
                   2812:            env->psrs?'S':'-', env->psrps?'P':'-', 
                   2813:            env->psret?'E':'-', env->wim);
1.1.1.3 ! root     2814: #endif
1.1       root     2815:     cpu_fprintf(f, "fsr: 0x%08x\n", GET_FSR32(env));
                   2816: }
                   2817: 
                   2818: #if defined(CONFIG_USER_ONLY)
                   2819: target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
                   2820: {
                   2821:     return addr;
                   2822: }
                   2823: 
                   2824: #else
                   2825: extern int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
                   2826:                                  int *access_index, target_ulong address, int rw,
                   2827:                                  int is_user);
                   2828: 
                   2829: target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
                   2830: {
                   2831:     target_phys_addr_t phys_addr;
                   2832:     int prot, access_index;
                   2833: 
                   2834:     if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2, 0) != 0)
1.1.1.3 ! root     2835:         if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 0, 0) != 0)
        !          2836:             return -1;
1.1       root     2837:     return phys_addr;
                   2838: }
                   2839: #endif
                   2840: 
                   2841: void helper_flush(target_ulong addr)
                   2842: {
                   2843:     addr &= ~7;
                   2844:     tb_invalidate_page_range(addr, addr + 8);
                   2845: }

unix.superglobalmegacorp.com

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