// REQUIRES: aarch64 // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o // RUN: ld.lld -fix-cortex-a53-843419 -verbose -t %t.o -o %t2 | FileCheck %s // Test cases for Cortex-A53 Erratum 843419 that we don't expect to recognize // as needing a patch as one or more of the conditions isn't satisfied. // 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 // Expect no patches detected. // CHECK-NOT: detected cortex-a53-843419 erratum sequence // erratum sequence but adrp (address & 0xfff) is not 0xff8 or 0xffc .section .text.01, "ax", %progbits .balign 4096 .globl t3_0_ldr .type t3_ff8_ldr, %function t3_0_ldr: adrp x0, dat ldr x1, [x1, #0] ldr x0, [x0, :got_lo12:dat] ret .section .text.02, "ax", %progbits .balign 4096 .globl t3_ff4_ldr .space 4096 - 12 .type t3_ff4_ldr, %function t3_ff4_ldr: adrp x0, dat ldr x1, [x1, #0] ldr x0, [x0, :got_lo12:dat] ret // Close matches for erratum sequence, with adrp at correct address but // instruction 2 is a load or store but not one that matches the erratum // conditions, but with a similar encoding to an instruction that does. // ldp is not part of sequence, although stp is. .section .text.03, "ax", %progbits .balign 4096 .globl t3_ff8_ldp .type t3_ff8_ldp, %function .space 4096 - 8 t3_ff8_ldp: adrp x16, dat ldp x1,x2, [x3, #0] ldr x13, [x16, :got_lo12:dat] ret // st2 is not part of sequence although st1 is. .section .text.04, "ax", %progbits .balign 4096 .globl t3_ffc_st2 .type t3_ffc_st2, %function .space 4096 - 4 t3_ffc_st2: adrp x16, dat st2 { v0.16b, v1.16b }, [x1] ldr x13, [x16, :got_lo12:dat] ret // st3 is not part of sequence although st1 is. .section .text.05, "ax", %progbits .balign 4096 .globl t3_ffc_st3 .type t3_ffc_st3, %function .space 4096 - 4 t3_ffc_st3: adrp x16, dat st3 { v0.16b, v1.16b, v2.16b }, [x1], x2 ldr x13, [x16, :got_lo12:dat] ret // ld1 is not part of sequence although st1 is. .section .text.06, "ax", %progbits .balign 4096 .globl t3_ffc_ld2 .type t3_ffc_st3, %function .space 4096 - 4 t3_ffc_ld1: adrp x16, dat ld1 { v0.16b }, [x2], x3 ldr x13, [x16, :got_lo12:dat] ret // ldnp is not part of sequence although stnp is. .section .text.07, "ax", %progbits .balign 4096 .globl t4_ff8_ldnp .type t4_ff8_ldnp, %function .space 4096 - 8 t4_ff8_ldnp: adrp x7, dat ldnp x1,x2, [x3, #0] nop ldr x10, [x7, :got_lo12:dat] ret // Close match for erratum sequence, with adrp at correct address but // instruction 2 writes to Rn, with Rn as either destination or as the // transfer register but with writeback. // ldr instruction writes to Rn .section .text.08, "ax", %progbits .balign 4096 .globl t3_ff8_ldr .type t3_ff8_ldr, %function .space 4096 - 8 t3_ff8_ldr: adrp x0, dat ldr x0, [x1, #0] ldr x0, [x0, :got_lo12:dat] ret // str instruction writes to Rn via writeback (pre index) .section .text.09, "ax", %progbits .balign 4096 .globl t3_ff8_str .type t3_ff8_str, %function .space 4096 - 8 t3_ff8_str: adrp x0, dat str x1, [x0, #4]! ldr x0, [x0, :got_lo12:dat] ret // ldr instruction writes to Rn via writeback (post index) .section .text.09, "ax", %progbits .balign 4096 .globl t3_ffc_ldr .type t3_ffc_ldr, %function .space 4096 - 8 t3_ffc_ldr: adrp x0, dat ldr x1, [x0], 0x8 ldr x0, [x0, :got_lo12:dat] ret // stp writes to Rn via writeback (pre index) .section .text.10, "ax", %progbits .balign 4096 .globl t4_ffc_stppre .type t4_ffc_stppre, %function .space 4096 - 4 t4_ffc_stppre: adrp x16, dat stp x1,x2, [x16, #16]! mul x3, x16, x16 ldr x14, [x16, #8] ret // stp writes to Rn via writeback (post index) .section .text.11, "ax", %progbits .balign 4096 .globl t4_ff8_stppost .type t4_ff8_stppost, %function .space 4096 - 8 t4_ff8_stppost: adrp x16, dat stp x1,x2, [x16], #16 mul x3, x16, x16 ldr x14, [x16, #8] ret // st1 writes to Rn via writeback .section .text.12, "ax", %progbits .balign 4096 .globl t3_ff8_st1 .type t3_ff8_st1, %function .space 4096 - 8 t3_ff8_st1: adrp x16, dat st1 { v0.16b}, [x16], x2 ldr x13, [x16, :got_lo12:dat] ret // Close match for erratum sequence, but with optional instruction 3 a branch // function call via immediate .section .text.13, "ax", %progbits .balign 4096 .globl t4_ffc_blimm .type t4_ffc_blimm, %function .space 4096 - 4 t4_ffc_blimm: adrp x7, dat stnp x1,x2, [x3, #0] bl t4_ffc_blimm ldr x10, [x7, :got_lo12:dat] ret // function call via register .section .text.14, "ax", %progbits .balign 4096 .globl t4_ffc_blreg .type t4_ffc_blreg, %function .space 4096 - 4 t4_ffc_blreg: adrp x7, dat stnp x1,x2, [x3, #0] blr x4 ldr x10, [x7, :got_lo12:dat] ret // Unconditional branch immediate .section .text.15, "ax", %progbits .balign 4096 .globl t4_ffc_branchimm .type t4_ffc_branchimm, %function .space 4096 - 4 t4_ffc_branchimm: adrp x7, dat stnp x1,x2, [x3, #0] b t4_ffc_branchimm ldr x10, [x7, :got_lo12:dat] ret // Unconditional branch register .section .text.16, "ax", %progbits .balign 4096 .globl t4_ffc_branchreg .type t4_ffc_branchreg, %function .space 4096 - 4 t4_ffc_branchreg: adrp x7, dat stnp x1,x2, [x3, #0] br x4 ldr x10, [x7, :got_lo12:dat] ret // Conditional branch .section .text.17, "ax", %progbits .balign 4096 .globl t4_ffc_branchcond .type t4_ffc_branchcond, %function .space 4096 - 4 t4_ffc_branchcond: adrp x7, dat stnp x1,x2, [x3, #0] cbz x5, t4_ffc_branchcond ldr x10, [x7, :got_lo12:dat] ret // Conditional branch immediate .section .text.18, "ax", %progbits .balign 4096 .globl t4_ffc_branchcondimm .type t4_ffc_branchcondimm, %function .space 4096 - 4 t4_ffc_branchcondimm: adrp x7, dat stnp x1,x2, [x3, #0] beq t4_ffc_branchcondimm ldr x10, [x7, :got_lo12:dat] ret // Bitpattern matches erratum sequence but either all or part of the sequence // is in inline literal data .section .text.19, "ax", %progbits .balign 4096 .globl t3_ffc_ldrtraildata .type t3_ff8_ldrtraildata, %function .space 4096 - 8 t3_ff8_ldrtraildata: adrp x0, dat ldr x1, [x1, #0] // 0xf9400000 = ldr x0, [x0] .byte 0x00 .byte 0x00 .byte 0x40 .byte 0xf9 ldr x0, [x0, :got_lo12:dat] ret .section .text.20, "ax", %progbits .balign 4096 .globl t3_ffc_ldrpredata .type t3_ff8_ldrpredata, %function .space 4096 - 8 t3_ff8_ldrpredata: // 0x90000000 = adrp x0, #0 .byte 0x00 .byte 0x00 .byte 0x00 .byte 0x90 ldr x1, [x1, #0] ldr x0, [x0, :got_lo12:dat] ret .section .text.21, "ax", %progbits .balign 4096 .globl t3_ffc_ldralldata .type t3_ff8_ldralldata, %function .space 4096 - 8 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 ret .text .globl _start .type _start, %function _start: ret // Bitpattern matches erratum sequence but section is not executable .data .globl dat dat: .word 0