From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7106 invoked by alias); 18 Apr 2006 19:44:08 -0000 Received: (qmail 7097 invoked by uid 22791); 18 Apr 2006 19:44:07 -0000 X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 18 Apr 2006 19:44:02 +0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.11.20060308/8.12.11) with ESMTP id k3IJi1Nk015696 for ; Tue, 18 Apr 2006 15:44:01 -0400 Received: from post-office.corp.redhat.com (post-office.corp.redhat.com [172.16.52.227]) by int-mx1.corp.redhat.com (8.12.11.20060308/8.11.6) with ESMTP id k3IJi1GB012679 for ; Tue, 18 Apr 2006 15:44:01 -0400 Received: from greed.delorie.com (dj.cipe.redhat.com [10.0.0.222]) by post-office.corp.redhat.com (8.11.6/8.11.6) with ESMTP id k3IJi0501836 for ; Tue, 18 Apr 2006 15:44:00 -0400 Received: from greed.delorie.com (greed.delorie.com [127.0.0.1]) by greed.delorie.com (8.13.1/8.13.1) with ESMTP id k3IJi05L004644 for ; Tue, 18 Apr 2006 15:44:00 -0400 Received: (from dj@localhost) by greed.delorie.com (8.13.1/8.13.1/Submit) id k3IJhtJ2004641; Tue, 18 Apr 2006 15:43:55 -0400 Date: Tue, 18 Apr 2006 19:44:00 -0000 Message-Id: <200604181943.k3IJhtJ2004641@greed.delorie.com> From: DJ Delorie To: gdb-patches@sourceware.org In-reply-to: <200604132336.k3DNan1h001282@greed.delorie.com> (message from DJ Delorie on Thu, 13 Apr 2006 19:36:49 -0400) Subject: Re: [v850 sim] REVISED correcting psw flags for divide special cases. References: <200604132336.k3DNan1h001282@greed.delorie.com> X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2006-04/txt/msg00248.txt.bz2 This adds two more related fixes to the previous ones (the v850 has a lot of divide instructions) Ok? 2006-04-13 DJ Delorie * simops.c (OP_2C207E0): Correct PSW flags for special divu conditions. (OP_2C007E0): Likewise, for div. (OP_28207E0): Likewise, for divhu. (OP_28007E0): Likewise, for divh. Also, sign-extend the correct operand. * v850.igen (divh): Likewise, for 2-op divh. Index: simops.c =================================================================== RCS file: /cvs/src/src/sim/v850/simops.c,v retrieving revision 1.8 diff -p -U3 -r1.8 simops.c --- simops.c 18 Jan 2004 14:56:40 -0000 1.8 +++ simops.c 18 Apr 2006 19:42:43 -0000 @@ -2264,19 +2264,20 @@ OP_2C207E0 (void) if (divide_by == 0) { - overflow = 1; - divide_by = 1; + PSW |= PSW_OV; } + else + { + State.regs[ OP[1] ] = quotient = divide_this / divide_by; + State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by; - State.regs[ OP[1] ] = quotient = divide_this / divide_by; - State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by; - - /* Set condition codes. */ - PSW &= ~(PSW_Z | PSW_S | PSW_OV); + /* Set condition codes. */ + PSW &= ~(PSW_Z | PSW_S | PSW_OV); - if (overflow) PSW |= PSW_OV; - if (quotient == 0) PSW |= PSW_Z; - if (quotient & 0x80000000) PSW |= PSW_S; + if (overflow) PSW |= PSW_OV; + if (quotient == 0) PSW |= PSW_Z; + if (quotient & 0x80000000) PSW |= PSW_S; + } trace_output (OP_REG_REG_REG); @@ -2291,7 +2292,6 @@ OP_2C007E0 (void) signed long int remainder; signed long int divide_by; signed long int divide_this; - int overflow = 0; trace_input ("div", OP_REG_REG_REG, 0); @@ -2300,21 +2300,28 @@ OP_2C007E0 (void) divide_by = State.regs[ OP[0] ]; divide_this = State.regs[ OP[1] ]; - if (divide_by == 0 || (divide_by == -1 && divide_this == (1 << 31))) + if (divide_by == 0) { - overflow = 1; - divide_by = 1; + PSW |= PSW_OV; } + else if (divide_by == -1 && divide_this == (1 << 31)) + { + PSW &= ~PSW_Z; + PSW |= PSW_OV | PSW_S; + State.regs[ OP[1] ] = (1 << 31); + State.regs[ OP[2] >> 11 ] = 0; + } + else + { + State.regs[ OP[1] ] = quotient = divide_this / divide_by; + State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by; - State.regs[ OP[1] ] = quotient = divide_this / divide_by; - State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by; - - /* Set condition codes. */ - PSW &= ~(PSW_Z | PSW_S | PSW_OV); + /* Set condition codes. */ + PSW &= ~(PSW_Z | PSW_S | PSW_OV); - if (overflow) PSW |= PSW_OV; - if (quotient == 0) PSW |= PSW_Z; - if (quotient < 0) PSW |= PSW_S; + if (quotient == 0) PSW |= PSW_Z; + if (quotient < 0) PSW |= PSW_S; + } trace_output (OP_REG_REG_REG); @@ -2340,19 +2347,20 @@ OP_28207E0 (void) if (divide_by == 0) { - overflow = 1; - divide_by = 1; + PSW |= PSW_OV; } + else + { + State.regs[ OP[1] ] = quotient = divide_this / divide_by; + State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by; - State.regs[ OP[1] ] = quotient = divide_this / divide_by; - State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by; - - /* Set condition codes. */ - PSW &= ~(PSW_Z | PSW_S | PSW_OV); + /* Set condition codes. */ + PSW &= ~(PSW_Z | PSW_S | PSW_OV); - if (overflow) PSW |= PSW_OV; - if (quotient == 0) PSW |= PSW_Z; - if (quotient & 0x80000000) PSW |= PSW_S; + if (overflow) PSW |= PSW_OV; + if (quotient == 0) PSW |= PSW_Z; + if (quotient & 0x80000000) PSW |= PSW_S; + } trace_output (OP_REG_REG_REG); @@ -2373,24 +2381,31 @@ OP_28007E0 (void) /* Compute the result. */ - divide_by = State.regs[ OP[0] ]; - divide_this = EXTEND16 (State.regs[ OP[1] ]); + divide_by = EXTEND16 (State.regs[ OP[0] ]); + divide_this = State.regs[ OP[1] ]; - if (divide_by == 0 || (divide_by == -1 && divide_this == (1 << 31))) + if (divide_by == 0) { - overflow = 1; - divide_by = 1; + PSW |= PSW_OV; } + else if (divide_by == -1 && divide_this == (1 << 31)) + { + PSW &= ~PSW_Z; + PSW |= PSW_OV | PSW_S; + State.regs[ OP[1] ] = (1 << 31); + State.regs[ OP[2] >> 11 ] = 0; + } + else + { + State.regs[ OP[1] ] = quotient = divide_this / divide_by; + State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by; - State.regs[ OP[1] ] = quotient = divide_this / divide_by; - State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by; - - /* Set condition codes. */ - PSW &= ~(PSW_Z | PSW_S | PSW_OV); + /* Set condition codes. */ + PSW &= ~(PSW_Z | PSW_S | PSW_OV); - if (overflow) PSW |= PSW_OV; - if (quotient == 0) PSW |= PSW_Z; - if (quotient < 0) PSW |= PSW_S; + if (quotient == 0) PSW |= PSW_Z; + if (quotient < 0) PSW |= PSW_S; + } trace_output (OP_REG_REG_REG); Index: v850.igen =================================================================== RCS file: /cvs/src/src/sim/v850/v850.igen,v retrieving revision 1.7 diff -p -U3 -r1.7 v850.igen --- v850.igen 5 Sep 2003 17:46:52 -0000 1.7 +++ v850.igen 18 Apr 2006 19:42:43 -0000 @@ -358,28 +358,28 @@ rrrrr!0,000010,RRRRR!0:I:::divh if (op0 == 0xffffffff && op1 == 0x80000000) { - result = 0x80000000; - ov = 1; + PSW &= ~PSW_Z; + PSW |= PSW_OV | PSW_S; + State.regs[OP[1]] = 0x80000000; } - else if (op0 != 0) + else if (op0 == 0) { - result = op1 / op0; - ov = 0; + PSW |= PSW_OV; } else { - result = 0x0; - ov = 1; - } - - /* Compute the condition codes. */ - z = (result == 0); - s = (result & 0x80000000); + result = op1 / op0; + ov = 0; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); - /* Store the result and condition codes. */ - State.regs[OP[1]] = result; - PSW &= ~(PSW_Z | PSW_S | PSW_OV); - PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | (ov ? PSW_OV : 0)); + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + PSW &= ~(PSW_Z | PSW_S | PSW_OV); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | (ov ? PSW_OV : 0)); + } trace_output (OP_REG_REG);