From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43817) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YaKfR-0004MZ-8s for qemu-devel@nongnu.org; Tue, 24 Mar 2015 04:58:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YaKfN-0007bB-6F for qemu-devel@nongnu.org; Tue, 24 Mar 2015 04:58:33 -0400 Received: from mail.uni-paderborn.de ([131.234.142.9]:35529) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YaKfM-0007b0-Vl for qemu-devel@nongnu.org; Tue, 24 Mar 2015 04:58:29 -0400 From: Bastian Koppelmann Date: Tue, 24 Mar 2015 09:58:19 +0100 Message-Id: <1427187499-28387-5-git-send-email-kbastian@mail.uni-paderborn.de> In-Reply-To: <1427187499-28387-1-git-send-email-kbastian@mail.uni-paderborn.de> References: <1427187499-28387-1-git-send-email-kbastian@mail.uni-paderborn.de> Subject: [Qemu-devel] [PULL 4/4] target-tricore: properly fix dvinit_b/h_13 List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: peter.maydell@linaro.org The TriCore documentation was wrong on how to calculate ovf bits for those two instructions, which I confirmed with real hardware (TC1796 chip). An ovf actually happens, if the result (without remainder) does not fit into 8/16 bits. Signed-off-by: Bastian Koppelmann --- target-tricore/op_helper.c | 40 ++++++++++------------------------------ 1 file changed, 10 insertions(+), 30 deletions(-) diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c index 2cfa95d..220ec4a 100644 --- a/target-tricore/op_helper.c +++ b/target-tricore/op_helper.c @@ -1942,29 +1942,19 @@ uint64_t helper_unpack(target_ulong arg1) uint64_t helper_dvinit_b_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2) { uint64_t ret; - int32_t abs_sig_dividend, abs_base_dividend, abs_divisor; - int32_t quotient_sign; + int32_t abs_sig_dividend, abs_divisor; ret = sextract32(r1, 0, 32); ret = ret << 24; - quotient_sign = 0; if (!((r1 & 0x80000000) == (r2 & 0x80000000))) { ret |= 0xffffff; - quotient_sign = 1; } - abs_sig_dividend = abs((int32_t)r1) >> 7; - abs_base_dividend = abs((int32_t)r1) & 0x7f; + abs_sig_dividend = abs((int32_t)r1) >> 8; abs_divisor = abs((int32_t)r2); - /* calc overflow */ - env->PSW_USB_V = 0; - if ((quotient_sign) && (abs_divisor)) { - env->PSW_USB_V = (((abs_sig_dividend == abs_divisor) && - (abs_base_dividend >= abs_divisor)) || - (abs_sig_dividend > abs_divisor)); - } else { - env->PSW_USB_V = (abs_sig_dividend >= abs_divisor); - } + /* calc overflow + ofv if (a/b >= 255) <=> (a/255 >= b) */ + env->PSW_USB_V = (abs_sig_dividend >= abs_divisor) << 31; env->PSW_USB_V = env->PSW_USB_V << 31; env->PSW_USB_SV |= env->PSW_USB_V; env->PSW_USB_AV = 0; @@ -1992,29 +1982,19 @@ uint64_t helper_dvinit_b_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2) uint64_t helper_dvinit_h_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2) { uint64_t ret; - int32_t abs_sig_dividend, abs_base_dividend, abs_divisor; - int32_t quotient_sign; + int32_t abs_sig_dividend, abs_divisor; ret = sextract32(r1, 0, 32); ret = ret << 16; - quotient_sign = 0; if (!((r1 & 0x80000000) == (r2 & 0x80000000))) { ret |= 0xffff; - quotient_sign = 1; } - abs_sig_dividend = abs((int32_t)r1) >> 7; - abs_base_dividend = abs((int32_t)r1) & 0x7f; + abs_sig_dividend = abs((int32_t)r1) >> 16; abs_divisor = abs((int32_t)r2); - /* calc overflow */ - env->PSW_USB_V = 0; - if ((quotient_sign) && (abs_divisor)) { - env->PSW_USB_V = (((abs_sig_dividend == abs_divisor) && - (abs_base_dividend >= abs_divisor)) || - (abs_sig_dividend > abs_divisor)); - } else { - env->PSW_USB_V = (abs_sig_dividend >= abs_divisor); - } + /* calc overflow + ofv if (a/b >= 0xffff) <=> (a/0xffff >= b) */ + env->PSW_USB_V = (abs_sig_dividend >= abs_divisor) << 31; env->PSW_USB_V = env->PSW_USB_V << 31; env->PSW_USB_SV |= env->PSW_USB_V; env->PSW_USB_AV = 0; -- 2.3.3