# Copyright 2009 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>.
#
# Support library for testing the combined debugger for Linux
# on the Cell Broadband Engine.

# Compile SPU objects.
proc gdb_compile_cell_spu {source dest type options} {
  global board

  # Save and unset multilib flags; these are not appropriate
  # for the SPU compiler.
  set board [target_info name]
  set save_multilib_flag [board_info $board multilib_flags]
  unset_board_info "multilib_flags"

  set options_spu [concat $options [list compiler=spu-gcc]]
  set ccout [gdb_compile $source $dest $type $options_spu]

  set_board_info multilib_flags $save_multilib_flag
  return $ccout
}

# Compile PPU objects.  This is just like gdb_compile_pthreads, except that we
# always add the libspe2 library for compiling Cell/B.E. programs.
proc gdb_compile_cell_ppu {source dest type options} {
    # We do not need to try multiple names for the pthread library
    # -lpthread works on all Cell/B.E. systems
    set lib "-lspe2 -lpthread"
    set options_ppu [concat $options [list libs=$lib]]
    return [gdb_compile $source $dest $type $options_ppu]
}

# Embed SPU executable into a PPU object.
proc gdb_cell_embedspu {source dest options} {
    global CC_FOR_TARGET

    if [info exists CC_FOR_TARGET] {
        set compiler $CC_FOR_TARGET
    } else {
	set compiler [board_info [target_info name] compiler]
    }

    # We assume the PPU compiler is called gcc or ppu-gcc,
    # and find the appropriate embedspu based on that.
    regsub gcc "$compiler" embedspu embedspu

    # Determine default embedded symbol name from source filename.
    set path [split "$source" /]
    set filename [lindex $path [expr [llength $path] - 1]]
    regsub -all -- "\[-\.\]" "$filename" "_" symbol

    set options_embed [concat $options [list compiler=$embedspu]]
    return [gdb_compile "$symbol $source $dest" "" none $options_embed]
}

# Run a test on the target to see if it supports Cell/B.E. hardware.
# Return 0 if so, 1 if it does not.
proc skip_cell_tests {} {
    global skip_cell_tests_saved
    global srcdir subdir gdb_prompt

    # Use the cached value, if it exists.
    set me "skip_cell_tests"
    if [info exists skip_cell_tests_saved] {
        verbose "$me:  returning saved $skip_cell_tests_saved" 2
        return $skip_cell_tests_saved
    }

    # Set up, compile, and execute a combined Cell/B.E. test program.
    # Include the current process ID in the file names to prevent conflicts
    # with invocations for multiple testsuites.
    set src cell[pid].c
    set exe cell[pid].x
    set src_spu cell[pid]-spu.c
    set exe_spu cell[pid]-spu.x

    set f [open $src "w"]
    puts $f "#include <libspe2.h>"
    puts $f "extern spe_program_handle_t cell[pid]_spu_x;"
    puts $f "int main (void) {"
    puts $f "unsigned int entry = SPE_DEFAULT_ENTRY;"
    puts $f "spe_context_ptr_t ctx = spe_context_create (0, NULL);"
    puts $f "spe_program_load (ctx, &cell[pid]_spu_x);"
    puts $f "return spe_context_run (ctx, &entry, 0, NULL, NULL, NULL); }"
    close $f

    set f [open $src_spu "w"]
    puts $f "int main (void) { return 0; }"
    close $f

    verbose "$me:  compiling testfile $src" 2
    set compile_flags {debug nowarnings quiet}

    if { [gdb_compile_cell_spu $src_spu $exe_spu executable $compile_flags] != "" } {
        verbose "$me:  compiling spu binary failed, returning 1" 2
        return [set skip_cell_tests_saved 1]
    }
    if { [gdb_cell_embedspu $exe_spu $exe_spu-embed.o $compile_flags]  != "" } {
        verbose "$me:  embedding spu binary failed, returning 1" 2
        return [set skip_cell_tests_saved 1]
    }
    if { [gdb_compile_cell_ppu [list $src $exe_spu-embed.o] $exe executable $compile_flags] != "" } {
        verbose "$me:  compiling ppu binary failed, returning 1" 2
        return [set skip_cell_tests_saved 1]
    }
    file delete $src
    file delete $src_spu
    file delete $exe_spu
    file delete $exe_spu-embed.o

    # Compilation succeeded so now run it via gdb.

    gdb_exit
    gdb_start
    gdb_reinitialize_dir $srcdir/$subdir
    gdb_load "$exe"
    gdb_run_cmd
    gdb_expect {
        -re ".*Program exited normally.*${gdb_prompt} $" {
            verbose -log "\n$me: Cell/B.E. hardware detected"
            set skip_cell_tests_saved 0
        }
        -re ".*Program exited with code.*${gdb_prompt} $" {
            verbose -log "\n$me: Cell/B.E. hardware not detected"
            set skip_cell_tests_saved 1
        }
        default {
            verbose -log "\n$me Cell/B.E. hardware not detected (default case)"
            set skip_cell_tests_saved 1
        }
    }
    gdb_exit
    remote_file build delete $exe

    verbose "$me:  returning $skip_cell_tests_saved" 2
    return $skip_cell_tests_saved
}

# Delete all breakpoints and stop on the next new SPU thread
proc cont_spu_main { } {
  delete_breakpoints
  gdb_test "set spu stop-on-load on"
  gdb_test "continue" \
           "Continuing.*Temporary breakpoint .*main .*" \
           "continue to SPU main"
}

# Continue to MARKER
proc c_to { marker srcfile } {
  set line [gdb_get_line_number $marker $srcfile]
  gdb_test "break $line" \
	   "Breakpoint.*at.*file.*$srcfile.*line $line.*" \
	   "break $line"
  gdb_test "continue" \
	   "Continuing.*Breakpoint.*at.*$srcfile.*$line.*" \
	   "continue to $line"
}

# Check if the current thread has SPU architecture
proc check_spu_arch { msg } {
  if { $msg == "" } {
    set msg "spu architecture is spu256K"
  }
  gdb_test "show architecture" \
	   "The target architecture is set automatically.*currently spu:256K.*" \
	   $msg
}
