mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 20:23:11 +01:00
[AVR] Fix rotate instructions
This patch fixes some issues with the RORB pseudo instruction. - A minor issue in which the instructions were said to use the SREG, which is not true. - An issue with the BLD instruction, which did not have an output operand. - A major issue in which invalid instructions were generated. The fix also reduce RORB from 4 to 3 instructions, so it's also a small optimization. These issues were flagged by the machine verifier. Differential Revision: https://reviews.llvm.org/D96957
This commit is contained in:
parent
1bf9d7e37d
commit
8ded1a7aa8
@ -1345,42 +1345,20 @@ bool AVRExpandPseudo::expand<AVR::RORBRd>(Block &MBB, BlockIt MBBI) {
|
|||||||
// to explicitly add the carry bit.
|
// to explicitly add the carry bit.
|
||||||
|
|
||||||
MachineInstr &MI = *MBBI;
|
MachineInstr &MI = *MBBI;
|
||||||
unsigned OpShiftOut, OpLoad, OpShiftIn, OpAdd;
|
|
||||||
Register DstReg = MI.getOperand(0).getReg();
|
Register DstReg = MI.getOperand(0).getReg();
|
||||||
bool DstIsDead = MI.getOperand(0).isDead();
|
|
||||||
OpShiftOut = AVR::LSRRd;
|
|
||||||
OpLoad = AVR::LDIRdK;
|
|
||||||
OpShiftIn = AVR::RORRd;
|
|
||||||
OpAdd = AVR::ORRdRr;
|
|
||||||
|
|
||||||
// lsr r16
|
// bst r16, 0
|
||||||
// ldi r0, 0
|
// ror r16
|
||||||
// ror r0
|
// bld r16, 7
|
||||||
// or r16, r17
|
|
||||||
|
|
||||||
// Shift out
|
// Move the lowest bit from DstReg into the T bit
|
||||||
buildMI(MBB, MBBI, OpShiftOut)
|
buildMI(MBB, MBBI, AVR::BST).addReg(DstReg).addImm(0);
|
||||||
.addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
|
|
||||||
.addReg(DstReg);
|
|
||||||
|
|
||||||
// Put 0 in temporary register
|
// Rotate to the right
|
||||||
buildMI(MBB, MBBI, OpLoad)
|
buildMI(MBB, MBBI, AVR::RORRd, DstReg).addReg(DstReg);
|
||||||
.addReg(SCRATCH_REGISTER, RegState::Define | getDeadRegState(true))
|
|
||||||
.addImm(0x00);
|
|
||||||
|
|
||||||
// Shift in
|
// Move the T bit into the highest bit of DstReg.
|
||||||
buildMI(MBB, MBBI, OpShiftIn)
|
buildMI(MBB, MBBI, AVR::BLD, DstReg).addReg(DstReg).addImm(7);
|
||||||
.addReg(SCRATCH_REGISTER, RegState::Define | getDeadRegState(true))
|
|
||||||
.addReg(SCRATCH_REGISTER);
|
|
||||||
|
|
||||||
// Add the results together using an or-instruction
|
|
||||||
auto MIB = buildMI(MBB, MBBI, OpAdd)
|
|
||||||
.addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
|
|
||||||
.addReg(DstReg)
|
|
||||||
.addReg(SCRATCH_REGISTER);
|
|
||||||
|
|
||||||
// SREG is always implicitly killed
|
|
||||||
MIB->getOperand(2).setIsKill();
|
|
||||||
|
|
||||||
MI.eraseFromParent();
|
MI.eraseFromParent();
|
||||||
return true;
|
return true;
|
||||||
|
@ -1735,20 +1735,19 @@ Defs = [SREG] in
|
|||||||
"asrw\t$rd",
|
"asrw\t$rd",
|
||||||
[(set i16:$rd, (AVRasr i16:$src)), (implicit SREG)]>;
|
[(set i16:$rd, (AVRasr i16:$src)), (implicit SREG)]>;
|
||||||
|
|
||||||
|
def ROLBRd : Pseudo<(outs GPR8:$rd),
|
||||||
|
(ins GPR8:$src),
|
||||||
|
"rolb\t$rd",
|
||||||
|
[(set i8:$rd, (AVRrol i8:$src)), (implicit SREG)]>;
|
||||||
|
|
||||||
|
def RORBRd : Pseudo<(outs GPR8:$rd),
|
||||||
|
(ins GPR8:$src),
|
||||||
|
"rorb\t$rd",
|
||||||
|
[(set i8:$rd, (AVRror i8:$src)), (implicit SREG)]>;
|
||||||
|
|
||||||
// Bit rotate operations.
|
// Bit rotate operations.
|
||||||
let Uses = [SREG] in
|
let Uses = [SREG] in
|
||||||
{
|
{
|
||||||
// 8-bit ROL is an alias of ADC Rd, Rd
|
|
||||||
|
|
||||||
def ROLBRd : Pseudo<(outs GPR8:$rd),
|
|
||||||
(ins GPR8:$src),
|
|
||||||
"rolb\t$rd",
|
|
||||||
[(set i8:$rd, (AVRrol i8:$src)), (implicit SREG)]>;
|
|
||||||
|
|
||||||
def RORBRd : Pseudo<(outs GPR8:$rd),
|
|
||||||
(ins GPR8:$src),
|
|
||||||
"rorb\t$rd",
|
|
||||||
[(set i8:$rd, (AVRror i8:$src)), (implicit SREG)]>;
|
|
||||||
|
|
||||||
def ROLWRd : Pseudo<(outs DREGS:$rd),
|
def ROLWRd : Pseudo<(outs DREGS:$rd),
|
||||||
(ins DREGS:$src),
|
(ins DREGS:$src),
|
||||||
@ -1804,10 +1803,11 @@ def BST : FRdB<0b01,
|
|||||||
"bst\t$rd, $b",
|
"bst\t$rd, $b",
|
||||||
[]>;
|
[]>;
|
||||||
|
|
||||||
let Uses = [SREG] in
|
let Constraints = "$src = $rd",
|
||||||
|
Uses = [SREG] in
|
||||||
def BLD : FRdB<0b00,
|
def BLD : FRdB<0b00,
|
||||||
(outs),
|
(outs GPR8:$rd),
|
||||||
(ins GPR8:$rd, i8imm:$b),
|
(ins GPR8:$src, i8imm:$b),
|
||||||
"bld\t$rd, $b",
|
"bld\t$rd, $b",
|
||||||
[]>;
|
[]>;
|
||||||
|
|
||||||
|
@ -37,10 +37,9 @@ define i8 @ror8(i8 %val, i8 %amt) {
|
|||||||
; CHECK-NEXT: brmi .LBB1_2
|
; CHECK-NEXT: brmi .LBB1_2
|
||||||
|
|
||||||
; CHECK-NEXT: .LBB1_1:
|
; CHECK-NEXT: .LBB1_1:
|
||||||
; CHECK-NEXT: lsr r24
|
; CHECK-NEXT: bst r24, 0
|
||||||
; CHECK-NEXT: ldi r0, 0
|
; CHECK-NEXT: ror r24
|
||||||
; CHECK-NEXT: ror r0
|
; CHECK-NEXT: bld r24, 7
|
||||||
; CHECK-NEXT: or r24, r0
|
|
||||||
; CHECK-NEXT: dec r22
|
; CHECK-NEXT: dec r22
|
||||||
; CHECK-NEXT: brpl .LBB1_1
|
; CHECK-NEXT: brpl .LBB1_1
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user