summaryrefslogtreecommitdiff
path: root/target-sparc/translate.c
diff options
context:
space:
mode:
authorblueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162>2008-05-09 20:13:43 +0000
committerblueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162>2008-05-09 20:13:43 +0000
commit64a88d5d3ac0fa2280eaf1983d974628dcfb9374 (patch)
treea0e611602e3642bf782db76fe43fa30968a88bc9 /target-sparc/translate.c
parent0828b4485a5864482e9a9a7b3c3dcea4033906f6 (diff)
downloadqemu-64a88d5d3ac0fa2280eaf1983d974628dcfb9374.tar.gz
CPU feature selection support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4399 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-sparc/translate.c')
-rw-r--r--target-sparc/translate.c279
1 files changed, 135 insertions, 144 deletions
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index c5f9c69901..b9bc2db217 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -63,6 +63,7 @@ typedef struct DisasContext {
int mem_idx;
int fpu_enabled;
struct TranslationBlock *tb;
+ uint32_t features;
} DisasContext;
extern FILE *logfile;
@@ -140,7 +141,6 @@ static void gen_op_store_DT0_fpr(unsigned int dst)
tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 1]));
}
-#ifdef CONFIG_USER_ONLY
static void gen_op_load_fpr_QT0(unsigned int src)
{
tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
@@ -176,7 +176,6 @@ static void gen_op_store_QT0_fpr(unsigned int dst)
tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lowest));
tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 3]));
}
-#endif
/* moves */
#ifdef CONFIG_USER_ONLY
@@ -1463,14 +1462,12 @@ static GenOpFunc * const gen_fcmpd[4] = {
helper_fcmpd_fcc3,
};
-#if defined(CONFIG_USER_ONLY)
static GenOpFunc * const gen_fcmpq[4] = {
helper_fcmpq,
helper_fcmpq_fcc1,
helper_fcmpq_fcc2,
helper_fcmpq_fcc3,
};
-#endif
static GenOpFunc * const gen_fcmpes[4] = {
helper_fcmpes,
@@ -1486,14 +1483,12 @@ static GenOpFunc * const gen_fcmped[4] = {
helper_fcmped_fcc3,
};
-#if defined(CONFIG_USER_ONLY)
static GenOpFunc * const gen_fcmpeq[4] = {
helper_fcmpeq,
helper_fcmpeq_fcc1,
helper_fcmpeq_fcc2,
helper_fcmpeq_fcc3,
};
-#endif
static inline void gen_op_fcmps(int fccno)
{
@@ -1505,12 +1500,10 @@ static inline void gen_op_fcmpd(int fccno)
tcg_gen_helper_0_0(gen_fcmpd[fccno]);
}
-#if defined(CONFIG_USER_ONLY)
static inline void gen_op_fcmpq(int fccno)
{
tcg_gen_helper_0_0(gen_fcmpq[fccno]);
}
-#endif
static inline void gen_op_fcmpes(int fccno)
{
@@ -1522,12 +1515,10 @@ static inline void gen_op_fcmped(int fccno)
tcg_gen_helper_0_0(gen_fcmped[fccno]);
}
-#if defined(CONFIG_USER_ONLY)
static inline void gen_op_fcmpeq(int fccno)
{
tcg_gen_helper_0_0(gen_fcmpeq[fccno]);
}
-#endif
#else
@@ -1541,12 +1532,10 @@ static inline void gen_op_fcmpd(int fccno)
tcg_gen_helper_0_0(helper_fcmpd);
}
-#if defined(CONFIG_USER_ONLY)
static inline void gen_op_fcmpq(int fccno)
{
tcg_gen_helper_0_0(helper_fcmpq);
}
-#endif
static inline void gen_op_fcmpes(int fccno)
{
@@ -1558,15 +1547,12 @@ static inline void gen_op_fcmped(int fccno)
tcg_gen_helper_0_0(helper_fcmped);
}
-#if defined(CONFIG_USER_ONLY)
static inline void gen_op_fcmpeq(int fccno)
{
tcg_gen_helper_0_0(helper_fcmpeq);
}
#endif
-#endif
-
static inline void gen_op_fpexception_im(int fsr_flags)
{
tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~FSR_FTT_MASK);
@@ -1820,6 +1806,13 @@ static inline TCGv get_src2(unsigned int insn, TCGv def)
return r_rs2;
}
+#define CHECK_IU_FEATURE(dc, FEATURE) \
+ if (!((dc)->features & CPU_FEATURE_ ## FEATURE)) \
+ goto illegal_insn;
+#define CHECK_FPU_FEATURE(dc, FEATURE) \
+ if (!((dc)->features & CPU_FEATURE_ ## FEATURE)) \
+ goto nfpu_insn;
+
/* before an instruction, dc->pc must be static */
static void disas_sparc_insn(DisasContext * dc)
{
@@ -2255,6 +2248,7 @@ static void disas_sparc_insn(DisasContext * dc)
gen_op_store_FT0_fpr(rd);
break;
case 0x29: /* fsqrts */
+ CHECK_FPU_FEATURE(dc, FSQRT);
gen_op_load_fpr_FT1(rs2);
gen_clear_float_exceptions();
tcg_gen_helper_0_0(helper_fsqrts);
@@ -2262,6 +2256,7 @@ static void disas_sparc_insn(DisasContext * dc)
gen_op_store_FT0_fpr(rd);
break;
case 0x2a: /* fsqrtd */
+ CHECK_FPU_FEATURE(dc, FSQRT);
gen_op_load_fpr_DT1(DFPREG(rs2));
gen_clear_float_exceptions();
tcg_gen_helper_0_0(helper_fsqrtd);
@@ -2269,16 +2264,13 @@ static void disas_sparc_insn(DisasContext * dc)
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x2b: /* fsqrtq */
-#if defined(CONFIG_USER_ONLY)
+ CHECK_FPU_FEATURE(dc, FLOAT128);
gen_op_load_fpr_QT1(QFPREG(rs2));
gen_clear_float_exceptions();
tcg_gen_helper_0_0(helper_fsqrtq);
tcg_gen_helper_0_0(helper_check_ieee_exceptions);
gen_op_store_QT0_fpr(QFPREG(rd));
break;
-#else
- goto nfpu_insn;
-#endif
case 0x41:
gen_op_load_fpr_FT0(rs1);
gen_op_load_fpr_FT1(rs2);
@@ -2296,7 +2288,7 @@ static void disas_sparc_insn(DisasContext * dc)
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x43: /* faddq */
-#if defined(CONFIG_USER_ONLY)
+ CHECK_FPU_FEATURE(dc, FLOAT128);
gen_op_load_fpr_QT0(QFPREG(rs1));
gen_op_load_fpr_QT1(QFPREG(rs2));
gen_clear_float_exceptions();
@@ -2304,9 +2296,6 @@ static void disas_sparc_insn(DisasContext * dc)
tcg_gen_helper_0_0(helper_check_ieee_exceptions);
gen_op_store_QT0_fpr(QFPREG(rd));
break;
-#else
- goto nfpu_insn;
-#endif
case 0x45:
gen_op_load_fpr_FT0(rs1);
gen_op_load_fpr_FT1(rs2);
@@ -2324,7 +2313,7 @@ static void disas_sparc_insn(DisasContext * dc)
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x47: /* fsubq */
-#if defined(CONFIG_USER_ONLY)
+ CHECK_FPU_FEATURE(dc, FLOAT128);
gen_op_load_fpr_QT0(QFPREG(rs1));
gen_op_load_fpr_QT1(QFPREG(rs2));
gen_clear_float_exceptions();
@@ -2332,10 +2321,8 @@ static void disas_sparc_insn(DisasContext * dc)
tcg_gen_helper_0_0(helper_check_ieee_exceptions);
gen_op_store_QT0_fpr(QFPREG(rd));
break;
-#else
- goto nfpu_insn;
-#endif
- case 0x49:
+ case 0x49: /* fmuls */
+ CHECK_FPU_FEATURE(dc, FMUL);
gen_op_load_fpr_FT0(rs1);
gen_op_load_fpr_FT1(rs2);
gen_clear_float_exceptions();
@@ -2343,7 +2330,8 @@ static void disas_sparc_insn(DisasContext * dc)
tcg_gen_helper_0_0(helper_check_ieee_exceptions);
gen_op_store_FT0_fpr(rd);
break;
- case 0x4a:
+ case 0x4a: /* fmuld */
+ CHECK_FPU_FEATURE(dc, FMUL);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
gen_clear_float_exceptions();
@@ -2352,7 +2340,8 @@ static void disas_sparc_insn(DisasContext * dc)
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x4b: /* fmulq */
-#if defined(CONFIG_USER_ONLY)
+ CHECK_FPU_FEATURE(dc, FLOAT128);
+ CHECK_FPU_FEATURE(dc, FMUL);
gen_op_load_fpr_QT0(QFPREG(rs1));
gen_op_load_fpr_QT1(QFPREG(rs2));
gen_clear_float_exceptions();
@@ -2360,9 +2349,6 @@ static void disas_sparc_insn(DisasContext * dc)
tcg_gen_helper_0_0(helper_check_ieee_exceptions);
gen_op_store_QT0_fpr(QFPREG(rd));
break;
-#else
- goto nfpu_insn;
-#endif
case 0x4d:
gen_op_load_fpr_FT0(rs1);
gen_op_load_fpr_FT1(rs2);
@@ -2380,7 +2366,7 @@ static void disas_sparc_insn(DisasContext * dc)
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x4f: /* fdivq */
-#if defined(CONFIG_USER_ONLY)
+ CHECK_FPU_FEATURE(dc, FLOAT128);
gen_op_load_fpr_QT0(QFPREG(rs1));
gen_op_load_fpr_QT1(QFPREG(rs2));
gen_clear_float_exceptions();
@@ -2388,9 +2374,6 @@ static void disas_sparc_insn(DisasContext * dc)
tcg_gen_helper_0_0(helper_check_ieee_exceptions);
gen_op_store_QT0_fpr(QFPREG(rd));
break;
-#else
- goto nfpu_insn;
-#endif
case 0x69:
gen_op_load_fpr_FT0(rs1);
gen_op_load_fpr_FT1(rs2);
@@ -2400,7 +2383,7 @@ static void disas_sparc_insn(DisasContext * dc)
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x6e: /* fdmulq */
-#if defined(CONFIG_USER_ONLY)
+ CHECK_FPU_FEATURE(dc, FLOAT128);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
gen_clear_float_exceptions();
@@ -2408,9 +2391,6 @@ static void disas_sparc_insn(DisasContext * dc)
tcg_gen_helper_0_0(helper_check_ieee_exceptions);
gen_op_store_QT0_fpr(QFPREG(rd));
break;
-#else
- goto nfpu_insn;
-#endif
case 0xc4:
gen_op_load_fpr_FT1(rs2);
gen_clear_float_exceptions();
@@ -2426,16 +2406,13 @@ static void disas_sparc_insn(DisasContext * dc)
gen_op_store_FT0_fpr(rd);
break;
case 0xc7: /* fqtos */
-#if defined(CONFIG_USER_ONLY)
+ CHECK_FPU_FEATURE(dc, FLOAT128);
gen_op_load_fpr_QT1(QFPREG(rs2));
gen_clear_float_exceptions();
tcg_gen_helper_0_0(helper_fqtos);
tcg_gen_helper_0_0(helper_check_ieee_exceptions);
gen_op_store_FT0_fpr(rd);
break;
-#else
- goto nfpu_insn;
-#endif
case 0xc8:
gen_op_load_fpr_FT1(rs2);
tcg_gen_helper_0_0(helper_fitod);
@@ -2447,43 +2424,31 @@ static void disas_sparc_insn(DisasContext * dc)
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0xcb: /* fqtod */
-#if defined(CONFIG_USER_ONLY)
+ CHECK_FPU_FEATURE(dc, FLOAT128);
gen_op_load_fpr_QT1(QFPREG(rs2));
gen_clear_float_exceptions();
tcg_gen_helper_0_0(helper_fqtod);
tcg_gen_helper_0_0(helper_check_ieee_exceptions);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
-#else
- goto nfpu_insn;
-#endif
case 0xcc: /* fitoq */
-#if defined(CONFIG_USER_ONLY)
+ CHECK_FPU_FEATURE(dc, FLOAT128);
gen_op_load_fpr_FT1(rs2);
tcg_gen_helper_0_0(helper_fitoq);
gen_op_store_QT0_fpr(QFPREG(rd));
break;
-#else
- goto nfpu_insn;
-#endif
case 0xcd: /* fstoq */
-#if defined(CONFIG_USER_ONLY)
+ CHECK_FPU_FEATURE(dc, FLOAT128);
gen_op_load_fpr_FT1(rs2);
tcg_gen_helper_0_0(helper_fstoq);
gen_op_store_QT0_fpr(QFPREG(rd));
break;
-#else
- goto nfpu_insn;
-#endif
case 0xce: /* fdtoq */
-#if defined(CONFIG_USER_ONLY)
+ CHECK_FPU_FEATURE(dc, FLOAT128);
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fdtoq);
gen_op_store_QT0_fpr(QFPREG(rd));
break;
-#else
- goto nfpu_insn;
-#endif
case 0xd1:
gen_op_load_fpr_FT1(rs2);
gen_clear_float_exceptions();
@@ -2499,57 +2464,45 @@ static void disas_sparc_insn(DisasContext * dc)
gen_op_store_FT0_fpr(rd);
break;
case 0xd3: /* fqtoi */
-#if defined(CONFIG_USER_ONLY)
+ CHECK_FPU_FEATURE(dc, FLOAT128);
gen_op_load_fpr_QT1(QFPREG(rs2));
gen_clear_float_exceptions();
tcg_gen_helper_0_0(helper_fqtoi);
tcg_gen_helper_0_0(helper_check_ieee_exceptions);
gen_op_store_FT0_fpr(rd);
break;
-#else
- goto nfpu_insn;
-#endif
#ifdef TARGET_SPARC64
case 0x2: /* V9 fmovd */
gen_op_load_fpr_DT0(DFPREG(rs2));
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x3: /* V9 fmovq */
-#if defined(CONFIG_USER_ONLY)
+ CHECK_FPU_FEATURE(dc, FLOAT128);
gen_op_load_fpr_QT0(QFPREG(rs2));
gen_op_store_QT0_fpr(QFPREG(rd));
break;
-#else
- goto nfpu_insn;
-#endif
case 0x6: /* V9 fnegd */
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fnegd);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x7: /* V9 fnegq */
-#if defined(CONFIG_USER_ONLY)
+ CHECK_FPU_FEATURE(dc, FLOAT128);
gen_op_load_fpr_QT1(QFPREG(rs2));
tcg_gen_helper_0_0(helper_fnegq);
gen_op_store_QT0_fpr(QFPREG(rd));
break;
-#else
- goto nfpu_insn;
-#endif
case 0xa: /* V9 fabsd */
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fabsd);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0xb: /* V9 fabsq */
-#if defined(CONFIG_USER_ONLY)
+ CHECK_FPU_FEATURE(dc, FLOAT128);
gen_op_load_fpr_QT1(QFPREG(rs2));
tcg_gen_helper_0_0(helper_fabsq);
gen_op_store_QT0_fpr(QFPREG(rd));
break;
-#else
- goto nfpu_insn;
-#endif
case 0x81: /* V9 fstox */
gen_op_load_fpr_FT1(rs2);
gen_clear_float_exceptions();
@@ -2565,16 +2518,13 @@ static void disas_sparc_insn(DisasContext * dc)
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x83: /* V9 fqtox */
-#if defined(CONFIG_USER_ONLY)
+ CHECK_FPU_FEATURE(dc, FLOAT128);
gen_op_load_fpr_QT1(QFPREG(rs2));
gen_clear_float_exceptions();
tcg_gen_helper_0_0(helper_fqtox);
tcg_gen_helper_0_0(helper_check_ieee_exceptions);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
-#else
- goto nfpu_insn;
-#endif
case 0x84: /* V9 fxtos */
gen_op_load_fpr_DT1(DFPREG(rs2));
gen_clear_float_exceptions();
@@ -2590,16 +2540,13 @@ static void disas_sparc_insn(DisasContext * dc)
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x8c: /* V9 fxtoq */
-#if defined(CONFIG_USER_ONLY)
+ CHECK_FPU_FEATURE(dc, FLOAT128);
gen_op_load_fpr_DT1(DFPREG(rs2));
gen_clear_float_exceptions();
tcg_gen_helper_0_0(helper_fxtoq);
tcg_gen_helper_0_0(helper_check_ieee_exceptions);
gen_op_store_QT0_fpr(QFPREG(rd));
break;
-#else
- goto nfpu_insn;
-#endif
#endif
default:
goto illegal_insn;
@@ -2640,9 +2587,9 @@ static void disas_sparc_insn(DisasContext * dc)
gen_set_label(l1);
break;
} else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
-#if defined(CONFIG_USER_ONLY)
int l1;
+ CHECK_FPU_FEATURE(dc, FLOAT128);
l1 = gen_new_label();
cond = GET_FIELD_SP(insn, 14, 17);
cpu_src1 = get_src1(insn, cpu_src1);
@@ -2652,9 +2599,6 @@ static void disas_sparc_insn(DisasContext * dc)
gen_op_store_QT0_fpr(QFPREG(rd));
gen_set_label(l1);
break;
-#else
- goto nfpu_insn;
-#endif
}
#endif
switch (xop) {
@@ -2681,12 +2625,9 @@ static void disas_sparc_insn(DisasContext * dc)
FMOVCC(D, 0);
break;
case 0x003: /* V9 fmovqcc %fcc0 */
-#if defined(CONFIG_USER_ONLY)
+ CHECK_FPU_FEATURE(dc, FLOAT128);
FMOVCC(Q, 0);
break;
-#else
- goto nfpu_insn;
-#endif
case 0x041: /* V9 fmovscc %fcc1 */
FMOVCC(F, 1);
break;
@@ -2694,12 +2635,9 @@ static void disas_sparc_insn(DisasContext * dc)
FMOVCC(D, 1);
break;
case 0x043: /* V9 fmovqcc %fcc1 */
-#if defined(CONFIG_USER_ONLY)
+ CHECK_FPU_FEATURE(dc, FLOAT128);
FMOVCC(Q, 1);
break;
-#else
- goto nfpu_insn;
-#endif
case 0x081: /* V9 fmovscc %fcc2 */
FMOVCC(F, 2);
break;
@@ -2707,12 +2645,9 @@ static void disas_sparc_insn(DisasContext * dc)
FMOVCC(D, 2);
break;
case 0x083: /* V9 fmovqcc %fcc2 */
-#if defined(CONFIG_USER_ONLY)
+ CHECK_FPU_FEATURE(dc, FLOAT128);
FMOVCC(Q, 2);
break;
-#else
- goto nfpu_insn;
-#endif
case 0x0c1: /* V9 fmovscc %fcc3 */
FMOVCC(F, 3);
break;
@@ -2720,12 +2655,9 @@ static void disas_sparc_insn(DisasContext * dc)
FMOVCC(D, 3);
break;
case 0x0c3: /* V9 fmovqcc %fcc3 */
-#if defined(CONFIG_USER_ONLY)
+ CHECK_FPU_FEATURE(dc, FLOAT128);
FMOVCC(Q, 3);
break;
-#else
- goto nfpu_insn;
-#endif
#undef FMOVCC
#define FMOVCC(size_FDQ, icc) \
{ \
@@ -2749,12 +2681,9 @@ static void disas_sparc_insn(DisasContext * dc)
case 0x102: /* V9 fmovdcc %icc */
FMOVCC(D, 0);
case 0x103: /* V9 fmovqcc %icc */
-#if defined(CONFIG_USER_ONLY)
- FMOVCC(D, 0);
+ CHECK_FPU_FEATURE(dc, FLOAT128);
+ FMOVCC(Q, 0);
break;
-#else
- goto nfpu_insn;
-#endif
case 0x181: /* V9 fmovscc %xcc */
FMOVCC(F, 1);
break;
@@ -2762,12 +2691,9 @@ static void disas_sparc_insn(DisasContext * dc)
FMOVCC(D, 1);
break;
case 0x183: /* V9 fmovqcc %xcc */
-#if defined(CONFIG_USER_ONLY)
+ CHECK_FPU_FEATURE(dc, FLOAT128);
FMOVCC(Q, 1);
break;
-#else
- goto nfpu_insn;
-#endif
#undef FMOVCC
#endif
case 0x51: /* fcmps, V9 %fcc */
@@ -2781,14 +2707,11 @@ static void disas_sparc_insn(DisasContext * dc)
gen_op_fcmpd(rd & 3);
break;
case 0x53: /* fcmpq, V9 %fcc */
-#if defined(CONFIG_USER_ONLY)
+ CHECK_FPU_FEATURE(dc, FLOAT128);
gen_op_load_fpr_QT0(QFPREG(rs1));
gen_op_load_fpr_QT1(QFPREG(rs2));
gen_op_fcmpq(rd & 3);
break;
-#else /* !defined(CONFIG_USER_ONLY) */
- goto nfpu_insn;
-#endif
case 0x55: /* fcmpes, V9 %fcc */
gen_op_load_fpr_FT0(rs1);
gen_op_load_fpr_FT1(rs2);
@@ -2800,14 +2723,11 @@ static void disas_sparc_insn(DisasContext * dc)
gen_op_fcmped(rd & 3);
break;
case 0x57: /* fcmpeq, V9 %fcc */
-#if defined(CONFIG_USER_ONLY)
+ CHECK_FPU_FEATURE(dc, FLOAT128);
gen_op_load_fpr_QT0(QFPREG(rs1));
gen_op_load_fpr_QT1(QFPREG(rs2));
gen_op_fcmpeq(rd & 3);
break;
-#else/* !defined(CONFIG_USER_ONLY) */
- goto nfpu_insn;
-#endif
default:
goto illegal_insn;
}
@@ -2979,11 +2899,13 @@ static void disas_sparc_insn(DisasContext * dc)
break;
#endif
case 0xa:
+ CHECK_IU_FEATURE(dc, MUL);
gen_op_umul(cpu_dst, cpu_src1, cpu_src2);
if (xop & 0x10)
gen_op_logic_cc(cpu_dst);
break;
case 0xb:
+ CHECK_IU_FEATURE(dc, MUL);
gen_op_smul(cpu_dst, cpu_src1, cpu_src2);
if (xop & 0x10)
gen_op_logic_cc(cpu_dst);
@@ -3004,11 +2926,13 @@ static void disas_sparc_insn(DisasContext * dc)
break;
#endif
case 0xe:
+ CHECK_IU_FEATURE(dc, DIV);
tcg_gen_helper_1_2(helper_udiv, cpu_dst, cpu_src1, cpu_src2);
if (xop & 0x10)
gen_op_div_cc(cpu_dst);
break;
case 0xf:
+ CHECK_IU_FEATURE(dc, DIV);
tcg_gen_helper_1_2(helper_sdiv, cpu_dst, cpu_src1, cpu_src2);
if (xop & 0x10)
gen_op_div_cc(cpu_dst);
@@ -3476,6 +3400,7 @@ static void disas_sparc_insn(DisasContext * dc)
// XXX
goto illegal_insn;
case 0x010: /* VIS I array8 */
+ CHECK_FPU_FEATURE(dc, VIS1);
cpu_src1 = get_src1(insn, cpu_src1);
gen_movl_reg_TN(rs2, cpu_src2);
tcg_gen_helper_1_2(helper_array8, cpu_dst, cpu_src1,
@@ -3483,6 +3408,7 @@ static void disas_sparc_insn(DisasContext * dc)
gen_movl_TN_reg(rd, cpu_dst);
break;
case 0x012: /* VIS I array16 */
+ CHECK_FPU_FEATURE(dc, VIS1);
cpu_src1 = get_src1(insn, cpu_src1);
gen_movl_reg_TN(rs2, cpu_src2);
tcg_gen_helper_1_2(helper_array8, cpu_dst, cpu_src1,
@@ -3491,6 +3417,7 @@ static void disas_sparc_insn(DisasContext * dc)
gen_movl_TN_reg(rd, cpu_dst);
break;
case 0x014: /* VIS I array32 */
+ CHECK_FPU_FEATURE(dc, VIS1);
cpu_src1 = get_src1(insn, cpu_src1);
gen_movl_reg_TN(rs2, cpu_src2);
tcg_gen_helper_1_2(helper_array8, cpu_dst, cpu_src1,
@@ -3499,6 +3426,7 @@ static void disas_sparc_insn(DisasContext * dc)
gen_movl_TN_reg(rd, cpu_dst);
break;
case 0x018: /* VIS I alignaddr */
+ CHECK_FPU_FEATURE(dc, VIS1);
cpu_src1 = get_src1(insn, cpu_src1);
gen_movl_reg_TN(rs2, cpu_src2);
tcg_gen_helper_1_2(helper_alignaddr, cpu_dst, cpu_src1,
@@ -3510,90 +3438,105 @@ static void disas_sparc_insn(DisasContext * dc)
// XXX
goto illegal_insn;
case 0x020: /* VIS I fcmple16 */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fcmple16);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x022: /* VIS I fcmpne16 */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fcmpne16);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x024: /* VIS I fcmple32 */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fcmple32);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x026: /* VIS I fcmpne32 */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fcmpne32);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x028: /* VIS I fcmpgt16 */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fcmpgt16);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x02a: /* VIS I fcmpeq16 */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fcmpeq16);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x02c: /* VIS I fcmpgt32 */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fcmpgt32);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x02e: /* VIS I fcmpeq32 */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fcmpeq32);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x031: /* VIS I fmul8x16 */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fmul8x16);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x033: /* VIS I fmul8x16au */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fmul8x16au);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x035: /* VIS I fmul8x16al */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fmul8x16al);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x036: /* VIS I fmul8sux16 */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fmul8sux16);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x037: /* VIS I fmul8ulx16 */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fmul8ulx16);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x038: /* VIS I fmuld8sux16 */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fmuld8sux16);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x039: /* VIS I fmuld8ulx16 */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fmuld8ulx16);
@@ -3606,12 +3549,14 @@ static void disas_sparc_insn(DisasContext * dc)
// XXX
goto illegal_insn;
case 0x048: /* VIS I faligndata */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_faligndata);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x04b: /* VIS I fpmerge */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fpmerge);
@@ -3621,228 +3566,269 @@ static void disas_sparc_insn(DisasContext * dc)
// XXX
goto illegal_insn;
case 0x04d: /* VIS I fexpand */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fexpand);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x050: /* VIS I fpadd16 */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fpadd16);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x051: /* VIS I fpadd16s */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_FT0(rs1);
gen_op_load_fpr_FT1(rs2);
tcg_gen_helper_0_0(helper_fpadd16s);
gen_op_store_FT0_fpr(rd);
break;
case 0x052: /* VIS I fpadd32 */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fpadd32);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x053: /* VIS I fpadd32s */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_FT0(rs1);
gen_op_load_fpr_FT1(rs2);
tcg_gen_helper_0_0(helper_fpadd32s);
gen_op_store_FT0_fpr(rd);
break;
case 0x054: /* VIS I fpsub16 */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fpsub16);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x055: /* VIS I fpsub16s */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_FT0(rs1);
gen_op_load_fpr_FT1(rs2);
tcg_gen_helper_0_0(helper_fpsub16s);
gen_op_store_FT0_fpr(rd);
break;
case 0x056: /* VIS I fpsub32 */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fpadd32);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x057: /* VIS I fpsub32s */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_FT0(rs1);
gen_op_load_fpr_FT1(rs2);
tcg_gen_helper_0_0(helper_fpsub32s);
gen_op_store_FT0_fpr(rd);
break;
case 0x060: /* VIS I fzero */
+ CHECK_FPU_FEATURE(dc, VIS1);
tcg_gen_helper_0_0(helper_movl_DT0_0);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x061: /* VIS I fzeros */
+ CHECK_FPU_FEATURE(dc, VIS1);
tcg_gen_helper_0_0(helper_movl_FT0_0);
gen_op_store_FT0_fpr(rd);
break;
case 0x062: /* VIS I fnor */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fnor);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x063: /* VIS I fnors */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_FT0(rs1);
gen_op_load_fpr_FT1(rs2);
tcg_gen_helper_0_0(helper_fnors);
gen_op_store_FT0_fpr(rd);
break;
case 0x064: /* VIS I fandnot2 */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT1(DFPREG(rs1));
gen_op_load_fpr_DT0(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fandnot);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x065: /* VIS I fandnot2s */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_FT1(rs1);
gen_op_load_fpr_FT0(rs2);
tcg_gen_helper_0_0(helper_fandnots);
gen_op_store_FT0_fpr(rd);
break;
case 0x066: /* VIS I fnot2 */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fnot);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x067: /* VIS I fnot2s */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_FT1(rs2);
tcg_gen_helper_0_0(helper_fnot);
gen_op_store_FT0_fpr(rd);
break;
case 0x068: /* VIS I fandnot1 */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fandnot);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x069: /* VIS I fandnot1s */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_FT0(rs1);
gen_op_load_fpr_FT1(rs2);
tcg_gen_helper_0_0(helper_fandnots);
gen_op_store_FT0_fpr(rd);
break;
case 0x06a: /* VIS I fnot1 */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT1(DFPREG(rs1));
tcg_gen_helper_0_0(helper_fnot);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x06b: /* VIS I fnot1s */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_FT1(rs1);
tcg_gen_helper_0_0(helper_fnot);
gen_op_store_FT0_fpr(rd);
break;
case 0x06c: /* VIS I fxor */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fxor);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x06d: /* VIS I fxors */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_FT0(rs1);
gen_op_load_fpr_FT1(rs2);
tcg_gen_helper_0_0(helper_fxors);
gen_op_store_FT0_fpr(rd);
break;
case 0x06e: /* VIS I fnand */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fnand);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x06f: /* VIS I fnands */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_FT0(rs1);
gen_op_load_fpr_FT1(rs2);
tcg_gen_helper_0_0(helper_fnands);
gen_op_store_FT0_fpr(rd);
break;
case 0x070: /* VIS I fand */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fand);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x071: /* VIS I fands */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_FT0(rs1);
gen_op_load_fpr_FT1(rs2);
tcg_gen_helper_0_0(helper_fands);
gen_op_store_FT0_fpr(rd);
break;
case 0x072: /* VIS I fxnor */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fxnor);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x073: /* VIS I fxnors */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_FT0(rs1);
gen_op_load_fpr_FT1(rs2);
tcg_gen_helper_0_0(helper_fxnors);
gen_op_store_FT0_fpr(rd);
break;
case 0x074: /* VIS I fsrc1 */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x075: /* VIS I fsrc1s */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_FT0(rs1);
gen_op_store_FT0_fpr(rd);
break;
case 0x076: /* VIS I fornot2 */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT1(DFPREG(rs1));
gen_op_load_fpr_DT0(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fornot);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x077: /* VIS I fornot2s */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_FT1(rs1);
gen_op_load_fpr_FT0(rs2);
tcg_gen_helper_0_0(helper_fornots);
gen_op_store_FT0_fpr(rd);
break;
case 0x078: /* VIS I fsrc2 */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs2));
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x079: /* VIS I fsrc2s */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_FT0(rs2);
gen_op_store_FT0_fpr(rd);
break;
case 0x07a: /* VIS I fornot1 */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_fornot);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x07b: /* VIS I fornot1s */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_FT0(rs1);
gen_op_load_fpr_FT1(rs2);
tcg_gen_helper_0_0(helper_fornots);
gen_op_store_FT0_fpr(rd);
break;
case 0x07c: /* VIS I for */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_DT0(DFPREG(rs1));
gen_op_load_fpr_DT1(DFPREG(rs2));
tcg_gen_helper_0_0(helper_for);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x07d: /* VIS I fors */
+ CHECK_FPU_FEATURE(dc, VIS1);
gen_op_load_fpr_FT0(rs1);
gen_op_load_fpr_FT1(rs2);
tcg_gen_helper_0_0(helper_fors);
gen_op_store_FT0_fpr(rd);
break;
case 0x07e: /* VIS I fone */
+ CHECK_FPU_FEATURE(dc, VIS1);
tcg_gen_helper_0_0(helper_movl_DT0_1);
gen_op_store_DT0_fpr(DFPREG(rd));
break;
case 0x07f: /* VIS I fones */
+ CHECK_FPU_FEATURE(dc, VIS1);
tcg_gen_helper_0_0(helper_movl_FT0_1);
gen_op_store_FT0_fpr(rd);
break;
@@ -3921,6 +3907,8 @@ static void disas_sparc_insn(DisasContext * dc)
goto jmp_insn;
#endif
case 0x3b: /* flush */
+ if (!((dc)->features & CPU_FEATURE_FLUSH))
+ goto unimp_flush;
tcg_gen_helper_0_1(helper_flush, cpu_dst);
break;
case 0x3c: /* save */
@@ -4034,6 +4022,7 @@ static void disas_sparc_insn(DisasContext * dc)
tcg_gen_qemu_st8(tcg_const_tl(0xff), cpu_addr, dc->mem_idx);
break;
case 0x0f: /* swap register with memory. Also atomically */
+ CHECK_IU_FEATURE(dc, SWAP);
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
gen_movl_reg_TN(rd, cpu_val);
ABI32_MASK(cpu_addr);
@@ -4113,6 +4102,7 @@ static void disas_sparc_insn(DisasContext * dc)
gen_ldstub_asi(cpu_val, cpu_addr, insn);
break;
case 0x1f: /* swap reg with alt. memory. Also atomically */
+ CHECK_IU_FEATURE(dc, SWAP);
#ifndef TARGET_SPARC64
if (IS_IMM)
goto illegal_insn;
@@ -4163,13 +4153,10 @@ static void disas_sparc_insn(DisasContext * dc)
case 0x3d: /* V9 prefetcha, no effect */
goto skip_move;
case 0x32: /* V9 ldqfa */
-#if defined(CONFIG_USER_ONLY)
+ CHECK_FPU_FEATURE(dc, FLOAT128);
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
gen_ldf_asi(cpu_addr, insn, 16, QFPREG(rd));
goto skip_move;
-#else
- goto nfpu_insn;
-#endif
#endif
default:
goto illegal_insn;
@@ -4196,15 +4183,12 @@ static void disas_sparc_insn(DisasContext * dc)
tcg_gen_helper_0_0(helper_ldfsr);
break;
case 0x22: /* load quad fpreg */
-#if defined(CONFIG_USER_ONLY)
+ CHECK_FPU_FEATURE(dc, FLOAT128);
tcg_gen_helper_0_2(helper_check_align, cpu_addr,
tcg_const_i32(7));
- tcg_gen_helper_0_1(helper_ldqf, cpu_addr);
+ tcg_gen_helper_0_2(helper_ldqf, cpu_addr, dc->mem_idx);
gen_op_store_QT0_fpr(QFPREG(rd));
break;
-#else
- goto nfpu_insn;
-#endif
case 0x23: /* load double fpreg */
tcg_gen_helper_0_2(helper_check_align, cpu_addr,
tcg_const_i32(7));
@@ -4334,16 +4318,13 @@ static void disas_sparc_insn(DisasContext * dc)
break;
case 0x26:
#ifdef TARGET_SPARC64
-#if defined(CONFIG_USER_ONLY)
/* V9 stqf, store quad fpreg */
+ CHECK_FPU_FEATURE(dc, FLOAT128);
tcg_gen_helper_0_2(helper_check_align, cpu_addr,
tcg_const_i32(7));
gen_op_load_fpr_QT0(QFPREG(rd));
- tcg_gen_helper_0_1(helper_stqf, cpu_addr);
+ tcg_gen_helper_0_2(helper_stqf, cpu_addr, dc->mem_idx);
break;
-#else
- goto nfpu_insn;
-#endif
#else /* !TARGET_SPARC64 */
/* stdfq, store floating point queue */
#if defined(CONFIG_USER_ONLY)
@@ -4375,14 +4356,12 @@ static void disas_sparc_insn(DisasContext * dc)
gen_stf_asi(cpu_addr, insn, 4, rd);
break;
case 0x36: /* V9 stqfa */
-#if defined(CONFIG_USER_ONLY)
- tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
+ CHECK_FPU_FEATURE(dc, FLOAT128);
+ tcg_gen_helper_0_2(helper_check_align, cpu_addr,
+ tcg_const_i32(7));
gen_op_load_fpr_QT0(QFPREG(rd));
gen_stf_asi(cpu_addr, insn, 16, QFPREG(rd));
break;
-#else
- goto nfpu_insn;
-#endif
case 0x37: /* V9 stdfa */
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
gen_op_load_fpr_DT0(DFPREG(rd));
@@ -4433,25 +4412,30 @@ static void disas_sparc_insn(DisasContext * dc)
tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_ILL_INSN));
dc->is_br = 1;
return;
+ unimp_flush:
+ save_state(dc, cpu_cond);
+ tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_UNIMP_FLUSH));
+ dc->is_br = 1;
+ return;
#if !defined(CONFIG_USER_ONLY)
priv_insn:
save_state(dc, cpu_cond);
tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_PRIV_INSN));
dc->is_br = 1;
return;
+#endif
nfpu_insn:
save_state(dc, cpu_cond);
gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
dc->is_br = 1;
return;
-#ifndef TARGET_SPARC64
+#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
nfq_insn:
save_state(dc, cpu_cond);
gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
dc->is_br = 1;
return;
#endif
-#endif
#ifndef TARGET_SPARC64
ncp_insn:
save_state(dc, cpu_cond);
@@ -4480,7 +4464,14 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb,
last_pc = dc->pc;
dc->npc = (target_ulong) tb->cs_base;
dc->mem_idx = cpu_mmu_index(env);
- dc->fpu_enabled = cpu_fpu_enabled(env);
+ dc->features = env->features;
+ if ((dc->features & CPU_FEATURE_FLOAT)) {
+ dc->fpu_enabled = cpu_fpu_enabled(env);
+#if defined(CONFIG_USER_ONLY)
+ dc->features |= CPU_FEATURE_FLOAT128;
+#endif
+ } else
+ dc->fpu_enabled = 0;
gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);