[llvm-commits] [llvm] r122663 - in /llvm/trunk/lib/Target/ARM: ARMAsmPrinter.cpp ARMAsmPrinter.h ARMISelDAGToDAG.cpp ARMInstrInfo.td
Anton Korobeynikov
asl at math.spbu.ru
Sat Jan 1 12:38:38 PST 2011
Author: asl
Date: Sat Jan 1 14:38:38 2011
New Revision: 122663
URL: http://llvm.org/viewvc/llvm-project?rev=122663&view=rev
Log:
Model operand restrictions of mul-like instructions on ARMv5 via
earlyclobber stuff. This should fix PRs 2313 and 8157.
Unfortunately, no testcase, since it'd be dependent on register
assignments.
Modified:
llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp
llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h
llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp?rev=122663&r1=122662&r2=122663&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp Sat Jan 1 14:38:38 2011
@@ -725,6 +725,16 @@
Inst.addOperand(MCOperand::CreateReg(ccreg));
}
+void ARMAsmPrinter::EmitPatchedInstruction(const MachineInstr *MI,
+ unsigned Opcode) {
+ MCInst TmpInst;
+
+ // Emit the instruction as usual, just patch the opcode.
+ LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
+ TmpInst.setOpcode(Opcode);
+ OutStreamer.EmitInstruction(TmpInst);
+}
+
void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
switch (MI->getOpcode()) {
default: break;
@@ -1376,6 +1386,30 @@
}
return;
}
+ // These are the pseudos created to comply with stricter operand restrictions
+ // on ARMv5. Lower them now to "normal" instructions, since all the
+ // restrictions are already satisfied.
+ case ARM::MULv5:
+ EmitPatchedInstruction(MI, ARM::MUL);
+ return;
+ case ARM::MLAv5:
+ EmitPatchedInstruction(MI, ARM::MLA);
+ return;
+ case ARM::SMULLv5:
+ EmitPatchedInstruction(MI, ARM::SMULL);
+ return;
+ case ARM::UMULLv5:
+ EmitPatchedInstruction(MI, ARM::UMULL);
+ return;
+ case ARM::SMLALv5:
+ EmitPatchedInstruction(MI, ARM::SMLAL);
+ return;
+ case ARM::UMLALv5:
+ EmitPatchedInstruction(MI, ARM::UMLAL);
+ return;
+ case ARM::UMAALv5:
+ EmitPatchedInstruction(MI, ARM::UMAAL);
+ return;
}
MCInst TmpInst;
Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h?rev=122663&r1=122662&r2=122663&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h Sat Jan 1 14:38:38 2011
@@ -79,6 +79,9 @@
// Helper for ELF .o only
void emitARMAttributeSection();
+ // Generic helper used to emit e.g. ARMv5 mul pseudos
+ void EmitPatchedInstruction(const MachineInstr *MI, unsigned TargetOpc);
+
public:
void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=122663&r1=122662&r2=122663&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Sat Jan 1 14:38:38 2011
@@ -2322,7 +2322,9 @@
SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
CurDAG->getRegister(0, MVT::i32) };
- return CurDAG->getMachineNode(ARM::UMULL, dl, MVT::i32, MVT::i32, Ops, 5);
+ return CurDAG->getMachineNode(Subtarget->hasV6Ops() ?
+ ARM::UMULL : ARM::UMULLv5,
+ dl, MVT::i32, MVT::i32, Ops, 5);
}
}
case ISD::SMUL_LOHI: {
@@ -2336,7 +2338,9 @@
SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
CurDAG->getRegister(0, MVT::i32) };
- return CurDAG->getMachineNode(ARM::SMULL, dl, MVT::i32, MVT::i32, Ops, 5);
+ return CurDAG->getMachineNode(Subtarget->hasV6Ops() ?
+ ARM::SMULL : ARM::SMULLv5,
+ dl, MVT::i32, MVT::i32, Ops, 5);
}
}
case ISD::LOAD: {
Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=122663&r1=122662&r2=122663&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Sat Jan 1 14:38:38 2011
@@ -149,6 +149,7 @@
def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">, AssemblerPredicate;
def HasV6 : Predicate<"Subtarget->hasV6Ops()">, AssemblerPredicate;
+def NoV6 : Predicate<"!Subtarget->hasV6Ops()">;
def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">, AssemblerPredicate;
def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">;
def HasV7 : Predicate<"Subtarget->hasV7Ops()">, AssemblerPredicate;
@@ -2504,14 +2505,31 @@
let Inst{3-0} = Rn;
}
-let isCommutable = 1 in
+let isCommutable = 1 in {
+let Constraints = "@earlyclobber $Rd" in
+def MULv5: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
+ IIC_iMUL32, [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>,
+ Requires<[IsARM, NoV6]>;
+
def MUL : AsMul1I32<0b0000000, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm",
- [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>;
+ [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>,
+ Requires<[IsARM, HasV6]>;
+}
+let Constraints = "@earlyclobber $Rd" in
+def MLAv5: PseudoInst<(outs GPR:$Rd),
+ (ins GPR:$Rn, GPR:$Rm, GPR:$Ra, pred:$p, cc_out:$s),
+ IIC_iMAC32, [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm),
+ GPR:$Ra))]>,
+ Requires<[IsARM, NoV6]> {
+ bits<4> Ra;
+ let Inst{15-12} = Ra;
+}
def MLA : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra",
- [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]> {
+ [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
+ Requires<[IsARM, HasV6]> {
bits<4> Ra;
let Inst{15-12} = Ra;
}
@@ -2534,23 +2552,54 @@
let neverHasSideEffects = 1 in {
let isCommutable = 1 in {
+let Constraints = "@earlyclobber $RdLo, at earlyclobber $RdHi" in {
+def SMULLv5 : PseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
+ (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
+ IIC_iMUL64, []>,
+ Requires<[IsARM, NoV6]>;
+
+def UMULLv5 : PseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
+ (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
+ IIC_iMUL64, []>,
+ Requires<[IsARM, NoV6]>;
+}
+
def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi),
(ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
- "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
+ "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
+ Requires<[IsARM, HasV6]>;
def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi),
(ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
- "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
+ "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
+ Requires<[IsARM, HasV6]>;
}
// Multiply + accumulate
+let Constraints = "@earlyclobber $RdLo, at earlyclobber $RdHi" in {
+def SMLALv5 : PseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
+ (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
+ IIC_iMAC64, []>,
+ Requires<[IsARM, NoV6]>;
+def UMLALv5 : PseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
+ (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
+ IIC_iMAC64, []>,
+ Requires<[IsARM, NoV6]>;
+def UMAALv5 : PseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
+ (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
+ IIC_iMAC64, []>,
+ Requires<[IsARM, NoV6]>;
+
+}
+
def SMLAL : AsMul1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi),
(ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
- "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
-
+ "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
+ Requires<[IsARM, HasV6]>;
def UMLAL : AsMul1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi),
(ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
- "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
+ "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
+ Requires<[IsARM, HasV6]>;
def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi),
(ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
More information about the llvm-commits
mailing list