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

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

unix.superglobalmegacorp.com

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