diff options
author | Richard Henderson <rth@twiddle.net> | 2012-10-05 16:55:05 -0700 |
---|---|---|
committer | Blue Swirl <blauwirbel@gmail.com> | 2012-10-07 16:39:33 +0000 |
commit | a2ea4aa9898086c1e45e1db9b5f94d16dbf0762e (patch) | |
tree | 3c74fb53034a28e2e6c77a69373cc050a07cc403 /target-sparc/helper.c | |
parent | bd49ed41ebe518c79bd52e46ce5b9cf278f8a2af (diff) |
target-sparc: Move taddcctv and tsubcctv out of line
The branches around the exception are maintaining an otherwise
unnecessary use of local temps for the cpu destination.
Note that gen_op_t{add,sub}_cc were identical to gen_op_{add,sub}_cc.
Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Diffstat (limited to 'target-sparc/helper.c')
-rw-r--r-- | target-sparc/helper.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/target-sparc/helper.c b/target-sparc/helper.c index 4555d2bfc0..556ac286eb 100644 --- a/target-sparc/helper.c +++ b/target-sparc/helper.c @@ -167,3 +167,61 @@ uint64_t helper_udivx(CPUSPARCState *env, uint64_t a, uint64_t b) return a / b; } #endif + +target_ulong helper_taddcctv(CPUSPARCState *env, target_ulong src1, + target_ulong src2) +{ + target_ulong dst; + + /* Tag overflow occurs if either input has bits 0 or 1 set. */ + if ((src1 | src2) & 3) { + goto tag_overflow; + } + + dst = src1 + src2; + + /* Tag overflow occurs if the addition overflows. */ + if (~(src1 ^ src2) & (src1 ^ dst) & (1u << 31)) { + goto tag_overflow; + } + + /* Only modify the CC after any exceptions have been generated. */ + env->cc_op = CC_OP_TADDTV; + env->cc_src = src1; + env->cc_src2 = src2; + env->cc_dst = dst; + return dst; + + tag_overflow: + cpu_restore_state2(env, GETPC()); + helper_raise_exception(env, TT_TOVF); +} + +target_ulong helper_tsubcctv(CPUSPARCState *env, target_ulong src1, + target_ulong src2) +{ + target_ulong dst; + + /* Tag overflow occurs if either input has bits 0 or 1 set. */ + if ((src1 | src2) & 3) { + goto tag_overflow; + } + + dst = src1 - src2; + + /* Tag overflow occurs if the subtraction overflows. */ + if ((src1 ^ src2) & (src1 ^ dst) & (1u << 31)) { + goto tag_overflow; + } + + /* Only modify the CC after any exceptions have been generated. */ + env->cc_op = CC_OP_TSUBTV; + env->cc_src = src1; + env->cc_src2 = src2; + env->cc_dst = dst; + return dst; + + tag_overflow: + cpu_restore_state2(env, GETPC()); + helper_raise_exception(env, TT_TOVF); +} |