This patch adds a pass that provides workarounds for the errata described in GRLIB-TN-0009, GRLIB-TN-0010, GRLIB-TN-0011, GRLIB-TN-0012, and GRLIB-TN-0013, that are applicable to the GR712RC and UT700. The documents are available for download from here: https://www.gaisler.com/index.php/information/app-tech-notes The pass will detect certain sensitive instruction sequences and prevent them from occurring by inserting NOP instruction. Below is an overview of each of the workarounds. A similar implementation is available in GCC. GRLIB-TN-0009: * Insert NOPs to prevent the sequence (stb/sth/st/stf) -> (single non-store/load instruction) -> (any store) * Insert NOPs to prevent the sequence (std/stdf) -> (any store) GRLIB-TN-0010: * Insert a NOP between load instruction and atomic instruction (swap and casa). * Insert a NOP at branch target if load in delay slot and atomic instruction at branch target. * Do not allow functions to begin with atomic instruction. GRLIB-TN-0011: * Insert .p2align 4 before atomic instructions (swap and casa). GRLIB-TN-0012: * Place a NOP at the branch target of an integer branch if it is a floating-point operation or a floating-point branch. GRLIB-TN-0013: * Prevent (div/sqrt) instructions in the delay slot. * Insert NOPs to prevent the sequence (div/sqrt) -> (two or three floating point operations or loads) -> (div/sqrt). * Do not insert NOPs if any of the floating point operations have a dependency on the destination register of the first (div/sqrt). * Do not insert NOPs if one of the floating point operations is a (div/sqrt). * Insert NOPs to prevent (div/sqrt) followed by a branch.
80 lines
1.4 KiB
YAML
80 lines
1.4 KiB
YAML
# RUN: llc %s -mattr=+fix-tn0010 -march=sparc -run-pass=errata-workaround -o - \
|
|
# RUN: | FileCheck %s
|
|
|
|
---
|
|
# CHECK: LDrr
|
|
# CHECK-NEXT: NOP
|
|
# CHECK-NEXT: CASArr
|
|
# CHECK: LDrr
|
|
# CHECK-NEXT: NOP
|
|
# CHECK-NEXT: SWAPrr
|
|
# CHECK: LDrr
|
|
# CHECK-NEXT: NOP
|
|
# CHECK-NEXT: SWAPri
|
|
name: er-5-1
|
|
registers:
|
|
- { id: 0, class: intregs }
|
|
body: |
|
|
bb.0.entry:
|
|
%0 = LDrr $o0, $g0
|
|
%0 = CASArr $o2, $o3, %0, 10
|
|
%0 = LDrr $g0, $o0
|
|
%0 = SWAPrr $o2, $o3, %0
|
|
%0 = LDrr $g0, $o0
|
|
%0 = SWAPri $o2, 10, %0
|
|
|
|
---
|
|
# CHECK: bb.2:
|
|
# CHECK-NEXT: NOP
|
|
# CHECK-NEXT: CASArr
|
|
name: er-5-2
|
|
registers:
|
|
- { id: 0, class: intregs }
|
|
body: |
|
|
bb.0.entry:
|
|
successors: %bb.1, %bb.2
|
|
BCOND %bb.2, 10, implicit $icc {
|
|
%0 = LDrr $g0, $o0
|
|
}
|
|
|
|
bb.1.entry:
|
|
successors: %bb.2
|
|
NOP
|
|
|
|
bb.2:
|
|
%0 = CASArr $o1, $o2, %0, 10
|
|
|
|
---
|
|
# CHECK: bb.0.entry:
|
|
# CHECK-NEXT: NOP
|
|
# CHECK-NEXT: CASArr
|
|
name: er-5-3
|
|
registers:
|
|
- { id: 0, class: intregs }
|
|
body: |
|
|
bb.0.entry:
|
|
%0 = CASArr $o1, $o2, %0, 10
|
|
|
|
---
|
|
# CHECK: bb.1.entry:
|
|
# CHECK: NOP
|
|
# CHECK-NEXT: CASArr
|
|
name: er-5-4
|
|
registers:
|
|
- { id: 0, class: intregs }
|
|
body: |
|
|
bb.0.entry:
|
|
successors: %bb.1, %bb.2
|
|
BCOND %bb.2, 10, implicit $icc {
|
|
%0 = LDrr $g0, $o0
|
|
}
|
|
|
|
bb.1.entry:
|
|
successors: %bb.2
|
|
%0 = CASArr $o1, $o2, %0, 10
|
|
|
|
bb.2:
|
|
NOP
|
|
|
|
...
|