diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2012-09-19 04:23:56 +0400 |
---|---|---|
committer | Blue Swirl <blauwirbel@gmail.com> | 2012-09-22 17:59:12 +0000 |
commit | 0b6df8385d24a4eed0ff546493c59e047b16537b (patch) | |
tree | 2be0573070d7cadc07d62bb61b16b92a8d56043f /target-xtensa | |
parent | 9ed7ae12afacdd234a749aa5af27dd93ea1594ec (diff) | |
download | qemu-0b6df8385d24a4eed0ff546493c59e047b16537b.zip qemu-0b6df8385d24a4eed0ff546493c59e047b16537b.tar.gz qemu-0b6df8385d24a4eed0ff546493c59e047b16537b.tar.bz2 |
target-xtensa: implement FP0 arithmetic
These are FP arithmetic opcodes.
See ISA, 4.3.10 for more details.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Diffstat (limited to 'target-xtensa')
-rw-r--r-- | target-xtensa/helper.h | 7 | ||||
-rw-r--r-- | target-xtensa/op_helper.c | 37 | ||||
-rw-r--r-- | target-xtensa/translate.c | 61 |
3 files changed, 104 insertions, 1 deletions
diff --git a/target-xtensa/helper.h b/target-xtensa/helper.h index 1662552..4e6e417 100644 --- a/target-xtensa/helper.h +++ b/target-xtensa/helper.h @@ -37,5 +37,12 @@ DEF_HELPER_3(wsr_dbreaka, void, env, i32, i32) DEF_HELPER_3(wsr_dbreakc, void, env, i32, i32) DEF_HELPER_2(wur_fcr, void, env, i32) +DEF_HELPER_FLAGS_1(abs_s, TCG_CALL_CONST | TCG_CALL_PURE, f32, f32) +DEF_HELPER_FLAGS_1(neg_s, TCG_CALL_CONST | TCG_CALL_PURE, f32, f32) +DEF_HELPER_3(add_s, f32, env, f32, f32) +DEF_HELPER_3(sub_s, f32, env, f32, f32) +DEF_HELPER_3(mul_s, f32, env, f32, f32) +DEF_HELPER_4(madd_s, f32, env, f32, f32, f32) +DEF_HELPER_4(msub_s, f32, env, f32, f32, f32) #include "def-helper.h" diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c index 3bf7339..ba935a8 100644 --- a/target-xtensa/op_helper.c +++ b/target-xtensa/op_helper.c @@ -784,3 +784,40 @@ void HELPER(wur_fcr)(CPUXtensaState *env, uint32_t v) env->uregs[FCR] = v & 0xfffff07f; set_float_rounding_mode(rounding_mode[v & 3], &env->fp_status); } + +float32 HELPER(abs_s)(float32 v) +{ + return float32_abs(v); +} + +float32 HELPER(neg_s)(float32 v) +{ + return float32_chs(v); +} + +float32 HELPER(add_s)(CPUXtensaState *env, float32 a, float32 b) +{ + return float32_add(a, b, &env->fp_status); +} + +float32 HELPER(sub_s)(CPUXtensaState *env, float32 a, float32 b) +{ + return float32_sub(a, b, &env->fp_status); +} + +float32 HELPER(mul_s)(CPUXtensaState *env, float32 a, float32 b) +{ + return float32_mul(a, b, &env->fp_status); +} + +float32 HELPER(madd_s)(CPUXtensaState *env, float32 a, float32 b, float32 c) +{ + return float32_muladd(b, c, a, 0, + &env->fp_status); +} + +float32 HELPER(msub_s)(CPUXtensaState *env, float32 a, float32 b, float32 c) +{ + return float32_muladd(b, c, a, float_muladd_negate_product, + &env->fp_status); +} diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c index 0f85b36..2125b1d 100644 --- a/target-xtensa/translate.c +++ b/target-xtensa/translate.c @@ -1907,7 +1907,66 @@ static void disas_xtensa_insn(DisasContext *dc) case 10: /*FP0*/ HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR); - TBD(); + switch (OP2) { + case 0: /*ADD.Sf*/ + gen_helper_add_s(cpu_FR[RRR_R], cpu_env, + cpu_FR[RRR_S], cpu_FR[RRR_T]); + break; + + case 1: /*SUB.Sf*/ + gen_helper_sub_s(cpu_FR[RRR_R], cpu_env, + cpu_FR[RRR_S], cpu_FR[RRR_T]); + break; + + case 2: /*MUL.Sf*/ + gen_helper_mul_s(cpu_FR[RRR_R], cpu_env, + cpu_FR[RRR_S], cpu_FR[RRR_T]); + break; + + case 4: /*MADD.Sf*/ + gen_helper_madd_s(cpu_FR[RRR_R], cpu_env, + cpu_FR[RRR_R], cpu_FR[RRR_S], cpu_FR[RRR_T]); + break; + + case 5: /*MSUB.Sf*/ + gen_helper_msub_s(cpu_FR[RRR_R], cpu_env, + cpu_FR[RRR_R], cpu_FR[RRR_S], cpu_FR[RRR_T]); + break; + + case 15: /*FP1OP*/ + switch (RRR_T) { + case 0: /*MOV.Sf*/ + tcg_gen_mov_i32(cpu_FR[RRR_R], cpu_FR[RRR_S]); + break; + + case 1: /*ABS.Sf*/ + gen_helper_abs_s(cpu_FR[RRR_R], cpu_FR[RRR_S]); + break; + + case 4: /*RFRf*/ + gen_window_check1(dc, RRR_R); + tcg_gen_mov_i32(cpu_R[RRR_R], cpu_FR[RRR_S]); + break; + + case 5: /*WFRf*/ + gen_window_check1(dc, RRR_S); + tcg_gen_mov_i32(cpu_FR[RRR_R], cpu_R[RRR_S]); + break; + + case 6: /*NEG.Sf*/ + gen_helper_neg_s(cpu_FR[RRR_R], cpu_FR[RRR_S]); + break; + + default: /*reserved*/ + RESERVED(); + break; + } + break; + + default: /*reserved*/ + RESERVED(); + break; + } break; case 11: /*FP1*/ |