summaryrefslogtreecommitdiff
path: root/target-sparc/helper.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2012-10-05 16:55:05 -0700
committerBlue Swirl <blauwirbel@gmail.com>2012-10-07 16:39:33 +0000
commita2ea4aa9898086c1e45e1db9b5f94d16dbf0762e (patch)
tree3c74fb53034a28e2e6c77a69373cc050a07cc403 /target-sparc/helper.c
parentbd49ed41ebe518c79bd52e46ce5b9cf278f8a2af (diff)
downloadqemu-a2ea4aa9898086c1e45e1db9b5f94d16dbf0762e.tar.gz
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.c58
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);
+}