mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-21 01:12:32 +08:00
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:
parent
e5c4eb7a6c
commit
c5fbc25baf
@ -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
1
sim/configure
vendored
@ -3532,6 +3532,7 @@ subdirs="$subdirs ppc"
|
||||
subdirs="$subdirs v850"
|
||||
|
||||
igen=yes
|
||||
testsuite=yes
|
||||
;;
|
||||
*)
|
||||
# No simulator subdir, so the subdir "common" isn't needed.
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
39
sim/testsuite/sim/v850/allinsns.exp
Normal file
39
sim/testsuite/sim/v850/allinsns.exp
Normal 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]"]
|
||||
#}
|
||||
|
55
sim/testsuite/sim/v850/bsh.cgs
Normal file
55
sim/testsuite/sim/v850/bsh.cgs
Normal 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
|
118
sim/testsuite/sim/v850/div.cgs
Normal file
118
sim/testsuite/sim/v850/div.cgs
Normal 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
|
96
sim/testsuite/sim/v850/divh.cgs
Normal file
96
sim/testsuite/sim/v850/divh.cgs
Normal 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
|
130
sim/testsuite/sim/v850/divh_3.cgs
Normal file
130
sim/testsuite/sim/v850/divh_3.cgs
Normal 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
|
94
sim/testsuite/sim/v850/divhu.cgs
Normal file
94
sim/testsuite/sim/v850/divhu.cgs
Normal 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
|
83
sim/testsuite/sim/v850/divu.cgs
Normal file
83
sim/testsuite/sim/v850/divu.cgs
Normal 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
|
91
sim/testsuite/sim/v850/sar.cgs
Normal file
91
sim/testsuite/sim/v850/sar.cgs
Normal 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
|
79
sim/testsuite/sim/v850/satadd.cgs
Normal file
79
sim/testsuite/sim/v850/satadd.cgs
Normal 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
|
65
sim/testsuite/sim/v850/satsub.cgs
Normal file
65
sim/testsuite/sim/v850/satsub.cgs
Normal 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
|
59
sim/testsuite/sim/v850/satsubi.cgs
Normal file
59
sim/testsuite/sim/v850/satsubi.cgs
Normal 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
|
65
sim/testsuite/sim/v850/satsubr.cgs
Normal file
65
sim/testsuite/sim/v850/satsubr.cgs
Normal 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
|
75
sim/testsuite/sim/v850/shl.cgs
Normal file
75
sim/testsuite/sim/v850/shl.cgs
Normal 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
|
91
sim/testsuite/sim/v850/shr.cgs
Normal file
91
sim/testsuite/sim/v850/shr.cgs
Normal 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
|
12
sim/testsuite/sim/v850/testutils.cgs
Normal file
12
sim/testsuite/sim/v850/testutils.cgs
Normal 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
|
205
sim/testsuite/sim/v850/testutils.inc
Normal file
205
sim/testsuite/sim/v850/testutils.inc
Normal 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:
|
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user