mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +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:
parent
db0b0dabe6
commit
2a099fbc14
@ -415,6 +415,44 @@ bool AVRExpandPseudo::expand<AVR::COMWRd>(Block &MBB, BlockIt MBBI) {
|
||||
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 <>
|
||||
bool AVRExpandPseudo::expand<AVR::CPWRdRr>(Block &MBB, BlockIt MBBI) {
|
||||
MachineInstr &MI = *MBBI;
|
||||
@ -1616,6 +1654,7 @@ bool AVRExpandPseudo::expandMI(Block &MBB, BlockIt MBBI) {
|
||||
EXPAND(AVR::ORIWRdK);
|
||||
EXPAND(AVR::EORWRdRr);
|
||||
EXPAND(AVR::COMWRd);
|
||||
EXPAND(AVR::NEGWRd);
|
||||
EXPAND(AVR::CPWRdRr);
|
||||
EXPAND(AVR::CPCWRdRr);
|
||||
EXPAND(AVR::LDIWRdK);
|
||||
|
@ -732,13 +732,23 @@ Defs = [SREG] in
|
||||
"comw\t$rd",
|
||||
[(set i16:$rd, (not i16:$src)), (implicit SREG)]>;
|
||||
|
||||
//:TODO: optimize NEG for wider types
|
||||
def NEGRd : FRd<0b1001,
|
||||
0b0100001,
|
||||
(outs GPR8:$rd),
|
||||
(ins GPR8:$src),
|
||||
"neg\t$rd",
|
||||
[(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
|
||||
|
@ -6,3 +6,13 @@ define i8 @neg8(i8 %x) {
|
||||
%sub = sub i8 0, %x
|
||||
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
|
||||
}
|
||||
|
25
test/CodeGen/AVR/pseudo/NEGWRd.mir
Normal file
25
test/CodeGen/AVR/pseudo/NEGWRd.mir
Normal 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
|
||||
...
|
Loading…
Reference in New Issue
Block a user