903 lines
16 KiB
ArmAsm
903 lines
16 KiB
ArmAsm
; This testcase is part of GDB, the GNU debugger.
|
|
|
|
; Copyright 2017-2022 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 .data
|
|
some_variable:
|
|
.long 0xdeadbeef
|
|
|
|
.section .text
|
|
.global main
|
|
.type main, @function
|
|
|
|
; Standard prologue.
|
|
|
|
.align 4
|
|
standard_prologue:
|
|
push blink
|
|
sub sp,sp,12
|
|
st r13, [sp, 0]
|
|
st r14, [sp, 4]
|
|
st r18, [sp, 8]
|
|
add r0, r1, r2
|
|
ld r18, [sp, 8]
|
|
ld r14, [sp, 4]
|
|
ld r13, [sp, 0]
|
|
add sp,sp,12
|
|
pop blink
|
|
j [blink]
|
|
|
|
; Standard prologue using short instructions.
|
|
|
|
.align 4
|
|
mini_prologue:
|
|
push_s blink
|
|
sub_s sp,sp,12
|
|
; ST_S can store only some of the core registers.
|
|
st_s r13, [sp, 0]
|
|
st_s r15, [sp, 4]
|
|
st_s r14, [sp, 8]
|
|
add r0, r1, r2
|
|
add sp,sp,16
|
|
j [blink]
|
|
|
|
; Standard prologue without `sub sp,sp,INTEGER`.
|
|
|
|
.align 4
|
|
no_subsp_prologue:
|
|
push blink
|
|
push r13
|
|
push r20
|
|
push r25
|
|
add r0, r1, r2
|
|
pop r25
|
|
pop r20
|
|
pop r13
|
|
pop blink
|
|
j [blink]
|
|
|
|
; Standard prologue of leaf function.
|
|
|
|
.align 4
|
|
leaf_prologue:
|
|
sub sp,sp,8
|
|
st r13, [sp, 0]
|
|
st r15, [sp, 4]
|
|
add r0, r1, r2
|
|
ld r13, [sp, 0]
|
|
ld r15, [sp, 4]
|
|
j.d [blink]
|
|
add sp,sp,8
|
|
|
|
; Prologue with `push fp`.
|
|
|
|
.align 4
|
|
pushfp_prologue:
|
|
push r13
|
|
push r14
|
|
push fp
|
|
; mov fp,sp is part of prologue, but this test will not verify that.
|
|
; It will be checked later in the "arg_regs_fp" test.
|
|
mov fp, sp
|
|
add r0, r1, r2
|
|
pop fp
|
|
pop r14
|
|
pop r13
|
|
j [blink]
|
|
|
|
; Prologue with frame pointer and store relative to FP.
|
|
|
|
.align 4
|
|
fp_prologue_with_store:
|
|
push r13
|
|
push r14
|
|
push fp
|
|
mov fp, sp
|
|
sub_s sp,sp,4
|
|
st r15,[fp,-4]
|
|
add r0, r1, r2
|
|
pop r15
|
|
pop fp
|
|
pop r14
|
|
pop r13
|
|
j [blink]
|
|
|
|
; Verify that store of the non-callee saved registers is not part of prologue.
|
|
; Repeat this test for multiple registers, to check boundaries. Also check
|
|
; with both ST and PUSH (aka ST.AW). We have to use multiple functions for
|
|
; this, because GDB would stop analisys at the first instruction that is not
|
|
; part of prologue.
|
|
|
|
.align 4
|
|
noncallee_saved_regs_r12_st:
|
|
sub sp,sp,8
|
|
st r13, [sp, 4]
|
|
st r12, [sp, 0]
|
|
add r0, r1, r2
|
|
j.d [blink]
|
|
add sp,sp,8
|
|
|
|
.align 4
|
|
noncallee_saved_regs_r12_push:
|
|
push r13
|
|
push r12
|
|
add r0, r1, r2
|
|
j.d [blink]
|
|
add sp,sp,8
|
|
|
|
.align 4
|
|
noncallee_saved_regs_r2_push:
|
|
push r13
|
|
push r2
|
|
add r0, r1, r2
|
|
j.d [blink]
|
|
add sp,sp,8
|
|
|
|
.align 4
|
|
noncallee_saved_regs_gp_push:
|
|
push r25
|
|
push gp
|
|
add r0, r1, r2
|
|
j.d [blink]
|
|
add sp,sp,8
|
|
|
|
; LP_COUNT is treated like a normal register.
|
|
|
|
.align 4
|
|
noncallee_saved_regs_lp_count:
|
|
push r25
|
|
push lp_count
|
|
add r0, r1, r2
|
|
j.d [blink]
|
|
add sp,sp,8
|
|
|
|
; BLINK is saved, but after an instruction that is not part of prologue.
|
|
; Currently arc_analyze_prologue stops analisys at the first intstruction
|
|
; that is not a part of prologue. This might be not the best way, but it is
|
|
; what it is right now, so this test confirms this.
|
|
|
|
.align 4
|
|
noncallee_saved_regs_blink_out_of_prologue:
|
|
push r25
|
|
push gp
|
|
push blink
|
|
add r0, r1, r2
|
|
j.d [blink]
|
|
add sp,sp,12
|
|
|
|
; Saving arguments register via FP.
|
|
|
|
.align 4
|
|
arg_regs_fp:
|
|
push fp
|
|
mov fp, sp
|
|
sub sp, sp, 16
|
|
st r0, [fp, -4]
|
|
st r1, [fp, -8]
|
|
st r7, [fp, -12]
|
|
st r8, [fp, -16]
|
|
add r0, r1, r2
|
|
add sp,sp,16
|
|
pop fp
|
|
j [blink]
|
|
|
|
; Like the previous, but with mov_s.
|
|
|
|
.align 4
|
|
arg_regs_fp_mov_s:
|
|
push fp
|
|
mov_s fp, sp
|
|
sub sp, sp, 8
|
|
st r0, [fp, -4]
|
|
; Not part of the prologue.
|
|
st r8, [fp, -8]
|
|
add r0, r1, r2
|
|
add sp,sp,8
|
|
pop fp
|
|
j [blink]
|
|
|
|
; Saving arguments register without FP.
|
|
|
|
.align 4
|
|
arg_regs_sp:
|
|
sub sp, sp, 24
|
|
st r0, [sp, 0]
|
|
st r1, [sp, 4]
|
|
st r7, [sp, 8]
|
|
; Normally that would be done before saving args, but it is used as a
|
|
; marker that saving arguments relatively to SP is considered part of
|
|
; prologue.
|
|
st r13, [sp, 16]
|
|
; Not part of the prologue.
|
|
st r8, [sp, 12]
|
|
st r14, [sp, 20]
|
|
add r0, r1, r2
|
|
j.d [blink]
|
|
add sp,sp,24
|
|
|
|
; ENTER_S that does nothing.
|
|
|
|
.align 4
|
|
enter_s_nop:
|
|
; Effectively a nop.
|
|
enter_s 0
|
|
add r0,r1,r2
|
|
j [blink]
|
|
|
|
; ENTER_S that stores BLINK.
|
|
|
|
.align 4
|
|
enter_s_blink:
|
|
enter_s 32
|
|
add r0,r1,r2
|
|
j.d [blink]
|
|
add sp,sp,4
|
|
|
|
; ENTER_S that stores FP.
|
|
|
|
.align 4
|
|
enter_s_fp:
|
|
enter_s 16
|
|
add r0,r1,r2
|
|
j.d [blink]
|
|
add sp,sp,4
|
|
|
|
; ENTER_S that stores R13, FP and BLINK.
|
|
|
|
.align 4
|
|
enter_s_r13:
|
|
enter_s (32 + 16 + 1)
|
|
add r0,r1,r2
|
|
j.d [blink]
|
|
add sp,sp,12
|
|
|
|
; ENTER_S that stores R13-R15
|
|
|
|
.align 4
|
|
enter_s_r15:
|
|
enter_s 3
|
|
add r0,r1,r2
|
|
j.d [blink]
|
|
add sp,sp,12
|
|
|
|
; ENTER_S that stores everything it could.
|
|
|
|
.align 4
|
|
enter_s_all:
|
|
enter_s (32 + 16 + 14)
|
|
add r0,r1,r2
|
|
j.d [blink]
|
|
add sp,sp,64
|
|
|
|
; Deeper nesting.
|
|
|
|
.align 4
|
|
nested_prologue_inner:
|
|
sub sp,sp,8
|
|
st r18, [sp, 4]
|
|
st r13, [sp, 0]
|
|
add r0, r1, r2
|
|
ld r18, [sp, 4]
|
|
ld r13, [sp, 0]
|
|
j.d [blink]
|
|
add sp,sp,8
|
|
|
|
.align 4
|
|
nested_prologue_outer:
|
|
push blink
|
|
sub sp,sp,8
|
|
st r14, [sp, 0]
|
|
st r15, [sp, 4]
|
|
bl @nested_prologue_inner
|
|
add r0, r1, r2
|
|
ld r14, [sp, 0]
|
|
ld r15, [sp, 4]
|
|
add sp,sp,8
|
|
pop blink
|
|
j [blink]
|
|
|
|
; Prologue with maximum length.
|
|
; Expressions like (0xFFFFFFFF + 25) force assembler to use long immediate
|
|
; even for values that don't need it, thus letting us test maksimum prologue
|
|
; length without having huge frames.
|
|
.align 4
|
|
max_length_prologue:
|
|
; Variadic args
|
|
sub sp,sp,(0xFFFFFFFF + 25) ; 24 bytes
|
|
push blink
|
|
; Allocate space for 13 callee-saved and 8 arg regs.
|
|
sub sp,sp,(0xFFFFFFFF + 1 + 21 * 4)
|
|
st r13, [sp, 0]
|
|
st r14, [sp, 4]
|
|
st r15, [sp, 8]
|
|
st r16, [sp, 12]
|
|
st r17, [sp, 16]
|
|
st r18, [sp, 20]
|
|
st r19, [sp, 24]
|
|
st r20, [sp, 28]
|
|
st r21, [sp, 32]
|
|
st r22, [sp, 36]
|
|
st r23, [sp, 40]
|
|
st r24, [sp, 44]
|
|
st r25, [sp, 48]
|
|
st r0, [sp, 52]
|
|
st r1, [sp, 56]
|
|
st r2, [sp, 60]
|
|
st r3, [sp, 64]
|
|
st r4, [sp, 68]
|
|
st r5, [sp, 72]
|
|
st r6, [sp, 76]
|
|
st r7, [sp, 80]
|
|
push fp
|
|
mov fp,sp
|
|
sub sp,sp,(0xFFFFFFFF + 1 + 16) ; Space for local variables.
|
|
; End of prologue.
|
|
add sp,sp,24 + 21 * 4 + 16
|
|
j [blink]
|
|
|
|
; Few tests that test that prologue analysis stops at branch. There are four
|
|
; types of "branches": conditional and non-conditional, relative branches and
|
|
; absolute jumps.
|
|
|
|
.align 4
|
|
branch_in_prologue:
|
|
push r13
|
|
b @.L1
|
|
; This store on stack is not a prologue.
|
|
push r14
|
|
.L1:
|
|
add r0,r1,r2
|
|
j.d [blink]
|
|
add sp,sp,4
|
|
|
|
.align 4
|
|
cond_branch_in_prologue:
|
|
sub_s sp,sp,8
|
|
st_s r13,[sp,4]
|
|
; Doesn't matter if branch is taken or not.
|
|
breq r0,r1,@.L2
|
|
; This store on stack is not a prologue.
|
|
st_s r14,[sp,0]
|
|
.L2:
|
|
add r0,r1,r2
|
|
pop fp
|
|
j.d [blink]
|
|
add sp,sp,8
|
|
|
|
.align 4
|
|
jump_in_prologue:
|
|
push r13
|
|
j @.L3
|
|
; This store on stack is not a prologue.
|
|
push r14
|
|
.L3:
|
|
add r0,r1,r2
|
|
j.d [blink]
|
|
add sp,sp,4
|
|
|
|
.align 4
|
|
cond_jump_in_prologue:
|
|
sub_s sp,sp,8
|
|
st_s r13,[sp,4]
|
|
; It doesn't matter if jump is taken or not - prologue analysis has to
|
|
; stop before `jeq` in any case.
|
|
jeq @.L4
|
|
; This store on stack is not a prologue.
|
|
st_s r14,[sp,0]
|
|
.L4:
|
|
add r0,r1,r2
|
|
j.d [blink]
|
|
add sp,sp,8
|
|
|
|
.align 4
|
|
predicated_insn:
|
|
sub_s sp,sp,12
|
|
st_s r13,[sp,8]
|
|
st_s r15,[sp,0]
|
|
; Use SUB SP,SP,0 because it is otherwise a valid instruction for
|
|
; prologue, so it will halt analysis purely because of its predicate.
|
|
sub.eq sp,sp,0 ; This is not a prologue anymore.
|
|
st_s r14,[sp,4]
|
|
add sp,sp,12
|
|
j [blink]
|
|
|
|
; Loops should halt prologue analysis.
|
|
|
|
.align 4
|
|
loop_in_prologue:
|
|
push r25
|
|
push lp_count
|
|
mov lp_count, 4
|
|
lp @.Lloop_end1
|
|
push r26 ; Not part of prologue.
|
|
add r0, r1, r2
|
|
.Lloop_end1:
|
|
add r1, r1, r2
|
|
pop r26
|
|
add sp,sp,8
|
|
pop r25
|
|
j [blink]
|
|
|
|
; Store of a constant value (not a register).
|
|
|
|
.align 4
|
|
store_constant:
|
|
sub_s sp,sp,12
|
|
st_s r13,[sp,8]
|
|
st 0xdeadbeef,[sp,0]
|
|
st_s r14,[sp,4]
|
|
add sp,sp,12
|
|
j [blink]
|
|
|
|
; Test that store to immediate address halts prologue analysis.
|
|
.align 4
|
|
st_c_limm:
|
|
push r15
|
|
st r14,[@some_variable]
|
|
push r13
|
|
add sp,sp,8
|
|
j [blink]
|
|
|
|
; Store with AB writeback mode.
|
|
|
|
.align 4
|
|
st_ab_writeback:
|
|
sub sp,sp,8
|
|
st r13,[sp,4]
|
|
st.ab r14,[sp,-4]
|
|
st r15,[sp,0]
|
|
add sp,sp,12
|
|
j [blink]
|
|
|
|
; Store of a word with AS writeback mode.
|
|
|
|
.align 4
|
|
st_as_writeback:
|
|
sub sp,sp,12
|
|
st r13,[sp,8]
|
|
st.as r14,[sp,1] ; ST.AS, hence address is (offset << 2).
|
|
st r15,[sp,0]
|
|
add sp,sp,12
|
|
j [blink]
|
|
|
|
; Store of a halfword with AS writeback mode.
|
|
|
|
.align 4
|
|
sth_as_writeback:
|
|
sub sp,sp,12
|
|
st r13,[sp,8]
|
|
sth.as r14,[sp,2] ; STH.AS, hence address is (offset << 1).
|
|
st r15,[sp,0]
|
|
add sp,sp,12
|
|
j [blink]
|
|
|
|
; Store of a double word with AS writeback mode. Shift is still 2, like ST!
|
|
|
|
.align 4
|
|
std_as_writeback:
|
|
sub sp,sp,16
|
|
st r13,[sp,12]
|
|
#ifdef __ARC_LL64__
|
|
std.as r14,[sp,1] ; STD.AS, hence address is (offset << 2).
|
|
#else
|
|
st.as r14,[sp,1] ; STD.AS, hence address is (offset << 2).
|
|
st.as r15,[sp,2] ; STD.AS, hence address is (offset << 2).
|
|
#endif
|
|
st r16,[sp,0]
|
|
add sp,sp,12
|
|
j [blink]
|
|
|
|
; Store of the halfword. R14 will not be reported as "saved".
|
|
|
|
.align 4
|
|
st_halfword:
|
|
sub sp,sp,12
|
|
st r13,[sp,8]
|
|
sth r14,[sp,4]
|
|
st r15,[sp,0]
|
|
add sp,sp,12
|
|
j [blink]
|
|
|
|
; Store of the halfword. R14 will not be reported as "saved".
|
|
|
|
.align 4
|
|
sts_halfword:
|
|
sub sp,sp,12
|
|
st r13,[sp,8]
|
|
mov r13,sp
|
|
sth_s r14,[r13,4]
|
|
st r15,[sp,0]
|
|
add sp,sp,12
|
|
j [blink]
|
|
|
|
; Store of the byte. R14 will not be reported as "saved".
|
|
|
|
.align 4
|
|
st_byte:
|
|
sub sp,sp,12
|
|
st r13,[sp,8]
|
|
stb r14,[sp,4]
|
|
st r15,[sp,0]
|
|
add sp,sp,12
|
|
j [blink]
|
|
|
|
; Store of the byte. R14 will not be reported as "saved".
|
|
|
|
.align 4
|
|
sts_byte:
|
|
sub sp,sp,12
|
|
st r13,[sp,8]
|
|
mov r13,sp
|
|
stb_s r14,[r13,4]
|
|
st r15,[sp,0]
|
|
add sp,sp,12
|
|
j [blink]
|
|
|
|
; Store of the byte. R14 will not be reported as "saved".
|
|
|
|
.align 4
|
|
sts_byte_sp:
|
|
sub sp,sp,12
|
|
st r13,[sp,8]
|
|
stb_s r14,[sp,4]
|
|
st r15,[sp,0]
|
|
add sp,sp,12
|
|
j [blink]
|
|
|
|
; Double word store, optionally available for ARC HS.
|
|
|
|
.align 4
|
|
st_double:
|
|
sub sp,sp,8
|
|
#ifdef __ARC_LL64__
|
|
std r14,[sp,0]
|
|
std.aw r18,[sp,-8]
|
|
std.aw 0xdeadbeef,[sp,-8]
|
|
#else
|
|
st r14,[sp,0]
|
|
st r15,[sp,4]
|
|
st.aw r19,[sp,-4]
|
|
st.aw r18,[sp,-4]
|
|
sub sp,sp,8
|
|
#endif
|
|
add sp,sp,24
|
|
j [blink]
|
|
|
|
; Store relative to some register with a known value.
|
|
|
|
.align 4
|
|
r_relative_store:
|
|
sub_s sp,sp,12
|
|
st_s r13,[sp,8]
|
|
mov r13,sp
|
|
; Check for both mov and mov_s in one testcase.
|
|
mov_s r12,r13
|
|
st r15,[r12,0]
|
|
st_s r14,[sp,4]
|
|
add sp,sp,12
|
|
j [blink]
|
|
|
|
; Store relative to some register with a known value using sub.
|
|
; Like a previous test, but register is assigned via sub, instead of mov.
|
|
|
|
.align 4
|
|
r_relative_sub_store:
|
|
; Following is a complicated way to construct frame like this:
|
|
; sub_s sp,sp,12
|
|
; st_s r13,[sp,8]
|
|
; st_s r14,[sp,4]
|
|
; st_s r15,[sp,0]
|
|
sub_s sp,sp,12
|
|
st_s r13,[sp,8]
|
|
sub r13,sp,4
|
|
st r14,[r13,8]
|
|
st_s r15,[sp,0]
|
|
add sp,sp,12
|
|
j [blink]
|
|
|
|
; Like r_relative_store, but using st_s c,[b,u7] which has different opcode.
|
|
|
|
.align 4
|
|
r_relative_store_st_s:
|
|
sub_s sp,sp,12
|
|
st_s r13,[sp,8]
|
|
mov r13,sp
|
|
st_s r15,[r13,4]
|
|
st_s r14,[sp,0]
|
|
add sp,sp,12
|
|
j [blink]
|
|
|
|
; Store relative to some register with a unknown value.
|
|
|
|
.align 4
|
|
r_relative_store_unknown:
|
|
sub_s sp,sp,12
|
|
st_s r13,[sp,8]
|
|
st r15,[gp,0] ; GP value is not relative to SP.
|
|
st_s r14,[sp,4]
|
|
add sp,sp,12
|
|
j [blink]
|
|
|
|
; Store relative to some register with a unknown value, using st_s r0,[gp,s11].
|
|
|
|
.align 4
|
|
st_s_r0gp:
|
|
sub_s sp,sp,12
|
|
st_s r13,[sp,8]
|
|
st_s r0,[gp,0] ; GP value is not relative to SP.
|
|
st_s r14,[sp,4]
|
|
add sp,sp,12
|
|
j [blink]
|
|
|
|
; Check prologue that uses `push_s RR` instructions. `push_s b` and `push_s
|
|
; blink` use slightly different subopcodes.
|
|
|
|
.align 4
|
|
push_s_prologue:
|
|
push_s r12
|
|
push_s r0
|
|
push_s r3
|
|
push_s r13
|
|
push_s r1
|
|
push_s r14
|
|
push_s r15
|
|
push_s r2
|
|
push_s blink ; Also tested in mini_prologue ().
|
|
add sp,sp,(4 * 9)
|
|
j [blink]
|
|
|
|
; Check for SUB_S c,b,u3 presence - it doesn't affect prologue.
|
|
|
|
.align 4
|
|
sub_s_cbu3:
|
|
push_s r13
|
|
sub_s r0,r1,3
|
|
push_s r14
|
|
add sp,sp,8
|
|
j [blink]
|
|
|
|
; Check for SUB_S b,b,c presence - it doesn't affect prologue.
|
|
|
|
.align 4
|
|
sub_s_bbc:
|
|
push_s r13
|
|
sub_s r0,r0,r1
|
|
push_s r0
|
|
push_s r1
|
|
push_s r14
|
|
add sp,sp,16
|
|
j [blink]
|
|
|
|
; Check for SUB_S b,b,u5.
|
|
|
|
.align 4
|
|
sub_s_bbu5:
|
|
push_s r13
|
|
sub_s r2,r2,14
|
|
push_s r2
|
|
push_s r14
|
|
add sp,sp,12
|
|
j [blink]
|
|
|
|
; Check for SUB 0,b,c, which is effectively a noop (but it can set status
|
|
; flags). It shouldn't stop prologue analysis.
|
|
|
|
.align 4
|
|
sub_0bc:
|
|
push_s r13
|
|
sub 0,r1,r2
|
|
sub.f 0,r3,r4
|
|
push_s r14
|
|
add sp,sp,8
|
|
j [blink]
|
|
|
|
; Check for SUB a,limm,c.
|
|
|
|
.align 4
|
|
sub_alimmb:
|
|
push_s r13
|
|
sub r13,0xdeadbeef,r14
|
|
push_s r14
|
|
add sp,sp,8
|
|
j [blink]
|
|
|
|
; Check for sub_s.ne b,b,b. Has a condition code, hence should halt prologue.
|
|
|
|
.align 4
|
|
sub_s_ne_bbb:
|
|
push_s r13
|
|
sub_s.ne r13,r13,r13
|
|
push_s r14
|
|
add sp,sp,8
|
|
j [blink]
|
|
|
|
; Check MOV that uses LIMM values.
|
|
|
|
.align 4
|
|
mov_limm:
|
|
push_s r13
|
|
mov r13,0xdeadbeef
|
|
push_s r14
|
|
add sp,sp,4
|
|
pop_s r13
|
|
j [blink]
|
|
|
|
; Check MOV 0,c.
|
|
|
|
.align 4
|
|
mov0c_limm:
|
|
push_s r13
|
|
mov 0,r13
|
|
push_s r14
|
|
add sp,sp,4
|
|
pop_s r13
|
|
j [blink]
|
|
|
|
; Check that MOV_S h,s3 doesn't prevent prologue analysis.
|
|
|
|
.align 4
|
|
mov_s_hs3:
|
|
push_s r13
|
|
mov_s r5,1
|
|
push_s r14
|
|
add sp,sp,8
|
|
j [blink]
|
|
|
|
; Check that MOV_S b,u8 doesn't prevent prologue analysis.
|
|
|
|
.align 4
|
|
mov_s_bu8:
|
|
push_s r13
|
|
mov_s r12,250
|
|
push_s r14
|
|
add sp,sp,8
|
|
j [blink]
|
|
|
|
; Check that `mov_s.ne b,h` halts prologue analysis.
|
|
|
|
.align 4
|
|
mov_s_ne_bh:
|
|
push_s r13
|
|
mov_s.ne r13,r5
|
|
push_s r14
|
|
add sp,sp,8
|
|
j [blink]
|
|
|
|
; Check that register R12 which original value is not stored will not pop-up in
|
|
; the "Saved registers" list.
|
|
|
|
.align 4
|
|
unstored_reg:
|
|
sub_s sp,sp,12
|
|
st_s r13,[sp,0]
|
|
st_s r14,[sp,4]
|
|
mov r12,0x42
|
|
st_s r12,[sp,8]
|
|
add sp,sp,12
|
|
j [blink]
|
|
|
|
; Two stores at the same adddress. GDB should report only the R14.
|
|
|
|
.align 4
|
|
double_store:
|
|
sub_s sp,sp,4
|
|
st_s r13,[sp,0]
|
|
st_s r14,[sp,0]
|
|
add sp,sp,4
|
|
j [blink]
|
|
|
|
; Test for a case where callee has an alloca or anything else that might
|
|
; modify stack dynamically in the function body - after the prologue.
|
|
; This assumes that FP is set properly, so that GDB can use it - this holds
|
|
; true for frames generated by GCC.
|
|
|
|
.align 4
|
|
alloca_outer:
|
|
sub sp,sp,8
|
|
st blink,[sp,4]
|
|
st fp,[sp,0]
|
|
mov fp,sp
|
|
add r0,r1,r2 ; Not a prologue anymore.
|
|
sub sp,sp,8
|
|
bl @alloca_inner
|
|
add sp,sp,8
|
|
ld fp,[sp,0]
|
|
ld blink,[sp,4]
|
|
j.d [blink]
|
|
add sp,sp,8
|
|
|
|
.align 4
|
|
alloca_inner:
|
|
push r13
|
|
push r14
|
|
add sp,sp,8
|
|
j [blink]
|
|
|
|
|
|
.align 4
|
|
main:
|
|
push blink
|
|
# Create small section for GP-relative accesses.
|
|
push gp
|
|
sub sp,sp,16
|
|
add gp,sp,8
|
|
bl @standard_prologue
|
|
bl @mini_prologue
|
|
bl @no_subsp_prologue
|
|
bl @leaf_prologue
|
|
bl @pushfp_prologue
|
|
bl @fp_prologue_with_store
|
|
bl @noncallee_saved_regs_r12_st
|
|
bl @noncallee_saved_regs_r12_push
|
|
bl @noncallee_saved_regs_r2_push
|
|
bl @noncallee_saved_regs_gp_push
|
|
bl @noncallee_saved_regs_lp_count
|
|
bl @noncallee_saved_regs_blink_out_of_prologue
|
|
bl @arg_regs_fp
|
|
bl @arg_regs_fp_mov_s
|
|
bl @arg_regs_sp
|
|
bl @enter_s_nop
|
|
bl @enter_s_blink
|
|
bl @enter_s_fp
|
|
bl @enter_s_r13
|
|
bl @enter_s_r15
|
|
bl @enter_s_all
|
|
bl @nested_prologue_outer
|
|
bl @max_length_prologue
|
|
bl @branch_in_prologue
|
|
bl @cond_branch_in_prologue
|
|
bl @jump_in_prologue
|
|
bl @cond_jump_in_prologue
|
|
bl @predicated_insn
|
|
bl @loop_in_prologue
|
|
bl @store_constant
|
|
bl @st_c_limm
|
|
bl @st_ab_writeback
|
|
bl @st_as_writeback
|
|
bl @sth_as_writeback
|
|
bl @std_as_writeback
|
|
bl @st_halfword
|
|
bl @sts_halfword
|
|
bl @st_byte
|
|
bl @sts_byte
|
|
bl @sts_byte_sp
|
|
bl @st_double
|
|
bl @r_relative_store
|
|
bl @r_relative_sub_store
|
|
bl @r_relative_store_st_s
|
|
bl @r_relative_store_unknown
|
|
bl @st_s_r0gp
|
|
bl @push_s_prologue
|
|
bl @sub_s_cbu3
|
|
bl @sub_s_bbc
|
|
bl @sub_s_bbu5
|
|
bl @sub_0bc
|
|
bl @sub_alimmb
|
|
bl @sub_s_ne_bbb
|
|
bl @mov_limm
|
|
bl @mov0c_limm
|
|
bl @mov_s_hs3
|
|
bl @mov_s_bu8
|
|
bl @mov_s_ne_bh
|
|
bl @unstored_reg
|
|
bl @double_store
|
|
bl @alloca_outer
|
|
add sp,sp,16
|
|
pop gp
|
|
pop blink
|
|
j_s [blink]
|
|
|
|
.align 4
|