mirror of https://github.com/xqemu/xqemu.git
Implemented cabs FP instructions, and improve exception handling for
trunc/floor/ceil/round. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2804 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
287c4b84f4
commit
5a1e8ffbe7
|
@ -1965,6 +1965,9 @@ FLOAT_OP(roundl, d)
|
||||||
set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
|
set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
|
||||||
DT2 = float64_round_to_int(FDT0, &env->fp_status);
|
DT2 = float64_round_to_int(FDT0, &env->fp_status);
|
||||||
RESTORE_ROUNDING_MODE;
|
RESTORE_ROUNDING_MODE;
|
||||||
|
update_fcr31();
|
||||||
|
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
|
||||||
|
DT2 = 0x7fffffffffffffffULL;
|
||||||
DEBUG_FPU_STATE();
|
DEBUG_FPU_STATE();
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
@ -1973,6 +1976,9 @@ FLOAT_OP(roundl, s)
|
||||||
set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
|
set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
|
||||||
DT2 = float32_round_to_int(FST0, &env->fp_status);
|
DT2 = float32_round_to_int(FST0, &env->fp_status);
|
||||||
RESTORE_ROUNDING_MODE;
|
RESTORE_ROUNDING_MODE;
|
||||||
|
update_fcr31();
|
||||||
|
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
|
||||||
|
DT2 = 0x7fffffffffffffffULL;
|
||||||
DEBUG_FPU_STATE();
|
DEBUG_FPU_STATE();
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
@ -1981,6 +1987,9 @@ FLOAT_OP(roundw, d)
|
||||||
set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
|
set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
|
||||||
WT2 = float64_round_to_int(FDT0, &env->fp_status);
|
WT2 = float64_round_to_int(FDT0, &env->fp_status);
|
||||||
RESTORE_ROUNDING_MODE;
|
RESTORE_ROUNDING_MODE;
|
||||||
|
update_fcr31();
|
||||||
|
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
|
||||||
|
WT2 = 0x7fffffff;
|
||||||
DEBUG_FPU_STATE();
|
DEBUG_FPU_STATE();
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
@ -1989,6 +1998,9 @@ FLOAT_OP(roundw, s)
|
||||||
set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
|
set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
|
||||||
WT2 = float32_round_to_int(FST0, &env->fp_status);
|
WT2 = float32_round_to_int(FST0, &env->fp_status);
|
||||||
RESTORE_ROUNDING_MODE;
|
RESTORE_ROUNDING_MODE;
|
||||||
|
update_fcr31();
|
||||||
|
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
|
||||||
|
WT2 = 0x7fffffff;
|
||||||
DEBUG_FPU_STATE();
|
DEBUG_FPU_STATE();
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
@ -1996,24 +2008,36 @@ FLOAT_OP(roundw, s)
|
||||||
FLOAT_OP(truncl, d)
|
FLOAT_OP(truncl, d)
|
||||||
{
|
{
|
||||||
DT2 = float64_to_int64_round_to_zero(FDT0, &env->fp_status);
|
DT2 = float64_to_int64_round_to_zero(FDT0, &env->fp_status);
|
||||||
|
update_fcr31();
|
||||||
|
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
|
||||||
|
DT2 = 0x7fffffffffffffffULL;
|
||||||
DEBUG_FPU_STATE();
|
DEBUG_FPU_STATE();
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
FLOAT_OP(truncl, s)
|
FLOAT_OP(truncl, s)
|
||||||
{
|
{
|
||||||
DT2 = float32_to_int64_round_to_zero(FST0, &env->fp_status);
|
DT2 = float32_to_int64_round_to_zero(FST0, &env->fp_status);
|
||||||
|
update_fcr31();
|
||||||
|
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
|
||||||
|
DT2 = 0x7fffffffffffffffULL;
|
||||||
DEBUG_FPU_STATE();
|
DEBUG_FPU_STATE();
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
FLOAT_OP(truncw, d)
|
FLOAT_OP(truncw, d)
|
||||||
{
|
{
|
||||||
WT2 = float64_to_int32_round_to_zero(FDT0, &env->fp_status);
|
WT2 = float64_to_int32_round_to_zero(FDT0, &env->fp_status);
|
||||||
|
update_fcr31();
|
||||||
|
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
|
||||||
|
WT2 = 0x7fffffff;
|
||||||
DEBUG_FPU_STATE();
|
DEBUG_FPU_STATE();
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
FLOAT_OP(truncw, s)
|
FLOAT_OP(truncw, s)
|
||||||
{
|
{
|
||||||
WT2 = float32_to_int32_round_to_zero(FST0, &env->fp_status);
|
WT2 = float32_to_int32_round_to_zero(FST0, &env->fp_status);
|
||||||
|
update_fcr31();
|
||||||
|
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
|
||||||
|
WT2 = 0x7fffffff;
|
||||||
DEBUG_FPU_STATE();
|
DEBUG_FPU_STATE();
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
@ -2023,6 +2047,9 @@ FLOAT_OP(ceill, d)
|
||||||
set_float_rounding_mode(float_round_up, &env->fp_status);
|
set_float_rounding_mode(float_round_up, &env->fp_status);
|
||||||
DT2 = float64_round_to_int(FDT0, &env->fp_status);
|
DT2 = float64_round_to_int(FDT0, &env->fp_status);
|
||||||
RESTORE_ROUNDING_MODE;
|
RESTORE_ROUNDING_MODE;
|
||||||
|
update_fcr31();
|
||||||
|
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
|
||||||
|
DT2 = 0x7fffffffffffffffULL;
|
||||||
DEBUG_FPU_STATE();
|
DEBUG_FPU_STATE();
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
@ -2031,6 +2058,9 @@ FLOAT_OP(ceill, s)
|
||||||
set_float_rounding_mode(float_round_up, &env->fp_status);
|
set_float_rounding_mode(float_round_up, &env->fp_status);
|
||||||
DT2 = float32_round_to_int(FST0, &env->fp_status);
|
DT2 = float32_round_to_int(FST0, &env->fp_status);
|
||||||
RESTORE_ROUNDING_MODE;
|
RESTORE_ROUNDING_MODE;
|
||||||
|
update_fcr31();
|
||||||
|
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
|
||||||
|
DT2 = 0x7fffffffffffffffULL;
|
||||||
DEBUG_FPU_STATE();
|
DEBUG_FPU_STATE();
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
@ -2039,6 +2069,9 @@ FLOAT_OP(ceilw, d)
|
||||||
set_float_rounding_mode(float_round_up, &env->fp_status);
|
set_float_rounding_mode(float_round_up, &env->fp_status);
|
||||||
WT2 = float64_round_to_int(FDT0, &env->fp_status);
|
WT2 = float64_round_to_int(FDT0, &env->fp_status);
|
||||||
RESTORE_ROUNDING_MODE;
|
RESTORE_ROUNDING_MODE;
|
||||||
|
update_fcr31();
|
||||||
|
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
|
||||||
|
WT2 = 0x7fffffff;
|
||||||
DEBUG_FPU_STATE();
|
DEBUG_FPU_STATE();
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
@ -2047,6 +2080,9 @@ FLOAT_OP(ceilw, s)
|
||||||
set_float_rounding_mode(float_round_up, &env->fp_status);
|
set_float_rounding_mode(float_round_up, &env->fp_status);
|
||||||
WT2 = float32_round_to_int(FST0, &env->fp_status);
|
WT2 = float32_round_to_int(FST0, &env->fp_status);
|
||||||
RESTORE_ROUNDING_MODE;
|
RESTORE_ROUNDING_MODE;
|
||||||
|
update_fcr31();
|
||||||
|
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
|
||||||
|
WT2 = 0x7fffffff;
|
||||||
DEBUG_FPU_STATE();
|
DEBUG_FPU_STATE();
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
@ -2056,6 +2092,9 @@ FLOAT_OP(floorl, d)
|
||||||
set_float_rounding_mode(float_round_down, &env->fp_status);
|
set_float_rounding_mode(float_round_down, &env->fp_status);
|
||||||
DT2 = float64_round_to_int(FDT0, &env->fp_status);
|
DT2 = float64_round_to_int(FDT0, &env->fp_status);
|
||||||
RESTORE_ROUNDING_MODE;
|
RESTORE_ROUNDING_MODE;
|
||||||
|
update_fcr31();
|
||||||
|
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
|
||||||
|
DT2 = 0x7fffffffffffffffULL;
|
||||||
DEBUG_FPU_STATE();
|
DEBUG_FPU_STATE();
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
@ -2064,6 +2103,9 @@ FLOAT_OP(floorl, s)
|
||||||
set_float_rounding_mode(float_round_down, &env->fp_status);
|
set_float_rounding_mode(float_round_down, &env->fp_status);
|
||||||
DT2 = float32_round_to_int(FST0, &env->fp_status);
|
DT2 = float32_round_to_int(FST0, &env->fp_status);
|
||||||
RESTORE_ROUNDING_MODE;
|
RESTORE_ROUNDING_MODE;
|
||||||
|
update_fcr31();
|
||||||
|
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
|
||||||
|
DT2 = 0x7fffffffffffffffULL;
|
||||||
DEBUG_FPU_STATE();
|
DEBUG_FPU_STATE();
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
@ -2072,6 +2114,9 @@ FLOAT_OP(floorw, d)
|
||||||
set_float_rounding_mode(float_round_down, &env->fp_status);
|
set_float_rounding_mode(float_round_down, &env->fp_status);
|
||||||
WT2 = float64_round_to_int(FDT0, &env->fp_status);
|
WT2 = float64_round_to_int(FDT0, &env->fp_status);
|
||||||
RESTORE_ROUNDING_MODE;
|
RESTORE_ROUNDING_MODE;
|
||||||
|
update_fcr31();
|
||||||
|
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
|
||||||
|
WT2 = 0x7fffffff;
|
||||||
DEBUG_FPU_STATE();
|
DEBUG_FPU_STATE();
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
@ -2080,6 +2125,9 @@ FLOAT_OP(floorw, s)
|
||||||
set_float_rounding_mode(float_round_down, &env->fp_status);
|
set_float_rounding_mode(float_round_down, &env->fp_status);
|
||||||
WT2 = float32_round_to_int(FST0, &env->fp_status);
|
WT2 = float32_round_to_int(FST0, &env->fp_status);
|
||||||
RESTORE_ROUNDING_MODE;
|
RESTORE_ROUNDING_MODE;
|
||||||
|
update_fcr31();
|
||||||
|
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
|
||||||
|
WT2 = 0x7fffffff;
|
||||||
DEBUG_FPU_STATE();
|
DEBUG_FPU_STATE();
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
@ -2396,6 +2444,20 @@ void op_cmp_d_ ## op (void) \
|
||||||
CLEAR_FP_COND(PARAM1, env); \
|
CLEAR_FP_COND(PARAM1, env); \
|
||||||
DEBUG_FPU_STATE(); \
|
DEBUG_FPU_STATE(); \
|
||||||
RETURN(); \
|
RETURN(); \
|
||||||
|
} \
|
||||||
|
void op_cmpabs_d_ ## op (void) \
|
||||||
|
{ \
|
||||||
|
int c; \
|
||||||
|
FDT0 &= ~(1ULL << 63); \
|
||||||
|
FDT1 &= ~(1ULL << 63); \
|
||||||
|
c = cond; \
|
||||||
|
update_fcr31(); \
|
||||||
|
if (c) \
|
||||||
|
SET_FP_COND(PARAM1, env); \
|
||||||
|
else \
|
||||||
|
CLEAR_FP_COND(PARAM1, env); \
|
||||||
|
DEBUG_FPU_STATE(); \
|
||||||
|
RETURN(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
int float64_is_unordered(int sig, float64 a, float64 b STATUS_PARAM)
|
int float64_is_unordered(int sig, float64 a, float64 b STATUS_PARAM)
|
||||||
|
@ -2444,6 +2506,20 @@ void op_cmp_s_ ## op (void) \
|
||||||
CLEAR_FP_COND(PARAM1, env); \
|
CLEAR_FP_COND(PARAM1, env); \
|
||||||
DEBUG_FPU_STATE(); \
|
DEBUG_FPU_STATE(); \
|
||||||
RETURN(); \
|
RETURN(); \
|
||||||
|
} \
|
||||||
|
void op_cmpabs_s_ ## op (void) \
|
||||||
|
{ \
|
||||||
|
int c; \
|
||||||
|
FST0 &= ~(1 << 31); \
|
||||||
|
FST1 &= ~(1 << 31); \
|
||||||
|
c = cond; \
|
||||||
|
update_fcr31(); \
|
||||||
|
if (c) \
|
||||||
|
SET_FP_COND(PARAM1, env); \
|
||||||
|
else \
|
||||||
|
CLEAR_FP_COND(PARAM1, env); \
|
||||||
|
DEBUG_FPU_STATE(); \
|
||||||
|
RETURN(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM)
|
flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM)
|
||||||
|
@ -2498,6 +2574,27 @@ void op_cmp_ps_ ## op (void) \
|
||||||
CLEAR_FP_COND(PARAM1 + 1, env); \
|
CLEAR_FP_COND(PARAM1 + 1, env); \
|
||||||
DEBUG_FPU_STATE(); \
|
DEBUG_FPU_STATE(); \
|
||||||
RETURN(); \
|
RETURN(); \
|
||||||
|
} \
|
||||||
|
void op_cmpabs_ps_ ## op (void) \
|
||||||
|
{ \
|
||||||
|
int cl, ch; \
|
||||||
|
FST0 &= ~(1 << 31); \
|
||||||
|
FSTH0 &= ~(1 << 31); \
|
||||||
|
FST1 &= ~(1 << 31); \
|
||||||
|
FSTH1 &= ~(1 << 31); \
|
||||||
|
cl = condl; \
|
||||||
|
ch = condh; \
|
||||||
|
update_fcr31(); \
|
||||||
|
if (cl) \
|
||||||
|
SET_FP_COND(PARAM1, env); \
|
||||||
|
else \
|
||||||
|
CLEAR_FP_COND(PARAM1, env); \
|
||||||
|
if (ch) \
|
||||||
|
SET_FP_COND(PARAM1 + 1, env); \
|
||||||
|
else \
|
||||||
|
CLEAR_FP_COND(PARAM1 + 1, env); \
|
||||||
|
DEBUG_FPU_STATE(); \
|
||||||
|
RETURN(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NOTE: the comma operator will make "cond" to eval to false,
|
/* NOTE: the comma operator will make "cond" to eval to false,
|
||||||
|
|
|
@ -490,33 +490,36 @@ FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr);
|
||||||
FGEN32(gen_op_load_fpr_WTH2, gen_op_load_fpr_WTH2_fpr);
|
FGEN32(gen_op_load_fpr_WTH2, gen_op_load_fpr_WTH2_fpr);
|
||||||
FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
|
FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
|
||||||
|
|
||||||
#define FOP_CONDS(fmt) \
|
#define FOP_CONDS(type, fmt) \
|
||||||
static GenOpFunc1 * cond_ ## fmt ## _table[16] = { \
|
static GenOpFunc1 * cond ## type ## _ ## fmt ## _table[16] = { \
|
||||||
gen_op_cmp_ ## fmt ## _f, \
|
gen_op_cmp ## type ## _ ## fmt ## _f, \
|
||||||
gen_op_cmp_ ## fmt ## _un, \
|
gen_op_cmp ## type ## _ ## fmt ## _un, \
|
||||||
gen_op_cmp_ ## fmt ## _eq, \
|
gen_op_cmp ## type ## _ ## fmt ## _eq, \
|
||||||
gen_op_cmp_ ## fmt ## _ueq, \
|
gen_op_cmp ## type ## _ ## fmt ## _ueq, \
|
||||||
gen_op_cmp_ ## fmt ## _olt, \
|
gen_op_cmp ## type ## _ ## fmt ## _olt, \
|
||||||
gen_op_cmp_ ## fmt ## _ult, \
|
gen_op_cmp ## type ## _ ## fmt ## _ult, \
|
||||||
gen_op_cmp_ ## fmt ## _ole, \
|
gen_op_cmp ## type ## _ ## fmt ## _ole, \
|
||||||
gen_op_cmp_ ## fmt ## _ule, \
|
gen_op_cmp ## type ## _ ## fmt ## _ule, \
|
||||||
gen_op_cmp_ ## fmt ## _sf, \
|
gen_op_cmp ## type ## _ ## fmt ## _sf, \
|
||||||
gen_op_cmp_ ## fmt ## _ngle, \
|
gen_op_cmp ## type ## _ ## fmt ## _ngle, \
|
||||||
gen_op_cmp_ ## fmt ## _seq, \
|
gen_op_cmp ## type ## _ ## fmt ## _seq, \
|
||||||
gen_op_cmp_ ## fmt ## _ngl, \
|
gen_op_cmp ## type ## _ ## fmt ## _ngl, \
|
||||||
gen_op_cmp_ ## fmt ## _lt, \
|
gen_op_cmp ## type ## _ ## fmt ## _lt, \
|
||||||
gen_op_cmp_ ## fmt ## _nge, \
|
gen_op_cmp ## type ## _ ## fmt ## _nge, \
|
||||||
gen_op_cmp_ ## fmt ## _le, \
|
gen_op_cmp ## type ## _ ## fmt ## _le, \
|
||||||
gen_op_cmp_ ## fmt ## _ngt, \
|
gen_op_cmp ## type ## _ ## fmt ## _ngt, \
|
||||||
}; \
|
}; \
|
||||||
static inline void gen_cmp_ ## fmt(int n, long cc) \
|
static inline void gen_cmp ## type ## _ ## fmt(int n, long cc) \
|
||||||
{ \
|
{ \
|
||||||
cond_ ## fmt ## _table[n](cc); \
|
cond ## type ## _ ## fmt ## _table[n](cc); \
|
||||||
}
|
}
|
||||||
|
|
||||||
FOP_CONDS(d)
|
FOP_CONDS(, d)
|
||||||
FOP_CONDS(s)
|
FOP_CONDS(abs, d)
|
||||||
FOP_CONDS(ps)
|
FOP_CONDS(, s)
|
||||||
|
FOP_CONDS(abs, s)
|
||||||
|
FOP_CONDS(, ps)
|
||||||
|
FOP_CONDS(abs, ps)
|
||||||
|
|
||||||
typedef struct DisasContext {
|
typedef struct DisasContext {
|
||||||
struct TranslationBlock *tb;
|
struct TranslationBlock *tb;
|
||||||
|
@ -4453,7 +4456,25 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
|
||||||
"c.le",
|
"c.le",
|
||||||
"c.ngt",
|
"c.ngt",
|
||||||
};
|
};
|
||||||
int binary = 0;
|
const char *condnames_abs[] = {
|
||||||
|
"cabs.f",
|
||||||
|
"cabs.un",
|
||||||
|
"cabs.eq",
|
||||||
|
"cabs.ueq",
|
||||||
|
"cabs.olt",
|
||||||
|
"cabs.ult",
|
||||||
|
"cabs.ole",
|
||||||
|
"cabs.ule",
|
||||||
|
"cabs.sf",
|
||||||
|
"cabs.ngle",
|
||||||
|
"cabs.seq",
|
||||||
|
"cabs.ngl",
|
||||||
|
"cabs.lt",
|
||||||
|
"cabs.nge",
|
||||||
|
"cabs.le",
|
||||||
|
"cabs.ngt",
|
||||||
|
};
|
||||||
|
enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
|
||||||
uint32_t func = ctx->opcode & 0x3f;
|
uint32_t func = ctx->opcode & 0x3f;
|
||||||
|
|
||||||
switch (ctx->opcode & FOP(0x3f, 0x1f)) {
|
switch (ctx->opcode & FOP(0x3f, 0x1f)) {
|
||||||
|
@ -4463,7 +4484,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
|
||||||
gen_op_float_add_s();
|
gen_op_float_add_s();
|
||||||
GEN_STORE_FTN_FREG(fd, WT2);
|
GEN_STORE_FTN_FREG(fd, WT2);
|
||||||
opn = "add.s";
|
opn = "add.s";
|
||||||
binary = 1;
|
optype = BINOP;
|
||||||
break;
|
break;
|
||||||
case FOP(1, 16):
|
case FOP(1, 16):
|
||||||
GEN_LOAD_FREG_FTN(WT0, fs);
|
GEN_LOAD_FREG_FTN(WT0, fs);
|
||||||
|
@ -4471,7 +4492,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
|
||||||
gen_op_float_sub_s();
|
gen_op_float_sub_s();
|
||||||
GEN_STORE_FTN_FREG(fd, WT2);
|
GEN_STORE_FTN_FREG(fd, WT2);
|
||||||
opn = "sub.s";
|
opn = "sub.s";
|
||||||
binary = 1;
|
optype = BINOP;
|
||||||
break;
|
break;
|
||||||
case FOP(2, 16):
|
case FOP(2, 16):
|
||||||
GEN_LOAD_FREG_FTN(WT0, fs);
|
GEN_LOAD_FREG_FTN(WT0, fs);
|
||||||
|
@ -4479,7 +4500,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
|
||||||
gen_op_float_mul_s();
|
gen_op_float_mul_s();
|
||||||
GEN_STORE_FTN_FREG(fd, WT2);
|
GEN_STORE_FTN_FREG(fd, WT2);
|
||||||
opn = "mul.s";
|
opn = "mul.s";
|
||||||
binary = 1;
|
optype = BINOP;
|
||||||
break;
|
break;
|
||||||
case FOP(3, 16):
|
case FOP(3, 16):
|
||||||
GEN_LOAD_FREG_FTN(WT0, fs);
|
GEN_LOAD_FREG_FTN(WT0, fs);
|
||||||
|
@ -4487,7 +4508,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
|
||||||
gen_op_float_div_s();
|
gen_op_float_div_s();
|
||||||
GEN_STORE_FTN_FREG(fd, WT2);
|
GEN_STORE_FTN_FREG(fd, WT2);
|
||||||
opn = "div.s";
|
opn = "div.s";
|
||||||
binary = 1;
|
optype = BINOP;
|
||||||
break;
|
break;
|
||||||
case FOP(4, 16):
|
case FOP(4, 16):
|
||||||
GEN_LOAD_FREG_FTN(WT0, fs);
|
GEN_LOAD_FREG_FTN(WT0, fs);
|
||||||
|
@ -4635,8 +4656,13 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
|
||||||
case FOP(63, 16):
|
case FOP(63, 16):
|
||||||
GEN_LOAD_FREG_FTN(WT0, fs);
|
GEN_LOAD_FREG_FTN(WT0, fs);
|
||||||
GEN_LOAD_FREG_FTN(WT1, ft);
|
GEN_LOAD_FREG_FTN(WT1, ft);
|
||||||
gen_cmp_s(func-48, cc);
|
if (ctx->opcode & (1 << 6)) {
|
||||||
opn = condnames[func-48];
|
gen_cmpabs_s(func-48, cc);
|
||||||
|
opn = condnames_abs[func-48];
|
||||||
|
} else {
|
||||||
|
gen_cmp_s(func-48, cc);
|
||||||
|
opn = condnames[func-48];
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case FOP(0, 17):
|
case FOP(0, 17):
|
||||||
CHECK_FR(ctx, fs | ft | fd);
|
CHECK_FR(ctx, fs | ft | fd);
|
||||||
|
@ -4645,7 +4671,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
|
||||||
gen_op_float_add_d();
|
gen_op_float_add_d();
|
||||||
GEN_STORE_FTN_FREG(fd, DT2);
|
GEN_STORE_FTN_FREG(fd, DT2);
|
||||||
opn = "add.d";
|
opn = "add.d";
|
||||||
binary = 1;
|
optype = BINOP;
|
||||||
break;
|
break;
|
||||||
case FOP(1, 17):
|
case FOP(1, 17):
|
||||||
CHECK_FR(ctx, fs | ft | fd);
|
CHECK_FR(ctx, fs | ft | fd);
|
||||||
|
@ -4654,7 +4680,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
|
||||||
gen_op_float_sub_d();
|
gen_op_float_sub_d();
|
||||||
GEN_STORE_FTN_FREG(fd, DT2);
|
GEN_STORE_FTN_FREG(fd, DT2);
|
||||||
opn = "sub.d";
|
opn = "sub.d";
|
||||||
binary = 1;
|
optype = BINOP;
|
||||||
break;
|
break;
|
||||||
case FOP(2, 17):
|
case FOP(2, 17):
|
||||||
CHECK_FR(ctx, fs | ft | fd);
|
CHECK_FR(ctx, fs | ft | fd);
|
||||||
|
@ -4663,7 +4689,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
|
||||||
gen_op_float_mul_d();
|
gen_op_float_mul_d();
|
||||||
GEN_STORE_FTN_FREG(fd, DT2);
|
GEN_STORE_FTN_FREG(fd, DT2);
|
||||||
opn = "mul.d";
|
opn = "mul.d";
|
||||||
binary = 1;
|
optype = BINOP;
|
||||||
break;
|
break;
|
||||||
case FOP(3, 17):
|
case FOP(3, 17):
|
||||||
CHECK_FR(ctx, fs | ft | fd);
|
CHECK_FR(ctx, fs | ft | fd);
|
||||||
|
@ -4672,7 +4698,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
|
||||||
gen_op_float_div_d();
|
gen_op_float_div_d();
|
||||||
GEN_STORE_FTN_FREG(fd, DT2);
|
GEN_STORE_FTN_FREG(fd, DT2);
|
||||||
opn = "div.d";
|
opn = "div.d";
|
||||||
binary = 1;
|
optype = BINOP;
|
||||||
break;
|
break;
|
||||||
case FOP(4, 17):
|
case FOP(4, 17):
|
||||||
CHECK_FR(ctx, fs | fd);
|
CHECK_FR(ctx, fs | fd);
|
||||||
|
@ -4801,8 +4827,13 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
|
||||||
CHECK_FR(ctx, fs | ft);
|
CHECK_FR(ctx, fs | ft);
|
||||||
GEN_LOAD_FREG_FTN(DT0, fs);
|
GEN_LOAD_FREG_FTN(DT0, fs);
|
||||||
GEN_LOAD_FREG_FTN(DT1, ft);
|
GEN_LOAD_FREG_FTN(DT1, ft);
|
||||||
gen_cmp_d(func-48, cc);
|
if (ctx->opcode & (1 << 6)) {
|
||||||
opn = condnames[func-48];
|
gen_cmpabs_d(func-48, cc);
|
||||||
|
opn = condnames_abs[func-48];
|
||||||
|
} else {
|
||||||
|
gen_cmp_d(func-48, cc);
|
||||||
|
opn = condnames[func-48];
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case FOP(32, 17):
|
case FOP(32, 17):
|
||||||
CHECK_FR(ctx, fs);
|
CHECK_FR(ctx, fs);
|
||||||
|
@ -5042,18 +5073,30 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
|
||||||
GEN_LOAD_FREG_FTN(WTH0, fs);
|
GEN_LOAD_FREG_FTN(WTH0, fs);
|
||||||
GEN_LOAD_FREG_FTN(WT1, ft);
|
GEN_LOAD_FREG_FTN(WT1, ft);
|
||||||
GEN_LOAD_FREG_FTN(WTH1, ft);
|
GEN_LOAD_FREG_FTN(WTH1, ft);
|
||||||
gen_cmp_ps(func-48, cc);
|
if (ctx->opcode & (1 << 6)) {
|
||||||
opn = condnames[func-48];
|
gen_cmpabs_ps(func-48, cc);
|
||||||
|
opn = condnames_abs[func-48];
|
||||||
|
} else {
|
||||||
|
gen_cmp_ps(func-48, cc);
|
||||||
|
opn = condnames[func-48];
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
MIPS_INVAL(opn);
|
MIPS_INVAL(opn);
|
||||||
generate_exception (ctx, EXCP_RI);
|
generate_exception (ctx, EXCP_RI);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (binary)
|
switch (optype) {
|
||||||
|
case BINOP:
|
||||||
MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
|
MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
|
||||||
else
|
break;
|
||||||
|
case CMPOP:
|
||||||
|
MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
|
MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Coprocessor 3 (FPU) */
|
/* Coprocessor 3 (FPU) */
|
||||||
|
|
Loading…
Reference in New Issue