| Index: lib/Target/Mips/MipsMCInstLower.cpp
|
| diff --git a/lib/Target/Mips/MipsMCInstLower.cpp b/lib/Target/Mips/MipsMCInstLower.cpp
|
| index d836975eb7d227a972350120aee3e0c5a6926d8a..91eddc1bdacdc520b47196daa77435141f139e3c 100644
|
| --- a/lib/Target/Mips/MipsMCInstLower.cpp
|
| +++ b/lib/Target/Mips/MipsMCInstLower.cpp
|
| @@ -21,6 +21,10 @@
|
| #include "llvm/MC/MCContext.h"
|
| #include "llvm/MC/MCExpr.h"
|
| #include "llvm/MC/MCInst.h"
|
| +// @LOCALMOD-START
|
| +#include "llvm/MC/MCELFStreamer.h"
|
| +#include "llvm/MC/MCSymbol.h"
|
| +// @LOCALMOD-END
|
| #include "llvm/Target/Mangler.h"
|
|
|
| using namespace llvm;
|
| @@ -152,7 +156,81 @@ MCOperand MipsMCInstLower::LowerOperand(const MachineOperand &MO,
|
| return MCOperand();
|
| }
|
|
|
| +// @LOCALMOD-START
|
| +
|
| +// TempSymbol cannot be member of MipsMCInstLower since Lower methods are const.
|
| +static MCSymbol *TempSymbol = NULL;
|
| +
|
| +void MipsMCInstLower::LowerNaClLongBranchLUi(const MachineInstr *MI,
|
| + MCInst &OutMI) const {
|
| + OutMI.setOpcode(Mips::LUi);
|
| +
|
| + // Lower register operand.
|
| + MCOperand Reg = LowerOperand(MI->getOperand(0));
|
| + if (Reg.isValid())
|
| + OutMI.addOperand(Reg);
|
| +
|
| + // Create %hi($tgt-$baltgt). Since Mips backend currently doesn't support
|
| + // %hi(sym1-sym2) expressions, we first create temp symbol
|
| + // tmp = $tgt-$baltgt, and then create %hi(tmp) expression.
|
| + const MCSymbol *Symbol1 = MI->getOperand(1).getMBB()->getSymbol();
|
| + const MCSymbolRefExpr *MCSym1 = MCSymbolRefExpr::Create(Symbol1, *Ctx);
|
| + const MCSymbol *Symbol2 = MI->getOperand(2).getMBB()->getSymbol();
|
| + const MCSymbolRefExpr *MCSym2 = MCSymbolRefExpr::Create(Symbol2, *Ctx);
|
| +
|
| + assert(TempSymbol == NULL);
|
| + TempSymbol = Ctx->CreateTempSymbol();
|
| + TempSymbol->setVariableValue(MCBinaryExpr::CreateSub(MCSym1, MCSym2, *Ctx));
|
| +
|
| + const MCSymbolRefExpr *TempHi = MCSymbolRefExpr::Create(TempSymbol,
|
| + MCSymbolRefExpr::VK_Mips_ABS_HI, *Ctx);
|
| + OutMI.addOperand(MCOperand::CreateExpr(TempHi));
|
| +
|
| + if (AsmPrinter.OutStreamer.hasRawTextSupport()) {
|
| + // For .s files, emit directive ".set $tmp, $tgt-$baltgt"
|
| + AsmPrinter.OutStreamer.EmitRawText(StringRef("\t.set\t")
|
| + + TempSymbol->getName()
|
| + + StringRef(", ")
|
| + + Symbol1->getName()
|
| + + StringRef("-")
|
| + + Symbol2->getName());
|
| + }
|
| +}
|
| +
|
| +void MipsMCInstLower::LowerNaClLongBranchADDiu(const MachineInstr *MI,
|
| + MCInst &OutMI) const {
|
| + OutMI.setOpcode(Mips::ADDiu);
|
| +
|
| + // Lower two register operands.
|
| + for (unsigned i = 0, e = 2; i != e; ++i) {
|
| + const MachineOperand &MO = MI->getOperand(i);
|
| + MCOperand Reg = LowerOperand(MO);
|
| +
|
| + if (Reg.isValid())
|
| + OutMI.addOperand(Reg);
|
| + }
|
| +
|
| + // Create %lo($tgt-$baltgt). See the comment above for %hi version.
|
| + assert(TempSymbol != NULL);
|
| + const MCSymbolRefExpr *TempLo = MCSymbolRefExpr::Create(TempSymbol,
|
| + MCSymbolRefExpr::VK_Mips_ABS_LO, *Ctx);
|
| + OutMI.addOperand(MCOperand::CreateExpr(TempLo));
|
| + TempSymbol = NULL;
|
| +}
|
| +// @LOCALMOD-END
|
| +
|
| void MipsMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
|
| + // @LOCALMOD-START
|
| + if (MI->getOpcode() == Mips::NACL_LONG_BRANCH_LUi) {
|
| + LowerNaClLongBranchLUi(MI, OutMI);
|
| + return;
|
| + }
|
| + if (MI->getOpcode() == Mips::NACL_LONG_BRANCH_ADDiu) {
|
| + LowerNaClLongBranchADDiu(MI, OutMI);
|
| + return;
|
| + }
|
| + // @LOCALMOD-END
|
| +
|
| OutMI.setOpcode(MI->getOpcode());
|
|
|
| for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
|
|