diff options
author | Anton Kolesov <Anton.Kolesov@synopsys.com> | 2017-02-10 14:12:06 +0300 |
---|---|---|
committer | Anton Kolesov <Anton.Kolesov@synopsys.com> | 2017-03-28 21:36:35 +0300 |
commit | eea787570f708e51048f812808e6cbd76fde6919 (patch) | |
tree | b3df9e1ebf01db2652e0c1b99cab8b68e814eddb /gdb/testsuite | |
parent | 3be78afdeddd3ebf57eb0df8b029cf596f468c7a (diff) | |
download | gdb-eea787570f708e51048f812808e6cbd76fde6919.zip gdb-eea787570f708e51048f812808e6cbd76fde6919.tar.gz gdb-eea787570f708e51048f812808e6cbd76fde6919.tar.bz2 |
arc: Add disassembler helper
Add disassembler helper for GDB, that uses opcodes structure arc_instruction
and adds convenience functions to handle instruction operands. This interface
solves at least those problems with arc_instruction:
* Some instructions, like "push_s", have implicit operands which are not
directly present in arc_instruction.
* Operands of particular meaning, like branch/jump targets, have various
locations and meaning depending on type of branch/target.
* Access to operand value is abstracted into a separate function, so callee
code shouldn't bother if operand value is an immediate value or in a
register.
Testcases included in this commit are fairly limited - they test exclusively
branch instructions, something that will be used in software single stepping.
Most of the other parts of this disassembler helper are tested during prologue
analysis testing.
gdb/ChangeLog:
yyyy-mm-dd Anton Kolesov <anton.kolesov@synopsys.com>
* configure.tgt: Add arc-insn.o.
* arc-tdep.c (arc_delayed_print_insn): Make non-static.
(dump_arc_instruction_command): New function.
(arc_fprintf_disasm): Likewise.
(arc_disassemble_info): Likewise.
(arc_insn_get_operand_value): Likewise.
(arc_insn_get_operand_value_signed): Likewise.
(arc_insn_get_memory_base_reg): Likewise.
(arc_insn_get_memory_offset): Likewise.
(arc_insn_get_branch_target): Likewise.
(arc_insn_dump): Likewise.
(arc_insn_get_linear_next_pc): Likewise.
* arc-tdep.h (arc_delayed_print_insn): Add function declaration.
(arc_disassemble_info): Likewise.
(arc_insn_get_branch_target): Likewise.
(arc_insn_get_linear_next_pc): Likewise.
* NEWS: Mention new "maint print arc arc-instruction".
gdb/doc/ChangeLog:
yyyy-mm-dd Anton Kolesov <anton.kolesov@synopsys.com>
* gdb.texinfo (Synopsys ARC): Add "maint print arc arc-instruction".
gdb/testsuite/ChangeLog:
yyyy-mm-dd Anton Kolesov <anton.kolesov@synopsys.com>
* gdb.arch/arc-decode-insn.S: New file.
* gdb.arch/arc-decode-insn.exp: Likewise.
Diffstat (limited to 'gdb/testsuite')
-rw-r--r-- | gdb/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/testsuite/gdb.arch/arc-decode-insn.S | 1002 | ||||
-rw-r--r-- | gdb/testsuite/gdb.arch/arc-decode-insn.exp | 132 |
3 files changed, 1139 insertions, 0 deletions
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 3bd066c..efccd01 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-03-28 Anton Kolesov <anton.kolesov@synopsys.com> + + * gdb.arch/arc-decode-insn.S: New file. + * gdb.arch/arc-decode-insn.exp: Likewise. + 2017-03-21 Ivo Raisr <ivo.raisr@oracle.com> PR tdep/20928 diff --git a/gdb/testsuite/gdb.arch/arc-decode-insn.S b/gdb/testsuite/gdb.arch/arc-decode-insn.S new file mode 100644 index 0000000..e1127d0 --- /dev/null +++ b/gdb/testsuite/gdb.arch/arc-decode-insn.S @@ -0,0 +1,1002 @@ +; This testcase is part of GDB, the GNU debugger. + +; Copyright 2017 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/>. + +.section .text +.global main + +#define TEST_J +#define TEST_JCC +#define TEST_JL +#define TEST_JLCC +#define TEST_B +#define TEST_BBIT +#define TEST_BCC +#define TEST_BI +#define TEST_BL +#define TEST_BRCC +#define TEST_JLI +#define TEST_LEAVE_S +#define TEST_LPCC + +; JLI-specific stuff +#ifdef TEST_JLI +jli_table: + .word 0xdeadbeea + .word 0xdeadbeea +jli_target: + .word 0xdeadbeea + .word 0xdeadbeea + +.set jli_offset, 3 +#endif +main: + +; Each test case requires several symbols to be set, that identify expected +; parameters of this instruction. Required symbols: +; ${test}_start: symbol points to start of the test +; ${test}_end: symbol points to the instruction after the jump/branch +; instruction. +; ${test}_target: branch target address. +; ${test}_has_delay_slot: whether instruction has delay slot. +; ${test}_cc: condition code numeric value. + + .set r12_value, 0xdead0000 + .set blink_value, 0xdead0004 + .set limm_value, 0xdead0008 + ; Just an integer + .set r4_value, 0xdead000c + ; Just an integer + .set r5_value, 0xdead0010 + ; offset index for BI [c] + .set r7_value, 4 + .set u6_value, 0x20 + .set s12_target, 0x100 + + mov r12, @r12_value + mov r4, @r4_value + mov r5, @r5_value + mov r7, @r7_value + mov blink, @blink_value +#ifdef TEST_JLI + ; jli_base aux regnum = 0x290 + sr jli_table, [0x290] +#endif + +start_branch_tests: + +#ifdef TEST_J + +#define TEST_NAME j_c + ; j [c] + .set j_c_target, @r4_value + .set j_c_has_delay_slot, 0 + .set j_c_cc, 0 + j_c_start: + j [r4] + j_c_end: + + ; j [blink] + .set j_blink_target, @blink_value + .set j_blink_has_delay_slot, 0 + .set j_blink_cc, 0 + mov blink, @j_blink_target + j_blink_start: + j [blink] + j_blink_end: + + ; j limm + .set j_limm_target, @limm_value + .set j_limm_has_delay_slot, 0 + .set j_limm_cc, 0 + j_limm_start: + j @j_limm_target + j_limm_end: + + ; j u6 + .set j_u6_target, @u6_value + .set j_u6_has_delay_slot, 0 + .set j_u6_cc, 0 + j_u6_start: + j @j_u6_target + j_u6_end: + + ; j s12 + .set j_s12_target, @s12_target + .set j_s12_has_delay_slot, 0 + .set j_s12_cc, 0 + j_s12_start: + j @j_s12_target + j_s12_end: + + ; j.d [c] + .set j_d_c_target, @r4_value + .set j_d_c_has_delay_slot, 1 + .set j_d_c_cc, 0 + j_d_c_start: + j.d [r4] + j_d_c_end: + nop_s + + ; j.d [blink] + .set j_d_blink_target, @blink_value + .set j_d_blink_has_delay_slot, 1 + .set j_d_blink_cc, 0 + j_d_blink_start: + j.d [blink] + j_d_blink_end: + nop_s + + ; j.d u6 + .set j_d_u6_target, @u6_value + .set j_d_u6_has_delay_slot, 1 + .set j_d_u6_cc, 0 + j_d_u6_start: + j.d @j_d_u6_target + j_d_u6_end: + nop_s + + ; j.d s12 + .set j_d_s12_target, @s12_target + .set j_d_s12_has_delay_slot, 1 + .set j_d_s12_cc, 0 + j_d_s12_start: + j.d @j_d_s12_target + j_d_s12_end: + nop_s + + ; j_s [b] + .set j_s_b_target, @r12_value + .set j_s_b_has_delay_slot, 0 + .set j_s_b_cc, 0 + j_s_b_start: + j_s [r12] + j_s_b_end: + + ; j_s.d [b] + .set j_s_d_b_target, @r12_value + .set j_s_d_b_has_delay_slot, 1 + .set j_s_d_b_cc, 0 + j_s_d_b_start: + j_s.d [r12] + j_s_d_b_end: + nop_s + + ; j_s [blink] + .set j_s_blink_target, @blink_value + .set j_s_blink_has_delay_slot, 0 + .set j_s_blink_cc, 0 + j_s_blink_start: + j_s [blink] + j_s_blink_end: + + ; j_s.d [blink] + .set j_s_d_blink_target, @blink_value + .set j_s_d_blink_has_delay_slot, 1 + .set j_c_cc, 0 + j_s_d_blink_start: + j_s.d [blink] + j_s_d_blink_end: + nop_s +#endif /* TEST_J */ + +#ifdef TEST_JCC + ; jcc [c] + .set jcc_c_target, @r4_value + .set jcc_c_has_delay_slot, 0 + .set jcc_c_cc, 1 + jcc_c_start: + jeq [r4] + jcc_c_end: + + ; jcc [blink] + .set jcc_blink_target, @blink_value + .set jcc_blink_has_delay_slot, 0 + .set jcc_blink_cc, 2 + jcc_blink_start: + jnz [blink] + jcc_blink_end: + + ; jcc limm + .set jcc_limm_target, @limm_value + .set jcc_limm_has_delay_slot, 0 + .set jcc_limm_cc, 9 + jcc_limm_start: + jgt @jcc_limm_target + jcc_limm_end: + + ; jcc u6 + .set jcc_u6_target, @u6_value + .set jcc_u6_has_delay_slot, 0 + .set jcc_u6_cc, 0xA + jcc_u6_start: + jge @jcc_u6_target + jcc_u6_end: + + ; jcc.d [c] + .set jcc_d_c_target, @r4_value + .set jcc_d_c_has_delay_slot, 1 + .set jcc_d_c_cc, 0xB + jcc_d_c_start: + jlt.d [r4] + jcc_d_c_end: + nop_s + + ; jcc.d [blink] + .set jcc_d_blink_target, @blink_value + .set jcc_d_blink_has_delay_slot, 1 + .set jcc_d_blink_cc, 0xC + jcc_d_blink_start: + jle.d [blink] + jcc_d_blink_end: + nop_s + + ; jcc.d u6 + .set jcc_d_u6_target, @u6_value + .set jcc_d_u6_has_delay_slot, 1 + .set jcc_d_u6_cc, 0xE + jcc_d_u6_start: + jls.d @jcc_d_u6_target + jcc_d_u6_end: + nop_s + + ; jeq_s [blink] + .set jcc_eq_s_blink_target, @blink_value + .set jcc_eq_s_blink_has_delay_slot, 0 + .set jcc_eq_s_blink_cc, 1 + jcc_eq_s_blink_start: + jeq_s [blink] + jcc_eq_s_blink_end: + + ; jne_s [blink] + .set jcc_ne_s_blink_target, @blink_value + .set jcc_ne_s_blink_has_delay_slot, 0 + .set jcc_ne_s_blink_cc, 2 + jcc_ne_s_blink_start: + jne_s [blink] + jcc_ne_s_blink_end: +#endif /* TEST_JCC */ + +#ifdef TEST_JL + ; jl [c] + .set jl_c_target, @r4_value + .set jl_c_has_delay_slot, 0 + .set jl_c_cc, 0 + jl_c_start: + jl [r4] + jl_c_end: + + ; jl limm + .set jl_limm_target, @limm_value + .set jl_limm_has_delay_slot, 0 + .set jl_limm_cc, 0 + jl_limm_start: + jl @jl_limm_target + jl_limm_end: + + ; jl u6 + .set jl_u6_target, @u6_value + .set jl_u6_has_delay_slot, 0 + .set jl_u6_cc, 0 + jl_u6_start: + jl @jl_u6_target + jl_u6_end: + + ; jl s12 + .set jl_s12_target, @s12_target + .set jl_s12_has_delay_slot, 0 + .set jl_s12_cc, 0 + jl_s12_start: + jl @jl_s12_target + jl_s12_end: + + ; jl.d [c] + .set jl_d_c_target, @r4_value + .set jl_d_c_has_delay_slot, 1 + .set jl_d_c_cc, 0 + jl_d_c_start: + jl.d [r4] + jl_d_c_end: + nop_s + + ; jl.d u6 + .set jl_d_u6_target, @u6_value + .set jl_d_u6_has_delay_slot, 1 + .set jl_d_u6_cc, 0 + jl_d_u6_start: + jl.d @jl_d_u6_target + jl_d_u6_end: + nop_s + + ; jl.d s12 + .set jl_d_s12_target, @s12_target + .set jl_d_s12_has_delay_slot, 1 + .set jl_d_s12_cc, 0 + jl_d_s12_start: + jl.d @jl_d_s12_target + jl_d_s12_end: + nop_s + + ; jl_s [b] + .set jl_s_b_target, @r12_value + .set jl_s_b_has_delay_slot, 0 + .set jl_s_b_cc, 0 + jl_s_b_start: + jl_s [r12] + jl_s_b_end: + + ; jl_s.d [b] + .set jl_s_d_b_target, @r12_value + .set jl_s_d_b_has_delay_slot, 1 + .set jl_s_d_b_cc, 0 + jl_s_d_b_start: + jl_s.d [r12] + jl_s_d_b_end: + nop_s +#endif /* TEST_JL */ + +#ifdef TEST_JLCC + ; jlcc [c] + .set jlcc_c_target, @r4_value + .set jlcc_c_has_delay_slot, 0 + .set jlcc_c_cc, 1 + jlcc_c_start: + jleq [r4] + jlcc_c_end: + + ; jlcc limm + .set jlcc_limm_target, @limm_value + .set jlcc_limm_has_delay_slot, 0 + .set jlcc_limm_cc, 0x9 + jlcc_limm_start: + jlgt @jlcc_limm_target + jlcc_limm_end: + + ; jlcc u6 + .set jlcc_u6_target, @u6_value + .set jlcc_u6_has_delay_slot, 0 + .set jlcc_u6_cc, 0xA + jlcc_u6_start: + jlge @jlcc_u6_target + jlcc_u6_end: + + ; jlcc.d [c] + .set jlcc_d_c_target, @r4_value + .set jlcc_d_c_has_delay_slot, 1 + .set jlcc_d_c_cc, 0xB + jlcc_d_c_start: + jllt.d [r4] + jlcc_d_c_end: + nop_s + + ; jlcc.d u6 + .set jlcc_d_u6_target, @u6_value + .set jlcc_d_u6_has_delay_slot, 1 + .set jlcc_d_u6_cc, 0xE + jlcc_d_u6_start: + jlls.d @jlcc_d_u6_target + jlcc_d_u6_end: + nop_s +#endif /* TEST_JLCC */ + +#ifdef TEST_B +.Lb_target: + ; Artifical nop, so that first b will not branch to itself. + nop_s + ; b s25 + .set b_s25_target, @.Lb_target + .set b_s25_has_delay_slot, 0 + .set b_s25_cc, 0 + b_s25_start: + b @b_s25_target + b_s25_end: + + ; b.d s25 + .set b_d_s25_target, @.Lb_target + .set b_d_s25_has_delay_slot, 1 + .set b_d_s25_cc, 0 + b_d_s25_start: + b.d @b_d_s25_target + b_d_s25_end: + nop_s + + ; b_s s10 + .set b_s_s10_target, @.Lb_target + .set b_s_s10_has_delay_slot, 0 + .set b_s_s10_cc, 0 + b_s_s10_start: + b_s @b_s_s10_target + b_s_s10_end: +#endif /* TEST_B */ + +#ifdef TEST_BBIT + +; Due to specifics of bbit implementation in assembler, only local symbols can +; be used as a branch targets for bbit and brcc. +; bbits and brcc don't have condition code set to anything. +.Lbbit_target: + nop_s + + ; bbit0.nt b,c,s9 + .set bbit0_nt_b_c_s9_target, @.Lbbit_target + .set bbit0_nt_b_c_s9_has_delay_slot, 0 + .set bbit0_nt_b_c_s9_cc, 0 + bbit0_nt_b_c_s9_start: + bbit0.nt r4,r5,@bbit0_nt_b_c_s9_target + bbit0_nt_b_c_s9_end: + + ; bbit0.d.nt b,c,s9 + .set bbit0_d_nt_b_c_s9_target, @.Lbbit_target + .set bbit0_d_nt_b_c_s9_has_delay_slot, 1 + .set bbit0_d_nt_b_c_s9_cc, 0 + bbit0_d_nt_b_c_s9_start: + bbit0.d.nt r4,r5,@.Lbbit_target + bbit0_d_nt_b_c_s9_end: + nop_s + + ; bbit0.t b,c,s9 + .set bbit0_t_b_c_s9_target, @.Lbbit_target + .set bbit0_t_b_c_s9_has_delay_slot, 0 + .set bbit0_t_b_c_s9_cc, 0 + bbit0_t_b_c_s9_start: + bbit0.t r4,r5,@.Lbbit_target + bbit0_t_b_c_s9_end: + + ; bbit0.d.t b,c,s9 + .set bbit0_d_t_b_c_s9_target, @.Lbbit_target + .set bbit0_d_t_b_c_s9_has_delay_slot, 1 + .set bbit0_d_t_b_c_s9_cc, 0 + bbit0_d_t_b_c_s9_start: + bbit0.d.t r4,r5,@.Lbbit_target + bbit0_d_t_b_c_s9_end: + nop_s + + ; bbit0.nt b,u6,s9 + .set bbit0_nt_b_u6_s9_target, @.Lbbit_target + .set bbit0_nt_b_u6_s9_has_delay_slot, 0 + .set bbit0_nt_b_u6_s9_cc, 0 + bbit0_nt_b_u6_s9_start: + bbit0.nt r4,u6_value,@.Lbbit_target + bbit0_nt_b_u6_s9_end: + + ; bbit0.d.nt b,u6,s9 + .set bbit0_d_nt_b_u6_s9_target, @.Lbbit_target + .set bbit0_d_nt_b_u6_s9_has_delay_slot, 1 + .set bbit0_d_nt_b_u6_s9_cc, 0 + bbit0_d_nt_b_u6_s9_start: + bbit0.d.nt r4,u6_value,@.Lbbit_target + bbit0_d_nt_b_u6_s9_end: + nop_s + + ; bbit0.nt b,u6,s9 + .set bbit0_t_b_u6_s9_target, @.Lbbit_target + .set bbit0_t_b_u6_s9_has_delay_slot, 0 + .set bbit0_t_b_u6_s9_cc, 0 + bbit0_t_b_u6_s9_start: + bbit0.t r4,u6_value,@.Lbbit_target + bbit0_t_b_u6_s9_end: + + ; bbit0.d.nt b,u6,s9 + .set bbit0_d_t_b_u6_s9_target, @.Lbbit_target + .set bbit0_d_t_b_u6_s9_has_delay_slot, 1 + .set bbit0_d_t_b_u6_s9_cc, 0 + bbit0_d_t_b_u6_s9_start: + bbit0.d.t r4,u6_value,@.Lbbit_target + bbit0_d_t_b_u6_s9_end: + nop_s + + ; bbit0.nt b,limm,s9 + .set bbit0_nt_b_limm_s9_target, @.Lbbit_target + .set bbit0_nt_b_limm_s9_has_delay_slot, 0 + .set bbit0_nt_b_limm_s9_cc, 0 + bbit0_nt_b_limm_s9_start: + bbit0.nt r4,limm_value,@.Lbbit_target + bbit0_nt_b_limm_s9_end: + + ; bbit0.t b,limm,s9 + .set bbit0_t_b_limm_s9_target, @.Lbbit_target + .set bbit0_t_b_limm_s9_has_delay_slot, 0 + .set bbit0_t_b_limm_s9_cc, 0 + bbit0_t_b_limm_s9_start: + bbit0.t r4,limm_value,@.Lbbit_target + bbit0_t_b_limm_s9_end: + + ; bbit0.nt limm,c,s9 + .set bbit0_nt_limm_c_s9_target, @.Lbbit_target + .set bbit0_nt_limm_c_s9_has_delay_slot, 0 + .set bbit0_nt_limm_c_s9_cc, 0 + bbit0_nt_limm_c_s9_start: + bbit0.nt limm_value,r4,@.Lbbit_target + bbit0_nt_limm_c_s9_end: + + ; bbit0.t limm,c,s9 + .set bbit0_t_limm_c_s9_target, @.Lbbit_target + .set bbit0_t_limm_c_s9_has_delay_slot, 0 + .set bbit0_t_limm_c_s9_cc, 0 + bbit0_t_limm_c_s9_start: + bbit0.t limm_value,r4,@.Lbbit_target + bbit0_t_limm_c_s9_end: + + ; bbit0.nt limm,u6,s9 + .set bbit0_nt_limm_u6_s9_target, @.Lbbit_target + .set bbit0_nt_limm_u6_s9_has_delay_slot, 0 + .set bbit0_nt_limm_u6_s9_cc, 0 + bbit0_nt_limm_u6_s9_start: + bbit0.nt limm_value,u6_value,@.Lbbit_target + bbit0_nt_limm_u6_s9_end: + + ; bbit0.t limm,u6,s9 + .set bbit0_t_limm_u6_s9_target, @.Lbbit_target + .set bbit0_t_limm_u6_s9_has_delay_slot, 0 + .set bbit0_t_limm_u6_s9_cc, 0 + bbit0_t_limm_u6_s9_start: + bbit0.t limm_value,u6_value,@.Lbbit_target + bbit0_t_limm_u6_s9_end: + + ; bbit1.nt b,c,s9 + .set bbit1_nt_b_c_s9_target, @.Lbbit_target + .set bbit1_nt_b_c_s9_has_delay_slot, 0 + .set bbit1_nt_b_c_s9_cc, 0 + bbit1_nt_b_c_s9_start: + bbit1.nt r4,r5,@.Lbbit_target + bbit1_nt_b_c_s9_end: + + ; bbit1.d.nt b,c,s9 + .set bbit1_d_nt_b_c_s9_target, @.Lbbit_target + .set bbit1_d_nt_b_c_s9_has_delay_slot, 1 + .set bbit1_d_nt_b_c_s9_cc, 0 + bbit1_d_nt_b_c_s9_start: + bbit1.d.nt r4,r5,@.Lbbit_target + bbit1_d_nt_b_c_s9_end: + nop_s + + ; bbit1.t b,c,s9 + .set bbit1_t_b_c_s9_target, @.Lbbit_target + .set bbit1_t_b_c_s9_has_delay_slot, 0 + .set bbit1_t_b_c_s9_cc, 0 + bbit1_t_b_c_s9_start: + bbit1.t r4,r5,@.Lbbit_target + bbit1_t_b_c_s9_end: + + ; bbit1.d.t b,c,s9 + .set bbit1_d_t_b_c_s9_target, @.Lbbit_target + .set bbit1_d_t_b_c_s9_has_delay_slot, 1 + .set bbit1_d_t_b_c_s9_cc, 0 + bbit1_d_t_b_c_s9_start: + bbit1.d.t r4,r5,@.Lbbit_target + bbit1_d_t_b_c_s9_end: + nop_s + + ; bbit1.nt b,u6,s9 + .set bbit1_nt_b_u6_s9_target, @.Lbbit_target + .set bbit1_nt_b_u6_s9_has_delay_slot, 0 + .set bbit1_nt_b_u6_s9_cc, 0 + bbit1_nt_b_u6_s9_start: + bbit1.nt r4,u6_value,@.Lbbit_target + bbit1_nt_b_u6_s9_end: + + ; bbit1.d.nt b,u6,s9 + .set bbit1_d_nt_b_u6_s9_target, @.Lbbit_target + .set bbit1_d_nt_b_u6_s9_has_delay_slot, 1 + .set bbit1_d_nt_b_u6_s9_cc, 0 + bbit1_d_nt_b_u6_s9_start: + bbit1.d.nt r4,u6_value,@.Lbbit_target + bbit1_d_nt_b_u6_s9_end: + nop_s + + ; bbit1.nt b,u6,s9 + .set bbit1_t_b_u6_s9_target, @.Lbbit_target + .set bbit1_t_b_u6_s9_has_delay_slot, 0 + .set bbit1_t_b_u6_s9_cc, 0 + bbit1_t_b_u6_s9_start: + bbit1.t r4,u6_value,@.Lbbit_target + bbit1_t_b_u6_s9_end: + + ; bbit1.d.nt b,u6,s9 + .set bbit1_d_t_b_u6_s9_target, @.Lbbit_target + .set bbit1_d_t_b_u6_s9_has_delay_slot, 1 + .set bbit1_d_t_b_u6_s9_cc, 0 + bbit1_d_t_b_u6_s9_start: + bbit1.d.t r4,u6_value,@.Lbbit_target + bbit1_d_t_b_u6_s9_end: + nop_s + + ; bbit1.nt b,limm,s9 + .set bbit1_nt_b_limm_s9_target, @.Lbbit_target + .set bbit1_nt_b_limm_s9_has_delay_slot, 0 + .set bbit1_nt_b_limm_s9_cc, 0 + bbit1_nt_b_limm_s9_start: + bbit1.nt r4,limm_value,@.Lbbit_target + bbit1_nt_b_limm_s9_end: + + ; bbit1.t b,limm,s9 + .set bbit1_t_b_limm_s9_target, @.Lbbit_target + .set bbit1_t_b_limm_s9_has_delay_slot, 0 + .set bbit1_t_b_limm_s9_cc, 0 + bbit1_t_b_limm_s9_start: + bbit1.t r4,limm_value,@.Lbbit_target + bbit1_t_b_limm_s9_end: + + ; bbit1.nt limm,c,s9 + .set bbit1_nt_limm_c_s9_target, @.Lbbit_target + .set bbit1_nt_limm_c_s9_has_delay_slot, 0 + .set bbit1_nt_limm_c_s9_cc, 0 + bbit1_nt_limm_c_s9_start: + bbit1.nt limm_value,r4,@.Lbbit_target + bbit1_nt_limm_c_s9_end: + + ; bbit1.t limm,c,s9 + .set bbit1_t_limm_c_s9_target, @.Lbbit_target + .set bbit1_t_limm_c_s9_has_delay_slot, 0 + .set bbit1_t_limm_c_s9_cc, 0 + bbit1_t_limm_c_s9_start: + bbit1.t limm_value,r4,@.Lbbit_target + bbit1_t_limm_c_s9_end: + + ; bbit1.nt limm,u6,s9 + .set bbit1_nt_limm_u6_s9_target, @.Lbbit_target + .set bbit1_nt_limm_u6_s9_has_delay_slot, 0 + .set bbit1_nt_limm_u6_s9_cc, 0 + bbit1_nt_limm_u6_s9_start: + bbit1.nt limm_value,u6_value,@.Lbbit_target + bbit1_nt_limm_u6_s9_end: + + ; bbit1.t limm,u6,s9 + .set bbit1_t_limm_u6_s9_target, @.Lbbit_target + .set bbit1_t_limm_u6_s9_has_delay_slot, 0 + .set bbit1_t_limm_u6_s9_cc, 0 + bbit1_t_limm_u6_s9_start: + bbit1.t limm_value,u6_value,@.Lbbit_target + bbit1_t_limm_u6_s9_end: +#endif /* TEST_BBIT */ + +#ifdef TEST_BCC +.Lbcc_target: + ; bcc s21 + .set bcc_s21_target, @.Lbcc_target + .set bcc_s21_has_delay_slot, 0 + .set bcc_s21_cc, 1 + bcc_s21_start: + ; beq @bcc_s21_target + beq @.Lbcc_target + bcc_s21_end: + + ; bcc.d s21 + .set bcc_d_s21_target, @.Lbcc_target + .set bcc_d_s21_has_delay_slot, 1 + .set bcc_d_s21_cc, 1 + bcc_d_s21_start: + beq.d @bcc_d_s21_target + bcc_d_s21_end: + nop_s + +.Lbcc_s_target: + ; beq_s s10 + .set beq_s_s10_target, @.Lbcc_s_target + .set beq_s_s10_has_delay_slot, 0 + .set beq_s_s10_cc, 1 + beq_s_s10_start: + # beq_s.d @beq_s_s10_target + beq_s @.Lbcc_s_target + beq_s_s10_end: + + ; bne_s s10 + .set bne_s_s10_target, @.Lbcc_s_target + .set bne_s_s10_has_delay_slot, 0 + .set bne_s_s10_cc, 2 + bne_s_s10_start: + bne_s @bne_s_s10_target + bne_s_s10_end: + + ; bgt_s s7 + .set bgt_s_s7_target, @.Lbcc_s_target + .set bgt_s_s7_has_delay_slot, 0 + .set bgt_s_s7_cc, 0x9 + bgt_s_s7_start: + bgt_s @bgt_s_s7_target + bgt_s_s7_end: + + ; bge_s s7 + .set bge_s_s7_target, @.Lbcc_s_target + .set bge_s_s7_has_delay_slot, 0 + .set bge_s_s7_cc, 0xA + bge_s_s7_start: + bge_s @bge_s_s7_target + bge_s_s7_end: + + ; blt_s s7 + .set blt_s_s7_target, @.Lbcc_s_target + .set blt_s_s7_has_delay_slot, 0 + .set blt_s_s7_cc, 0xB + blt_s_s7_start: + blt_s @blt_s_s7_target + blt_s_s7_end: + + ; ble_s s7 + .set ble_s_s7_target, @.Lbcc_s_target + .set ble_s_s7_has_delay_slot, 0 + .set ble_s_s7_cc, 0xC + ble_s_s7_start: + ble_s @ble_s_s7_target + ble_s_s7_end: + + ; bhi_s s7 + .set bhi_s_s7_target, @.Lbcc_s_target + .set bhi_s_s7_has_delay_slot, 0 + .set bhi_s_s7_cc, 0xD + bhi_s_s7_start: + bhi_s @bhi_s_s7_target + bhi_s_s7_end: + + ; bhs_s s7 + .set bhs_s_s7_target, @.Lbcc_s_target + .set bhs_s_s7_has_delay_slot, 0 + .set bhs_s_s7_cc, 0x6 + bhs_s_s7_start: + bhs_s @bhs_s_s7_target + bhs_s_s7_end: + + ; blo_s s7 + .set blo_s_s7_target, @.Lbcc_s_target + .set blo_s_s7_has_delay_slot, 0 + .set blo_s_s7_cc, 0x5 + blo_s_s7_start: + blo_s @blo_s_s7_target + blo_s_s7_end: + + ; bls_s s7 + .set bls_s_s7_target, @.Lbcc_s_target + .set bls_s_s7_has_delay_slot, 0 + .set bls_s_s7_cc, 0xE + bls_s_s7_start: + bls_s @bls_s_s7_target + bls_s_s7_end: +#endif /* TEST_BCC */ + +#ifdef TEST_BI + ; bi [c] + .set bi_c_target, @bi_c_end + (@r7_value << 2) + .set bi_c_has_delay_slot, 0 + .set bi_c_cc, 0 + bi_c_start: + bi [r7] + bi_c_end: + + ; bih [c] + .set bih_c_target, @bih_c_end + (@r7_value << 1) + .set bih_c_has_delay_slot, 0 + .set bih_c_cc, 0 + bih_c_start: + bih [r7] + bih_c_end: +#endif /* TEST_BI */ + +#ifdef TEST_BL +.Lbl_target: + ; bl s25 + .set bl_s25_target, @.Lbl_target + .set bl_s25_has_delay_slot, 0 + .set bl_s25_cc, 0 + bl_s25_start: + bl @bl_s25_target + bl_s25_end: + + ; bl.d s25 + .set bl_d_s25_target, @.Lbl_target + .set bl_d_s25_has_delay_slot, 1 + .set bl_d_s25_cc, 0 + bl_d_s25_start: + bl.d @bl_d_s25_target + bl_d_s25_end: + nop_s + + ; bl_s s13 + .set bl_s_s13_target, @.Lbl_target + .set bl_s_s13_has_delay_slot, 0 + .set bl_s_s13_cc, 0 + bl_s_s13_start: + bl_s @bl_s_s13_target + bl_s_s13_end: + + ; blcc s21 + .set blcc_s21_target, @.Lbl_target + .set blcc_s21_has_delay_slot, 0 + .set blcc_s21_cc, 1 + blcc_s21_start: + bleq @blcc_s21_target + blcc_s21_end: + + ; blcc.d s21 + .set blcc_d_s21_target, @.Lbl_target + .set blcc_d_s21_has_delay_slot, 1 + .set blcc_d_s21_cc, 2 + blcc_d_s21_start: + blnz.d @blcc_d_s21_target + blcc_d_s21_end: + nop_s +#endif /* TEST_BL */ + +#ifdef TEST_BRCC +.Lbrcc_target: + ; breq.nt b,c,s9 + .set breq_nt_b_c_s9_target, @.Lbrcc_target + .set breq_nt_b_c_s9_has_delay_slot, 0 + .set breq_nt_b_c_s9_cc, 1 + breq_nt_b_c_s9_start: + breq.nt r4,r5,@.Lbrcc_target + breq_nt_b_c_s9_end: + + ; breq.d.nt b,c,s9 + .set breq_d_nt_b_c_s9_target, @.Lbrcc_target + .set breq_d_nt_b_c_s9_has_delay_slot, 1 + .set breq_d_nt_b_c_s9_cc, 1 + breq_d_nt_b_c_s9_start: + breq.d.nt r4,r5,@.Lbrcc_target + breq_d_nt_b_c_s9_end: + nop_s + + ; breq.t b,c,s9 + .set breq_t_b_c_s9_target, @.Lbrcc_target + .set breq_t_b_c_s9_has_delay_slot, 0 + .set breq_t_b_c_s9_cc, 1 + breq_t_b_c_s9_start: + breq.t r4,r5,@.Lbrcc_target + breq_t_b_c_s9_end: + + ; breq.d.t b,c,s9 + .set breq_d_t_b_c_s9_target, @.Lbrcc_target + .set breq_d_t_b_c_s9_has_delay_slot, 1 + .set breq_d_t_b_c_s9_cc, 1 + breq_d_t_b_c_s9_start: + breq.d.t r4,r5,@.Lbrcc_target + breq_d_t_b_c_s9_end: + nop_s + + ; breq.nt b,u6,s9 + .set breq_nt_b_u6_s9_target, @.Lbrcc_target + .set breq_nt_b_u6_s9_has_delay_slot, 0 + .set breq_nt_b_u6_s9_cc, 1 + breq_nt_b_u6_s9_start: + breq.nt r4,u6_value,@.Lbrcc_target + breq_nt_b_u6_s9_end: + + ; breq.d.nt b,u6,s9 + .set breq_d_nt_b_u6_s9_target, @.Lbrcc_target + .set breq_d_nt_b_u6_s9_has_delay_slot, 1 + .set breq_d_nt_b_u6_s9_cc, 1 + breq_d_nt_b_u6_s9_start: + breq.d.nt r4,u6_value,@.Lbrcc_target + breq_d_nt_b_u6_s9_end: + nop_s + + ; breq.nt b,u6,s9 + .set breq_t_b_u6_s9_target, @.Lbrcc_target + .set breq_t_b_u6_s9_has_delay_slot, 0 + .set breq_t_b_u6_s9_cc, 1 + breq_t_b_u6_s9_start: + breq.t r4,u6_value,@.Lbrcc_target + breq_t_b_u6_s9_end: + + ; breq.d.nt b,u6,s9 + .set breq_d_t_b_u6_s9_target, @.Lbrcc_target + .set breq_d_t_b_u6_s9_has_delay_slot, 1 + .set breq_d_t_b_u6_s9_cc, 1 + breq_d_t_b_u6_s9_start: + breq.d.t r4,u6_value,@.Lbrcc_target + breq_d_t_b_u6_s9_end: + nop_s + + ; breq.nt b,limm,s9 + .set breq_nt_b_limm_s9_target, @.Lbrcc_target + .set breq_nt_b_limm_s9_has_delay_slot, 0 + .set breq_nt_b_limm_s9_cc, 1 + breq_nt_b_limm_s9_start: + breq.nt r4,limm_value,@.Lbrcc_target + breq_nt_b_limm_s9_end: + + ; breq.t b,limm,s9 + .set breq_t_b_limm_s9_target, @.Lbrcc_target + .set breq_t_b_limm_s9_has_delay_slot, 0 + .set breq_t_b_limm_s9_cc, 1 + breq_t_b_limm_s9_start: + breq.t r4,limm_value,@.Lbrcc_target + breq_t_b_limm_s9_end: + + ; breq.nt limm,c,s9 + .set breq_nt_limm_c_s9_target, @.Lbrcc_target + .set breq_nt_limm_c_s9_has_delay_slot, 0 + .set breq_nt_limm_c_s9_cc, 1 + breq_nt_limm_c_s9_start: + breq.nt limm_value,r4,@.Lbrcc_target + breq_nt_limm_c_s9_end: + + ; breq.t limm,c,s9 + .set breq_t_limm_c_s9_target, @.Lbrcc_target + .set breq_t_limm_c_s9_has_delay_slot, 0 + .set breq_t_limm_c_s9_cc, 1 + breq_t_limm_c_s9_start: + breq.t limm_value,r4,@.Lbrcc_target + breq_t_limm_c_s9_end: + + ; breq.nt limm,u6,s9 + .set breq_nt_limm_u6_s9_target, @.Lbrcc_target + .set breq_nt_limm_u6_s9_has_delay_slot, 0 + .set breq_nt_limm_u6_s9_cc, 1 + breq_nt_limm_u6_s9_start: + breq.nt limm_value,u6_value,@.Lbrcc_target + breq_nt_limm_u6_s9_end: + + ; breq.t limm,u6,s9 + .set breq_t_limm_u6_s9_target, @.Lbrcc_target + .set breq_t_limm_u6_s9_has_delay_slot, 0 + .set breq_t_limm_u6_s9_cc, 1 + breq_t_limm_u6_s9_start: + breq.t limm_value,u6_value,@.Lbrcc_target + breq_t_limm_u6_s9_end: + + ; brne_s b,0,s8 + .set brne_s_b_0_s8_target, @.Lbrcc_target + .set brne_s_b_0_s8_has_delay_slot, 0 + .set brne_s_b_0_s8_cc, 1 + brne_s_b_0_s8_start: + brne r12,0,@.Lbrcc_target + brne_s_b_0_s8_end: + + ; breq_s b,0,s8 + .set breq_s_b_0_s8_target, @.Lbrcc_target + .set breq_s_b_0_s8_has_delay_slot, 0 + .set breq_s_b_0_s8_cc, 1 + breq_s_b_0_s8_start: + breq r12,0,@.Lbrcc_target + breq_s_b_0_s8_end: +#endif /* TEST_BRCC */ + +#ifdef TEST_JLI + ; jli_s u10 + .set jli_s_u10_target, @jli_target + .set jli_s_u10_has_delay_slot, 0 + .set jli_s_u10_cc, 0 + jli_s_u10_start: + jli_s jli_offset + jli_s_u10_end: +#endif + +#ifdef TEST_LEAVE_S + ; leave_s + .set leave_s_target, @blink_value + .set leave_s_has_delay_slot, 0 + .set leave_s_cc, 0 + leave_s_start: + ; leave_s [r13-gp,fp,blink,pcl] + leave_s (14 + 16 + 32 + 64) + leave_s_end: +#endif + +#ifdef TEST_LPCC + ; lpcc + .set lpcc_u7_target, @.Llpcc_end + .set lpcc_u7_has_delay_slot, 0 + .set lpcc_u7_cc, 1 + lpcc_u7_start: + lpeq @lpcc_u7_target + lpcc_u7_end: + nop + nop +.Llpcc_end: +#endif + +.Lend: + diff --git a/gdb/testsuite/gdb.arch/arc-decode-insn.exp b/gdb/testsuite/gdb.arch/arc-decode-insn.exp new file mode 100644 index 0000000..ffc283d --- /dev/null +++ b/gdb/testsuite/gdb.arch/arc-decode-insn.exp @@ -0,0 +1,132 @@ +# This testcase is part of GDB, the GNU debugger. + +# Copyright 2017 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/>. + + +# These tests provides certain degree of testing for arc_insn functions, +# however it is not a comprehensive testsuite that would go through all +# possible ARC instructions - instead this particular test is focused on branch +# instructions and whether branch targets are evaluated properly. Most of the +# non-branch aspects of instruction decoder are used during prologue analysis, +# so are indirictly tested there. + +# To maintain separation of test data and test logic, all of the information +# about instructions, like if it has delay slot, condition code, branch target +# address, is all specified in the test assembly file as a symbols, while this +# test case reads those symbols to learn which values are right, then compares +# values coming from decoder with those found in symbols. More information +# about requirements to actual test cases can be found in corresponding +# assembly file of this test case (arc-decode-insn.S). + +if {![istarget "arc*-*-*"]} then { + verbose "Skipping ARC decoder test." + return +} + +standard_testfile .S + +if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { + return -1 +} + +if ![runto_main] { + fail "Can't run to main" + return 0 +} + +# Helper function that reads properties of instruction from the ELF file via +# its symbols and then confirms that decoder output aligns to the expected +# values. +proc test_branch_insn { test_name } { + + # Make messages for failed cases more clear, by using hex in them. + set pc [get_hexadecimal_valueof &${test_name}_start -1] + + # Calculate instruction length, based on ${test_name}_end symbol. + set end_pc [get_hexadecimal_valueof &${test_name}_end -1] + set length [expr $end_pc - $pc] + + set target_address [get_hexadecimal_valueof &${test_name}_target -1] + + # Figure out if there is a delay slot, using symbol + # ${test_name}_has_delay_slot. Note that it should be read via &, + # otherwise it would try to print value at the address specified in + # ${test_name}_has_delay_slot, while a symbol value itself is required. + if { 0 == [get_integer_valueof &${test_name}_has_delay_slot 0] } { + set has_delay_slot 0 + } else { + set has_delay_slot 1 + } + + set cc [get_hexadecimal_valueof &${test_name}_cc 0] + + # Can't use {} to create a list of items, because variables will not be + # evaluated inside the {}. + gdb_test_sequence "mt print arc arc-instruction $pc" "" [list \ + "length_with_limm = $length" \ + "cc = $cc" \ + "is_control_flow = 1" \ + "has_delay_slot = $has_delay_slot" \ + "branch_target = $target_address"] +} + +set branch_test_list { } + +# Add items in the same groups as they can be enabled/disabled in assembly +# file. +lappend branch_test_list \ + j_c j_blink j_limm j_u6 j_s12 j_d_c j_d_blink j_d_u6 +lappend branch_test_list \ + jcc_c jcc_blink jcc_limm jcc_u6 jcc_d_c jcc_d_blink jcc_d_u6 \ + jcc_eq_s_blink jcc_ne_s_blink +lappend branch_test_list \ + jl_c jl_limm jl_u6 jl_s12 jl_d_c jl_d_u6 jl_d_s12 jl_s_b jl_s_d_b +lappend branch_test_list \ + jlcc_c jlcc_limm jlcc_u6 jlcc_d_c jlcc_d_u6 +lappend branch_test_list \ + b_s25 b_d_s25 b_s_s10 +lappend branch_test_list \ + bbit0_nt_b_c_s9 bbit0_d_nt_b_c_s9 bbit0_t_b_c_s9 bbit0_d_t_b_c_s9 \ + bbit0_nt_b_u6_s9 bbit0_d_nt_b_u6_s9 bbit0_t_b_u6_s9 bbit0_d_t_b_u6_s9 \ + bbit0_nt_b_limm_s9 bbit0_t_b_limm_s9 bbit0_nt_limm_c_s9 bbit0_t_limm_c_s9 \ + bbit0_nt_limm_u6_s9 bbit0_t_limm_u6_s9 \ + bbit1_nt_b_c_s9 bbit1_d_nt_b_c_s9 bbit1_t_b_c_s9 bbit1_d_t_b_c_s9 \ + bbit1_nt_b_u6_s9 bbit1_d_nt_b_u6_s9 bbit1_t_b_u6_s9 bbit1_d_t_b_u6_s9 \ + bbit1_nt_b_limm_s9 bbit1_t_b_limm_s9 bbit1_nt_limm_c_s9 bbit1_t_limm_c_s9 \ + bbit1_nt_limm_u6_s9 bbit1_t_limm_u6_s9 +lappend branch_test_list \ + bcc_s21 bcc_d_s21 \ + beq_s_s10 bne_s_s10 bgt_s_s7 bge_s_s7 blt_s_s7 ble_s_s7 bhi_s_s7 bhs_s_s7 \ + blo_s_s7 bls_s_s7 +lappend branch_test_list \ + bi_c bih_c +lappend branch_test_list \ + bl_s25 bl_d_s25 bl_s_s13 \ + blcc_s21 blcc_d_s21 +lappend branch_test_list \ + breq_nt_b_c_s9 breq_d_nt_b_c_s9 breq_t_b_c_s9 breq_d_t_b_c_s9 \ + breq_nt_b_u6_s9 breq_d_nt_b_u6_s9 breq_t_b_u6_s9 breq_d_t_b_u6_s9 \ + breq_nt_b_limm_s9 breq_t_b_limm_s9 breq_nt_limm_c_s9 breq_t_limm_c_s9 \ + breq_nt_limm_u6_s9 breq_t_limm_u6_s9 +# lappend branch_test_list jli_s_u10 +lappend branch_test_list leave_s +lappend branch_test_list lpcc_u7 + +runto start_branch_tests +foreach test $branch_test_list { + test_branch_insn $test +} + |