X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FMips%2FMipsMCInstLower.cpp;h=85f78674661105670d4cd47b1be1e9d0d3954e47;hb=7ef85447c950ef801414251a2ce49d2564cbf5da;hp=d65e74d2c5366dbc6ba8811b32b53c4dfc9c0473;hpb=714313b4828cec98b086b54b356407540aa775c4;p=oota-llvm.git diff --git a/lib/Target/Mips/MipsMCInstLower.cpp b/lib/Target/Mips/MipsMCInstLower.cpp index d65e74d2c53..85f78674661 100644 --- a/lib/Target/Mips/MipsMCInstLower.cpp +++ b/lib/Target/Mips/MipsMCInstLower.cpp @@ -11,26 +11,24 @@ // 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" 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 +61,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 +73,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; @@ -149,78 +151,90 @@ MCOperand MipsMCInstLower::LowerOperand(const MachineOperand &MO, return MCOperand(); } -void MipsMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { - OutMI.setOpcode(MI->getOpcode()); +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); - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - const MachineOperand &MO = MI->getOperand(i); - MCOperand MCOp = LowerOperand(MO); + return MCOperand::CreateExpr(MipsMCExpr::Create(Kind, Sub, *Ctx)); +} - if (MCOp.isValid()) - OutMI.addOperand(MCOp); - } +void MipsMCInstLower:: +lowerLongBranchLUi(const MachineInstr *MI, MCInst &OutMI, int Opcode, + MCSymbolRefExpr::VariantKind Kind) const { + OutMI.setOpcode(Opcode); + + // Lower register operand. + OutMI.addOperand(LowerOperand(MI->getOperand(0))); + + // Create %hi($tgt-$baltgt) or %highest($tgt-$baltgt). + OutMI.addOperand(createSub(MI->getOperand(1).getMBB(), + MI->getOperand(2).getMBB(), Kind)); } -// 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)); +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), %hi($tgt-$baltgt) or %higher($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: - // 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; + return false; + case Mips::LONG_BRANCH_LUi: + lowerLongBranchLUi(MI, OutMI, Mips::LUi, MCSymbolRefExpr::VK_Mips_ABS_HI); + return true; + case Mips::LONG_BRANCH_LUi64: + lowerLongBranchLUi(MI, OutMI, Mips::LUi64, + MCSymbolRefExpr::VK_Mips_HIGHEST); + 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_HIGHER) + lowerLongBranchADDiu(MI, OutMI, Mips::DADDiu, + MCSymbolRefExpr::VK_Mips_HIGHER); + else 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; } } -// Pick a DEXT instruction variant based on the pos and size operands -void MipsMCInstLower::LowerDEXT(const MachineInstr *MI, MCInst& Inst) { - - assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands for DEXT!"); - assert(MI->getOperand(2).isImm()); - int64_t pos = MI->getOperand(2).getImm(); - assert(MI->getOperand(3).isImm()); - int64_t size = MI->getOperand(3).getImm(); - - // rt - Inst.addOperand(LowerOperand(MI->getOperand(0))); - // rs - Inst.addOperand(LowerOperand(MI->getOperand(1))); - - // DEXT - if ((pos < 32) && (size <= 32)) { - Inst.addOperand(MCOperand::CreateImm(pos)); - Inst.addOperand(MCOperand::CreateImm(size)); - Inst.setOpcode(Mips::DEXT); - } - // DEXTU - else if ((pos < 64) && (size <= 32)) { - Inst.addOperand(MCOperand::CreateImm(pos - 32)); - Inst.addOperand(MCOperand::CreateImm(size)); - Inst.setOpcode(Mips::DEXTU); - } - // DEXTM - else { - Inst.addOperand(MCOperand::CreateImm(pos)); - Inst.addOperand(MCOperand::CreateImm(size - 32)); - Inst.setOpcode(Mips::DEXTM); +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) { + const MachineOperand &MO = MI->getOperand(i); + MCOperand MCOp = LowerOperand(MO); + + if (MCOp.isValid()) + OutMI.addOperand(MCOp); } - return; } +