blob: 9a557c506922a2b9496290ef255f1858baa1e70f [file] [log] [blame]
# RUN: llc -mtriple=armv7-none-none-eabihf -mcpu=cortex-r5 -o - %s -run-pass=prologepilog \
# RUN: | FileCheck --check-prefix=CHECK-R-ARM %s
# RUN: llc -mtriple=armv7-none-none-eabihf -mcpu=cortex-r4 -o - %s -run-pass=prologepilog \
# RUN: | FileCheck --check-prefix=CHECK-R-ARM %s
# RUN: llc -mtriple=thumbv7-none-none-eabihf -mcpu=cortex-r5 -o - %s -run-pass=prologepilog \
# RUN: | FileCheck --check-prefix=CHECK-R-THUMB %s
# RUN: llc -mtriple=thumbv7-none-none-eabihf -mcpu=cortex-r4 -o - %s -run-pass=prologepilog \
# RUN: | FileCheck --check-prefix=CHECK-R-THUMB %s
# RUN: llc -mtriple=thumbv7-none-none-eabihf -mcpu=cortex-m3 -o - %s -run-pass=prologepilog \
# RUN: | FileCheck --check-prefix=CHECK-M-THUMB %s
# RUN: llc -mtriple=thumbv7-none-none-eabihf -mcpu=cortex-m4 -o - %s -run-pass=prologepilog \
# RUN: | FileCheck --check-prefix=CHECK-M-THUMB %s
# RUN: llc -mtriple=thumbv8-none-none-eabihf -mcpu=cortex-m33 -o - %s -run-pass=prologepilog \
# RUN: | FileCheck --check-prefix=CHECK-M-THUMB %s
# =============================================================================
# ============================ cortex-r arm-mode ==============================
# =============================================================================
# This IRQ will save 104 bytes:
#
# |---------+------+----------|
# | reg | size | zone |
# |---------+------+----------|
# | LR | 4x1 | GPR |
# | R12-R10 | 4x3 | |
# | R5-R0 | 4x6 | |
# |---------+------+----------|
# | FPEXC | 4x1 | FPStatus |
# | FPSCR | 4x1 | |
# |---------+------+----------|
# | D7-D0 | 8x8 | FPRegs |
# |---------+------+----------|
# | | 112 | |
# |---------+------+----------|
#
# ================================= Prologue =================================
#
# Frame pointer (r11) will be store at $original_sp - 12, but we can't save the
# FP until after we save the GPR zone of registers. The GPR zone of registers
# moves the stack by 40 bytes. So $original_sp = $current_sp + 40. Thus,
# $current_sp + 40 - 12 = $current_sp + 28. Thus, we see the instruction:
#
# $r11 = ADDri $sp, 28
#
# We don't have dwarf information for the FPEXC and FPSCR registers, so there's
# no CFI_INSTRUCTION for those saves. So, we should see an 8 byte disparity in
# the register offsets. $r0 is -40, and $d7 is -56.
#
# (-40) - (-56) = 16.
# 16 = 8 (bytes from $d7) + 8 (bytes from FPSCR + FPEXC)
#
# There's an extra BFC to force the stack to be aligned.
#
# $sp = BFC $sp, 4294967288 /* ~0x7 */
#
# ================================= Epilogue =================================
#
# We use the frame pointer to restore the SP. Since $r11 is currently pointing
# to the previous $r11's stack position (aka base_of_stack - 12), and we
# allocated 112 bytes, $sp = $r11 - (112 - 12), or $sp = $r11 - 100, which is
# why we see this instruction:
#
# $sp = SUBri $r11, 100
# CHECK-R-ARM-LABEL: name: irq_fn
# CHECK-R-ARM-LABEL: bb.0 (%ir-block.0):
# CHECK-R-ARM: $sp = frame-setup STMDB_UPD $sp, 14 /* CC::al */, $noreg, killed $r0, killed $r1, killed $r2, killed $r3, killed $r4, killed $r5, killed $r10, killed $r11, killed $r12, killed $lr
# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 40
# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $lr, -4
# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $ra_auth_code, -8
# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $r11, -12
# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $r10, -16
# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $r5, -20
# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $r4, -24
# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $r3, -28
# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $r2, -32
# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $r1, -36
# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $r0, -40
# CHECK-R-ARM-NEXT: $r11 = frame-setup ADDri killed $sp, 28, 14 /* CC::al */, $noreg, $noreg
# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION def_cfa $r11, 12
# CHECK-R-ARM-NEXT: $r4 = frame-setup VMRS 14 /* CC::al */, $noreg, implicit $fpscr
# CHECK-R-ARM-NEXT: $r5 = frame-setup VMRS_FPEXC 14 /* CC::al */, $noreg, implicit $fpscr
# CHECK-R-ARM-NEXT: $sp = frame-setup STMDB_UPD $sp, 14 /* CC::al */, $noreg, $r4, $r5
# CHECK-R-ARM-NEXT: $sp = frame-setup VSTMDDB_UPD $sp, 14 /* CC::al */, $noreg, killed $d0, killed $d1, killed $d2, killed $d3, killed $d4, killed $d5, killed $d6, killed $d7
# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $d7, -56
# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $d6, -64
# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $d5, -72
# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $d4, -80
# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $d3, -88
# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $d2, -96
# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $d1, -104
# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $d0, -112
# CHECK-R-ARM-NEXT: $sp = BFC killed $sp, 4294967288, 14 /* CC::al */, $noreg
# CHECK-R-ARM-NEXT: BL @bar, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
# CHECK-R-ARM-NEXT: $sp = frame-destroy SUBri killed $r11, 100, 14 /* CC::al */, $noreg, $noreg
# CHECK-R-ARM-NEXT: $sp = frame-destroy VLDMDIA_UPD $sp, 14 /* CC::al */, $noreg, def $d0, def $d1, def $d2, def $d3, def $d4, def $d5, def $d6, def $d7
# CHECK-R-ARM-NEXT: $sp = frame-destroy LDMIA_UPD $sp, 14 /* CC::al */, $noreg, def $r4, def $r5
# CHECK-R-ARM-NEXT: frame-destroy VMSR $r4, 14 /* CC::al */, $noreg, implicit-def $fpscr
# CHECK-R-ARM-NEXT: frame-destroy VMSR_FPEXC $r5, 14 /* CC::al */, $noreg, implicit-def $fpscr
# =============================================================================
# =========================== cortex-r thumb-mode =============================
# =============================================================================
# This IRQ will save 112 bytes:
#
# |-------+------+----------|
# | reg | size | zone |
# |-------+------+----------|
# | LR | 4x1 | GPR |
# | R12 | 4x1 | |
# | R7-R0 | 4x8 | |
# |-------+------+----------|
# | FPEXC | 4x1 | FPStatus |
# | FPSCR | 4x1 | |
# |-------+------+----------|
# | D7-D0 | 8x8 | FPRegs |
# |-------+------+----------|
# | | 112 | |
# |-------+------+----------|
#
# ================================= Prologue =================================
#
# Frame pointer (r7) will be store at $original_sp - 12, but we can't save the
# FP until after we save the GPR zone of registers. The GPR zone of registers
# moves the stack by 40 bytes. So $original_sp = $current_sp + 40. Thus,
# $current_sp + 40 - 12 = $current_sp + 28. Thus, we see the instruction:
#
# $r7 = t2ADDri $sp, 28
#
# We don't have dwarf information for the FPEXC and FPSCR registers, so there's
# no CFI_INSTRUCTION for those saves. So, we should see an 8 byte disparity in
# the register offsets. $r0 is -40, and $d7 is -56.
#
# (-32) - (-48) = 16.
# 16 = 8 (bytes from $d7) + 8 (bytes from FPSCR + FPEXC)
#
# There's an extra BFC to force the stack to be aligned. This is done in 3
# steps, because the value of $sp needs to be moved into a low register
# (r0-r7), and then operated on, and then moved back.
#
# $r4 = tMOVr $sp, 14
# $r4 = t2BFC $r4, 4294967288 /* ~0x7 */, 14
# $sp = tMOVr $r4, 14
#
# ================================= Epilogue =================================
#
# We use the frame pointer to restore the SP. Since $r7 is currently pointing
# to the previous $r7's stack position (aka base_of_stack - 12), and we
# allocated 112 bytes, $sp = $r7 - (112 - 12), or $sp = $r7 - 100, which is
# why we see this instruction:
#
# $r4 = t2SUBri $r7, 100
# $sp = tMOVr $r4
# CHECK-R-THUMB-LABEL: name: irq_fn
# CHECK-R-THUMB-LABEL: bb.0 (%ir-block.0):
# CHECK-R-THUMB: $sp = frame-setup t2STMDB_UPD $sp, 14 /* CC::al */, $noreg, killed $r0, killed $r1, killed $r2, killed $r3, killed $r4, killed $r5, killed $r6, killed $r7, killed $r12, killed $lr
# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 40
# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $lr, -4
# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $ra_auth_code, -8
# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $r7, -12
# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $r6, -16
# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $r5, -20
# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $r4, -24
# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $r3, -28
# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $r2, -32
# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $r1, -36
# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $r0, -40
# CHECK-R-THUMB-NEXT: $r7 = frame-setup t2ADDri killed $sp, 28, 14 /* CC::al */, $noreg, $noreg
# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION def_cfa $r7, 12
# CHECK-R-THUMB-NEXT: $r4 = frame-setup VMRS 14 /* CC::al */, $noreg, implicit $fpscr
# CHECK-R-THUMB-NEXT: $r5 = frame-setup VMRS_FPEXC 14 /* CC::al */, $noreg, implicit $fpscr
# CHECK-R-THUMB-NEXT: $sp = frame-setup t2STMDB_UPD $sp, 14 /* CC::al */, $noreg, $r4, $r5
# CHECK-R-THUMB-NEXT: $sp = frame-setup VSTMDDB_UPD $sp, 14 /* CC::al */, $noreg, killed $d0, killed $d1, killed $d2, killed $d3, killed $d4, killed $d5, killed $d6, killed $d7
# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d7, -56
# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d6, -64
# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d5, -72
# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d4, -80
# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d3, -88
# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d2, -96
# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d1, -104
# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d0, -112
# CHECK-R-THUMB-NEXT: $r4 = tMOVr killed $sp, 14 /* CC::al */, $noreg
# CHECK-R-THUMB-NEXT: $r4 = t2BFC killed $r4, 4294967288, 14 /* CC::al */, $noreg
# CHECK-R-THUMB-NEXT: $sp = tMOVr killed $r4, 14 /* CC::al */, $noreg
# CHECK-R-THUMB-NEXT: BL @bar, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
# CHECK-R-THUMB-NEXT: $r4 = frame-destroy t2SUBri killed $r7, 100, 14 /* CC::al */, $noreg, $noreg
# CHECK-R-THUMB-NEXT: $sp = frame-destroy tMOVr $r4, 14 /* CC::al */, $noreg
# CHECK-R-THUMB-NEXT: $sp = frame-destroy VLDMDIA_UPD $sp, 14 /* CC::al */, $noreg, def $d0, def $d1, def $d2, def $d3, def $d4, def $d5, def $d6, def $d7
# CHECK-R-THUMB-NEXT: $sp = frame-destroy t2LDMIA_UPD $sp, 14 /* CC::al */, $noreg, def $r4, def $r5
# CHECK-R-THUMB-NEXT: frame-destroy VMSR $r4, 14 /* CC::al */, $noreg, implicit-def $fpscr
# CHECK-R-THUMB-NEXT: frame-destroy VMSR_FPEXC $r5, 14 /* CC::al */, $noreg, implicit-def $fpscr
# CHECK-R-THUMB-NEXT: $sp = frame-destroy t2LDMIA_UPD $sp, 14 /* CC::al */, $noreg, def $r0, def $r1, def $r2, def $r3, def $r4, def $r5, def $r6, def $r7, def $r12, def $lr
# CHECK-R-THUMB-NEXT: SUBS_PC_LR 4, 14 /* CC::al */, $noreg
# =============================================================================
# ============================== cortex-m thumb ===============================
# =============================================================================
# This IRQ will save 88 bytes:
#
# |---------+------+----------|
# | reg | size | zone |
# |---------+------+----------|
# | LR | 4x1 | GPR |
# | R7-R6 | 4x2 | |
# | R4 | 4x1 | |
# |---------+------+----------|
# | FPSCR | 4x1 | FPStatus |
# |---------+------+----------|
# | EMPTY | 4x1 | Align |
# |---------+------+----------|
# | D7-D0 | 8x8 | FPRegs |
# |---------+------+----------|
# | | 88 | |
# |---------+------+----------|
# CHECK-M-THUMB-LABEL: name: irq_fn
# CHECK-M-THUMB-LABEL: bb.0 (%ir-block.0):
# CHECK-M-THUMB: $sp = frame-setup t2STMDB_UPD $sp, 14 /* CC::al */, $noreg, killed $r4, killed $r6, killed $r7, killed $lr
# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 16
# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $lr, -4
# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $r7, -8
# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $r6, -12
# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $r4, -16
# CHECK-M-THUMB-NEXT: $r7 = frame-setup t2ADDri killed $sp, 8, 14 /* CC::al */, $noreg, $noreg
# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION def_cfa $r7, 8
# CHECK-M-THUMB-NEXT: $r4 = frame-setup VMRS 14 /* CC::al */, $noreg, implicit $fpscr
# CHECK-M-THUMB-NEXT: $sp = frame-setup t2STMDB_UPD $sp, 14 /* CC::al */, $noreg, $r4
# CHECK-M-THUMB-NEXT: $sp = frame-setup tSUBspi $sp, 1, 14 /* CC::al */, $noreg
# CHECK-M-THUMB-NEXT: $sp = frame-setup VSTMDDB_UPD $sp, 14 /* CC::al */, $noreg, killed $d0, killed $d1, killed $d2, killed $d3, killed $d4, killed $d5, killed $d6, killed $d7
# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d7, -32
# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d6, -40
# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d5, -48
# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d4, -56
# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d3, -64
# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d2, -72
# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d1, -80
# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d0, -88
# CHECK-M-THUMB-NEXT: $r4 = tMOVr killed $sp, 14 /* CC::al */, $noreg
# CHECK-M-THUMB-NEXT: $r4 = t2BFC killed $r4, 4294967288, 14 /* CC::al */, $noreg
# CHECK-M-THUMB-NEXT: $sp = tMOVr killed $r4, 14 /* CC::al */, $noreg
# CHECK-M-THUMB-NEXT: BL @bar, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
# CHECK-M-THUMB-NEXT: $r4 = frame-destroy t2SUBri killed $r7, 80, 14 /* CC::al */, $noreg, $noreg
# CHECK-M-THUMB-NEXT: $sp = frame-destroy tMOVr $r4, 14 /* CC::al */, $noreg
# CHECK-M-THUMB-NEXT: $sp = frame-destroy VLDMDIA_UPD $sp, 14 /* CC::al */, $noreg, def $d0, def $d1, def $d2, def $d3, def $d4, def $d5, def $d6, def $d7
# CHECK-M-THUMB-NEXT: $sp = frame-destroy tADDspi $sp, 1, 14 /* CC::al */, $noreg
# CHECK-M-THUMB-NEXT: $sp = frame-destroy t2LDMIA_UPD $sp, 14 /* CC::al */, $noreg, def $r4
# CHECK-M-THUMB-NEXT: frame-destroy VMSR $r4, 14 /* CC::al */, $noreg, implicit-def $fpscr
# CHECK-M-THUMB-NEXT: $sp = frame-destroy t2LDMIA_UPD $sp, 14 /* CC::al */, $noreg, def $r4, def $r6, def $r7, def $lr
# CHECK-M-THUMB-NEXT: SUBS_PC_LR 4, 14 /* CC::al */, $noreg
--- |
; ModuleID = '/scratch/benson/tools2/llvm_cgt/llvm-project/llvm/test/CodeGen/ARM/fp-attr-fpscr.ll'
source_filename = "/scratch/benson/tools2/llvm_cgt/llvm-project/llvm/test/CodeGen/ARM/fp-attr-fpscr.ll"
target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
declare arm_aapcscc void @bar()
; Function Attrs: alignstack(8)
define arm_aapcscc void @irq_fn() #1 {
call arm_aapcscc void @bar()
ret void
}
attributes #1 = { alignstack=8 "interrupt"="IRQ" "target-features"="+fpregs" "save-fp" }
...
---
name: irq_fn
frameInfo:
adjustsStack: true
alignment: 16
body: |
bb.0 (%ir-block.0):
ADJCALLSTACKDOWN 0, 0, 14 /* CC::al */, $noreg, implicit-def dead $sp, implicit $sp
BL @bar, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
ADJCALLSTACKUP 0, -1, 14 /* CC::al */, $noreg, implicit-def dead $sp, implicit $sp
SUBS_PC_LR 4, 14 /* CC::al */, $noreg
...