提交 68c8bd93 编写于 作者: R Richard Henderson

target-s390: Convert CONVERT TO FIXED

Signed-off-by: NRichard Henderson <rth@twiddle.net>
上级 24db8412
...@@ -387,8 +387,9 @@ uint32_t HELPER(cxb)(CPUS390XState *env, uint64_t ah, uint64_t al, ...@@ -387,8 +387,9 @@ uint32_t HELPER(cxb)(CPUS390XState *env, uint64_t ah, uint64_t al,
return float_comp_to_cc(env, cmp); return float_comp_to_cc(env, cmp);
} }
static void set_round_mode(CPUS390XState *env, int m3) static int swap_round_mode(CPUS390XState *env, int m3)
{ {
int ret = env->fpu_status.float_rounding_mode;
switch (m3) { switch (m3) {
case 0: case 0:
/* current mode */ /* current mode */
...@@ -412,86 +413,69 @@ static void set_round_mode(CPUS390XState *env, int m3) ...@@ -412,86 +413,69 @@ static void set_round_mode(CPUS390XState *env, int m3)
set_float_rounding_mode(float_round_down, &env->fpu_status); set_float_rounding_mode(float_round_down, &env->fpu_status);
break; break;
} }
return ret;
} }
/* convert 32-bit float to 64-bit int */ /* convert 32-bit float to 64-bit int */
uint32_t HELPER(cgebr)(CPUS390XState *env, uint32_t r1, uint32_t f2, uint64_t HELPER(cgeb)(CPUS390XState *env, uint64_t v2, uint32_t m3)
uint32_t m3)
{ {
float32 v2 = env->fregs[f2].l.upper; int hold = swap_round_mode(env, m3);
int64_t ret = float32_to_int64(v2, &env->fpu_status);
set_round_mode(env, m3); set_float_rounding_mode(hold, &env->fpu_status);
env->regs[r1] = float32_to_int64(v2, &env->fpu_status); handle_exceptions(env, GETPC());
return set_cc_nz_f32(v2); return ret;
} }
/* convert 64-bit float to 64-bit int */ /* convert 64-bit float to 64-bit int */
uint32_t HELPER(cgdbr)(CPUS390XState *env, uint32_t r1, uint32_t f2, uint64_t HELPER(cgdb)(CPUS390XState *env, uint64_t v2, uint32_t m3)
uint32_t m3)
{ {
float64 v2 = env->fregs[f2].d; int hold = swap_round_mode(env, m3);
int64_t ret = float64_to_int64(v2, &env->fpu_status);
set_round_mode(env, m3); set_float_rounding_mode(hold, &env->fpu_status);
env->regs[r1] = float64_to_int64(v2, &env->fpu_status); handle_exceptions(env, GETPC());
return set_cc_nz_f64(v2); return ret;
} }
/* convert 128-bit float to 64-bit int */ /* convert 128-bit float to 64-bit int */
uint32_t HELPER(cgxbr)(CPUS390XState *env, uint32_t r1, uint32_t f2, uint64_t HELPER(cgxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m3)
uint32_t m3)
{ {
CPU_QuadU v2; int hold = swap_round_mode(env, m3);
float128 v2 = make_float128(h, l);
v2.ll.upper = env->fregs[f2].ll; int64_t ret = float128_to_int64(v2, &env->fpu_status);
v2.ll.lower = env->fregs[f2 + 2].ll; set_float_rounding_mode(hold, &env->fpu_status);
set_round_mode(env, m3); handle_exceptions(env, GETPC());
env->regs[r1] = float128_to_int64(v2.q, &env->fpu_status); return ret;
if (float128_is_any_nan(v2.q)) {
return 3;
} else if (float128_is_zero(v2.q)) {
return 0;
} else if (float128_is_neg(v2.q)) {
return 1;
} else {
return 2;
}
} }
/* convert 32-bit float to 32-bit int */ /* convert 32-bit float to 32-bit int */
uint32_t HELPER(cfebr)(CPUS390XState *env, uint32_t r1, uint32_t f2, uint64_t HELPER(cfeb)(CPUS390XState *env, uint64_t v2, uint32_t m3)
uint32_t m3)
{ {
float32 v2 = env->fregs[f2].l.upper; int hold = swap_round_mode(env, m3);
int32_t ret = float32_to_int32(v2, &env->fpu_status);
set_round_mode(env, m3); set_float_rounding_mode(hold, &env->fpu_status);
env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | handle_exceptions(env, GETPC());
float32_to_int32(v2, &env->fpu_status); return ret;
return set_cc_nz_f32(v2);
} }
/* convert 64-bit float to 32-bit int */ /* convert 64-bit float to 32-bit int */
uint32_t HELPER(cfdbr)(CPUS390XState *env, uint32_t r1, uint32_t f2, uint64_t HELPER(cfdb)(CPUS390XState *env, uint64_t v2, uint32_t m3)
uint32_t m3)
{ {
float64 v2 = env->fregs[f2].d; int hold = swap_round_mode(env, m3);
int32_t ret = float64_to_int32(v2, &env->fpu_status);
set_round_mode(env, m3); set_float_rounding_mode(hold, &env->fpu_status);
env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | handle_exceptions(env, GETPC());
float64_to_int32(v2, &env->fpu_status); return ret;
return set_cc_nz_f64(v2);
} }
/* convert 128-bit float to 32-bit int */ /* convert 128-bit float to 32-bit int */
uint32_t HELPER(cfxbr)(CPUS390XState *env, uint32_t r1, uint32_t f2, uint64_t HELPER(cfxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m3)
uint32_t m3)
{ {
CPU_QuadU v2; int hold = swap_round_mode(env, m3);
float128 v2 = make_float128(h, l);
v2.ll.upper = env->fregs[f2].ll; int32_t ret = float128_to_int32(v2, &env->fpu_status);
v2.ll.lower = env->fregs[f2 + 2].ll; set_float_rounding_mode(hold, &env->fpu_status);
env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | handle_exceptions(env, GETPC());
float128_to_int32(v2.q, &env->fpu_status); return ret;
return set_cc_nz_f128(v2.q);
} }
/* 32-bit FP multiply and add */ /* 32-bit FP multiply and add */
......
...@@ -59,12 +59,12 @@ DEF_HELPER_3(lexb, i64, env, i64, i64) ...@@ -59,12 +59,12 @@ DEF_HELPER_3(lexb, i64, env, i64, i64)
DEF_HELPER_FLAGS_3(ceb, TCG_CALL_NO_WG_SE, i32, env, i64, i64) DEF_HELPER_FLAGS_3(ceb, TCG_CALL_NO_WG_SE, i32, env, i64, i64)
DEF_HELPER_FLAGS_3(cdb, TCG_CALL_NO_WG_SE, i32, env, i64, i64) DEF_HELPER_FLAGS_3(cdb, TCG_CALL_NO_WG_SE, i32, env, i64, i64)
DEF_HELPER_FLAGS_5(cxb, TCG_CALL_NO_WG_SE, i32, env, i64, i64, i64, i64) DEF_HELPER_FLAGS_5(cxb, TCG_CALL_NO_WG_SE, i32, env, i64, i64, i64, i64)
DEF_HELPER_4(cgebr, i32, env, i32, i32, i32) DEF_HELPER_3(cgeb, i64, env, i64, i32)
DEF_HELPER_4(cgdbr, i32, env, i32, i32, i32) DEF_HELPER_3(cgdb, i64, env, i64, i32)
DEF_HELPER_4(cgxbr, i32, env, i32, i32, i32) DEF_HELPER_4(cgxb, i64, env, i64, i64, i32)
DEF_HELPER_4(cfebr, i32, env, i32, i32, i32) DEF_HELPER_3(cfeb, i64, env, i64, i32)
DEF_HELPER_4(cfdbr, i32, env, i32, i32, i32) DEF_HELPER_3(cfdb, i64, env, i64, i32)
DEF_HELPER_4(cfxbr, i32, env, i32, i32, i32) DEF_HELPER_4(cfxb, i64, env, i64, i64, i32)
DEF_HELPER_4(maeb, i64, env, i64, i64, i64) DEF_HELPER_4(maeb, i64, env, i64, i64, i64)
DEF_HELPER_4(madb, i64, env, i64, i64, i64) DEF_HELPER_4(madb, i64, env, i64, i64, i64)
DEF_HELPER_4(mseb, i64, env, i64, i64, i64) DEF_HELPER_4(mseb, i64, env, i64, i64, i64)
......
...@@ -163,6 +163,13 @@ ...@@ -163,6 +163,13 @@
/* CONVERT TO DECIMAL */ /* CONVERT TO DECIMAL */
C(0x4e00, CVD, RX_a, Z, r1_o, a2, 0, 0, cvd, 0) C(0x4e00, CVD, RX_a, Z, r1_o, a2, 0, 0, cvd, 0)
C(0xe326, CVDY, RXY_a, LD, r1_o, a2, 0, 0, cvd, 0) C(0xe326, CVDY, RXY_a, LD, r1_o, a2, 0, 0, cvd, 0)
/* CONVERT TO FIXED */
C(0xb398, CFEBR, RRF_e, Z, 0, e2, new, r1_32, cfeb, 0)
C(0xb399, CFDBR, RRF_e, Z, 0, f2_o, new, r1_32, cfdb, 0)
C(0xb39a, CFXBR, RRF_e, Z, 0, x2_o, new, r1_32, cfxb, 0)
C(0xb3a8, CGEBR, RRF_e, Z, 0, e2, r1, 0, cgeb, 0)
C(0xb3a9, CGDBR, RRF_e, Z, 0, f2_o, r1, 0, cgdb, 0)
C(0xb3aa, CGXBR, RRF_e, Z, 0, x2_o, r1, 0, cgxb, 0)
/* DIVIDE */ /* DIVIDE */
C(0x1d00, DR, RR_a, Z, r1_D32, r2_32s, new_P, r1_P32, divs32, 0) C(0x1d00, DR, RR_a, Z, r1_D32, r2_32s, new_P, r1_P32, divs32, 0)
......
...@@ -485,6 +485,21 @@ static inline void set_cc_nz_u64(DisasContext *s, TCGv_i64 val) ...@@ -485,6 +485,21 @@ static inline void set_cc_nz_u64(DisasContext *s, TCGv_i64 val)
gen_op_update1_cc_i64(s, CC_OP_NZ, val); gen_op_update1_cc_i64(s, CC_OP_NZ, val);
} }
static inline void gen_set_cc_nz_f32(DisasContext *s, TCGv_i64 val)
{
gen_op_update1_cc_i64(s, CC_OP_NZ_F32, val);
}
static inline void gen_set_cc_nz_f64(DisasContext *s, TCGv_i64 val)
{
gen_op_update1_cc_i64(s, CC_OP_NZ_F64, val);
}
static inline void gen_set_cc_nz_f128(DisasContext *s, TCGv_i64 vh, TCGv_i64 vl)
{
gen_op_update2_cc_i64(s, CC_OP_NZ_F128, vh, vl);
}
static inline void cmp_32(DisasContext *s, TCGv_i32 v1, TCGv_i32 v2, static inline void cmp_32(DisasContext *s, TCGv_i32 v1, TCGv_i32 v2,
enum cc_op cond) enum cc_op cond)
{ {
...@@ -1367,7 +1382,7 @@ static void disas_b3(CPUS390XState *env, DisasContext *s, int op, int m3, ...@@ -1367,7 +1382,7 @@ static void disas_b3(CPUS390XState *env, DisasContext *s, int op, int m3,
int r1, int r2) int r1, int r2)
{ {
TCGv_i64 tmp; TCGv_i64 tmp;
TCGv_i32 tmp32_1, tmp32_2, tmp32_3; TCGv_i32 tmp32_1, tmp32_2;
LOG_DISAS("disas_b3: op 0x%x m3 0x%x r1 %d r2 %d\n", op, m3, r1, r2); LOG_DISAS("disas_b3: op 0x%x m3 0x%x r1 %d r2 %d\n", op, m3, r1, r2);
#define FP_HELPER(i) \ #define FP_HELPER(i) \
tmp32_1 = tcg_const_i32(r1); \ tmp32_1 = tcg_const_i32(r1); \
...@@ -1411,30 +1426,6 @@ static void disas_b3(CPUS390XState *env, DisasContext *s, int op, int m3, ...@@ -1411,30 +1426,6 @@ static void disas_b3(CPUS390XState *env, DisasContext *s, int op, int m3,
tcg_temp_free_i32(tmp32_1); tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i32(tmp32_2); tcg_temp_free_i32(tmp32_2);
break; break;
case 0x98: /* CFEBR R1,R2 [RRE] */
case 0x99: /* CFDBR R1,R2 [RRE] */
case 0x9a: /* CFXBR R1,R2 [RRE] */
tmp32_1 = tcg_const_i32(r1);
tmp32_2 = tcg_const_i32(r2);
tmp32_3 = tcg_const_i32(m3);
switch (op) {
case 0x98:
gen_helper_cfebr(cc_op, cpu_env, tmp32_1, tmp32_2, tmp32_3);
break;
case 0x99:
gen_helper_cfdbr(cc_op, cpu_env, tmp32_1, tmp32_2, tmp32_3);
break;
case 0x9a:
gen_helper_cfxbr(cc_op, cpu_env, tmp32_1, tmp32_2, tmp32_3);
break;
default:
tcg_abort();
}
set_cc_static(s);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i32(tmp32_2);
tcg_temp_free_i32(tmp32_3);
break;
case 0xa4: /* CEGBR R1,R2 [RRE] */ case 0xa4: /* CEGBR R1,R2 [RRE] */
case 0xa5: /* CDGBR R1,R2 [RRE] */ case 0xa5: /* CDGBR R1,R2 [RRE] */
tmp32_1 = tcg_const_i32(r1); tmp32_1 = tcg_const_i32(r1);
...@@ -1459,36 +1450,6 @@ static void disas_b3(CPUS390XState *env, DisasContext *s, int op, int m3, ...@@ -1459,36 +1450,6 @@ static void disas_b3(CPUS390XState *env, DisasContext *s, int op, int m3,
tcg_temp_free_i32(tmp32_1); tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i64(tmp); tcg_temp_free_i64(tmp);
break; break;
case 0xa8: /* CGEBR R1,R2 [RRE] */
tmp32_1 = tcg_const_i32(r1);
tmp32_2 = tcg_const_i32(r2);
tmp32_3 = tcg_const_i32(m3);
gen_helper_cgebr(cc_op, cpu_env, tmp32_1, tmp32_2, tmp32_3);
set_cc_static(s);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i32(tmp32_2);
tcg_temp_free_i32(tmp32_3);
break;
case 0xa9: /* CGDBR R1,R2 [RRE] */
tmp32_1 = tcg_const_i32(r1);
tmp32_2 = tcg_const_i32(r2);
tmp32_3 = tcg_const_i32(m3);
gen_helper_cgdbr(cc_op, cpu_env, tmp32_1, tmp32_2, tmp32_3);
set_cc_static(s);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i32(tmp32_2);
tcg_temp_free_i32(tmp32_3);
break;
case 0xaa: /* CGXBR R1,R2 [RRE] */
tmp32_1 = tcg_const_i32(r1);
tmp32_2 = tcg_const_i32(r2);
tmp32_3 = tcg_const_i32(m3);
gen_helper_cgxbr(cc_op, cpu_env, tmp32_1, tmp32_2, tmp32_3);
set_cc_static(s);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i32(tmp32_2);
tcg_temp_free_i32(tmp32_3);
break;
default: default:
LOG_DISAS("illegal b3 operation 0x%x\n", op); LOG_DISAS("illegal b3 operation 0x%x\n", op);
gen_illegal_opcode(s); gen_illegal_opcode(s);
...@@ -2129,6 +2090,60 @@ static ExitStatus op_cxb(DisasContext *s, DisasOps *o) ...@@ -2129,6 +2090,60 @@ static ExitStatus op_cxb(DisasContext *s, DisasOps *o)
return NO_EXIT; return NO_EXIT;
} }
static ExitStatus op_cfeb(DisasContext *s, DisasOps *o)
{
TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
gen_helper_cfeb(o->out, cpu_env, o->in2, m3);
tcg_temp_free_i32(m3);
gen_set_cc_nz_f32(s, o->in2);
return NO_EXIT;
}
static ExitStatus op_cfdb(DisasContext *s, DisasOps *o)
{
TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
gen_helper_cfdb(o->out, cpu_env, o->in2, m3);
tcg_temp_free_i32(m3);
gen_set_cc_nz_f64(s, o->in2);
return NO_EXIT;
}
static ExitStatus op_cfxb(DisasContext *s, DisasOps *o)
{
TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
gen_helper_cfxb(o->out, cpu_env, o->in1, o->in2, m3);
tcg_temp_free_i32(m3);
gen_set_cc_nz_f128(s, o->in1, o->in2);
return NO_EXIT;
}
static ExitStatus op_cgeb(DisasContext *s, DisasOps *o)
{
TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
gen_helper_cgeb(o->out, cpu_env, o->in2, m3);
tcg_temp_free_i32(m3);
gen_set_cc_nz_f32(s, o->in2);
return NO_EXIT;
}
static ExitStatus op_cgdb(DisasContext *s, DisasOps *o)
{
TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
gen_helper_cgdb(o->out, cpu_env, o->in2, m3);
tcg_temp_free_i32(m3);
gen_set_cc_nz_f64(s, o->in2);
return NO_EXIT;
}
static ExitStatus op_cgxb(DisasContext *s, DisasOps *o)
{
TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
gen_helper_cgxb(o->out, cpu_env, o->in1, o->in2, m3);
tcg_temp_free_i32(m3);
gen_set_cc_nz_f128(s, o->in1, o->in2);
return NO_EXIT;
}
static ExitStatus op_clc(DisasContext *s, DisasOps *o) static ExitStatus op_clc(DisasContext *s, DisasOps *o)
{ {
int l = get_field(s->fields, l1); int l = get_field(s->fields, l1);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册