# Copyright (C) 2004, 2005, 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 this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  

# Please email any bugs, comments, and/or additions to this file to:
# binutils@sources.redhat.com

# This scripts tests all available SH architectures with all the assembler
# options related to the architecture. It ensures that those combinations
# which should not work do not work, and that those that should work
# produce the correct output architecture.
#
# It looks for files in the same directory as this file named sh*.s .
# Each file must contain all the instructions available within
# that architecture. The architecture name is inferred from the file name.
#
# The sh*.s files should NOT be hand edited. Whenever the script is run
# (e.g. with 'make check') it creates a set of new (usually identical) files
# in the <objdir>/gas/testsuite directory. These are compared against the
# old ones in the testsuite. When the expected results change (or new
# architectures are added) these new files can be used to replace the old
# ones with no modification required.
#
# The script generates the architecture/option permutations automatically,
# but it reads the expected results from the file arch_expected.txt (also
# found in the same directory as this script).
#
# The arch_expected.txt file should NOT be hand edited. Whenever the script
# is run (e.g. with 'make check') it creates a new (usually identical) file
# named arch_results.txt in the <objdir>/gas/testsuite directory. When the
# expected results change (or new architectures are added) this new file
# can be used to replace arch_expected.txt with no modification required.

if {[istarget sh*-*-*]} then {


# This procedure extracts the architecture name from the objdump output.
# If there is no architecture name (or objdump output changes significantly)
# then the behaviour is undefined, but it will most likely return junk.

proc get_sh_arch { ofile } {
    global comp_output

    objdump "-f $ofile"
    send_log $comp_output

    set comp_output [string replace $comp_output 0 \
	    [expr [string first "architecture:" $comp_output] + 13] ""]

    return [string range $comp_output 0 [expr [string first "," $comp_output] - 1]]
}


# This procedure runs two tests:
#   Test 1: Check the assembler can assemble the given file with
#           given options.
#   Test 2: Check that the resultant architecture is as expected.
# It also writes an entry to the arch_results.txt file.

proc test_arch { file opt arch resultfile } {
    global comp_output

    set name [file tail $file]
    set rootname [file rootname $name]

    if [string equal $opt "default-options"] then {
	gas_run $name "-o ${rootname}-#${opt}#.o" ""
    } else {
	gas_run $name "$opt -o ${rootname}-#${opt}#.o" ""
    }

    if [want_no_output "$rootname file should assemble with $opt"] then {
	set result [get_sh_arch "${rootname}-#${opt}#.o"]
	puts $resultfile [format "%-20s %-25s %s" $file $opt $result]

	if {$result == $arch} then {
	    pass "$rootname file with $opt should assemble to arch $arch"
	    file delete "${rootname}-#${opt}#.o"
	} else {
	    send_log $comp_output
	    fail "$rootname file with $opt should assemble to arch $arch"
	}
    } else {
	puts $resultfile [format "%-20s %-25s ERROR" $file $opt]
	untested "$rootname file with $opt should assemble to arch $arch"
    }

}


# This procedure tests that a file that is not suposed to assemble
# with a given option does, in fact, not assemble.
# It also writes an entry to the arch_results.txt file.

proc test_arch_error { file opt resultfile} {
    global comp_output

    set name [file tail $file]
    set rootname [file rootname $name]

    if [string equal $opt "default-options"] then {
	gas_run $name "-o ${rootname}-#${opt}#.o" ""
    } else {
	gas_run $name "$opt -o ${rootname}-#${opt}#.o" ""
    }

    if [string match "" $comp_output] then {
	fail "$rootname file with $opt should not assemble"
	puts $resultfile [format "%-20s %-25s [get_sh_arch ${rootname}-#${opt}#.o]" $file $opt]
    } else {
	pass "$rootname file with $opt should not assemble"
	puts $resultfile [format "%-20s %-25s ERROR" $file $opt]
    }
}   

# These tests are not suitable for sh-coff because
# coff does not store the architecture information.

if [istarget sh*-*-elf] then {
    global subdir srcdir

    # Find all the architectures and generate the
    # list of options we will test.

    set filelist [lsort -ascii [glob "$srcdir/$subdir/sh*.s"]]
    set optlist {"default-options" "-dsp" "-isa=any" "-isa=dsp" "-isa=fp"}
    foreach file $filelist {
	set arch [file rootname [file tail $file]]
	lappend optlist "-isa=$arch" "-isa=${arch}-up"
    }

    # Initialise the results file

    set outfile [open "arch_results.txt" w 0666]
    puts $outfile "# Generated file. DO NOT EDIT"
    puts $outfile "#"
    puts $outfile "# This file is generated by gas/testsuite/gas/sh/arch/arch.exp ."
    puts $outfile "# It contains the expected results of the tests."
    puts $outfile "# If the tests are failing because the expected results"
    puts $outfile "# have changed then run 'make check' and copy the new file"
    puts $outfile "# from <objdir>/gas/testsuite/arch_results.txt"
    puts $outfile "# to   <srcdir>/gas/testsuite/gas/sh/arch/arch_expected.txt ."
    puts $outfile "# Make sure the new expected results are ALL correct."
    puts $outfile "#"
    puts $outfile [format "# %-18s %-25s %s" "FILE" "OPTION" "OUTPUT"]
    puts $outfile [format "# %-18s %-25s %s" "----" "------" "------"]

    # Open the expected results file and skip the header

    set infile [open "$srcdir/$subdir/arch_expected.txt" r]
    while {[gets $infile line] >= 0 && [string match {\#*} $line]} {send_log "reading '$line'\n"}

    foreach file $filelist {
	foreach opt $optlist {
	    set name [file tail $file]
	    set rootname [file rootname $name]

	    # Decode the expected result from the file

	    scan $line "%s %s %s" exfile exopt exarch
	    send_log "exfile = '$exfile', exopt = '$exopt', exarch = '$exarch'\n"
	    send_log "  name = '$name',   opt = '$opt'\n"

	    if {[string equal $exfile $name] && [string equal $exopt $opt]} then {
		# The expected result file makes sense and
		# appears up-to-date (the file and options match)

		if {[string equal $exarch "ERROR"]} then {
		    test_arch_error $name $opt $outfile
		} else {
		    test_arch $name $opt $exarch $outfile
		}
	    } else {
		# The expected result file isn't right somehow
		# so just try any old test. This will cause
		# many failures, but will generate the results file.

		test_arch $name $opt $rootname $outfile
	    }

	    # Read the next line from the expected result file.
	    # This is at the end because the process of skipping
	    # the header reads the first real line

	    if [gets $infile line] then {
		send_log "reading '$line'\n"
	    }
	}
    }

    close $infile
    close $outfile
}

return

#########################################################################
# Generate one sh*.s file for each architecture defined in sh-opc.h
# This will contain all the instructions valid on that platform
#
# This code produces pass or fail reports for each instruction
# in order to ensure that problems are visible to the developer,
# rather than just warnings hidden in the log file.

# These variables will contains the architecture
# and instruction data extracted from sh-opc.h
array set arches {}
set archcount 0
array set insns {}
set insncount 0

# Pull the architecture inheritance macros out of sh-opc.h
# Pull all the insns out of the sh-opc.h file.
send_log "Reading sh-opc.h\n"
send_log "========================================================\n"
spawn -noecho cat "$srcdir/../../opcodes/sh-opc.h"   ;# -open doesn't seem to be reliable
expect {
    -re {#define\s+arch_([^ ]*)_up\s*\(([^)]*)\)} {
	set arches($archcount) [string map {_ -} $expect_out(1,string)]
	set arches($archcount,descendents) [string map {_ -} $expect_out(2,string)]
	incr archcount
	pass "Architecture arch_$expect_out(1,string) read OK"
	exp_continue
    }
    # Match all 32 bit opcodes
    -re {(?x)           # enable expanded regexp syntax
         ^/\*           # open C comment at start of input
         (?:\s*\S+){2}  #   2 binary words (for 32 bit opcodes)
     \s+ ([^*]+?)       #   instruction mnemonics (must not leave comment)
     \s* \*/            # close C comment
     \s* \{             # open brace of data initialiser
	 (?:[^\}]+\}){2}#   2 brace pairs (operands and nibbles)
     \s* ,              #   comma
     \s* arch_(\S+)_up  #   architecture name
     \s* \|             #   literal or
     \s* arch_op32      #   32 bit opcode indicator
     \s* \}             # close brace of data initialiser
	} {
	    set insns(insn,$insncount) $expect_out(1,string)
	    set insns(arch,$insncount) [string map {_ -} $expect_out(2,string)]
	    set insns(context,$insncount) $expect_out(0,string)
	    incr insncount
	    pass "Instruction '$expect_out(1,string)' read OK"
	    exp_continue
	}
    # Special case: Match the repeat pseudo op
    -re {(?x)           # enable expanded regexp syntax
	 ^/\*           # open C comment at start of input
     \s* repeat         #   repeat does not have a bit pattern
     \s+ start\s+end    #   don't read fake operands as such (replaced below)
     \s+ ([^*]+?)       #   instruction operand
     \s* \*/            # close C comment
     \s* \{             # open brace of data initialiser
	 (?:[^\}]+\}){2}#   2 brace pairs (operands and nibbles)
     \s* ,              #   comma
     \s* arch_(\S+)_up  #   architecture name
     \s* \}             # close brace of data initialiser
        } {
	    set insns(insn,$insncount) "repeat 10 20 $expect_out(1,string)"
	    set insns(arch,$insncount) [string map {_ -} $expect_out(2,string)]
	    set insns(context,$insncount) $expect_out(0,string)
	    incr insncount
	    pass "Instruction '$expect_out(1,string)' read OK"
	    exp_continue
	}
    # Match all 16 bit opcodes
    -re {(?x)           # enable expanded regexp syntax
         ^/\*           # open C comment at start of input
     \s* \S+            #   1 binary word (for 16 bit opcodes)
     \s+ ([^*]+?)       #   instruction mnemonics (must not leave comment)
     \s* \*/            # close C comment
     \s* \{             # open brace of data initialiser
	 (?:[^\}]+\}){2}#   2 brace pairs (operands and nibbles)
     \s* ,              #   comma
     \s* arch_(\S+)_up  #   architecture name
     \s* \}             # close brace of data initialiser
	} {
	    set insns(insn,$insncount) $expect_out(1,string)
	    set insns(arch,$insncount) [string map {_ -} $expect_out(2,string)]
	    set insns(context,$insncount) $expect_out(0,string)
	    incr insncount
	    pass "Instruction '$expect_out(1,string)' read OK"
	    exp_continue
	}
    # Match all remaining possible instructions (error detection)
    -re {(?x)           # enable expanded regexp syntax
	 ^/\*           # open C comment at start of input
	 (?:[^*]*(?:\*[^/])?)+ # match contents of comment allowing *
	 \*/            # close C comment
     \s* \{             # open brace of data initialiser
	 (?:[^\}]+\}){2}#   2 brace pairs (operands and nibbles)
     \s* ,              #   comma
	 [^\}]*
	 arch           #   look for 'arch' anywhere before closing brace
	 [^\}]*
	 \}             # close brace of data initialiser
        } {
	    fail "Found something that looks like an instruction but cannot be decoded:\n\t$expect_out(0,string)"
	    exp_continue
	}
    # No match so move to next (possible) comment
    -re {^.+?((?=/\*)|(?=\#\s*define))} exp_continue
}
send_log "--------------------------------------------------------\n"

if {$archcount == 0} then {
    fail "Unable to read any architectures from sh-opc.h"
} else {
    pass "Read architecture data from sh-opc.h"
}
if {$insncount == 0} then {
    fail "Unable to read any instructions from sh-opc.h"
} else {
    pass "Read instruction data from sh-opc.h"
}

# Munge the insns such that they will assemble
# Each instruction in sh-opc.h has an example format
# with placeholders for the parameters. These placeholders
# need to be replaced with real registers and constants
# as appropriate in order to assemble correctly.
for {set i 0} {$i < $insncount} {incr i} {
    set out $insns(insn,$i)
    if {[regexp {AY_.{3,4}_N} $insns(context,$i)] == 1} then {
	regsub -nocase {<REG_N>} $out {r6} out
    } else {
	regsub -nocase {<REG_N>} $out {r4} out
    }
    regsub -nocase {<REG_M>} $out {r5} out
    if {[regexp {IMM0_20BY8} $insns(context,$i)] == 1} then {
	regsub -nocase {<imm>} $out {1024} out
    } else {
	regsub -nocase {<imm>} $out {4} out
    }
    regsub -nocase {<bdisp\d*>} $out {.+8} out
    regsub -nocase {<disp12>} $out {2048} out
    regsub -nocase {<disp\d*>} $out {8} out
    regsub -nocase {Rn_BANK} $out {r1_bank} out
    regsub -nocase {Rm_BANK} $out {r2_bank} out
    regsub -nocase {<F_REG_N>} $out {fr1} out
    regsub -nocase {<F_REG_M>} $out {fr2} out
    regsub -nocase {<D_REG_N>} $out {dr2} out
    regsub -nocase {<D_REG_M>} $out {dr4} out
    regsub -nocase {<V_REG_N>} $out {fv0} out
    regsub -nocase {<V_REG_M>} $out {fv4} out
    regsub -nocase {<DX_REG_N>} $out {xd2} out
    regsub -nocase {<DX_REG_M>} $out {xd4} out
    regsub -nocase (XMTRX_M4) $out {xmtrx} out
    regsub -nocase (<DSP_REG_X>) $out {x1} out
    regsub -nocase (<DSP_REG_Y>) $out {y0} out
    regsub -nocase (<DSP_REG_M>) $out {a1} out
    regsub -nocase (<DSP_REG_N>) $out {m0} out
    regsub -nocase (<REG_Axy>) $out {r1} out
    regsub -nocase (<REG_Ayx>) $out {r3} out
    regsub -nocase (<DSP_REG_XY>) $out {y1} out
    regsub -nocase (<DSP_REG_YX>) $out {y1} out
    regsub -nocase (<DSP_REG_AX>) $out {a0} out
    regsub -nocase (<DSP_REG_AY>) $out {a0} out
    regsub (Se) $out {x0} out
    regsub (Sf) $out {y0} out
    regsub (Dg) $out {m0} out
    # Put in a dct in order to differentiate between
    # conditional and non-conditional pabs and prnd
    # i.e. between sh-dsp and sh4al-dsp
    if {[regexp {PPIC} $insns(context,$i)] == 1} then {
	set out "dct $out"
    }
    # Make sure the proper alignments are ok.
    if [regexp {i8p4} $insns(context,$i)] {
      set out ".align 2\n\t$out"
    }

    # Write back the results.
    set insns(insn,$i) $out
    set insns(context,$i) [string map {\n " " \r " "} $insns(context,$i)]
}

# Initialise the data structure for the inheritance
array set archtree {}
for {set a 0} {$a < $archcount} {incr a} {
    set archtree($arches($a)) {}
}

# For each architecture, extract its immediate parents
for {set a 0} {$a < $archcount} {incr a} {
    set s $arches($a,descendents)
    regsub -all {[\s|]+} $s { } s
    foreach word [split $s { }] {
	# Word should be one of arch-..., | (or), or arch-...-up
	# We only want the -up information
	# Note that the _ -> - translation was done above
	if {[regexp {^arch-(.*)-up$} $word match arch] == 1} then {
	    # $arch is the descendent of $arches($a),
	    # so $arches($a) is the parent of $arch
	    lappend archtree($arch) $arches($a)
	}
    }
}

# Propagate the inhertances through the list
# Iterate to ensure all inheritances are found (necessary?)
set changesmade 1
while {$changesmade == 1} {
    set changesmade 0
    foreach a [array names archtree] {
	foreach b [array names archtree] {
	    # If arch 'a' is a parent of arch 'b' then b inherits from a
	    if {[lsearch -exact $archtree($b) $a] != -1} then {
		# Only add each arch if it is not already present
		foreach arch $archtree($a) {
		    if {[lsearch -exact $archtree($b) $arch] == -1} then {
			lappend archtree($b) $arch
			set changesmade 1
		    }
		}
	    }
	}
    }
}

# Generate the assembler file for each architecture
# Also count up how many instructions should be valid for each architecture
array set insns_valid {}
for {set arch 0} {$arch < $archcount} {incr arch} {
    set insns_valid($arches($arch)) 0
    set fd [open $arches($arch).s w 0666]
    puts $fd "! Generated file. DO NOT EDIT.\n!"
    puts $fd "! This file was generated by gas/testsuite/gas/sh/arch/arch.exp ."
    puts $fd "! This file should contain every instruction valid on"
    puts $fd "! architecture $arches($arch) but no more."
    puts $fd "! If the tests are failing because the expected results"
    puts $fd "! have changed then run 'make check' and copy the new file"
    puts $fd "! from <objdir>/gas/testsuite/$arches($arch).s"
    puts $fd "! to   <srcdir>/gas/testsuite/gas/sh/arch/$arches($arch).s ."
    puts $fd "! Make sure there are no unexpected or missing instructions."
    puts $fd "\n\t.section .text"
    puts $fd "[string map {- _} $arches($arch)]:"
    puts $fd "! Instructions introduced into $arches($arch)"
    for {set i 0} {$i < $insncount} {incr i} {
	if [string equal $arches($arch) $insns(arch,$i)] then {
	    puts $fd [format "\t%-25s ;!%s" $insns(insn,$i) $insns(context,$i)]
	    incr insns_valid($arches($arch))
	}
    }
    puts $fd "\n! Instructions inherited from ancestors: [lsort -increasing $archtree($arches($arch))]"
    for {set i 0} {$i < $insncount} {incr i} {
	if {[string equal $arches($arch) $insns(arch,$i)] != 1 && [lsearch -exact $archtree($arches($arch)) $insns(arch,$i)] != -1} then {
	    puts $fd [format "\t%-25s ;!%s" $insns(insn,$i) $insns(context,$i)]
	    incr insns_valid($arches($arch))
	}
    }
    close $fd
}


###################################################################
# Compare the newly created sh*.s files with the existing
# ones in the testsuite

for {set arch 0} {$arch < $archcount} {incr arch} {
    send_log "diff $srcdir/$subdir/$arches($arch).s $arches($arch).s\n"
    catch "exec diff $srcdir/$subdir/$arches($arch).s $arches($arch).s" diff_output
    if {[string equal $diff_output ""] == 0} then {
	send_log $diff_output
	fail "Check $arches($arch) architecture has not changed"
    } else {
	pass "Check $arches($arch) architecture has not changed"
    }
}


###################################################################
# Generate an assembler file with every instruction
# Then use it to test how many failures there are for
# each architecture. If this does not match the predicted value
# then the assembler accepts too many instructions for a given
# architecture.


set fd [open "all_insns.s" w 0666]
for {set i 0} {$i < $insncount} {incr i} {
    puts $fd [format "\t%-25s ;!%s" $insns(insn,$i) $insns(context,$i)]
}
close $fd

# Assemble the all_insns.s file for each isa and count how many failures there are
foreach arch [array names insns_valid] {
    set errormessages 0
    set expected [expr $insncount - $insns_valid($arch)]

    # The -Z option ensures that all error messages are output,
    # even those from later phases of assembly (such as offset range errors)
    send_log "$AS -Z -isa=$arch all_insns.s -o /dev/null\n"
    spawn $AS -Z -isa=$arch all_insns.s -o /dev/null
    expect Error: {incr errormessages; exp_continue}

    if {$errormessages == $expected} then {
	pass "$expected insns should not assemble on $arch"
    } else {
	if {([istarget sh*-*-coff] || [istarget sh*-hms]) && [string match {*dsp} $arch]} {
	    xfail "$expected insns should not assemble on $arch ($errormessages did not)"
	} else {
	    fail "$expected insns should not assemble on $arch ($errormessages did not)"
	}
    }
}


} ;# istarget sh*-*-*
