summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp35
-rw-r--r--llvm/test/MC/PowerPC/ppc64-fixup-apply.s6
2 files changed, 30 insertions, 11 deletions
diff --git a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
index ae24c8a88e6..d1664febd39 100644
--- a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
+++ b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
@@ -665,6 +665,29 @@ void PPCOperand::print(raw_ostream &OS) const {
}
}
+static void
+addNegOperand(MCInst &Inst, MCOperand &Op, MCContext &Ctx) {
+ if (Op.isImm()) {
+ Inst.addOperand(MCOperand::CreateImm(-Op.getImm()));
+ return;
+ }
+ const MCExpr *Expr = Op.getExpr();
+ if (const MCUnaryExpr *UnExpr = dyn_cast<MCUnaryExpr>(Expr)) {
+ if (UnExpr->getOpcode() == MCUnaryExpr::Minus) {
+ Inst.addOperand(MCOperand::CreateExpr(UnExpr->getSubExpr()));
+ return;
+ }
+ } else if (const MCBinaryExpr *BinExpr = dyn_cast<MCBinaryExpr>(Expr)) {
+ if (BinExpr->getOpcode() == MCBinaryExpr::Sub) {
+ const MCExpr *NE = MCBinaryExpr::CreateSub(BinExpr->getRHS(),
+ BinExpr->getLHS(), Ctx);
+ Inst.addOperand(MCOperand::CreateExpr(NE));
+ return;
+ }
+ }
+ Inst.addOperand(MCOperand::CreateExpr(MCUnaryExpr::CreateMinus(Expr, Ctx)));
+}
+
void PPCAsmParser::ProcessInstruction(MCInst &Inst,
const OperandVector &Operands) {
int Opcode = Inst.getOpcode();
@@ -680,41 +703,37 @@ void PPCAsmParser::ProcessInstruction(MCInst &Inst,
}
case PPC::SUBI: {
MCInst TmpInst;
- int64_t N = Inst.getOperand(2).getImm();
TmpInst.setOpcode(PPC::ADDI);
TmpInst.addOperand(Inst.getOperand(0));
TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(MCOperand::CreateImm(-N));
+ addNegOperand(TmpInst, Inst.getOperand(2), getContext());
Inst = TmpInst;
break;
}
case PPC::SUBIS: {
MCInst TmpInst;
- int64_t N = Inst.getOperand(2).getImm();
TmpInst.setOpcode(PPC::ADDIS);
TmpInst.addOperand(Inst.getOperand(0));
TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(MCOperand::CreateImm(-N));
+ addNegOperand(TmpInst, Inst.getOperand(2), getContext());
Inst = TmpInst;
break;
}
case PPC::SUBIC: {
MCInst TmpInst;
- int64_t N = Inst.getOperand(2).getImm();
TmpInst.setOpcode(PPC::ADDIC);
TmpInst.addOperand(Inst.getOperand(0));
TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(MCOperand::CreateImm(-N));
+ addNegOperand(TmpInst, Inst.getOperand(2), getContext());
Inst = TmpInst;
break;
}
case PPC::SUBICo: {
MCInst TmpInst;
- int64_t N = Inst.getOperand(2).getImm();
TmpInst.setOpcode(PPC::ADDICo);
TmpInst.addOperand(Inst.getOperand(0));
TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(MCOperand::CreateImm(-N));
+ addNegOperand(TmpInst, Inst.getOperand(2), getContext());
Inst = TmpInst;
break;
}
diff --git a/llvm/test/MC/PowerPC/ppc64-fixup-apply.s b/llvm/test/MC/PowerPC/ppc64-fixup-apply.s
index 16934052477..24bd83ffd18 100644
--- a/llvm/test/MC/PowerPC/ppc64-fixup-apply.s
+++ b/llvm/test/MC/PowerPC/ppc64-fixup-apply.s
@@ -14,13 +14,13 @@ addis 1, 1, target
.set target, 0x1234
-addi 1, 1, target2@l
-addis 1, 1, target2@ha
+subi 1, 1, -target2@l
+subis 1, 1, -target2@ha
.set target2, 0x12345678
addi 1, 1, target3-target4@l
-addis 1, 1, target3-target4@ha
+subis 1, 1, target4-target3@ha
.set target3, 0x23455678
.set target4, 0x12341234
OpenPOWER on IntegriCloud