// to explicitly add the carry bit.
MachineInstr &MI = *MBBI;
- unsigned OpShiftOut, OpLoad, OpShiftIn, OpAdd;
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
- // ldi r0, 0
- // ror r0
- // or r16, r17
-
- // Shift out
- buildMI(MBB, MBBI, OpShiftOut)
- .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
- .addReg(DstReg);
- // Put 0 in temporary register
- buildMI(MBB, MBBI, OpLoad)
- .addReg(SCRATCH_REGISTER, RegState::Define | getDeadRegState(true))
- .addImm(0x00);
+ // bst r16, 0
+ // ror r16
+ // bld r16, 7
- // Shift in
- buildMI(MBB, MBBI, OpShiftIn)
- .addReg(SCRATCH_REGISTER, RegState::Define | getDeadRegState(true))
- .addReg(SCRATCH_REGISTER);
+ // Move the lowest bit from DstReg into the T bit
+ buildMI(MBB, MBBI, AVR::BST).addReg(DstReg).addImm(0);
- // 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);
+ // Rotate to the right
+ buildMI(MBB, MBBI, AVR::RORRd, DstReg).addReg(DstReg);
- // SREG is always implicitly killed
- MIB->getOperand(2).setIsKill();
+ // Move the T bit into the highest bit of DstReg.
+ buildMI(MBB, MBBI, AVR::BLD, DstReg).addReg(DstReg).addImm(7);
MI.eraseFromParent();
return true;
"asrw\t$rd",
[(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.
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),
(ins DREGS:$src),
"bst\t$rd, $b",
[]>;
-let Uses = [SREG] in
+let Constraints = "$src = $rd",
+Uses = [SREG] in
def BLD : FRdB<0b00,
- (outs),
- (ins GPR8:$rd, i8imm:$b),
+ (outs GPR8:$rd),
+ (ins GPR8:$src, i8imm:$b),
"bld\t$rd, $b",
[]>;
; CHECK-NEXT: brmi .LBB1_2
; CHECK-NEXT: .LBB1_1:
- ; CHECK-NEXT: lsr r24
- ; CHECK-NEXT: ldi r0, 0
- ; CHECK-NEXT: ror r0
- ; CHECK-NEXT: or r24, r0
+ ; CHECK-NEXT: bst r24, 0
+ ; CHECK-NEXT: ror r24
+ ; CHECK-NEXT: bld r24, 7
; CHECK-NEXT: dec r22
; CHECK-NEXT: brpl .LBB1_1