[AVR] Improve expansion of pseudo instruction SPREAD (#186780)
It would be better to set the higher register to zero for devices without `SPH`.
This commit is contained in:
parent
81841b722b
commit
297d52ba7d
@ -2496,26 +2496,36 @@ template <> bool AVRExpandPseudo::expand<AVR::ZEXT>(Block &MBB, BlockIt MBBI) {
|
||||
|
||||
template <>
|
||||
bool AVRExpandPseudo::expand<AVR::SPREAD>(Block &MBB, BlockIt MBBI) {
|
||||
const AVRSubtarget &STI = MBB.getParent()->getSubtarget<AVRSubtarget>();
|
||||
MachineInstr &MI = *MBBI;
|
||||
Register DstLoReg, DstHiReg;
|
||||
Register DstReg = MI.getOperand(0).getReg();
|
||||
bool DstIsDead = MI.getOperand(0).isDead();
|
||||
unsigned Flags = MI.getFlags();
|
||||
unsigned OpLo = AVR::INRdA;
|
||||
unsigned OpHi = AVR::INRdA;
|
||||
TRI->splitReg(DstReg, DstLoReg, DstHiReg);
|
||||
|
||||
// Low part
|
||||
buildMI(MBB, MBBI, OpLo)
|
||||
buildMI(MBB, MBBI, AVR::INRdA)
|
||||
.addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
|
||||
.addImm(0x3d)
|
||||
.addImm(STI.getIORegSPL())
|
||||
.setMIFlags(Flags);
|
||||
|
||||
// High part
|
||||
buildMI(MBB, MBBI, OpHi)
|
||||
.addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
|
||||
.addImm(0x3e)
|
||||
.setMIFlags(Flags);
|
||||
if (STI.getIORegSPH() != -1) {
|
||||
buildMI(MBB, MBBI, AVR::INRdA)
|
||||
.addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
|
||||
.addImm(STI.getIORegSPH())
|
||||
.setMIFlags(Flags);
|
||||
} else {
|
||||
// Clear the upper byte if there is no SPH.
|
||||
auto MI0 =
|
||||
buildMI(MBB, MBBI, AVR::EORRdRr)
|
||||
.addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
|
||||
.addReg(DstHiReg, RegState::Kill)
|
||||
.addReg(DstHiReg);
|
||||
// SREG is implicitly dead.
|
||||
MI0->getOperand(3).setIsDead();
|
||||
}
|
||||
|
||||
MI.eraseFromParent();
|
||||
return true;
|
||||
@ -2536,7 +2546,6 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
|
||||
// a write to SPL will automatically disable interrupts
|
||||
// for up to four instructions or until the next I/O memory write.
|
||||
if (STI.getELFArch() >= 102) { // An XMEGA device
|
||||
|
||||
buildMI(MBB, MBBI, AVR::OUTARr)
|
||||
.addImm(STI.getIORegSPL())
|
||||
.addReg(SrcLoReg, getKillRegState(SrcIsKill))
|
||||
@ -2546,12 +2555,9 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
|
||||
.addImm(STI.getIORegSPH())
|
||||
.addReg(SrcHiReg, getKillRegState(SrcIsKill))
|
||||
.setMIFlags(Flags);
|
||||
|
||||
} else { // Disable interrupts for older devices with SPH (3 extra
|
||||
// instructions)
|
||||
|
||||
if (STI.getIORegSPH() != -1) {
|
||||
|
||||
buildMI(MBB, MBBI, AVR::INRdA)
|
||||
.addReg(STI.getTmpRegister(), RegState::Define)
|
||||
.addImm(STI.getIORegSREG())
|
||||
|
||||
@ -46,7 +46,7 @@ define i16 @foo3(i16 %a, i16 %b, i16 %c, i16 %d) {
|
||||
; CHECK-NEXT: push r28
|
||||
; CHECK-NEXT: push r29
|
||||
; CHECK-NEXT: in r28, 61
|
||||
; CHECK-NEXT: in r29, 62
|
||||
; CHECK-NEXT: clr r29
|
||||
; CHECK-NEXT: in r16, 63
|
||||
; CHECK-NEXT: subi r28, 251
|
||||
; CHECK-NEXT: sbci r29, 255
|
||||
@ -79,7 +79,7 @@ define i32 @foo4(i32 %a, i32 %b) {
|
||||
; CHECK-NEXT: push r28
|
||||
; CHECK-NEXT: push r29
|
||||
; CHECK-NEXT: in r28, 61
|
||||
; CHECK-NEXT: in r29, 62
|
||||
; CHECK-NEXT: clr r29
|
||||
; CHECK-NEXT: in r16, 63
|
||||
; CHECK-NEXT: subi r28, 251
|
||||
; CHECK-NEXT: sbci r29, 255
|
||||
@ -122,7 +122,7 @@ define i8 @foo5([5 x i8] %0, i8 %1) {
|
||||
; CHECK-NEXT: push r28
|
||||
; CHECK-NEXT: push r29
|
||||
; CHECK-NEXT: in r28, 61
|
||||
; CHECK-NEXT: in r29, 62
|
||||
; CHECK-NEXT: clr r29
|
||||
; CHECK-NEXT: mov r26, r28
|
||||
; CHECK-NEXT: mov r27, r29
|
||||
; CHECK-NEXT: subi r26, 251
|
||||
@ -157,7 +157,7 @@ define i8 @foo7([3 x i8] %0, [3 x i8] %1) {
|
||||
; CHECK-NEXT: push r28
|
||||
; CHECK-NEXT: push r29
|
||||
; CHECK-NEXT: in r28, 61
|
||||
; CHECK-NEXT: in r29, 62
|
||||
; CHECK-NEXT: clr r29
|
||||
; CHECK-NEXT: mov r26, r28
|
||||
; CHECK-NEXT: mov r27, r29
|
||||
; CHECK-NEXT: subi r26, 251
|
||||
@ -181,7 +181,7 @@ define i8 @foo8([3 x i8] %0, i8 %1, i8 %2) {
|
||||
; CHECK-NEXT: push r28
|
||||
; CHECK-NEXT: push r29
|
||||
; CHECK-NEXT: in r28, 61
|
||||
; CHECK-NEXT: in r29, 62
|
||||
; CHECK-NEXT: clr r29
|
||||
; CHECK-NEXT: add r22, r20
|
||||
; CHECK-NEXT: mov r26, r28
|
||||
; CHECK-NEXT: mov r27, r29
|
||||
@ -205,7 +205,7 @@ define i8 @foo9([7 x i8] %0) {
|
||||
; CHECK-NEXT: push r28
|
||||
; CHECK-NEXT: push r29
|
||||
; CHECK-NEXT: in r28, 61
|
||||
; CHECK-NEXT: in r29, 62
|
||||
; CHECK-NEXT: clr r29
|
||||
; CHECK-NEXT: mov r26, r28
|
||||
; CHECK-NEXT: mov r27, r29
|
||||
; CHECK-NEXT: subi r26, 250
|
||||
@ -233,7 +233,7 @@ define i8 @fooa([6 x i8] %0, i8 %1, i8 %2) {
|
||||
; CHECK-NEXT: push r28
|
||||
; CHECK-NEXT: push r29
|
||||
; CHECK-NEXT: in r28, 61
|
||||
; CHECK-NEXT: in r29, 62
|
||||
; CHECK-NEXT: clr r29
|
||||
; CHECK-NEXT: mov r26, r28
|
||||
; CHECK-NEXT: mov r27, r29
|
||||
; CHECK-NEXT: subi r26, 251
|
||||
|
||||
28
llvm/test/CodeGen/AVR/pseudo/SPREAD.mir
Normal file
28
llvm/test/CodeGen/AVR/pseudo/SPREAD.mir
Normal file
@ -0,0 +1,28 @@
|
||||
# RUN: llc -O0 -run-pass=avr-expand-pseudo -mtriple=avr -mcpu=attiny13 %s -o - \
|
||||
# RUN: | FileCheck --check-prefix=NOSPH %s
|
||||
# RUN: llc -O0 -run-pass=avr-expand-pseudo -mtriple=avr -mcpu=atmega328 %s -o - \
|
||||
# RUN: | FileCheck %s
|
||||
|
||||
--- |
|
||||
target triple = "avr--"
|
||||
define void @test() {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
...
|
||||
|
||||
---
|
||||
name: test
|
||||
body: |
|
||||
bb.0.entry:
|
||||
|
||||
; CHECK-LABEL: test
|
||||
; CHECK: $r14 = INRdA 61
|
||||
; CHECK: $r15 = INRdA 62
|
||||
|
||||
; NOSPH-LABEL: test
|
||||
; NOSPH: $r14 = INRdA 61
|
||||
; NOSPH: $r15 = EORRdRr killed $r15, $r15, implicit-def dead $sreg
|
||||
|
||||
$r15r14 = SPREAD $sp, implicit $sp
|
||||
...
|
||||
@ -40,5 +40,5 @@ body: |
|
||||
; XMEGA-LABEL: OUTARr 61, $r14
|
||||
; XMEGA-LABEL: OUTARr 62, $r15
|
||||
|
||||
$sp = SPWRITE implicit-def $sp, implicit $sp, $r15r14
|
||||
$sp = SPWRITE implicit-def $sp, $r15r14, implicit $sp
|
||||
...
|
||||
|
||||
@ -135,7 +135,7 @@ define i32 @return32_arg2(i32 %x, i32 %y, i32 %z) {
|
||||
; TINY-NEXT: push r28
|
||||
; TINY-NEXT: push r29
|
||||
; TINY-NEXT: in r28, 61
|
||||
; TINY-NEXT: in r29, 62
|
||||
; TINY-NEXT: clr r29
|
||||
; TINY-NEXT: in r16, 63
|
||||
; TINY-NEXT: subi r28, 247
|
||||
; TINY-NEXT: sbci r29, 255
|
||||
@ -221,7 +221,7 @@ define i64 @return64_arg(i64 %x) {
|
||||
; TINY-NEXT: push r28
|
||||
; TINY-NEXT: push r29
|
||||
; TINY-NEXT: in r28, 61
|
||||
; TINY-NEXT: in r29, 62
|
||||
; TINY-NEXT: clr r29
|
||||
; TINY-NEXT: in r16, 63
|
||||
; TINY-NEXT: subi r28, 245
|
||||
; TINY-NEXT: sbci r29, 255
|
||||
@ -314,7 +314,7 @@ define i64 @return64_arg2(i64 %x, i64 %y, i64 %z) {
|
||||
; TINY-NEXT: push r28
|
||||
; TINY-NEXT: push r29
|
||||
; TINY-NEXT: in r28, 61
|
||||
; TINY-NEXT: in r29, 62
|
||||
; TINY-NEXT: clr r29
|
||||
; TINY-NEXT: in r16, 63
|
||||
; TINY-NEXT: subi r28, 229
|
||||
; TINY-NEXT: sbci r29, 255
|
||||
@ -403,7 +403,7 @@ define i32 @return64_trunc(i32 %a, i32 %b, i32 %c, i64 %d) {
|
||||
; TINY-NEXT: push r28
|
||||
; TINY-NEXT: push r29
|
||||
; TINY-NEXT: in r28, 61
|
||||
; TINY-NEXT: in r29, 62
|
||||
; TINY-NEXT: clr r29
|
||||
; TINY-NEXT: in r16, 63
|
||||
; TINY-NEXT: subi r28, 243
|
||||
; TINY-NEXT: sbci r29, 255
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user