# Copyright (C) 2002, 2003, 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, see <http://www.gnu.org/licenses/>.
#

# Tests for Powerpc AltiVec ABI


if $tracelevel then {
    strace $tracelevel
}

#
# This file uses altivec-abi.c for input.
#

if {![istarget "powerpc*"] || [skip_altivec_tests]} then {
    verbose "Skipping altivec abi tests."
    return
}

set testfile "altivec-abi"
set binfile ${objdir}/${subdir}/${testfile}
set srcfile ${testfile}.c

if [get_compiler_info $binfile] {
    warning "get_compiler failed"
    return -1
}

proc altivec_abi_tests { extra_flags force_abi } {
    global testfile binfile srcfile srcdir subdir
    global gdb_prompt

    set compile_flags "debug nowarnings $extra_flags"

    if  { [gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile} executable $compile_flags] != "" } {
	untested altivec-abi.exp
	return -1
    }

    if { "$force_abi" == "auto" } {
	# If the toolchain does not record attributes, skip auto-ABI tests.
	set readelf_program [transform readelf]
	set result [catch "exec $readelf_program -A $binfile" output]

	if {$result == 0 && ![regexp Tag_GNU_Power_ABI_Vector $output]} {
	    untested "ABI not marked"
	    return
	}
    }

    gdb_exit
    gdb_start
    gdb_reinitialize_dir $srcdir/$subdir
    gdb_load ${binfile}

    # Run to `main' where we begin our tests.
    if ![runto_main] then {
	untested altivec-abi.exp
	return -1
    }

    gdb_test "set powerpc vector-abi $force_abi"

    gdb_test "b marker" "Breakpoint 2 at.*file.*altivec-abi.c, line \[0-9\]+." "break marker"
    gdb_test "continue" "Breakpoint 2.*marker.*altivec-abi.c.*" "continue to marker"
    gdb_test "finish" "Run till exit from .0.*marker.*at.*altivec-abi.c.*main \\(\\) at.*altivec-abi.c.*result = vec_func \\(vshort,.*goes in v2.*" "back to main (1)"

    # now all the arguments of vec_fun are initialized

    set pattern "vec_func .vshort_f=.111, 222, 333, 444, 555, 666, 777, 888., vushort_f=.100, 200, 300, 400, 500, 600, 700, 800., vint_f=.-10, -20, -30, -40., vuint_f=.1111, 2222, 3333, 4444., vchar_f=.abcdefghilmnopqr., vuchar_f=.ABCDEFGHILMNOPQR., vfloat_f=.1.25, 3.75, 5.5, 1.25., x_f=.1, 2, 3, 4, 5, 6, 7, 8., y_f=.12, 22, 32, 42., a_f=.vector of chars.., b_f=.5.5, 4.5, 3.75, 2.25., c_f=.1.25, 3.5, 5.5, 7.75., intv_on_stack_f=.12, 34, 56, 78.."

    set pattern1 $pattern
    append pattern1 " at.*altivec-abi.c.*vint_res  = vec_add.*vint_f, intv_on_stack_f.;"

    # Now let's call the function.  This function has > 12 args,
    # the last one will go on the stack.
    set msg "call inferior function with vectors (1)"
    gdb_test "p vec_func(vshort,vushort,vint,vuint,vchar,vuchar,vfloat,x,y,a,b,c,intv_on_stack)" \
	".\[0-9\]+ = .2, 2, 2, 2." "call inferior function with vectors (1)"

    # Let's call the function again with dummy arguments.  This is to clean
    # up the contents of the vector registers before the next call.
    gdb_test "p vec_func(vshort_d,vushort_d,vint_d,vuint_d,vchar_d,vuchar_d,vfloat_d,x_d,y_d,a_d,b_d,c_d,intv_on_stack_d)" \
	".\[0-9\]+ = .0, 0, 0, 0." "call inferior function with vectors (2)"

    # Let's step into the function, to see if the args are printed correctly.
    gdb_test "step" \
	$pattern1 \
	"step into vec_fun"

    set pattern2 $pattern
    append pattern2 " at.*altivec-abi.c.*main.*result = vec_func .vshort,.*goes in v2.*Value returned is.*= .2, 2, 2, 2."

    # Let's see if the result is returned correctly.
    gdb_test "finish" "Run till exit from .0.*$pattern2" \
	"vector value returned correctly"

    # can we print the args correctly for this function?
    gdb_test "break struct_of_vector_func" "" ""

    set pattern "struct_of_vector_func .vector_struct=.vshort1 = .1, 2, 3, 4, 5, 6, 7, 8., vshort2 = .11, 12, 13, 14, 15, 16, 17, 18., vshort3 = .21, 22, 23, 24, 25, 26, 27, 28., vshort4 = .31, 32, 33, 34, 35, 36, 37, 38... at.*altivec-abi.c.*"

    gdb_test "continue" \
	"Breakpoint 3, $pattern.*vector_struct.vshort1 = vec_add .vector_struct.vshort1, vector_struct.vshort2.;" \
	"continue to struct_of_vector_func"

    gdb_test "finish" \
	"Run till exit from .0  $pattern\[ \r\n\]+main.*altivec-abi.c.*array_of_vector_func.*" \
	"back to main (2)"

    gdb_test "step" "" "step into array_of_vector_func"
    gdb_test "p matrix\[0\]" ".*= .1, 2, 3, 4, 5, 6, 7, 8." "print first vector"
    gdb_test "p matrix\[1\]" ".*= .11, 12, 13, 14, 15, 16, 17, 18." "print second vector"
    gdb_test "p matrix\[2\]" ".*= .21, 22, 23, 24, 25, 26, 27, 28." "print third vector"
    gdb_test "p matrix\[3\]" ".*= .31, 32, 33, 34, 35, 36, 37, 38." "print fourth vector"
}

if [test_compiler_info gcc*] {
    set saved_prefix $pf_prefix

    set pf_prefix "${saved_prefix} default ABI, auto:"
    altivec_abi_tests "additional_flags=-maltivec" "auto"

    # On GNU/Linux, we can mix -mabi=no-altivec and -mabi=altivec.
    # So test some combinations.
    if { [istarget "powerpc*-linux*"] } {
	set binfile ${objdir}/${subdir}/${testfile}-ge-ge
	set pf_prefix "${saved_prefix} generic ABI, forced:"
	altivec_abi_tests "additional_flags=-maltivec additional_flags=-mabi=no-altivec" "generic"

	set binfile ${objdir}/${subdir}/${testfile}-av-av
	set pf_prefix "${saved_prefix} AltiVec ABI, forced:"
	altivec_abi_tests "additional_flags=-maltivec additional_flags=-mabi=altivec" "altivec"

	set binfile ${objdir}/${subdir}/${testfile}-av-auto
	set pf_prefix "${saved_prefix} AltiVec ABI, auto:"
	altivec_abi_tests "additional_flags=-maltivec additional_flags=-mabi=altivec" "auto"
    }
} elseif [test_compiler_info xlc*] {
    altivec_abi_tests "additional_flags=-qaltivec" "auto"
} else {
    warning "unknown compiler"
    return -1
}
