diff options
author | Bastian Koppelmann <kbastian@mail.uni-paderborn.de> | 2015-02-06 14:48:33 +0000 |
---|---|---|
committer | Bastian Koppelmann <kbastian@mail.uni-paderborn.de> | 2015-03-03 01:06:00 +0000 |
commit | bebe80fc78cc91c4225cfb98ef3a916b9c861c60 (patch) | |
tree | f59fb6e656cb9090c4abbe0051706422e1989dc5 /target-tricore/op_helper.c | |
parent | b00aa8ecbc6fd7468178a0dabc7dfd0b7e1b8cd6 (diff) |
target-tricore: Add instructions of RRR1 opcode format, which have 0xc3 as first opcode
Add helpers helper_addsur_h/_ssov which adds one halfword and subtracts one
halfword, rounds / and saturates each half word independently.
Add microcode helper functions:
* gen_maddsu_h/sus_h: multiply two halfwords left justified and add to the
first one word and subtract from the second one word
/ and saturate each resulting word independetly.
* gen_maddsum_h/sums_h: multiply two halfwords in q-format left justified
and add to the first one word and subtract from
the second one word / and saturate each resulting
word independetly.
* gen_maddsur32_h/32s_h: multiply two halfwords in q-format left justified
and add to the first one word and subtract from
the second one word, round both results / and
saturate each resulting word independetly.
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'target-tricore/op_helper.c')
-rw-r--r-- | target-tricore/op_helper.c | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c index 2755d45aa7..40d32af5d3 100644 --- a/target-tricore/op_helper.c +++ b/target-tricore/op_helper.c @@ -265,6 +265,52 @@ uint32_t helper_addr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); } +uint32_t helper_addsur_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, + uint32_t r2_h) +{ + int64_t mul_res0 = sextract64(r1, 0, 32); + int64_t mul_res1 = sextract64(r1, 32, 32); + int64_t r2_low = sextract64(r2_l, 0, 32); + int64_t r2_high = sextract64(r2_h, 0, 32); + int64_t result0, result1; + uint32_t ovf0, ovf1; + uint32_t avf0, avf1; + + ovf0 = ovf1 = 0; + + result0 = r2_low - mul_res0 + 0x8000; + result1 = r2_high + mul_res1 + 0x8000; + + avf0 = result0 * 2u; + avf0 = result0 ^ avf0; + avf1 = result1 * 2u; + avf1 = result1 ^ avf1; + + if (result0 > INT32_MAX) { + ovf0 = (1 << 31); + result0 = INT32_MAX; + } else if (result0 < INT32_MIN) { + ovf0 = (1 << 31); + result0 = INT32_MIN; + } + + if (result1 > INT32_MAX) { + ovf1 = (1 << 31); + result1 = INT32_MAX; + } else if (result1 < INT32_MIN) { + ovf1 = (1 << 31); + result1 = INT32_MIN; + } + + env->PSW_USB_V = ovf0 | ovf1; + env->PSW_USB_SV |= env->PSW_USB_V; + + env->PSW_USB_AV = avf0 | avf1; + env->PSW_USB_SAV |= env->PSW_USB_AV; + + return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); +} + target_ulong helper_add_suov(CPUTriCoreState *env, target_ulong r1, target_ulong r2) @@ -854,6 +900,44 @@ uint32_t helper_addr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); } +uint32_t helper_addsur_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, + uint32_t r2_h) +{ + int64_t mul_res0 = sextract64(r1, 0, 32); + int64_t mul_res1 = sextract64(r1, 32, 32); + int64_t r2_low = sextract64(r2_l, 0, 32); + int64_t r2_high = sextract64(r2_h, 0, 32); + int64_t result0, result1; + uint32_t ovf0, ovf1; + uint32_t avf0, avf1; + + ovf0 = ovf1 = 0; + + result0 = r2_low - mul_res0 + 0x8000; + result1 = r2_high + mul_res1 + 0x8000; + + if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) { + ovf0 = (1 << 31); + } + + if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) { + ovf1 = (1 << 31); + } + + env->PSW_USB_V = ovf0 | ovf1; + env->PSW_USB_SV |= env->PSW_USB_V; + + avf0 = result0 * 2u; + avf0 = result0 ^ avf0; + avf1 = result1 * 2u; + avf1 = result1 ^ avf1; + + env->PSW_USB_AV = avf0 | avf1; + env->PSW_USB_SAV |= env->PSW_USB_AV; + + return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); +} + uint32_t helper_maddr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2, uint32_t r3, uint32_t n) { |