mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-24 22:24:54 +00:00
Expand .cprestore directive to multiple instructions if the offset does not fit
in a 16-bit field. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146469 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -96,19 +96,17 @@ void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
|||||||
|
|
||||||
if (!OutStreamer.hasRawTextSupport()) {
|
if (!OutStreamer.hasRawTextSupport()) {
|
||||||
// Lower CPLOAD and CPRESTORE
|
// Lower CPLOAD and CPRESTORE
|
||||||
if (Opc == Mips::CPLOAD) {
|
if (Opc == Mips::CPLOAD)
|
||||||
MCInstLowering.LowerCPLOAD(MI, MCInsts);
|
MCInstLowering.LowerCPLOAD(MI, MCInsts);
|
||||||
for (SmallVector<MCInst, 4>::iterator I = MCInsts.begin(); I
|
else if (Opc == Mips::CPRESTORE)
|
||||||
!= MCInsts.end(); ++I)
|
MCInstLowering.LowerCPRESTORE(MI, MCInsts);
|
||||||
|
|
||||||
|
if (!MCInsts.empty()) {
|
||||||
|
for (SmallVector<MCInst, 4>::iterator I = MCInsts.begin();
|
||||||
|
I != MCInsts.end(); ++I)
|
||||||
OutStreamer.EmitInstruction(*I);
|
OutStreamer.EmitInstruction(*I);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Opc == Mips::CPRESTORE) {
|
|
||||||
MCInstLowering.LowerCPRESTORE(MI, TmpInst0);
|
|
||||||
OutStreamer.EmitInstruction(TmpInst0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OutStreamer.EmitInstruction(TmpInst0);
|
OutStreamer.EmitInstruction(TmpInst0);
|
||||||
|
@@ -137,14 +137,35 @@ void MipsMCInstLower::LowerCPLOAD(const MachineInstr *MI,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Lower ".cprestore offset" to "sw $gp, offset($sp)".
|
// Lower ".cprestore offset" to "sw $gp, offset($sp)".
|
||||||
void MipsMCInstLower::LowerCPRESTORE(const MachineInstr *MI, MCInst &OutMI) {
|
void MipsMCInstLower::LowerCPRESTORE(const MachineInstr *MI,
|
||||||
OutMI.clear();
|
SmallVector<MCInst, 4>& MCInsts) {
|
||||||
OutMI.setOpcode(Mips::SW);
|
|
||||||
OutMI.addOperand(MCOperand::CreateReg(Mips::GP));
|
|
||||||
OutMI.addOperand(MCOperand::CreateReg(Mips::SP));
|
|
||||||
const MachineOperand &MO = MI->getOperand(0);
|
const MachineOperand &MO = MI->getOperand(0);
|
||||||
assert(MO.isImm() && "CPRESTORE's operand must be an immediate.");
|
assert(MO.isImm() && "CPRESTORE's operand must be an immediate.");
|
||||||
OutMI.addOperand(MCOperand::CreateImm(MO.getImm()));
|
unsigned Offset = MO.getImm(), Reg = Mips::SP;
|
||||||
|
MCInst Sw;
|
||||||
|
|
||||||
|
if (Offset >= 0x8000) {
|
||||||
|
unsigned Hi = (Offset >> 16) + ((Offset & 0x8000) != 0);
|
||||||
|
Offset &= 0xffff;
|
||||||
|
Reg = Mips::AT;
|
||||||
|
|
||||||
|
// lui at,hi
|
||||||
|
// addu at,at,sp
|
||||||
|
MCInsts.resize(2);
|
||||||
|
MCInsts[0].setOpcode(Mips::LUi);
|
||||||
|
MCInsts[0].addOperand(MCOperand::CreateReg(Mips::AT));
|
||||||
|
MCInsts[0].addOperand(MCOperand::CreateImm(Hi));
|
||||||
|
MCInsts[1].setOpcode(Mips::ADDu);
|
||||||
|
MCInsts[1].addOperand(MCOperand::CreateReg(Mips::AT));
|
||||||
|
MCInsts[1].addOperand(MCOperand::CreateReg(Mips::AT));
|
||||||
|
MCInsts[1].addOperand(MCOperand::CreateReg(Mips::SP));
|
||||||
|
}
|
||||||
|
|
||||||
|
Sw.setOpcode(Mips::SW);
|
||||||
|
Sw.addOperand(MCOperand::CreateReg(Mips::GP));
|
||||||
|
Sw.addOperand(MCOperand::CreateReg(Reg));
|
||||||
|
Sw.addOperand(MCOperand::CreateImm(Offset));
|
||||||
|
MCInsts.push_back(Sw);
|
||||||
}
|
}
|
||||||
|
|
||||||
MCOperand MipsMCInstLower::LowerOperand(const MachineOperand& MO,
|
MCOperand MipsMCInstLower::LowerOperand(const MachineOperand& MO,
|
||||||
|
@@ -36,7 +36,7 @@ public:
|
|||||||
MipsAsmPrinter &asmprinter);
|
MipsAsmPrinter &asmprinter);
|
||||||
void Lower(const MachineInstr *MI, MCInst &OutMI) const;
|
void Lower(const MachineInstr *MI, MCInst &OutMI) const;
|
||||||
void LowerCPLOAD(const MachineInstr *MI, SmallVector<MCInst, 4>& MCInsts);
|
void LowerCPLOAD(const MachineInstr *MI, SmallVector<MCInst, 4>& MCInsts);
|
||||||
void LowerCPRESTORE(const MachineInstr *MI, MCInst &OutMI);
|
void LowerCPRESTORE(const MachineInstr *MI, SmallVector<MCInst, 4>& MCInsts);
|
||||||
void LowerUnalignedLoadStore(const MachineInstr *MI,
|
void LowerUnalignedLoadStore(const MachineInstr *MI,
|
||||||
SmallVector<MCInst, 4>& MCInsts);
|
SmallVector<MCInst, 4>& MCInsts);
|
||||||
private:
|
private:
|
||||||
|
Reference in New Issue
Block a user