1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 20:23:11 +01:00

[AVR] Optimize the 16-bit NEGW pseudo instruction

Reviewed By: dylanmckay

Differential Revision: https://reviews.llvm.org/D88658
This commit is contained in:
Ben Shi 2020-11-17 17:51:58 +08:00
parent db0b0dabe6
commit 2a099fbc14
4 changed files with 85 additions and 1 deletions

View File

@ -415,6 +415,44 @@ bool AVRExpandPseudo::expand<AVR::COMWRd>(Block &MBB, BlockIt MBBI) {
return true; return true;
} }
template <>
bool AVRExpandPseudo::expand<AVR::NEGWRd>(Block &MBB, BlockIt MBBI) {
MachineInstr &MI = *MBBI;
Register DstLoReg, DstHiReg;
Register DstReg = MI.getOperand(0).getReg();
bool DstIsDead = MI.getOperand(0).isDead();
bool DstIsKill = MI.getOperand(1).isKill();
bool ImpIsDead = MI.getOperand(2).isDead();
TRI->splitReg(DstReg, DstLoReg, DstHiReg);
// Do NEG on the upper byte.
auto MIBHI =
buildMI(MBB, MBBI, AVR::NEGRd)
.addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
.addReg(DstHiReg, getKillRegState(DstIsKill));
// SREG is always implicitly dead
MIBHI->getOperand(2).setIsDead();
// Do NEG on the lower byte.
buildMI(MBB, MBBI, AVR::NEGRd)
.addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
.addReg(DstLoReg, getKillRegState(DstIsKill));
// Do an extra SBCI.
auto MISBCI =
buildMI(MBB, MBBI, AVR::SBCIRdK)
.addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
.addReg(DstHiReg, getKillRegState(DstIsKill))
.addImm(0);
if (ImpIsDead)
MISBCI->getOperand(3).setIsDead();
// SREG is always implicitly killed
MISBCI->getOperand(4).setIsKill();
MI.eraseFromParent();
return true;
}
template <> template <>
bool AVRExpandPseudo::expand<AVR::CPWRdRr>(Block &MBB, BlockIt MBBI) { bool AVRExpandPseudo::expand<AVR::CPWRdRr>(Block &MBB, BlockIt MBBI) {
MachineInstr &MI = *MBBI; MachineInstr &MI = *MBBI;
@ -1616,6 +1654,7 @@ bool AVRExpandPseudo::expandMI(Block &MBB, BlockIt MBBI) {
EXPAND(AVR::ORIWRdK); EXPAND(AVR::ORIWRdK);
EXPAND(AVR::EORWRdRr); EXPAND(AVR::EORWRdRr);
EXPAND(AVR::COMWRd); EXPAND(AVR::COMWRd);
EXPAND(AVR::NEGWRd);
EXPAND(AVR::CPWRdRr); EXPAND(AVR::CPWRdRr);
EXPAND(AVR::CPCWRdRr); EXPAND(AVR::CPCWRdRr);
EXPAND(AVR::LDIWRdK); EXPAND(AVR::LDIWRdK);

View File

@ -732,13 +732,23 @@ Defs = [SREG] in
"comw\t$rd", "comw\t$rd",
[(set i16:$rd, (not i16:$src)), (implicit SREG)]>; [(set i16:$rd, (not i16:$src)), (implicit SREG)]>;
//:TODO: optimize NEG for wider types
def NEGRd : FRd<0b1001, def NEGRd : FRd<0b1001,
0b0100001, 0b0100001,
(outs GPR8:$rd), (outs GPR8:$rd),
(ins GPR8:$src), (ins GPR8:$src),
"neg\t$rd", "neg\t$rd",
[(set i8:$rd, (ineg i8:$src)), (implicit SREG)]>; [(set i8:$rd, (ineg i8:$src)), (implicit SREG)]>;
// NEGW Rd+1:Rd
//
// Expands to:
// neg Rd+1
// neg Rd
// sbci Rd+1, 0
def NEGWRd : Pseudo<(outs DREGS:$rd),
(ins DREGS:$src),
"negw\t$rd",
[(set i16:$rd, (ineg i16:$src)), (implicit SREG)]>;
} }
// TST Rd // TST Rd

View File

@ -6,3 +6,13 @@ define i8 @neg8(i8 %x) {
%sub = sub i8 0, %x %sub = sub i8 0, %x
ret i8 %sub ret i8 %sub
} }
define i16 @neg16(i16 %x) {
; CHECK-LABEL: neg16:
; CHECK: neg r25
; CHECK-next: neg r24
; CHECK-next: sbci r25, 0
; CHECK-next: ret
%sub = sub i16 0, %x
ret i16 %sub
}

View File

@ -0,0 +1,25 @@
# RUN: llc -O0 -run-pass=avr-expand-pseudo %s -o - | FileCheck %s
# This test checks the expansion of the 16-bit NEG pseudo instruction.
--- |
target triple = "avr--"
define void @test_negwrd() {
entry:
ret void
}
...
---
name: test_negwrd
body: |
bb.0.entry:
; CHECK-LABEL: test_negwrd
; CHECK: $r15 = NEGRd $r15, implicit-def dead $sreg
; CHECK-NEXT: $r14 = NEGRd $r14
; CHECK-NEXT: $r15 = SBCIRdK $r15, 0, implicit-def $sreg, implicit killed $sreg
$r15r14 = NEGWRd $r15r14, implicit-def $sreg
...