From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18577 invoked by alias); 6 Feb 2008 00:40:38 -0000 Received: (qmail 18501 invoked by uid 22791); 6 Feb 2008 00:40:36 -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; Wed, 06 Feb 2008 00:40:15 +0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id m160eDJW009559 for ; Tue, 5 Feb 2008 19:40:13 -0500 Received: from post-office.corp.redhat.com (post-office.corp.redhat.com [10.11.254.111]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id m160eDKn022616 for ; Tue, 5 Feb 2008 19:40:13 -0500 Received: from greed.delorie.com (vpn-14-4.rdu.redhat.com [10.11.14.4]) by post-office.corp.redhat.com (8.13.8/8.13.8) with ESMTP id m160eCKK008848 for ; Tue, 5 Feb 2008 19:40:12 -0500 Received: from greed.delorie.com (greed.delorie.com [127.0.0.1]) by greed.delorie.com (8.13.8/8.13.8) with ESMTP id m160eCIE030646 for ; Tue, 5 Feb 2008 19:40:12 -0500 Received: (from dj@localhost) by greed.delorie.com (8.13.8/8.13.8/Submit) id m160eC0X030643; Tue, 5 Feb 2008 19:40:12 -0500 Date: Wed, 06 Feb 2008 00:40:00 -0000 Message-Id: <200802060040.m160eC0X030643@greed.delorie.com> From: DJ Delorie To: gdb-patches@sourceware.org Subject: [v850 sim] Fix div, shift, sat, bsh opcodes, add initial testsuite X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-02/txt/msg00117.txt.bz2 This patch corrects some sim errors relative to the documentation, and clarifies some opcodes based on information from NEC. It also adds an initial testsuite framework, with tests for the changed opcodes. Committed. Index: ChangeLog * configure.ac (v850): V850 now has a testsuite. * configure (v850): Likewise. Index: testsuite/ChangeLog * sim/v850/: New directory. * sim/v850/allinsns.exp: New. * sim/v850/bsh.cgs: New. * sim/v850/div.cgs: New. * sim/v850/divh.cgs: New. * sim/v850/divh_3.cgs: New. * sim/v850/divhu.cgs: New. * sim/v850/divu.cgs: New. * sim/v850/sar.cgs: New. * sim/v850/satadd.cgs: New. * sim/v850/satsub.cgs: New. * sim/v850/satsubi.cgs: New. * sim/v850/satsubr.cgs: New. * sim/v850/shl.cgs: New. * sim/v850/shr.cgs: New. * sim/v850/testutils.cgs: New. * sim/v850/testutils.inc: New. Index: v850/ChangeLog * simops.c (OP_C0): Correct saturation logic. (OP_220): Likewise. (OP_A0): Likewise. (OP_660): Likewise. (OP_80): Likewise. * simops.c (OP_2A0): If the shift count is zero, clear the carry. (OP_A007E0): Likewise. (OP_2C0): Likewise. (OP_C007E0): Likewise. (OP_280): Likewise. (OP_8007E0): Likewise. * 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. * v850.igen (bsh): Fix carry logic. Index: configure.ac =================================================================== RCS file: /cvs/src/src/sim/configure.ac,v retrieving revision 1.12 diff -p -U3 -r1.12 configure.ac --- configure.ac 29 Jan 2007 16:41:14 -0000 1.12 +++ configure.ac 6 Feb 2008 00:36:58 -0000 @@ -112,6 +112,7 @@ if test "${enable_sim}" != no; then v850*-*-* ) AC_CONFIG_SUBDIRS(v850) igen=yes + testsuite=yes ;; *) # No simulator subdir, so the subdir "common" isn't needed. Index: configure =================================================================== RCS file: /cvs/src/src/sim/configure,v retrieving revision 1.24 diff -p -U3 -r1.24 configure --- configure 29 Jan 2007 16:41:14 -0000 1.24 +++ configure 6 Feb 2008 00:36:58 -0000 @@ -3532,6 +3532,7 @@ subdirs="$subdirs ppc" subdirs="$subdirs v850" igen=yes + testsuite=yes ;; *) # No simulator subdir, so the subdir "common" isn't needed. Index: v850/simops.c =================================================================== RCS file: /cvs/src/src/sim/v850/simops.c,v retrieving revision 1.8 diff -p -U3 -r1.8 simops.c --- v850/simops.c 18 Jan 2004 14:56:40 -0000 1.8 +++ v850/simops.c 6 Feb 2008 00:36:59 -0000 @@ -864,18 +864,29 @@ OP_C0 () && (op0 & 0x80000000) != (result & 0x80000000)); sat = ov; + /* Handle saturated results. */ + if (sat && s) + { + /* An overflow that results in a negative result implies that we + became too positive. */ + result = 0x7fffffff; + s = 0; + } + else if (sat) + { + /* Any other overflow must have thus been too negative. */ + result = 0x80000000; + s = 1; + z = 0; + } + /* Store the result and condition codes. */ State.regs[OP[1]] = result; PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0) | (sat ? PSW_SAT : 0)); - - /* Handle saturated results. */ - if (sat && s) - State.regs[OP[1]] = 0x80000000; - else if (sat) - State.regs[OP[1]] = 0x7fffffff; + trace_output (OP_REG_REG); return 2; @@ -905,18 +916,28 @@ OP_220 () && (op0 & 0x80000000) != (result & 0x80000000)); sat = ov; + /* Handle saturated results. */ + if (sat && s) + { + /* An overflow that results in a negative result implies that we + became too positive. */ + result = 0x7fffffff; + s = 0; + } + else if (sat) + { + /* Any other overflow must have thus been too negative. */ + result = 0x80000000; + s = 1; + z = 0; + } + /* Store the result and condition codes. */ State.regs[OP[1]] = result; PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0) | (sat ? PSW_SAT : 0)); - - /* Handle saturated results. */ - if (sat && s) - State.regs[OP[1]] = 0x80000000; - else if (sat) - State.regs[OP[1]] = 0x7fffffff; trace_output (OP_IMM_REG); return 2; @@ -942,7 +963,23 @@ OP_A0 () ov = ((op1 & 0x80000000) != (op0 & 0x80000000) && (op1 & 0x80000000) != (result & 0x80000000)); sat = ov; - + + /* Handle saturated results. */ + if (sat && s) + { + /* An overflow that results in a negative result implies that we + became too positive. */ + result = 0x7fffffff; + s = 0; + } + else if (sat) + { + /* Any other overflow must have thus been too negative. */ + result = 0x80000000; + s = 1; + z = 0; + } + /* Store the result and condition codes. */ State.regs[OP[1]] = result; PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); @@ -950,11 +987,6 @@ OP_A0 () | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0) | (sat ? PSW_SAT : 0)); - /* Handle saturated results. */ - if (sat && s) - State.regs[OP[1]] = 0x80000000; - else if (sat) - State.regs[OP[1]] = 0x7fffffff; trace_output (OP_REG_REG); return 2; } @@ -982,6 +1014,22 @@ OP_660 () && (op1 & 0x80000000) != (result & 0x80000000)); sat = ov; + /* Handle saturated results. */ + if (sat && s) + { + /* An overflow that results in a negative result implies that we + became too positive. */ + result = 0x7fffffff; + s = 0; + } + else if (sat) + { + /* Any other overflow must have thus been too negative. */ + result = 0x80000000; + s = 1; + z = 0; + } + /* Store the result and condition codes. */ State.regs[OP[1]] = result; PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); @@ -989,11 +1037,6 @@ OP_660 () | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0) | (sat ? PSW_SAT : 0)); - /* Handle saturated results. */ - if (sat && s) - State.regs[OP[1]] = 0x80000000; - else if (sat) - State.regs[OP[1]] = 0x7fffffff; trace_output (OP_IMM_REG); return 4; @@ -1015,10 +1058,26 @@ OP_80 () /* Compute the condition codes. */ z = (result == 0); s = (result & 0x80000000); - cy = (result < op0); - ov = ((op1 & 0x80000000) != (op0 & 0x80000000) - && (op1 & 0x80000000) != (result & 0x80000000)); + cy = (op0 < op1); + ov = ((op0 & 0x80000000) != (op1 & 0x80000000) + && (op0 & 0x80000000) != (result & 0x80000000)); sat = ov; + + /* Handle saturated results. */ + if (sat && s) + { + /* An overflow that results in a negative result implies that we + became too positive. */ + result = 0x7fffffff; + s = 0; + } + else if (sat) + { + /* Any other overflow must have thus been too negative. */ + result = 0x80000000; + s = 1; + z = 0; + } /* Store the result and condition codes. */ State.regs[OP[1]] = result; @@ -1027,11 +1086,6 @@ OP_80 () | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0) | (sat ? PSW_SAT : 0)); - /* Handle saturated results. */ - if (sat && s) - State.regs[OP[1]] = 0x80000000; - else if (sat) - State.regs[OP[1]] = 0x7fffffff; trace_output (OP_REG_REG); return 2; @@ -1104,7 +1158,7 @@ OP_2A0 () /* Compute the condition codes. */ z = (result == 0); s = (result & 0x80000000); - cy = (op1 & (1 << (op0 - 1))); + cy = op0 ? (op1 & (1 << (op0 - 1))) : 0; /* Store the result and condition codes. */ State.regs[ OP[1] ] = result; @@ -1131,7 +1185,7 @@ OP_A007E0 () /* Compute the condition codes. */ z = (result == 0); s = (result & 0x80000000); - cy = (op1 & (1 << (op0 - 1))); + cy = op0 ? (op1 & (1 << (op0 - 1))) : 0; /* Store the result and condition codes. */ State.regs[OP[1]] = result; @@ -1157,7 +1211,7 @@ OP_2C0 () /* Compute the condition codes. */ z = (result == 0); s = (result & 0x80000000); - cy = (op1 & (1 << (32 - op0))); + cy = op0 ? (op1 & (1 << (32 - op0))) : 0; /* Store the result and condition codes. */ State.regs[OP[1]] = result; @@ -1183,7 +1237,7 @@ OP_C007E0 () /* Compute the condition codes. */ z = (result == 0); s = (result & 0x80000000); - cy = (op1 & (1 << (32 - op0))); + cy = op0 ? (op1 & (1 << (32 - op0))) : 0; /* Store the result and condition codes. */ State.regs[OP[1]] = result; @@ -1209,7 +1263,7 @@ OP_280 () /* Compute the condition codes. */ z = (result == 0); s = (result & 0x80000000); - cy = (op1 & (1 << (op0 - 1))); + cy = op0 ? (op1 & (1 << (op0 - 1))) : 0; /* Store the result and condition codes. */ State.regs[OP[1]] = result; @@ -1235,7 +1289,7 @@ OP_8007E0 () /* Compute the condition codes. */ z = (result == 0); s = (result & 0x80000000); - cy = (op1 & (1 << (op0 - 1))); + cy = op0 ? (op1 & (1 << (op0 - 1))) : 0; /* Store the result and condition codes. */ State.regs[OP[1]] = result; @@ -2264,19 +2318,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 +2346,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 +2354,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 +2401,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 +2435,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) + { + PSW |= PSW_OV; + } + else if (divide_by == -1 && divide_this == (1 << 31)) { - overflow = 1; - divide_by = 1; + 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/v850.igen =================================================================== RCS file: /cvs/src/src/sim/v850/v850.igen,v retrieving revision 1.7 diff -p -U3 -r1.7 v850.igen --- v850/v850.igen 5 Sep 2003 17:46:52 -0000 1.7 +++ v850/v850.igen 6 Feb 2008 00:36:59 -0000 @@ -171,9 +171,9 @@ rrrrr,11111100000 + wwwww,01101000010:XI GR[reg3] = value; PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); - if (value == 0) PSW |= PSW_Z; + if ((value & 0xffff) == 0) PSW |= PSW_Z; if (value & 0x80000000) PSW |= PSW_S; - if (((value & 0xff) == 0) || (value & 0x00ff) == 0) PSW |= PSW_CY; + if (((value & 0xff) == 0) || ((value & 0xff00) == 0)) PSW |= PSW_CY; TRACE_ALU_RESULT (GR[reg3]); } @@ -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);