forked from OSchip/llvm-project
182 lines
6.9 KiB
ArmAsm
182 lines
6.9 KiB
ArmAsm
// REQUIRES: aarch64
|
|
// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o
|
|
// RUN: echo "SECTIONS { \
|
|
// RUN: .text : { *(.text) *(.text.*) *(.newisd) } \
|
|
// RUN: .text2 : { *.(newos) } \
|
|
// RUN: .data : { *(.data) } }" > %t.script
|
|
// RUN: ld.lld --script %t.script -fix-cortex-a53-843419 -verbose %t.o -o %t2 2>&1 \
|
|
// RUN: | FileCheck -check-prefix=CHECK-PRINT %s
|
|
// RUN: llvm-objdump --triple=aarch64-linux-gnu -d %t2 | FileCheck %s
|
|
|
|
// Test cases for Cortex-A53 Erratum 843419 that involve interactions
|
|
// between the generated patches and the address of sections.
|
|
|
|
// See ARM-EPM-048406 Cortex_A53_MPCore_Software_Developers_Errata_Notice.pdf
|
|
// for full erratum details.
|
|
// In Summary
|
|
// 1.)
|
|
// ADRP (0xff8 or 0xffc).
|
|
// 2.)
|
|
// - load or store single register or either integer or vector registers.
|
|
// - STP or STNP of either vector or vector registers.
|
|
// - Advanced SIMD ST1 store instruction.
|
|
// - Must not write Rn.
|
|
// 3.) optional instruction, can't be a branch, must not write Rn, may read Rn.
|
|
// 4.) A load or store instruction from the Load/Store register unsigned
|
|
// immediate class using Rn as the base register.
|
|
|
|
// An aarch64 section can contain ranges of literal data embedded within the
|
|
// code, these ranges are encoded with mapping symbols. This tests that we
|
|
// can match the erratum sequence in code, but not data.
|
|
// - We can handle more than one patch per code range (denoted by mapping
|
|
// symbols).
|
|
// - We can handle a patch in more than range of code, with literal data
|
|
// inbetween.
|
|
// - We can handle redundant mapping symbols (two or more consecutive mapping
|
|
// symbols with the same type).
|
|
// - We can ignore erratum sequences in multiple literal data ranges.
|
|
|
|
// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at FF8 in unpatched output.
|
|
// CHECK: <t3_ff8_ldr>:
|
|
// CHECK-NEXT: ff8: 20 00 00 d0 adrp x0, #24576
|
|
// CHECK-NEXT: ffc: 21 00 40 f9 ldr x1, [x1]
|
|
// CHECK-NEXT: 1000: f9 0f 00 14 b 0x4fe4
|
|
// CHECK-NEXT: 1004: c0 03 5f d6 ret
|
|
.section .text.01, "ax", %progbits
|
|
.balign 4096
|
|
.space 4096 - 8
|
|
.globl t3_ff8_ldr
|
|
.type t3_ff8_ldr, %function
|
|
t3_ff8_ldr:
|
|
adrp x0, dat
|
|
ldr x1, [x1, #0]
|
|
ldr x0, [x0, :got_lo12:dat]
|
|
ret
|
|
|
|
// create a redundant mapping symbol as we are already in a $x range
|
|
// some object producers unconditionally generate a mapping symbol on
|
|
// every symbol so we need to handle the case of $x $x.
|
|
.local $x.999
|
|
$x.999:
|
|
// CHECK-PRINT-NEXT: detected cortex-a53-843419 erratum sequence starting at 1FFC in unpatched output.
|
|
// CHECK: <t3_ffc_ldrsimd>:
|
|
// CHECK-NEXT: 1ffc: 20 00 00 b0 adrp x0, #20480
|
|
// CHECK-NEXT: 2000: 21 00 40 bd ldr s1, [x1]
|
|
// CHECK-NEXT: 2004: fa 0b 00 14 b 0x4fec
|
|
// CHECK-NEXT: 2008: c0 03 5f d6 ret
|
|
.globl t3_ffc_ldrsimd
|
|
.type t3_ffc_ldrsimd, %function
|
|
.space 4096 - 12
|
|
t3_ffc_ldrsimd:
|
|
adrp x0, dat
|
|
ldr s1, [x1, #0]
|
|
ldr x2, [x0, :got_lo12:dat]
|
|
ret
|
|
|
|
// Inline data containing bit pattern of erratum sequence, expect no patch.
|
|
.globl t3_ffc_ldralldata
|
|
.type t3_ff8_ldralldata, %function
|
|
.space 4096 - 20
|
|
t3_ff8_ldralldata:
|
|
// 0x90000000 = adrp x0, #0
|
|
.byte 0x00
|
|
.byte 0x00
|
|
.byte 0x00
|
|
.byte 0x90
|
|
// 0xf9400021 = ldr x1, [x1]
|
|
.byte 0x21
|
|
.byte 0x00
|
|
.byte 0x40
|
|
.byte 0xf9
|
|
// 0xf9400000 = ldr x0, [x0]
|
|
.byte 0x00
|
|
.byte 0x00
|
|
.byte 0x40
|
|
.byte 0xf9
|
|
// Check that we can recognise the erratum sequence post literal data.
|
|
|
|
// CHECK-PRINT-NEXT: detected cortex-a53-843419 erratum sequence starting at 3FF8 in unpatched output.
|
|
// CHECK: <t3_ffc_ldr>:
|
|
// CHECK-NEXT: 3ff8: 00 00 00 f0 adrp x0, #12288
|
|
// CHECK-NEXT: 3ffc: 21 00 40 f9 ldr x1, [x1]
|
|
// CHECK-NEXT: 4000: fd 03 00 14 b 0x4ff4
|
|
// CHECK-NEXT: 4004: c0 03 5f d6 ret
|
|
.space 4096 - 12
|
|
.globl t3_ffc_ldr
|
|
.type t3_ffc_ldr, %function
|
|
t3_ffc_ldr:
|
|
adrp x0, dat
|
|
ldr x1, [x1, #0]
|
|
ldr x0, [x0, :got_lo12:dat]
|
|
ret
|
|
|
|
// CHECK: <__CortexA53843419_1000>:
|
|
// CHECK-NEXT: 4fe4: 00 0c 40 f9 ldr x0, [x0, #24]
|
|
// CHECK-NEXT: 4fe8: 07 f0 ff 17 b 0x1004
|
|
// CHECK: <__CortexA53843419_2004>:
|
|
// CHECK-NEXT: 4fec: 02 0c 40 f9 ldr x2, [x0, #24]
|
|
// CHECK-NEXT: 4ff0: 06 f4 ff 17 b 0x2008
|
|
// CHECK: <__CortexA53843419_4000>:
|
|
// CHECK-NEXT: 4ff4: 00 0c 40 f9 ldr x0, [x0, #24]
|
|
// CHECK-NEXT: 4ff8: 03 fc ff 17 b 0x4004
|
|
|
|
.section .text.02, "ax", %progbits
|
|
.space 4096 - 36
|
|
|
|
// Start a new InputSectionDescription (see Linker Script) so the
|
|
// start address will be affected by any patches added to previous
|
|
// InputSectionDescription.
|
|
|
|
// CHECK-PRINT-NEXT: detected cortex-a53-843419 erratum sequence starting at 4FFC in unpatched output
|
|
// CHECK: <t3_ffc_str>:
|
|
// CHECK-NEXT: 4ffc: 00 00 00 d0 adrp x0, #8192
|
|
// CHECK-NEXT: 5000: 21 00 00 f9 str x1, [x1]
|
|
// CHECK-NEXT: 5004: fb 03 00 14 b 0x5ff0
|
|
// CHECK-NEXT: 5008: c0 03 5f d6 ret
|
|
|
|
.section .newisd, "ax", %progbits
|
|
.globl t3_ffc_str
|
|
.type t3_ffc_str, %function
|
|
t3_ffc_str:
|
|
adrp x0, dat
|
|
str x1, [x1, #0]
|
|
ldr x0, [x0, :got_lo12:dat]
|
|
ret
|
|
.space 4096 - 28
|
|
|
|
// CHECK: <__CortexA53843419_5004>:
|
|
// CHECK-NEXT: 5ff0: 00 0c 40 f9 ldr x0, [x0, #24]
|
|
// CHECK-NEXT: 5ff4: 05 fc ff 17 b 0x5008
|
|
|
|
// Start a new OutputSection (see Linker Script) so the
|
|
// start address will be affected by any patches added to previous
|
|
// InputSectionDescription.
|
|
|
|
//CHECK-PRINT-NEXT: detected cortex-a53-843419 erratum sequence starting at 5FF8 in unpatched output
|
|
// CHECK: <t3_ff8_str>:
|
|
// CHECK-NEXT: 5ff8: 00 00 00 b0 adrp x0, #4096
|
|
// CHECK-NEXT: 5ffc: 21 00 00 f9 str x1, [x1]
|
|
// CHECK-NEXT: 6000: 03 00 00 14 b 0x600c
|
|
// CHECK-NEXT: 6004: c0 03 5f d6 ret
|
|
|
|
.section .newos, "ax", %progbits
|
|
.globl t3_ff8_str
|
|
.type t3_ff8_str, %function
|
|
t3_ff8_str:
|
|
adrp x0, dat
|
|
str x1, [x1, #0]
|
|
ldr x0, [x0, :got_lo12:dat]
|
|
ret
|
|
.globl _start
|
|
.type _start, %function
|
|
_start:
|
|
ret
|
|
|
|
// CHECK: <__CortexA53843419_6000>:
|
|
// CHECK-NEXT: 600c: 00 0c 40 f9 ldr x0, [x0, #24]
|
|
// CHECK-NEXT: 6010: fd ff ff 17 b 0x6004
|
|
|
|
.data
|
|
.globl dat
|
|
dat: .word 0
|