diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index fec626acf5e..1b802f18439 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -911,13 +911,26 @@ class AsMul1I opcod, dag oops, dag iops, InstrItinClass itin, } // Most significant word multiply -class AMul2I opcod, dag oops, dag iops, InstrItinClass itin, - string opc, string asm, list pattern> +class AMul2I opcod, bits<4> opc7_4, dag oops, dag iops, + InstrItinClass itin, string opc, string asm, list pattern> : I { - let Inst{7-4} = 0b1001; + bits<4> Rd; + bits<4> Rn; + bits<4> Rm; + let Inst{7-4} = opc7_4; let Inst{20} = 1; let Inst{27-21} = opcod; + let Inst{19-16} = Rd; + let Inst{11-8} = Rm; + let Inst{3-0} = Rn; +} +// MSW multiple w/ Ra operand +class AMul2Ia opcod, bits<4> opc7_4, dag oops, dag iops, + InstrItinClass itin, string opc, string asm, list pattern> + : AMul2I { + bits<4> Ra; + let Inst{15-12} = Ra; } // SMUL / SMULW / SMLA / SMLAW diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 35fa2b4507a..d28c8bc4f42 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -2265,8 +2265,8 @@ class AsMul1I64 opcod, dag oops, dag iops, InstrItinClass itin, bits<4> RdHi; bits<4> Rm; bits<4> Rn; - let Inst{19-16} = RdLo; - let Inst{15-12} = RdHi; + let Inst{19-16} = RdHi; + let Inst{15-12} = RdLo; let Inst{11-8} = Rm; let Inst{3-0} = Rn; } @@ -2333,49 +2333,43 @@ def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi), } // neverHasSideEffects // Most significant word multiply -def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b), - IIC_iMUL32, "smmul", "\t$dst, $a, $b", - [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>, +def SMMUL : AMul2I <0b0111010, 0b0001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), + IIC_iMUL32, "smmul", "\t$Rd, $Rn, $Rm", + [(set GPR:$Rd, (mulhs GPR:$Rn, GPR:$Rm))]>, Requires<[IsARM, HasV6]> { - let Inst{7-4} = 0b0001; let Inst{15-12} = 0b1111; } -def SMMULR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b), - IIC_iMUL32, "smmulr", "\t$dst, $a, $b", +def SMMULR : AMul2I <0b0111010, 0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), + IIC_iMUL32, "smmulr", "\t$Rd, $Rn, $Rm", [/* For disassembly only; pattern left blank */]>, Requires<[IsARM, HasV6]> { - let Inst{7-4} = 0b0011; // R = 1 let Inst{15-12} = 0b1111; } -def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), - IIC_iMAC32, "smmla", "\t$dst, $a, $b, $c", - [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>, - Requires<[IsARM, HasV6]> { - let Inst{7-4} = 0b0001; -} +def SMMLA : AMul2Ia <0b0111010, 0b0001, (outs GPR:$Rd), + (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), + IIC_iMAC32, "smmla", "\t$Rd, $Rn, $Rm, $Ra", + [(set GPR:$Rd, (add (mulhs GPR:$Rn, GPR:$Rm), GPR:$Ra))]>, + Requires<[IsARM, HasV6]>; -def SMMLAR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), - IIC_iMAC32, "smmlar", "\t$dst, $a, $b, $c", +def SMMLAR : AMul2Ia <0b0111010, 0b0011, (outs GPR:$Rd), + (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), + IIC_iMAC32, "smmlar", "\t$Rd, $Rn, $Rm, $Ra", [/* For disassembly only; pattern left blank */]>, - Requires<[IsARM, HasV6]> { - let Inst{7-4} = 0b0011; // R = 1 -} + Requires<[IsARM, HasV6]>; -def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), - IIC_iMAC32, "smmls", "\t$dst, $a, $b, $c", - [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>, - Requires<[IsARM, HasV6]> { - let Inst{7-4} = 0b1101; -} +def SMMLS : AMul2Ia <0b0111010, 0b1101, (outs GPR:$Rd), + (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), + IIC_iMAC32, "smmls", "\t$Rd, $Rn, $Rm, $Ra", + [(set GPR:$Rd, (sub GPR:$Ra, (mulhs GPR:$Rn, GPR:$Rm)))]>, + Requires<[IsARM, HasV6]>; -def SMMLSR : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), - IIC_iMAC32, "smmlsr", "\t$dst, $a, $b, $c", +def SMMLSR : AMul2Ia <0b0111010, 0b1111, (outs GPR:$Rd), + (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), + IIC_iMAC32, "smmlsr", "\t$Rd, $Rn, $Rm, $Ra", [/* For disassembly only; pattern left blank */]>, - Requires<[IsARM, HasV6]> { - let Inst{7-4} = 0b1111; // R = 1 -} + Requires<[IsARM, HasV6]>; multiclass AI_smul { def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b), diff --git a/test/MC/ARM/simple-encoding.ll b/test/MC/ARM/simple-encoding.ll index b8df75ab7c9..970e0e616c4 100644 --- a/test/MC/ARM/simple-encoding.ll +++ b/test/MC/ARM/simple-encoding.ll @@ -128,4 +128,26 @@ define i64 @f13() { entry: ret i64 9223372036854775807 } + +define i32 @f14(i32 %x, i32 %y) { +; CHECK: f14: +; CHECK: smmul r0, r1, r0 @ encoding: [0x11,0xf0,0x50,0xe7] + %tmp = sext i32 %x to i64 + %tmp1 = sext i32 %y to i64 + %tmp2 = mul i64 %tmp1, %tmp + %tmp3 = lshr i64 %tmp2, 32 + %tmp3.upgrd.1 = trunc i64 %tmp3 to i32 + ret i32 %tmp3.upgrd.1 +} + +define i32 @f15(i32 %x, i32 %y) { +; CHECK: f15: +; CHECK: umull r1, r0, r1, r0 @ encoding: [0x91,0x10,0x80,0xe0] + %tmp = zext i32 %x to i64 + %tmp1 = zext i32 %y to i64 + %tmp2 = mul i64 %tmp1, %tmp + %tmp3 = lshr i64 %tmp2, 32 + %tmp3.upgrd.2 = trunc i64 %tmp3 to i32 + ret i32 %tmp3.upgrd.2 +} declare void @llvm.trap() nounwind