From: DJ Delorie <dj@redhat.com>
To: gdb-patches@sourceware.org
Subject: Re: [v850 sim] REVISED correcting psw flags for divide special cases.
Date: Tue, 18 Apr 2006 19:44:00 -0000 [thread overview]
Message-ID: <200604181943.k3IJhtJ2004641@greed.delorie.com> (raw)
In-Reply-To: <200604132336.k3DNan1h001282@greed.delorie.com> (message from DJ Delorie on Thu, 13 Apr 2006 19:36:49 -0400)
This adds two more related fixes to the previous ones (the v850 has a
lot of divide instructions) Ok?
2006-04-13 DJ Delorie <dj@redhat.com>
* 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);
prev parent reply other threads:[~2006-04-18 19:44 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-04-13 23:37 [v850 sim] " DJ Delorie
2006-04-14 20:35 ` Daniel Jacobowitz
2006-04-14 20:36 ` Daniel Jacobowitz
2006-04-17 19:35 ` DJ Delorie
2006-04-17 19:49 ` Daniel Jacobowitz
2006-04-17 20:20 ` DJ Delorie
2006-04-18 19:25 ` Daniel Jacobowitz
2006-04-18 19:36 ` DJ Delorie
2006-04-20 13:09 ` Daniel Jacobowitz
2006-05-04 15:40 ` Daniel Jacobowitz
2006-04-18 19:44 ` DJ Delorie [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200604181943.k3IJhtJ2004641@greed.delorie.com \
--to=dj@redhat.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox