Changeset View
Changeset View
Standalone View
Standalone View
llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
Show First 20 Lines • Show All 642 Lines • ▼ Show 20 Lines | bool AVRExpandPseudo::expand<AVR::LDSWRdK>(Block &MBB, BlockIt MBBI) { | ||||
return true; | return true; | ||||
} | } | ||||
template <> | template <> | ||||
bool AVRExpandPseudo::expand<AVR::LDWRdPtr>(Block &MBB, BlockIt MBBI) { | bool AVRExpandPseudo::expand<AVR::LDWRdPtr>(Block &MBB, BlockIt MBBI) { | ||||
MachineInstr &MI = *MBBI; | MachineInstr &MI = *MBBI; | ||||
Register DstLoReg, DstHiReg; | Register DstLoReg, DstHiReg; | ||||
Register DstReg = MI.getOperand(0).getReg(); | Register DstReg = MI.getOperand(0).getReg(); | ||||
Register TmpReg = 0; // 0 for no temporary register | |||||
Register SrcReg = MI.getOperand(1).getReg(); | Register SrcReg = MI.getOperand(1).getReg(); | ||||
bool SrcIsKill = MI.getOperand(1).isKill(); | bool SrcIsKill = MI.getOperand(1).isKill(); | ||||
unsigned OpLo = AVR::LDRdPtr; | unsigned OpLo = AVR::LDRdPtr; | ||||
unsigned OpHi = AVR::LDDRdPtrQ; | unsigned OpHi = AVR::LDDRdPtrQ; | ||||
TRI->splitReg(DstReg, DstLoReg, DstHiReg); | TRI->splitReg(DstReg, DstLoReg, DstHiReg); | ||||
// Use a temporary register if src and dst registers are the same. | // DstReg has an earlyclobber so the register allocator will allocate them in | ||||
if (DstReg == SrcReg) | // separate registers. | ||||
TmpReg = scavengeGPR8(MI); | assert(DstReg != SrcReg && "Dst and Src registers are the same!"); | ||||
Register CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg; | |||||
Register CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg; | |||||
// Load low byte. | // Load low byte. | ||||
auto MIBLO = buildMI(MBB, MBBI, OpLo) | buildMI(MBB, MBBI, OpLo) | ||||
.addReg(CurDstLoReg, RegState::Define) | .addReg(DstLoReg, RegState::Define) | ||||
.addReg(SrcReg); | .addReg(SrcReg) | ||||
.setMemRefs(MI.memoperands()); | |||||
// Push low byte onto stack if necessary. | |||||
if (TmpReg) | |||||
buildMI(MBB, MBBI, AVR::PUSHRr).addReg(TmpReg); | |||||
// Load high byte. | // Load high byte. | ||||
auto MIBHI = buildMI(MBB, MBBI, OpHi) | buildMI(MBB, MBBI, OpHi) | ||||
.addReg(CurDstHiReg, RegState::Define) | .addReg(DstHiReg, RegState::Define) | ||||
.addReg(SrcReg, getKillRegState(SrcIsKill)) | .addReg(SrcReg, getKillRegState(SrcIsKill)) | ||||
.addImm(1); | .addImm(1) | ||||
.setMemRefs(MI.memoperands()); | |||||
if (TmpReg) { | |||||
// Move the high byte into the final destination. | |||||
buildMI(MBB, MBBI, AVR::MOVRdRr, DstHiReg).addReg(TmpReg); | |||||
// Move the low byte from the scratch space into the final destination. | |||||
buildMI(MBB, MBBI, AVR::POPRd, DstLoReg); | |||||
} | |||||
MIBLO.setMemRefs(MI.memoperands()); | |||||
MIBHI.setMemRefs(MI.memoperands()); | |||||
MI.eraseFromParent(); | MI.eraseFromParent(); | ||||
return true; | return true; | ||||
} | } | ||||
template <> | template <> | ||||
bool AVRExpandPseudo::expand<AVR::LDWRdPtrPi>(Block &MBB, BlockIt MBBI) { | bool AVRExpandPseudo::expand<AVR::LDWRdPtrPi>(Block &MBB, BlockIt MBBI) { | ||||
MachineInstr &MI = *MBBI; | MachineInstr &MI = *MBBI; | ||||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | bool AVRExpandPseudo::expand<AVR::LDWRdPtrPd>(Block &MBB, BlockIt MBBI) { | ||||
return true; | return true; | ||||
} | } | ||||
template <> | template <> | ||||
bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(Block &MBB, BlockIt MBBI) { | bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(Block &MBB, BlockIt MBBI) { | ||||
MachineInstr &MI = *MBBI; | MachineInstr &MI = *MBBI; | ||||
Register DstLoReg, DstHiReg; | Register DstLoReg, DstHiReg; | ||||
Register DstReg = MI.getOperand(0).getReg(); | Register DstReg = MI.getOperand(0).getReg(); | ||||
Register TmpReg = 0; // 0 for no temporary register | |||||
Register SrcReg = MI.getOperand(1).getReg(); | Register SrcReg = MI.getOperand(1).getReg(); | ||||
unsigned Imm = MI.getOperand(2).getImm(); | unsigned Imm = MI.getOperand(2).getImm(); | ||||
bool SrcIsKill = MI.getOperand(1).isKill(); | bool SrcIsKill = MI.getOperand(1).isKill(); | ||||
unsigned OpLo = AVR::LDDRdPtrQ; | unsigned OpLo = AVR::LDDRdPtrQ; | ||||
unsigned OpHi = AVR::LDDRdPtrQ; | unsigned OpHi = AVR::LDDRdPtrQ; | ||||
TRI->splitReg(DstReg, DstLoReg, DstHiReg); | TRI->splitReg(DstReg, DstLoReg, DstHiReg); | ||||
// Since we add 1 to the Imm value for the high byte below, and 63 is the | // Since we add 1 to the Imm value for the high byte below, and 63 is the | ||||
// highest Imm value allowed for the instruction, 62 is the limit here. | // highest Imm value allowed for the instruction, 62 is the limit here. | ||||
assert(Imm <= 62 && "Offset is out of range"); | assert(Imm <= 62 && "Offset is out of range"); | ||||
// Use a temporary register if src and dst registers are the same. | // DstReg has an earlyclobber so the register allocator will allocate them in | ||||
if (DstReg == SrcReg) | // separate registers. | ||||
TmpReg = scavengeGPR8(MI); | assert(DstReg != SrcReg && "Dst and Src registers are the same!"); | ||||
Register CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg; | |||||
Register CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg; | |||||
// Load low byte. | // Load low byte. | ||||
auto MIBLO = buildMI(MBB, MBBI, OpLo) | buildMI(MBB, MBBI, OpLo) | ||||
.addReg(CurDstLoReg, RegState::Define) | .addReg(DstLoReg, RegState::Define) | ||||
.addReg(SrcReg) | .addReg(SrcReg) | ||||
.addImm(Imm); | .addImm(Imm) | ||||
.setMemRefs(MI.memoperands()); | |||||
// Push low byte onto stack if necessary. | |||||
if (TmpReg) | |||||
buildMI(MBB, MBBI, AVR::PUSHRr).addReg(TmpReg); | |||||
// Load high byte. | // Load high byte. | ||||
auto MIBHI = buildMI(MBB, MBBI, OpHi) | buildMI(MBB, MBBI, OpHi) | ||||
.addReg(CurDstHiReg, RegState::Define) | .addReg(DstHiReg, RegState::Define) | ||||
.addReg(SrcReg, getKillRegState(SrcIsKill)) | .addReg(SrcReg, getKillRegState(SrcIsKill)) | ||||
.addImm(Imm + 1); | .addImm(Imm + 1) | ||||
.setMemRefs(MI.memoperands()); | |||||
if (TmpReg) { | |||||
// Move the high byte into the final destination. | |||||
buildMI(MBB, MBBI, AVR::MOVRdRr, DstHiReg).addReg(TmpReg); | |||||
// Move the low byte from the scratch space into the final destination. | |||||
buildMI(MBB, MBBI, AVR::POPRd, DstLoReg); | |||||
} | |||||
MIBLO.setMemRefs(MI.memoperands()); | |||||
MIBHI.setMemRefs(MI.memoperands()); | |||||
MI.eraseFromParent(); | MI.eraseFromParent(); | ||||
return true; | return true; | ||||
} | } | ||||
bool AVRExpandPseudo::expandLPMWELPMW(Block &MBB, BlockIt MBBI, bool IsExt) { | bool AVRExpandPseudo::expandLPMWELPMW(Block &MBB, BlockIt MBBI, bool IsExt) { | ||||
MachineInstr &MI = *MBBI; | MachineInstr &MI = *MBBI; | ||||
Register DstLoReg, DstHiReg; | Register DstLoReg, DstHiReg; | ||||
▲ Show 20 Lines • Show All 1,690 Lines • Show Last 20 Lines |