# Copyright 2009, 2011 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/>.
#
# Contributed by Markus Deuling <deuling@de.ibm.com>.
#
# Testsuite for Cell Broadband Engine combined debugger
# This testcases tests mixed-architecture backtrace support

load_lib cell.exp

set testfile "bt"
set ppu_file "bt"
set ppu_src ${srcdir}/${subdir}/${ppu_file}.c
set ppu_bin ${objdir}/${subdir}/${ppu_file}
set spu_file "bt-spu"
set spu_src ${srcdir}/${subdir}/${spu_file}.c
set spu_bin ${objdir}/${subdir}/${spu_file}
set spu2_file "bt2-spu"
set spu2_src ${srcdir}/${subdir}/${spu2_file}.c
set spu2_bin ${objdir}/${subdir}/${spu2_file}

if {[skip_cell_tests]} {
    return 0
}

# Compile SPU binaries.
if { [gdb_compile_cell_spu $spu_src $spu_bin executable {debug}]  != "" } {
  unsupported "Compiling spu binary failed."
  return -1
}
if { [gdb_compile_cell_spu $spu2_src $spu2_bin executable {debug}]  != "" } {
  unsupported "Compiling spu binary failed."
  return -1
}
# Compile PPU binary.
if { [gdb_cell_embedspu $spu_bin $spu_bin-embed.o {debug}]  != "" } {
  unsupported "Embedding spu binary failed."
  return -1
}
if { [gdb_cell_embedspu $spu2_bin $spu2_bin-embed.o {debug}]  != "" } {
  unsupported "Embedding spu binary failed."
  return -1
}
if { [gdb_compile_cell_ppu [list $ppu_src $spu_bin-embed.o $spu2_bin-embed.o] $ppu_bin executable {debug}] != "" } {
  unsupported "Compiling ppu binary failed."
  return -1
}

if [get_compiler_info ${ppu_bin}] {
  return -1
}

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

if ![runto_main] then {
  fail "Can't run to main"
  return 0
}

delete_breakpoints
gdb_test "continue" ".*Program received signal SIGABRT, Aborted.*"

gdb_test "backtrace" ".*abort.*crash_handler.*base.*offset.*<cross-architecture call>.*main.*speid.*argp.*envp.*at.*$spu2_file.c.*<cross-architecture call>.*spe_context_run.*indirect_handler.*base.*offset.*<cross-architecture call>.*main.*speid.*argp.*envp.*at.*$spu_file.c.*<cross-architecture call>.*spe_context_run.*spe_thread.*at.*$ppu_file.c.*"

for {set thread_id 2} {$thread_id < 7} {incr thread_id} {
  gdb_test "t $thread_id" \
           "Switching to thread $thread_id.*" \
           "switch to thread $thread_id"
  gdb_test "backtrace" \
	   ".*crash_handler.*base.*offset.*<cross-architecture call>.*main.*speid.*argp.*envp.*at.*$spu2_file.c.*<cross-architecture call>.*spe_context_run.*indirect_handler.*base.*offset.*<cross-architecture call>.*main.*speid.*argp.*envp.*at.*$spu_file.c.*<cross-architecture call>.*spe_context_run.*spe_thread.*at.*$ppu_file.c.*" \
	   "backtrace in thread $thread_id"
}

gdb_exit

return 0
