* 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.
+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.
subdirs="$subdirs v850"
igen=yes
+ testsuite=yes
;;
*)
# No simulator subdir, so the subdir "common" isn't needed.
v850*-*-* )
AC_CONFIG_SUBDIRS(v850)
igen=yes
+ testsuite=yes
;;
*)
# No simulator subdir, so the subdir "common" isn't needed.
+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
--- /dev/null
+# 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]"]
+#}
+
\ No newline at end of file
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+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:
+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.
&& (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;
&& (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;
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);
| (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;
}
&& (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);
| (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;
/* 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;
| (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;
/* 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;
/* 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;
/* 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;
/* 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;
/* 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;
/* 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;
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);
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);
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);
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);
/* 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);
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]);
}
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);