aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.7/gcc/testsuite/gcc.misc-tests/dectest.exp
diff options
context:
space:
mode:
authorBen Cheng <bccheng@google.com>2012-10-01 10:30:31 -0700
committerBen Cheng <bccheng@google.com>2012-10-01 10:30:31 -0700
commit82bcbebce43f0227f506d75a5b764b6847041bae (patch)
treefe9f8597b48a430c4daeb5123e3e8eb28e6f9da9 /gcc-4.7/gcc/testsuite/gcc.misc-tests/dectest.exp
parent3c052de3bb16ac53b6b6ed659ec7557eb84c7590 (diff)
downloadtoolchain_gcc-82bcbebce43f0227f506d75a5b764b6847041bae.tar.gz
toolchain_gcc-82bcbebce43f0227f506d75a5b764b6847041bae.tar.bz2
toolchain_gcc-82bcbebce43f0227f506d75a5b764b6847041bae.zip
Initial check-in of gcc 4.7.2.
Change-Id: I4a2f5a921c21741a0e18bda986d77e5f1bef0365
Diffstat (limited to 'gcc-4.7/gcc/testsuite/gcc.misc-tests/dectest.exp')
-rw-r--r--gcc-4.7/gcc/testsuite/gcc.misc-tests/dectest.exp527
1 files changed, 527 insertions, 0 deletions
diff --git a/gcc-4.7/gcc/testsuite/gcc.misc-tests/dectest.exp b/gcc-4.7/gcc/testsuite/gcc.misc-tests/dectest.exp
new file mode 100644
index 000000000..b86f2adec
--- /dev/null
+++ b/gcc-4.7/gcc/testsuite/gcc.misc-tests/dectest.exp
@@ -0,0 +1,527 @@
+# Copyright 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# DejaGnu test driver around Mike Cowlishaw's testsuite for decimal
+# decimal arithmetic ("decTest"). See:
+# <http://www2.hursley.ibm.com/decimal/dectest.html>.
+#
+# Contributed by Ben Elliston <bje@au.ibm.com>.
+
+set DEC_TORTURE_OPTIONS [list {} -O1 -O2 -O3 -Os -msoft-float]
+
+proc target-specific-flags {} {
+ set result "-frounding-math "
+ return $result
+}
+
+# Load support procs (borrow these from c-torture).
+load_lib c-torture.exp
+load_lib target-supports.exp
+load_lib torture-options.exp
+
+# Skip these tests for targets that don't support this extension.
+if { ![check_effective_target_dfp] } {
+ return
+}
+
+# The list format is [coefficient, max-exponent, min-exponent].
+set properties(_Decimal32) [list 7 96 -95]
+set properties(_Decimal64) [list 16 384 -383]
+set properties(_Decimal128) [list 34 6144 -6143]
+
+# Operations implemented by the compiler.
+set operators(add) {+}
+set operators(compare) {==}
+set operators(divide) {/}
+set operators(multiply) {*}
+set operators(subtract) {-}
+set operators(minus) {-}
+set operators(plus) {+}
+set operators(apply) {}
+
+# Operations imlemented by the library.
+set libfuncs(abs) fabsl
+set libfuncs(squareroot) sqrtl
+set libfuncs(max) fmaxl
+set libfuncs(min) fminl
+set libfuncs(quantize) quantize
+set libfuncs(samequantum) samequantum
+set libfuncs(power) powl
+set libfuncs(toSci) unknown
+set libfuncs(tosci) unknown
+set libfuncs(toEng) unknown
+set libfuncs(toeng) unknown
+set libfuncs(divideint) unknown
+set libfuncs(rescale) unknown
+set libfuncs(remainder) unknown
+set libfuncs(remaindernear) unknown
+set libfuncs(normalize) unknown
+set libfuncs(tointegral) unknown
+set libfuncs(trim) unknown
+
+# Run all of the tests listed in TESTCASES by invoking df-run-test on
+# each. Skip tests that not included by the user invoking runtest
+# with the foo.exp=test.c syntax.
+
+proc dfp-run-tests { testcases } {
+ global runtests
+ foreach test $testcases {
+ # If we're only testing specific files and this isn't one of
+ # them, skip it.
+ if ![runtest_file_p $runtests $test] continue
+ dfp-run-test $test
+ }
+}
+
+# Run a single test case named by TESTCASE.
+# Called for each test by dfp-run-tests.
+
+proc dfp-run-test { testcase } {
+ set fd [open $testcase r]
+ while {[gets $fd line] != -1} {
+ switch -regexp -- $line {
+ {^[ \t]*--.*$} {
+ # Ignore comments.
+ }
+ {^[ \t]*$} {
+ # Ignore blank lines.
+ }
+ {^[ \t]*[^:]*:[^:]*} {
+ regsub -- {[ \t]*--.*$} $line {} line
+ process-directive $line
+ }
+ default {
+ process-test-case $testcase $line
+ }
+ }
+ }
+ close $fd
+}
+
+# Return the appropriate constant from <fenv.h> for MODE.
+
+proc c-rounding-mode { mode } {
+ switch [string tolower $mode] {
+ "floor" { return 0 } # FE_DEC_DOWNWARD
+ "half_even" { return 1 } # FE_DEC_TONEARESTFROMZERO
+ "half_up" { return 2 } # FE_DEC_TONEAREST
+ "down" { return 3 } # FE_DEC_TOWARDZERO
+ "ceiling" { return 4 } # FE_DEC_UPWARD
+ }
+ error "unsupported rounding mode ($mode)"
+}
+
+# Return a string of C code that forms the preamble to perform the
+# test named ID.
+
+proc c-test-preamble { id } {
+ append result "/* Machine generated test case for $id */\n"
+ append result "\n"
+ append result "\#include <assert.h>\n"
+ append result "\#include <fenv.h>\n"
+ append result "\#include <math.h>\n"
+ append result "\n"
+ append result "int main ()\n"
+ append result "\{"
+ return $result
+}
+
+# Return a string of C code that forms the postable to the test named ID.
+
+proc c-test-postamble { id } {
+ return "\}"
+}
+
+# Generate a C unary expression that applies OPERATION to OP.
+
+proc c-unary-expression {operation op} {
+ global operators
+ global libfuncs
+ if [catch {set result "$operators($operation) $op"}] {
+ # If operation isn't in the operators or libfuncs arrays,
+ # we'll throw an error. That's what we want.
+ # FIXME: append d32, etc. here.
+ set result "$libfuncs($operation) ($op)"
+ }
+ return $result
+}
+
+# Generate a C binary expression that applies OPERATION to OP1 and OP2.
+
+proc c-binary-expression {operation op1 op2} {
+ global operators
+ global libfuncs
+ if [catch {set result "$op1 $operators($operation) $op2"}] {
+ # If operation isn't in the operators or libfuncs arrays,
+ # we'll throw an error. That's what we want.
+ set result "$libfuncs($operation) ($op1, $op2)"
+ }
+ return $result
+}
+
+# Return the most appropriate C type (_Decimal32, etc) for this test.
+
+proc c-decimal-type { } {
+ global directives
+ if [catch {set precision $directives(precision)}] {
+ set precision "_Decimal128"
+ }
+ if { $precision == 7 } {
+ set result "_Decimal32"
+ } elseif {$precision == 16} {
+ set result "_Decimal64"
+ } elseif {$precision == 34} {
+ set result "_Decimal128"
+ } else {
+ error "Unsupported precision"
+ }
+ return $result
+}
+
+# Return the size of the most appropriate C type, in bytes.
+
+proc c-sizeof-decimal-type { } {
+ switch [c-decimal-type] {
+ "_Decimal32" { return 4 }
+ "_Decimal64" { return 8 }
+ "_Decimal128" { return 16 }
+ }
+ error "Unsupported precision"
+}
+
+# Return the right literal suffix for CTYPE.
+
+proc c-type-suffix { ctype } {
+ switch $ctype {
+ "_Decimal32" { return "df" }
+ "_Decimal64" { return "dd" }
+ "_Decimal128" { return "dl" }
+ "float" { return "f" }
+ "long double" { return "l" }
+ }
+ return ""
+}
+
+proc nan-p { operand } {
+ if {[string match "NaN*" $operand] || [string match "-NaN*" $operand]} {
+ return 1
+ } else {
+ return 0
+ }
+}
+
+proc infinity-p { operand } {
+ if {[string match "Inf*" $operand] || [string match "-Inf*" $operand]} {
+ return 1
+ } else {
+ return 0
+ }
+}
+
+proc isnan-builtin-name { } {
+ set bits [expr [c-sizeof-decimal-type] * 8]
+ return "__builtin_isnand$bits"
+}
+
+proc isinf-builtin-name { } {
+ set bits [expr [c-sizeof-decimal-type] * 8]
+ return "__builtin_isinfd$bits"
+}
+
+# Return a string that declares a C union containing the decimal type
+# and an unsigned char array of the right size.
+
+proc c-union-decl { } {
+ append result " union {\n"
+ append result " [c-decimal-type] d;\n"
+ append result " unsigned char bytes\[[c-sizeof-decimal-type]\];\n"
+ append result " } u;"
+ return $result
+}
+
+proc transform-hex-constant {value} {
+ regsub \# $value {} value
+ regsub -all (\.\.) $value {0x\1, } bytes
+ return [list $bytes]
+}
+
+# Create a C program file (named using ID) containing a test for a
+# binary OPERATION on OP1 and OP2 that expects RESULT and CONDITIONS.
+
+proc make-c-test {testcase id operation result conditions op1 {op2 "NONE"}} {
+ global directives
+ set filename ${id}.c
+ set outfd [open $filename w]
+
+ puts $outfd [c-test-preamble $id]
+ puts $outfd [c-union-decl]
+ if {[string compare $result ?] != 0} {
+ if {[string index $result 0] == "\#"} {
+ puts $outfd " static unsigned char compare\[[c-sizeof-decimal-type]\] = [transform-hex-constant $result];"
+ }
+ }
+ if {[string compare $op2 NONE] == 0} {
+ if {[string index $op1 0] == "\#"} {
+ puts $outfd " static unsigned char fill\[[c-sizeof-decimal-type]\] = [transform-hex-constant $op1];"
+ }
+ }
+
+ puts $outfd ""
+ puts $outfd " /* FIXME: Set rounding mode with fesetround() once in libc. */"
+ puts $outfd " __dfp_set_round ([c-rounding-mode $directives(rounding)]);"
+ puts $outfd ""
+
+ # Build the expression to be tested.
+ if {[string compare $op2 NONE] == 0} {
+ if {[string index $op1 0] == "\#"} {
+ puts $outfd " memcpy (u.bytes, fill, [c-sizeof-decimal-type]);"
+ } else {
+ puts $outfd " u.d = [c-unary-expression $operation [c-operand $op1]];"
+ }
+ } else {
+ puts $outfd " u.d = [c-binary-expression $operation [c-operand $op1] [c-operand $op2]];"
+ }
+
+ # Test the result.
+ if {[string compare $result ?] != 0} {
+ # Not an undefined result ..
+ if {[string index $result 0] == "\#"} {
+ # Handle hex comparisons.
+ puts $outfd " return memcmp (u.bytes, compare, [c-sizeof-decimal-type]);"
+ } elseif {[nan-p $result]} {
+ puts $outfd " return ![isnan-builtin-name] (u.d);"
+ } elseif {[infinity-p $result]} {
+ puts $outfd " return ![isinf-builtin-name] (u.d);"
+ } else {
+ # Ordinary values.
+ puts $outfd " return !(u.d == [c-operand $result]);"
+ }
+ } else {
+ puts $outfd " return 0;"
+ }
+
+ puts $outfd [c-test-postamble $id]
+ close $outfd
+ return $filename
+}
+
+# Is the test supported for this target?
+
+proc supported-p { id op } {
+ global directives
+ global libfuncs
+
+ # Ops that are unsupported. Many of these tests fail because they
+ # do not tolerate the C front-end rounding the value of floating
+ # point literals to suit the type of the constant. Otherwise, by
+ # treating the `apply' operator like C assignment, some of them do
+ # pass.
+ switch -- $op {
+ apply { return 0 }
+ }
+
+ # Ditto for the following miscellaneous tests.
+ switch $id {
+ addx1130 { return 0 }
+ addx1131 { return 0 }
+ addx1132 { return 0 }
+ addx1133 { return 0 }
+ addx1134 { return 0 }
+ addx1135 { return 0 }
+ addx1136 { return 0 }
+ addx1138 { return 0 }
+ addx1139 { return 0 }
+ addx1140 { return 0 }
+ addx1141 { return 0 }
+ addx1142 { return 0 }
+ addx1151 { return 0 }
+ addx1152 { return 0 }
+ addx1153 { return 0 }
+ addx1154 { return 0 }
+ addx1160 { return 0 }
+ addx690 { return 0 }
+ mulx263 { return 0 }
+ subx947 { return 0 }
+ }
+
+ if [info exist libfuncs($op)] {
+ # No library support for now.
+ return 0
+ }
+ if [catch {c-rounding-mode $directives(rounding)}] {
+ # Unsupported rounding mode.
+ return 0
+ }
+ if [catch {c-decimal-type}] {
+ # Unsupported precision.
+ return 0
+ }
+ return 1
+}
+
+# Break LINE into a list of tokens. Be sensitive to quoting.
+# There has to be a better way to do this :-|
+
+proc tokenize { line } {
+ set quoting 0
+ set tokens [list]
+
+ foreach char [split $line {}] {
+ if {!$quoting} {
+ if { [info exists token] && $char == " " } {
+ if {[string compare "$token" "--"] == 0} {
+ # Only comments remain.
+ return $tokens
+ }
+ lappend tokens $token
+ unset token
+ } else {
+ if {![info exists token] && $char == "'" } {
+ set quoting 1
+ } else {
+ if { $char != " " } {
+ append token $char
+ }
+ }
+ }
+ } else {
+ # Quoting.
+ if { $char == "'" } {
+ set quoting 0
+ if [info exists token] {
+ lappend tokens $token
+ unset token
+ } else {
+ lappend tokens {}
+ }
+ } else {
+ append token $char
+ }
+ }
+ }
+ # Flush any residual token.
+ if {[info exists token] && [string compare $token "--"]} {
+ lappend tokens $token
+ }
+ return $tokens
+}
+
+# Process a directive in LINE.
+
+proc process-directive { line } {
+ global directives
+ set keyword [string tolower [string trim [lindex [split $line :] 0]]]
+ set value [string tolower [string trim [lindex [split $line :] 1]]]
+ set directives($keyword) $value
+}
+
+# Produce a C99-valid floating point literal.
+
+proc c-operand {operand} {
+ set bits [expr 8 * [c-sizeof-decimal-type]]
+
+ switch -glob -- $operand {
+ "Inf*" { return "__builtin_infd${bits} ()" }
+ "-Inf*" { return "- __builtin_infd${bits} ()" }
+ "NaN*" { return "__builtin_nand${bits} (\"\")" }
+ "-NaN*" { return "- __builtin_nand${bits} (\"\")" }
+ "sNaN*" { return "__builtin_nand${bits} (\"\")" }
+ "-sNaN*" { return "- __builtin_nand${bits} (\"\")" }
+ }
+
+ if {[string first . $operand] < 0 && \
+ [string first E $operand] < 0 && \
+ [string first e $operand] < 0} {
+ append operand .
+ }
+ set suffix [c-type-suffix [c-decimal-type]]
+ return [append operand $suffix]
+}
+
+# Process an arithmetic test in LINE from TESTCASE.
+
+proc process-test-case { testcase line } {
+ set testfile [file tail $testcase]
+
+ # Compress multiple spaces down to one.
+ regsub -all { *} $line { } line
+
+ set args [tokenize $line]
+ if {[llength $args] < 5} {
+ error "Skipping invalid test: $line"
+ return
+ }
+
+ set id [string trim [lindex $args 0]]
+ set operation [string trim [lindex $args 1]]
+ set operand1 [string trim [lindex $args 2]]
+
+ if { [string compare [lindex $args 3] -> ] == 0 } {
+ # Unary operation.
+ set operand2 NONE
+ set result_index 4
+ set cond_index 5
+ } else {
+ # Binary operation.
+ set operand2 [string trim [lindex $args 3]]
+ if { [string compare [lindex $args 4] -> ] != 0 } {
+ warning "Skipping invalid test: $line"
+ return
+ }
+ set result_index 5
+ set cond_index 6
+ }
+
+ set result [string trim [lindex $args $result_index]]
+ set conditions [list]
+ for { set i $cond_index } { $i < [llength $args] } { incr i } {
+ lappend conditions [string tolower [lindex $args $i]]
+ }
+
+ # If this test is unsupported, say so.
+ if ![supported-p $id $operation] {
+ unsupported "$testfile ($id)"
+ return
+ }
+
+ if {[string compare $operand1 \#] == 0 || \
+ [string compare $operand2 \#] == 0} {
+ unsupported "$testfile ($id), null reference"
+ return
+ }
+
+ # Construct a C program and then compile/execute it on the target.
+ # Grab some stuff from the c-torture.exp test driver for this.
+
+ set cprog [make-c-test $testfile $id $operation $result $conditions $operand1 $operand2]
+ c-torture-execute $cprog [target-specific-flags]
+}
+
+### Script mainline:
+
+if [catch {set testdir $env(DECTEST)}] {
+ # If $DECTEST is unset, skip this test driver altogether.
+ return
+}
+
+torture-init
+set-torture-options $DEC_TORTURE_OPTIONS
+
+note "Using tests in $testdir"
+dfp-run-tests [lsort [glob -nocomplain $testdir/*.decTest]]
+unset testdir
+
+torture-finish