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.
This commit is contained in:
DJ Delorie 2008-02-06 00:40:05 +00:00
parent e5c4eb7a6c
commit c5fbc25baf
23 changed files with 1579 additions and 100 deletions

View File

@ -1,3 +1,8 @@
2008-02-05 DJ Delorie <dj@redhat.com>
* configure.ac (v850): V850 now has a testsuite.
* configure (v850): Likewise.
2008-01-01 Daniel Jacobowitz <dan@codesourcery.com>
Updated copyright notices for most files.

1
sim/configure vendored
View File

@ -3532,6 +3532,7 @@ subdirs="$subdirs ppc"
subdirs="$subdirs v850"
igen=yes
testsuite=yes
;;
*)
# No simulator subdir, so the subdir "common" isn't needed.

View File

@ -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.

View File

@ -1,3 +1,23 @@
2008-02-05 DJ Delorie <dj@redhat.com>
* 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.
2007-11-08 Hans-Peter Nilsson <hp@axis.com>
* sim/cris/asm/x0-v10.ms, sim/cris/asm/x0-v32.ms: Tweak

View File

@ -0,0 +1,39 @@
# v850 simulator testsuite.
if [istarget v850*-*] {
global opt
# load support procs (none yet)
# load_lib cgen.exp
# all machines
switch -regexp -- $opt {
.*v850e.* {
set all_machs "v850e"
}
default {
set all_machs "v850"
}
}
# gas doesn't support any '=' option for v850.
#set cpu_option -m
# The .cgs suffix is for "cgen .s".
foreach src [lsort [glob -nocomplain $srcdir/$subdir/*.cgs]] {
# If we're only testing specific files and this isn't one of them,
# skip it.
if ![runtest_file_p $runtests $src] {
continue
}
run_sim_test $src $all_machs
}
}
#foreach var [lsort [info globals]] {
# if [array exists ::$var] {
# puts [format "%-27s %s" $var Array:]
# continue
# }
# puts [format "%-30s %s" $var "[set ::$var]"]
#}

View File

@ -0,0 +1,55 @@
# v850 bsh
# mach: v850e
# as(v850e): -mv850e
.include "testutils.inc"
seti 0x12345678, r1
bsh r1, r2
flags 0
reg r2, 0x34127856
# CY is 1 if one or more bytes in the result half-word is zero, else 0
seti 0x12345600, r1
bsh r1, r2
flags c
reg r2, 0x34120056
seti 0x12340078, r1
bsh r1, r2
flags c
reg r2, 0x34127800
seti 0x12005678, r1
bsh r1, r2
flags 0
reg r2, 0x00127856
seti 0x00345678, r1
bsh r1, r2
flags 0
reg r2, 0x34007856
# S is set if the result is negative
seti 0x00800000, r1
bsh r1, r2
flags s + c + z
reg r2, 0x80000000
# Z is set if the result is zero
# According to NEC, the Z flag depends on only the lower half-word
seti 0x00000000, r1
bsh r1, r2
flags c + z
reg r2, 0x00000000
seti 0xffff0000, r1
bsh r1, r2
flags c + s + z
reg r2, 0xffff0000
pass

View File

@ -0,0 +1,118 @@
# v850 div
# mach: v850e
# as(v850e): -mv850e
.include "testutils.inc"
# Regular division - check signs
# The S flag is based on the quotient, not the remainder
seti 6, r1
seti 45, r2
div r1, r2, r3
flags 0
reg r1, 6
reg r2, 7
reg r3, 3
seti -6, r1
seti 45, r2
div r1, r2, r3
flags s
reg r1, -6
reg r2, -7
reg r3, 3
seti 6, r1
seti -45, r2
div r1, r2, r3
flags s
reg r1, 6
reg r2, -7
reg r3, -3
seti -6, r1
seti -45, r2
div r1, r2, r3
flags 0
reg r1, -6
reg r2, 7
reg r3, -3
# If the data is divided by zero, OV=1 and the quotient is undefined.
# According to NEC, the S and Z flags, and the output registers, are
# unchanged.
noflags
seti 0, r1
seti 45, r2
seti 67, r3
div r1, r2, r3
flags v
reg r2, 45
reg r3, 67
allflags
seti 0, r1
seti 45, r2
seti 67, r3
div r1, r2, r3
flags sat + c + v + s + z
reg r2, 45
reg r3, 67
# Zero / (N!=0) => normal
noflags
seti 45, r1
seti 0, r2
seti 67, r3
div r1, r2, r3
flags z
reg r1, 45
reg r2, 0
reg r3, 0
# Test for regular overflow
noflags
seti -1, r1
seti 0x80000000, r2
seti 67, r3
div r1, r2, r3
flags v + s
reg r1, -1
reg r2, 0x80000000
reg r3, 0
# The Z flag is based on the quotient, not the remainder
noflags
seti 45, r1
seti 16, r2
div r1, r2, r3
flags z
reg r2, 0
reg r3, 16
# If the quot and rem registers are the same, the remainder is stored.
seti 6, r1
seti 45, r2
div r1, r2, r2
flags 0
reg r1, 6
reg r2, 3
pass

View File

@ -0,0 +1,96 @@
# v850 divh
# mach: all
.include "testutils.inc"
# Regular division - check signs
seti 6, r1
seti 45, r2
divh r1, r2
flags 0
reg r1, 6
reg r2, 7
seti -6, r1
seti 45, r2
divh r1, r2
flags s
reg r1, -6
reg r2, -7
seti 6, r1
seti -45, r2
divh r1, r2
flags s
reg r1, 6
reg r2, -7
seti -6, r1
seti -45, r2
divh r1, r2
flags 0
reg r1, -6
reg r2, 7
# Only the lower half of the dividend is used
seti 0x0000fffa, r1
seti -45, r2
divh r1, r2
flags 0
reg r1, 0x0000fffa
reg r2, 7
# If the data is divhided by zero, OV=1 and the quotient is undefined.
# According to NEC, the S and Z flags, and the output registers, are
# unchanged.
noflags
seti 0, r1
seti 45, r2
seti 67, r3
divh r1, r2
flags v
reg r2, 45
allflags
seti 0, r1
seti 45, r2
seti 67, r3
divh r1, r2
flags sat + c + v + s + z
reg r2, 45
# Zero / (N!=0) => normal
noflags
seti 45, r1
seti 0, r2
seti 67, r3
divh r1, r2
flags z
reg r1, 45
reg r2, 0
# Test for regular overflow
noflags
seti -1, r1
seti 0x80000000, r2
divh r1, r2
flags v + s
reg r1, -1
reg r2, 0x80000000
pass

View File

@ -0,0 +1,130 @@
# v850 divh_3
# mach: v850e
# as(v850e): -mv850e
.include "testutils.inc"
# Regular divhision - check signs
# The S flag is based on the quotient, not the remainder
seti 6, r1
seti 45, r2
divh r1, r2, r3
flags 0
reg r1, 6
reg r2, 7
reg r3, 3
seti -6, r1
seti 45, r2
divh r1, r2, r3
flags s
reg r1, -6
reg r2, -7
reg r3, 3
seti 6, r1
seti -45, r2
divh r1, r2, r3
flags s
reg r1, 6
reg r2, -7
reg r3, -3
seti -6, r1
seti -45, r2
divh r1, r2, r3
flags 0
reg r1, -6
reg r2, 7
reg r3, -3
# Only the lower half of the dividend is used
seti 0x0000fffa, r1
seti -45, r2
divh r1, r2, r3
flags 0
reg r1, 0x0000fffa
reg r2, 7
reg r3, -3
# If the data is divhided by zero, OV=1 and the quotient is undefined.
# According to NEC, the S and Z flags, and the output registers, are
# unchanged.
noflags
seti 0, r1
seti 45, r2
seti 67, r3
divh r1, r2, r3
flags v
reg r2, 45
reg r3, 67
allflags
seti 0, r1
seti 45, r2
seti 67, r3
divh r1, r2, r3
flags sat + c + v + s + z
reg r2, 45
reg r3, 67
# Zero / (N!=0) => normal
noflags
seti 45, r1
seti 0, r2
seti 67, r3
divh r1, r2, r3
flags z
reg r1, 45
reg r2, 0
reg r3, 0
# Test for regular overflow
noflags
seti -1, r1
seti 0x80000000, r2
seti 67, r3
divh r1, r2, r3
flags v + s
reg r1, -1
reg r2, 0x80000000
reg r3, 0
# The Z flag is based on the quotient, not the remainder
noflags
seti 45, r1
seti 16, r2
divh r1, r2, r3
flags z
reg r2, 0
reg r3, 16
# If the quot and rem registers are the same, the remainder is stored.
seti 6, r1
seti 45, r2
divh r1, r2, r2
flags 0
reg r1, 6
reg r2, 3
pass

View File

@ -0,0 +1,94 @@
# v850 divu
# mach: v850e
# as(v850e): -mv850e
.include "testutils.inc"
seti 6, r1
seti 45, r2
divu r1, r2, r3
flags 0
reg r1, 6
reg r2, 7
reg r3, 3
seti 4, r1
seti 0x40000000, r2
divu r1, r2, r3
flags 0
reg r1, 4
reg r2, 0x10000000
reg r3, 0
# Only the lower half of the dividend is used
seti 0x00010006, r1
seti 45, r2
divhu r1, r2, r3
flags 0
reg r1, 0x00010006
reg r2, 7
reg r3, 3
# If the data is divided by zero, OV=1 and the quotient is undefined.
# According to NEC, the S and Z flags, and the output registers, are
# unchanged.
noflags
seti 0, r1
seti 45, r2
seti 67, r3
divu r1, r2, r3
flags v
reg r2, 45
reg r3, 67
allflags
seti 0, r1
seti 45, r2
seti 67, r3
divu r1, r2, r3
flags sat + c + v + s + z
reg r2, 45
reg r3, 67
# Zero / (N!=0) => normal
noflags
seti 45, r1
seti 0, r2
seti 67, r3
divu r1, r2, r3
flags z
reg r1, 45
reg r2, 0
reg r3, 0
# The Z flag is based on the quotient, not the remainder
noflags
seti 45, r1
seti 16, r2
divu r1, r2, r3
flags z
reg r2, 0
reg r3, 16
# If the quot and rem registers are the same, the remainder is stored.
seti 6, r1
seti 45, r2
divu r1, r2, r2
flags 0
reg r1, 6
reg r2, 3
pass

View File

@ -0,0 +1,83 @@
# v850 divu
# mach: v850e
# as(v850e): -mv850e
.include "testutils.inc"
seti 6, r1
seti 45, r2
divu r1, r2, r3
flags 0
reg r1, 6
reg r2, 7
reg r3, 3
seti 4, r1
seti 0x40000000, r2
divu r1, r2, r3
flags 0
reg r1, 4
reg r2, 0x10000000
reg r3, 0
# If the data is divided by zero, OV=1 and the quotient is undefined.
# According to NEC, the S and Z flags, and the output registers, are
# unchanged.
noflags
seti 0, r1
seti 45, r2
seti 67, r3
divu r1, r2, r3
flags v
reg r2, 45
reg r3, 67
allflags
seti 0, r1
seti 45, r2
seti 67, r3
divu r1, r2, r3
flags sat + c + v + s + z
reg r2, 45
reg r3, 67
# Zero / (N!=0) => normal
noflags
seti 45, r1
seti 0, r2
seti 67, r3
divu r1, r2, r3
flags z
reg r1, 45
reg r2, 0
reg r3, 0
# The Z flag is based on the quotient, not the remainder
noflags
seti 45, r1
seti 16, r2
divu r1, r2, r3
flags z
reg r2, 0
reg r3, 16
# If the quot and rem registers are the same, the remainder is stored.
seti 6, r1
seti 45, r2
divu r1, r2, r2
flags 0
reg r1, 6
reg r2, 3
pass

View File

@ -0,0 +1,91 @@
# v850 sar
# mach: all
.include "testutils.inc"
# CY is set to 1 if the bit shifted out last is 1, else 0
# OV is set to zero.
# Z is set if the result is 0, else 0
noflags
seti 4, r1
seti 0x00000000, r2
sar r1, r2
flags z
reg r2, 0
noflags
seti 4, r1
seti 0x00000001, r2
sar r1, r2
flags z
reg r2, 0
noflags
seti 4, r1
seti 0x00000008, r2
sar r1, r2
flags c + z
reg r2, 0
noflags
seti 0x00000000, r2
sar 4, r2
flags z
reg r2, 0
noflags
seti 0x00000001, r2
sar 4, r2
flags z
reg r2, 0
noflags
seti 0x00000008, r2
sar 4, r2
flags c + z
reg r2, 0
# However, if the number of shifts is 0, CY is 0.
noflags
seti 0, r1
seti 0xffffffff, r2
sar r1, r2
flags s
reg r2, 0xffffffff
noflags
seti 0xffffffff, r2
sar 0, r2
flags s
reg r2, 0xffffffff
# Old MSB is copied as new MSB after shift
# S is 1 if the result is negative, else 0
noflags
seti 1, r1
seti 0x80000000, r2
sar r1, r2
flags s
reg r2, 0xc0000000
noflags
seti 1, r1
seti 0x40000000, r2
sar r1, r2
flags 0
reg r2, 0x20000000
pass

View File

@ -0,0 +1,79 @@
# v850 satadd
# mach: all
.include "testutils.inc"
# If the result of the add is "negative", that means we went too
# positive. The result should be the most positive number.
noflags
seti 0x70000000, r1
seti 0x70000000, r2
satadd r1, r2
flags sat + nc + v + ns + nz
reg r2, 0x7fffffff
noflags
seti 0x7ffffffe, r1
satadd 10, r1
flags sat + nc + v + ns + nz
reg r1, 0x7fffffff
# Similarly, if the result of the add is "positive", that means we
# went too negative. The result should be the most negative number.
noflags
seti 0x90000000, r1
seti 0x90000000, r2
satadd r1, r2
flags sat + c + v + s + nz
reg r2, 0x80000000
noflags
seti 0x80000001, r1
satadd -10, r1
flags sat + c + v + s + nz
reg r1, 0x80000000
# Check that the SAT flag remains set until reset
seti 1, r1
seti 2, r2
satadd r1,r2
flags sat + nc + nv + ns + nz
reg r2, 3
noflags
seti 1, r1
seti 2, r2
satadd r1,r2
flags nsat + nc + nv + ns + nz
reg r2, 3
# Check that results exactly equal to min/max don't saturate
noflags
seti 0x70000000, r1
seti 0x0fffffff, r2
satadd r1,r2
flags nsat + nc + nv + ns + nz
reg r2, 0x7fffffff
noflags
seti 0x90000000, r1
seti 0xf0000000, r2
satadd r1,r2
flags nsat + c + nv + s + nz
reg r2, 0x80000000
pass

View File

@ -0,0 +1,65 @@
# v850 satsub
# mach: all
.include "testutils.inc"
# If the result of the add is "negative", that means we went too
# positive. The result should be the most positive number.
noflags
seti 0x90000000, r1
seti 0x70000000, r2
satsub r1, r2
flags sat + c + v + ns + nz
reg r2, 0x7fffffff
# Similarly, if the result of the add is "positive", that means we
# went too negative. The result should be the most negative number.
noflags
seti 0x70000000, r1
seti 0x90000000, r2
satsub r1, r2
flags sat + nc + v + s + nz
reg r2, 0x80000000
# Check that the SAT flag remains set until reset
seti 1, r1
seti 2, r2
satsub r1,r2
flags sat + nc + nv + ns + nz
reg r2, 1
noflags
seti 1, r1
seti 2, r2
satsub r1,r2
flags nsat + nc + nv + ns + nz
reg r2, 1
# Check that results exactly equal to min/max don't saturate
noflags
seti 0x90000000, r1
seti 0x0fffffff, r2
satsub r1,r2
flags nsat + c + nv + ns + nz
reg r2, 0x7fffffff
noflags
seti 0x70000000, r1
seti 0xf0000000, r2
satsub r1,r2
flags nsat + nc + nv + s + nz
reg r2, 0x80000000
pass

View File

@ -0,0 +1,59 @@
# v850 satsubi
# mach: all
.include "testutils.inc"
# If the result of the add is "negative", that means we went too
# positive. The result should be the most positive number.
noflags
seti 0x7ffffffe, r1
satsubi -10, r1, r2
flags sat + c + v + ns + nz
reg r2, 0x7fffffff
# Similarly, if the result of the add is "positive", that means we
# went too negative. The result should be the most negative number.
noflags
seti 0x80000001, r1
satsubi 10, r1, r2
flags sat + nc + v + s + nz
reg r2, 0x80000000
# Check that the SAT flag remains set until reset
seti 2, r1
satsubi 1, r1, r2
flags sat + nc + nv + ns + nz
reg r2, 1
noflags
seti 2, r1
satsubi 1, r1, r2
flags nsat + nc + nv + ns + nz
reg r2, 1
# Check that results exactly equal to min/max don't saturate
noflags
seti 0x7ffffffe, r1
satsubi -1, r1, r2
flags nsat + c + nv + ns + nz
reg r2, 0x7fffffff
noflags
seti 0x80000001, r1
satsubi 1, r1, r2
flags nsat + nc + nv + s + nz
reg r2, 0x80000000
pass

View File

@ -0,0 +1,65 @@
# v850 satsub
# mach: all
.include "testutils.inc"
# If the result of the add is "negative", that means we went too
# positive. The result should be the most positive number.
noflags
seti 0x90000000, r1
seti 0x70000000, r2
satsubr r2, r1
flags sat + c + v + ns + nz
reg r1, 0x7fffffff
# Similarly, if the result of the add is "positive", that means we
# went too negative. The result should be the most negative number.
noflags
seti 0x70000000, r1
seti 0x90000000, r2
satsubr r2, r1
flags sat + nc + v + s + nz
reg r1, 0x80000000
# Check that the SAT flag remains set until reset
seti 1, r1
seti 2, r2
satsubr r2, r1
flags sat + nc + nv + ns + nz
reg r1, 1
noflags
seti 1, r1
seti 2, r2
satsubr r2, r1
flags nsat + nc + nv + ns + nz
reg r1, 1
# Check that results exactly equal to min/max don't saturate
noflags
seti 0x90000000, r1
seti 0x0fffffff, r2
satsubr r2, r1
flags nsat + c + nv + ns + nz
reg r1, 0x7fffffff
noflags
seti 0x70000000, r1
seti 0xf0000000, r2
satsubr r2, r1
flags nsat + nc + nv + s + nz
reg r1, 0x80000000
pass

View File

@ -0,0 +1,75 @@
# v850 shl
# mach: all
.include "testutils.inc"
# CY is set to 1 if the bit shifted out last is 1, else 0
# OV is set to zero.
# Z is set if the result is 0, else 0
noflags
seti 1, r1
seti 0x00000000, r2
shl r1, r2
flags z
reg r2, 0
noflags
seti 1, r1
seti 0x80000000, r2
shl r1, r2
flags c + z
reg r2, 0
noflags
seti 0x00000000, r2
shl 1, r2
flags z
reg r2, 0
noflags
seti 0x80000000, r2
shl 1, r2
flags c + z
reg r2, 0
# However, if the number of shifts is 0, CY is 0.
noflags
seti 0, r1
seti 0xffffffff, r2
shl r1, r2
flags s
reg r2, 0xffffffff
noflags
seti 0xffffffff, r2
shl 0, r2
flags s
reg r2, 0xffffffff
# Zero is shifted into the LSB
# S is 1 if the result is negative, else 0
noflags
seti 1, r1
seti 0x4000000f, r2
shl r1, r2
flags s
reg r2, 0x8000001e
noflags
seti 0x4000000f, r2
shl 1, r2
flags s
reg r2, 0x8000001e
pass

View File

@ -0,0 +1,91 @@
# v850 shr
# mach: all
.include "testutils.inc"
# CY is set to 1 if the bit shifted out last is 1, else 0
# OV is set to zero.
# Z is set if the result is 0, else 0
noflags
seti 4, r1
seti 0x00000000, r2
shr r1, r2
flags z
reg r2, 0
noflags
seti 4, r1
seti 0x00000001, r2
shr r1, r2
flags z
reg r2, 0
noflags
seti 4, r1
seti 0x00000008, r2
shr r1, r2
flags c + z
reg r2, 0
noflags
seti 0x00000000, r2
shr 4, r2
flags z
reg r2, 0
noflags
seti 0x00000001, r2
shr 4, r2
flags z
reg r2, 0
noflags
seti 0x00000008, r2
shr 4, r2
flags c + z
reg r2, 0
# However, if the number of shifts is 0, CY is 0.
noflags
seti 0, r1
seti 0xffffffff, r2
shr r1, r2
flags s
reg r2, 0xffffffff
noflags
seti 0xffffffff, r2
shr 0, r2
flags s
reg r2, 0xffffffff
# Zere is shifted into the MSB
# S is 1 if the result is negative, else 0
noflags
seti 1, r1
seti 0x80000000, r2
shr r1, r2
flags 0
reg r2, 0x40000000
noflags
seti 1, r1
seti 0x40000000, r2
shr r1, r2
flags 0
reg r2, 0x20000000
pass

View File

@ -0,0 +1,12 @@
# v850 test framework
# mach: all
.include "testutils.inc"
# This just makes sure that a passing test will pass.
seti 0x12345678, r1
reg r1, 0x12345678
pass

View File

@ -0,0 +1,205 @@
SYS_exit = 1
SYS_write = 4
.bss
.space 64
_stack:
.data
pass_text:
.string "pass\n"
fail_text:
.string "fail\n"
.text
.global _start
_start:
movhi hi(_stack), r0, sp
movea lo(_stack), sp, sp
jr start_test
.macro seti val reg
movhi hi(\val),r0,\reg
movea lo(\val),\reg,\reg
.endm
_pass_1:
mov SYS_write,r6
mov 1,r7
seti pass_text,r8
mov 5,r9
trap 31
mov 0, r7
jr _exit
_fail_1:
mov SYS_write,r6
mov 1,r7
seti fail_text,r8
mov 5,r9
trap 31
mov 1, r7
jr _exit
_exit:
mov SYS_exit, r6
mov 0, r8
mov 0, r9
trap 31
_pass:
jr _pass_1
_fail:
jr _fail_1
.macro pass
jr _pass
.endm
.macro fail
jr _fail
.endm
# These pass or fail if the given flag is set or not set
# Currently, it assumed that the code of any test is going to
# be less than 256 bytes. Else, we'll have to use a
# branch-around-jump design instead.
.macro pass_c
bc _pass
.endm
.macro fail_c
bc _fail
.endm
.macro pass_nc
bnc _pass
.endm
.macro fail_nc
bnc _fail
.endm
.macro pass_z
bz _pass
.endm
.macro fail_z
bz _fail
.endm
.macro pass_nz
bnz _pass
.endm
.macro fail_nz
bnz _fail
.endm
.macro pass_v
bv _pass
.endm
.macro fail_v
bv _fail
.endm
.macro pass_nv
bnv _pass
.endm
.macro fail_nv
bnv _fail
.endm
.macro pass_s
bn _pass
.endm
.macro fail_s
bn _fail
.endm
.macro pass_ns
bp _pass
.endm
.macro fail_ns
bp _fail
.endm
.macro pass_sat
bsa _pass
.endm
.macro fail_sat
bsa _fail
.endm
.macro pass_nsat
bsa 1f
br _pass
1:
.endm
.macro fail_nsat
bsa 1f
br _fail
1:
.endm
# These pass/fail if the given register has/hasn't the specified value in it.
.macro pass_req reg val
seti \val,r10
cmp r10,\reg
be _pass
.endm
.macro pass_rne reg val
seti \val,r10
cmp r10,\reg
bne _pass
.endm
.macro fail_req reg val
seti \val,r10
cmp r10,\reg
be _fail
.endm
.macro fail_rne reg val
seti \val,r10
cmp r10,\reg
bne _fail
.endm
# convenience version
.macro reg reg val
seti \val,r10
cmp r10,\reg
bne _fail
.endm
z = 1
nz = 0
s = 2
ns = 0
v = 4
nv = 0
c = 8
nc = 0
sat = 16
nsat = 0
# sat c v s z
.macro flags fval
stsr psw, r10
movea +(\fval), r0, r9
andi 31, r10, r10
cmp r9, r10
bne _fail
.endm
.macro noflags
stsr psw, r10
andi ~0x1f, r10, r10
ldsr r10, psw
.endm
.macro allflags
stsr psw, r10
ori 0x1f, r10, r10
ldsr r10, psw
.endm
start_test:

View File

@ -1,3 +1,29 @@
2008-02-05 DJ Delorie <dj@redhat.com>
* 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.
2007-02-20 Daniel Jacobowitz <dan@codesourcery.com>
* Makefile.in (interp.o): Uncomment and update.

View File

@ -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)
{
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);

View File

@ -171,9 +171,9 @@ rrrrr,11111100000 + wwwww,01101000010:XII:::bsh
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;
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));
}
/* 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));
trace_output (OP_REG_REG);