# Copyright 2017-2021 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/>.
#
# This file is part of the gdb testsuite.

# Test single stepping through POWER8/ISA 2.07 atomic sequences beginning with
# a lbarx/lharx/lqarx instruction and ending with a stbcx/sthcx/stqxc
# instruction.  Note that although lbarx, lharx, stbcx and sthcx instructions
# were introduced in ISA 2.06, they were implemented only in POWER8 (ISA 2.07).


if {![istarget "powerpc*"] || ![is_lp64_target]} {
    untested "skipping powerpc isa 207 atomic sequences test"
    return
}

standard_testfile  .c .S

if { [prepare_for_testing "failed to prepare" $testfile "$srcfile $srcfile2" \
      {debug quiet}] } {
    return -1
}

# The test proper.  DISPLACED is true if we should try with displaced
# stepping.

proc do_test { displaced } {
    global decimal hex
    global gdb_prompt inferior_exited_re srcfile srcfile2

    if ![runto_main] then {
	return -1
    }

    gdb_test_no_output "set displaced-stepping $displaced"

    gdb_breakpoint "test_atomic_sequences" "Breakpoint $decimal at $hex" \
	"set the breakpoint at the start of the test function"

    gdb_test_multiple "continue" "Continue until lbarx/stbcx start breakpoint" {
      -re "$inferior_exited_re with code 01.\[\r\n\]+$gdb_prompt $" {
	unsupported "POWER8/ISA 2.07 atomic instructions not supported."
	return -1
      }
      -re "Continuing.*Breakpoint $decimal.*$gdb_prompt $" {
	pass "continue until test_atomic_sequences function"
      }
    }

    set bp1 [gdb_get_line_number "lbarx" "$srcfile2"]
    gdb_breakpoint "$bp1" "Breakpoint $decimal at $hex" \
	"set the breakpoint at the start of the lbarx/stbcx sequence"

    set bp2 [gdb_get_line_number "lharx" "$srcfile2"]
    gdb_breakpoint "$bp2" "Breakpoint $decimal at $hex" \
	"set the breakpoint at the start of the lharx/sthcx sequence"

    set bp3 [gdb_get_line_number "lqarx" "$srcfile2"]
    gdb_breakpoint "$bp3" "Breakpoint $decimal at $hex" \
	"set the breakpoint at the start of the lqarx/stqcx sequence"

    gdb_test continue "Continuing.*Breakpoint $decimal.*" \
	"continue until lbarx/stbcx start breakpoint"

    gdb_test nexti "bne.*1b" \
	"step through the lbarx/stbcx sequence"

    gdb_test continue "Continuing.*Breakpoint $decimal.*" \
	"continue until lharx/sthcx start breakpoint"

    gdb_test nexti "bne.*2b" \
	"step through the lharx/sthcx sequence"

    gdb_test continue "Continuing.*Breakpoint $decimal.*" \
	"continue until ldqrx/stqcx start breakpoint"

    gdb_test nexti "bne.*3b" \
	"step through the lqarx/stqcx sequence"
}

foreach displaced { "off" "on" } {
    with_test_prefix "displaced=$displaced" {
	do_test $displaced
    }
}
