diff options
Diffstat (limited to 'lib/Target/ARM')
-rw-r--r-- | lib/Target/ARM/ARMInstrThumb.td | 18 | ||||
-rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 28 |
2 files changed, 41 insertions, 5 deletions
diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index 5825f9bede..9163629da1 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -1049,10 +1049,20 @@ def tMOVSr : T1I<(outs tGPR:$Rd), (ins tGPR:$Rm), IIC_iMOVr, // Multiply register let isCommutable = 1 in def tMUL : // A8.6.105 T1 - T1sItDPEncode<0b1101, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm), - IIC_iMUL32, - "mul", "\t$Rdn, $Rm, $Rdn", - [(set tGPR:$Rdn, (mul tGPR:$Rn, tGPR:$Rm))]>; + Thumb1sI<(outs tGPR:$Rd), (ins tGPR:$Rn, tGPR:$Rm), AddrModeNone, 2, + IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm", "$Rm = $Rd", + [(set tGPR:$Rd, (mul tGPR:$Rn, tGPR:$Rm))]>, + T1DataProcessing<0b1101> { + bits<3> Rd; + bits<3> Rn; + let Inst{5-3} = Rn; + let Inst{2-0} = Rd; + let AsmMatchConverter = "cvtThumbMultiply"; +} + +def : InstAlias<"mul${s}${p} $Rdm, $Rn", (tMUL tGPR:$Rdm, s_cc_out:$s, tGPR:$Rn, + pred:$p)>, + Requires<[IsThumb]>; // Move inverse register def tMVN : // A8.6.107 diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 33399ec14f..3495136824 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -145,6 +145,8 @@ class ARMAsmParser : public MCTargetAsmParser { const SmallVectorImpl<MCParsedAsmOperand*> &); bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, const SmallVectorImpl<MCParsedAsmOperand*> &); + bool cvtThumbMultiply(MCInst &Inst, unsigned Opcode, + const SmallVectorImpl<MCParsedAsmOperand*> &); bool validateInstruction(MCInst &Inst, const SmallVectorImpl<MCParsedAsmOperand*> &Ops); @@ -2371,6 +2373,29 @@ cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, return true; } +/// cvtThumbMultiple- Convert parsed operands to MCInst. +/// Needed here because the Asm Gen Matcher can't handle properly tied operands +/// when they refer multiple MIOperands inside a single one. +bool ARMAsmParser:: +cvtThumbMultiply(MCInst &Inst, unsigned Opcode, + const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { + // The second source operand must be the same register as the destination + // operand. + if (Operands.size() == 6 && + ((ARMOperand*)Operands[3])->getReg() != + ((ARMOperand*)Operands[5])->getReg()) { + Error(Operands[3]->getStartLoc(), + "destination register must match second source register"); + return false; + } + ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); + ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1); + ((ARMOperand*)Operands[4])->addRegOperands(Inst, 1); + Inst.addOperand(Inst.getOperand(0)); + ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2); + + return true; +} /// Parse an ARM memory expression, return false if successful else return true /// or an error. The first token must be a '[' when called. @@ -3220,7 +3245,8 @@ MatchAndEmitInstruction(SMLoc IDLoc, case Match_MnemonicFail: return Error(IDLoc, "invalid instruction"); case Match_ConversionFail: - return Error(IDLoc, "unable to convert operands to instruction"); + // The converter function will have already emited a diagnostic. + return true; case Match_RequiresITBlock: return Error(IDLoc, "instruction only valid inside IT block"); case Match_RequiresV6: |