# Copyright 2009, 2011-2012 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] {
  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
