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) { |