X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FMips%2FMipsMCInstLower.cpp;h=9e611804376bab2d562ca67c00e8204010e0078f;hb=bd75a9292e761dcab32855e322d9985d7d787d1e;hp=d4c5e6dd74cf07bf669303004e40dec4424d2ef1;hpb=b22c9289b0dd8255f63038e9bb8229111eb082ae;p=oota-llvm.git diff --git a/lib/Target/Mips/MipsMCInstLower.cpp b/lib/Target/Mips/MipsMCInstLower.cpp index d4c5e6dd74c..9e611804376 100644 --- a/lib/Target/Mips/MipsMCInstLower.cpp +++ b/lib/Target/Mips/MipsMCInstLower.cpp @@ -11,26 +11,25 @@ // MCInst records. // //===----------------------------------------------------------------------===// - #include "MipsMCInstLower.h" +#include "MCTargetDesc/MipsBaseInfo.h" #include "MipsAsmPrinter.h" #include "MipsInstrInfo.h" -#include "MCTargetDesc/MipsBaseInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineOperand.h" +#include "llvm/IR/Mangler.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" -#include "llvm/Target/Mangler.h" +#include "llvm/MC/MCStreamer.h" using namespace llvm; MipsMCInstLower::MipsMCInstLower(MipsAsmPrinter &asmprinter) : AsmPrinter(asmprinter) {} -void MipsMCInstLower::Initialize(Mangler *M, MCContext *C) { - Mang = M; +void MipsMCInstLower::Initialize(MCContext *C) { Ctx = C; } @@ -63,6 +62,10 @@ MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO, case MipsII::MO_GOT_OFST: Kind = MCSymbolRefExpr::VK_Mips_GOT_OFST; break; case MipsII::MO_HIGHER: Kind = MCSymbolRefExpr::VK_Mips_HIGHER; break; case MipsII::MO_HIGHEST: Kind = MCSymbolRefExpr::VK_Mips_HIGHEST; break; + case MipsII::MO_GOT_HI16: Kind = MCSymbolRefExpr::VK_Mips_GOT_HI16; break; + case MipsII::MO_GOT_LO16: Kind = MCSymbolRefExpr::VK_Mips_GOT_LO16; break; + case MipsII::MO_CALL_HI16: Kind = MCSymbolRefExpr::VK_Mips_CALL_HI16; break; + case MipsII::MO_CALL_LO16: Kind = MCSymbolRefExpr::VK_Mips_CALL_LO16; break; } switch (MOTy) { @@ -71,7 +74,7 @@ MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO, break; case MachineOperand::MO_GlobalAddress: - Symbol = Mang->getSymbol(MO.getGlobal()); + Symbol = AsmPrinter.getSymbol(MO.getGlobal()); Offset += MO.getOffset(); break; @@ -101,14 +104,14 @@ MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO, const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Symbol, Kind, *Ctx); if (!Offset) - return MCOperand::CreateExpr(MCSym); + return MCOperand::createExpr(MCSym); // Assume offset is never negative. assert(Offset > 0); const MCConstantExpr *OffsetExpr = MCConstantExpr::Create(Offset, *Ctx); const MCBinaryExpr *Add = MCBinaryExpr::CreateAdd(MCSym, OffsetExpr, *Ctx); - return MCOperand::CreateExpr(Add); + return MCOperand::createExpr(Add); } /* @@ -132,9 +135,9 @@ MCOperand MipsMCInstLower::LowerOperand(const MachineOperand &MO, case MachineOperand::MO_Register: // Ignore all implicit register operands. if (MO.isImplicit()) break; - return MCOperand::CreateReg(MO.getReg()); + return MCOperand::createReg(MO.getReg()); case MachineOperand::MO_Immediate: - return MCOperand::CreateImm(MO.getImm() + offset); + return MCOperand::createImm(MO.getImm() + offset); case MachineOperand::MO_MachineBasicBlock: case MachineOperand::MO_GlobalAddress: case MachineOperand::MO_ExternalSymbol: @@ -149,7 +152,75 @@ MCOperand MipsMCInstLower::LowerOperand(const MachineOperand &MO, return MCOperand(); } +MCOperand MipsMCInstLower::createSub(MachineBasicBlock *BB1, + MachineBasicBlock *BB2, + MCSymbolRefExpr::VariantKind Kind) const { + const MCSymbolRefExpr *Sym1 = MCSymbolRefExpr::Create(BB1->getSymbol(), *Ctx); + const MCSymbolRefExpr *Sym2 = MCSymbolRefExpr::Create(BB2->getSymbol(), *Ctx); + const MCBinaryExpr *Sub = MCBinaryExpr::CreateSub(Sym1, Sym2, *Ctx); + + return MCOperand::createExpr(MipsMCExpr::Create(Kind, Sub, *Ctx)); +} + +void MipsMCInstLower:: +lowerLongBranchLUi(const MachineInstr *MI, MCInst &OutMI) const { + OutMI.setOpcode(Mips::LUi); + + // Lower register operand. + OutMI.addOperand(LowerOperand(MI->getOperand(0))); + + // Create %hi($tgt-$baltgt). + OutMI.addOperand(createSub(MI->getOperand(1).getMBB(), + MI->getOperand(2).getMBB(), + MCSymbolRefExpr::VK_Mips_ABS_HI)); +} + +void MipsMCInstLower:: +lowerLongBranchADDiu(const MachineInstr *MI, MCInst &OutMI, int Opcode, + MCSymbolRefExpr::VariantKind Kind) const { + OutMI.setOpcode(Opcode); + + // Lower two register operands. + for (unsigned I = 0, E = 2; I != E; ++I) { + const MachineOperand &MO = MI->getOperand(I); + OutMI.addOperand(LowerOperand(MO)); + } + + // Create %lo($tgt-$baltgt) or %hi($tgt-$baltgt). + OutMI.addOperand(createSub(MI->getOperand(2).getMBB(), + MI->getOperand(3).getMBB(), Kind)); +} + +bool MipsMCInstLower::lowerLongBranch(const MachineInstr *MI, + MCInst &OutMI) const { + switch (MI->getOpcode()) { + default: + return false; + case Mips::LONG_BRANCH_LUi: + lowerLongBranchLUi(MI, OutMI); + return true; + case Mips::LONG_BRANCH_ADDiu: + lowerLongBranchADDiu(MI, OutMI, Mips::ADDiu, + MCSymbolRefExpr::VK_Mips_ABS_LO); + return true; + case Mips::LONG_BRANCH_DADDiu: + unsigned TargetFlags = MI->getOperand(2).getTargetFlags(); + if (TargetFlags == MipsII::MO_ABS_HI) + lowerLongBranchADDiu(MI, OutMI, Mips::DADDiu, + MCSymbolRefExpr::VK_Mips_ABS_HI); + else if (TargetFlags == MipsII::MO_ABS_LO) + lowerLongBranchADDiu(MI, OutMI, Mips::DADDiu, + MCSymbolRefExpr::VK_Mips_ABS_LO); + else + report_fatal_error("Unexpected flags for LONG_BRANCH_DADDiu"); + return true; + } +} + void MipsMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { + if (lowerLongBranch(MI, OutMI)) + return; + OutMI.setOpcode(MI->getOpcode()); for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { @@ -161,31 +232,3 @@ void MipsMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { } } -// If the D instruction has a shift amount that is greater -// than 31 (checked in calling routine), lower it to a D32 instruction -void MipsMCInstLower::LowerLargeShift(const MachineInstr *MI, - MCInst& Inst, - int64_t Shift) { - // rt - Inst.addOperand(LowerOperand(MI->getOperand(0))); - // rd - Inst.addOperand(LowerOperand(MI->getOperand(1))); - // saminus32 - Inst.addOperand(MCOperand::CreateImm(Shift)); - - switch (MI->getOpcode()) { - default: - // Calling function is not synchronized - llvm_unreachable("Unexpected shift instruction"); - break; - case Mips::DSLL: - Inst.setOpcode(Mips::DSLL32); - break; - case Mips::DSRL: - Inst.setOpcode(Mips::DSRL32); - break; - case Mips::DSRA: - Inst.setOpcode(Mips::DSRA32); - break; - } -}