diff --git a/target-alpha/op.c b/target-alpha/op.c index 409325221a..2a52be4f49 100644 --- a/target-alpha/op.c +++ b/target-alpha/op.c @@ -295,7 +295,7 @@ void OPPROTO op_mullv (void) void OPPROTO op_mulq (void) { - T0 *= T1; + T0 = (int64_t)T0 * (int64_t)T1; RETURN(); } @@ -307,7 +307,10 @@ void OPPROTO op_mulqv (void) void OPPROTO op_umulh (void) { - helper_umulh(); + uint64_t tl, th; + + mulu64(&tl, &th, T0, T1); + T0 = th; RETURN(); } diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c index e471a1f06f..3a34df49b6 100644 --- a/target-alpha/op_helper.c +++ b/target-alpha/op_helper.c @@ -199,30 +199,14 @@ void helper_mullv (void) void helper_mulqv () { - uint64_t res, tmp0, tmp1; + uint64_t tl, th; - res = (T0 >> 32) * (T1 >> 32); - tmp0 = ((T0 & 0xFFFFFFFF) * (T1 >> 32)) + - ((T0 >> 32) * (T1 & 0xFFFFFFFF)); - tmp1 = (T0 & 0xFFFFFFFF) * (T1 & 0xFFFFFFFF); - tmp0 += tmp1 >> 32; - res += tmp0 >> 32; - T0 *= T1; - if (unlikely(res != 0)) { + muls64(&tl, &th, T0, T1); + /* If th != 0 && th != -1, then we had an overflow */ + if (unlikely((th + 1) > 1)) { helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW); } -} - -void helper_umulh (void) -{ - uint64_t tmp0, tmp1; - - tmp0 = ((T0 & 0xFFFFFFFF) * (T1 >> 32)) + - ((T0 >> 32) * (T1 & 0xFFFFFFFF)); - tmp1 = (T0 & 0xFFFFFFFF) * (T1 & 0xFFFFFFFF); - tmp0 += tmp1 >> 32; - T0 = (T0 >> 32) * (T0 >> 32); - T0 += tmp0 >> 32; + T0 = tl; } void helper_ctpop (void) diff --git a/target-alpha/op_helper.h b/target-alpha/op_helper.h index 806a30d4a2..0c65fd4a33 100644 --- a/target-alpha/op_helper.h +++ b/target-alpha/op_helper.h @@ -34,7 +34,6 @@ void helper_subqv (void); void helper_sublv (void); void helper_mullv (void); void helper_mulqv (void); -void helper_umulh (void); void helper_ctpop (void); void helper_ctlz (void); void helper_cttz (void);