More ARM multiply instuction binary encodings.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@117121 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jim Grosbach 2010-10-22 18:35:16 +00:00
parent 76f920d316
commit 3870b750e6
3 changed files with 141 additions and 100 deletions

View File

@ -934,15 +934,42 @@ class AMul2Ia<bits<7> opcod, bits<4> opc7_4, dag oops, dag iops,
}
// SMUL<x><y> / SMULW<y> / SMLA<x><y> / SMLAW<x><y>
class AMulxyI<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
class AMulxyIbase<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
InstrItinClass itin, string opc, string asm, list<dag> pattern>
: I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, itin,
opc, asm, "", pattern> {
bits<4> Rn;
bits<4> Rm;
let Inst{4} = 0;
let Inst{7} = 1;
let Inst{20} = 0;
let Inst{27-21} = opcod;
let Inst{6-5} = bit6_5;
let Inst{11-8} = Rm;
let Inst{3-0} = Rn;
}
class AMulxyI<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
InstrItinClass itin, string opc, string asm, list<dag> pattern>
: AMulxyIbase<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> {
bits<4> Rd;
let Inst{19-16} = Rd;
}
// AMulxyI with Ra operand
class AMulxyIa<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
InstrItinClass itin, string opc, string asm, list<dag> pattern>
: AMulxyI<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> {
bits<4> Ra;
let Inst{15-12} = Ra;
}
// SMLAL*
class AMulxyI64<bits<7> opcod, bits<2> bit6_5, dag oops, dag iops,
InstrItinClass itin, string opc, string asm, list<dag> pattern>
: AMulxyIbase<opcod, bit6_5, oops, iops, itin, opc, asm, pattern> {
bits<4> RdLo;
bits<4> RdHi;
let Inst{19-16} = RdHi;
let Inst{15-12} = RdLo;
}
// Extend instructions.

View File

@ -2372,132 +2372,116 @@ def SMMLSR : AMul2Ia <0b0111010, 0b1111, (outs GPR:$Rd),
Requires<[IsARM, HasV6]>;
multiclass AI_smul<string opc, PatFrag opnode> {
def BB : AMulxyI<0b0001011, 0b00, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
IIC_iMUL16, !strconcat(opc, "bb"), "\t$dst, $a, $b",
[(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
(sext_inreg GPR:$b, i16)))]>,
Requires<[IsARM, HasV5TE]> {
}
def BB : AMulxyI<0b0001011, 0b00, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
IIC_iMUL16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm",
[(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
(sext_inreg GPR:$Rm, i16)))]>,
Requires<[IsARM, HasV5TE]>;
def BT : AMulxyI<0b0001011, 0b10, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
IIC_iMUL16, !strconcat(opc, "bt"), "\t$dst, $a, $b",
[(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
(sra GPR:$b, (i32 16))))]>,
Requires<[IsARM, HasV5TE]> {
}
def BT : AMulxyI<0b0001011, 0b10, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
IIC_iMUL16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm",
[(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16),
(sra GPR:$Rm, (i32 16))))]>,
Requires<[IsARM, HasV5TE]>;
def TB : AMulxyI<0b0001011, 0b01, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
IIC_iMUL16, !strconcat(opc, "tb"), "\t$dst, $a, $b",
[(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
(sext_inreg GPR:$b, i16)))]>,
Requires<[IsARM, HasV5TE]> {
}
def TB : AMulxyI<0b0001011, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
IIC_iMUL16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm",
[(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
(sext_inreg GPR:$Rm, i16)))]>,
Requires<[IsARM, HasV5TE]>;
def TT : AMulxyI<0b0001011, 0b11, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
IIC_iMUL16, !strconcat(opc, "tt"), "\t$dst, $a, $b",
[(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
(sra GPR:$b, (i32 16))))]>,
Requires<[IsARM, HasV5TE]> {
}
def TT : AMulxyI<0b0001011, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
IIC_iMUL16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm",
[(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)),
(sra GPR:$Rm, (i32 16))))]>,
Requires<[IsARM, HasV5TE]>;
def WB : AMulxyI<0b0001001, 0b01, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
IIC_iMUL16, !strconcat(opc, "wb"), "\t$dst, $a, $b",
[(set GPR:$dst, (sra (opnode GPR:$a,
(sext_inreg GPR:$b, i16)), (i32 16)))]>,
Requires<[IsARM, HasV5TE]> {
}
def WB : AMulxyI<0b0001001, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
IIC_iMUL16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm",
[(set GPR:$Rd, (sra (opnode GPR:$Rn,
(sext_inreg GPR:$Rm, i16)), (i32 16)))]>,
Requires<[IsARM, HasV5TE]>;
def WT : AMulxyI<0b0001001, 0b11, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
IIC_iMUL16, !strconcat(opc, "wt"), "\t$dst, $a, $b",
[(set GPR:$dst, (sra (opnode GPR:$a,
(sra GPR:$b, (i32 16))), (i32 16)))]>,
Requires<[IsARM, HasV5TE]> {
}
def WT : AMulxyI<0b0001001, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
IIC_iMUL16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm",
[(set GPR:$Rd, (sra (opnode GPR:$Rn,
(sra GPR:$Rm, (i32 16))), (i32 16)))]>,
Requires<[IsARM, HasV5TE]>;
}
multiclass AI_smla<string opc, PatFrag opnode> {
def BB : AMulxyI<0b0001000, 0b00, (outs GPR:$dst),
(ins GPR:$a, GPR:$b, GPR:$acc),
IIC_iMAC16, !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
[(set GPR:$dst, (add GPR:$acc,
(opnode (sext_inreg GPR:$a, i16),
(sext_inreg GPR:$b, i16))))]>,
Requires<[IsARM, HasV5TE]> {
}
def BB : AMulxyI<0b0001000, 0b00, (outs GPR:$Rd),
(ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
IIC_iMAC16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra",
[(set GPR:$Rd, (add GPR:$Ra,
(opnode (sext_inreg GPR:$Rn, i16),
(sext_inreg GPR:$Rm, i16))))]>,
Requires<[IsARM, HasV5TE]>;
def BT : AMulxyI<0b0001000, 0b10, (outs GPR:$dst),
(ins GPR:$a, GPR:$b, GPR:$acc),
IIC_iMAC16, !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
[(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
(sra GPR:$b, (i32 16)))))]>,
Requires<[IsARM, HasV5TE]> {
}
def BT : AMulxyI<0b0001000, 0b10, (outs GPR:$Rd),
(ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
IIC_iMAC16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra",
[(set GPR:$Rd, (add GPR:$Ra, (opnode (sext_inreg GPR:$Rn, i16),
(sra GPR:$Rm, (i32 16)))))]>,
Requires<[IsARM, HasV5TE]>;
def TB : AMulxyI<0b0001000, 0b01, (outs GPR:$dst),
(ins GPR:$a, GPR:$b, GPR:$acc),
IIC_iMAC16, !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
[(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
(sext_inreg GPR:$b, i16))))]>,
Requires<[IsARM, HasV5TE]> {
}
def TB : AMulxyI<0b0001000, 0b01, (outs GPR:$Rd),
(ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
IIC_iMAC16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra",
[(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
(sext_inreg GPR:$Rm, i16))))]>,
Requires<[IsARM, HasV5TE]>;
def TT : AMulxyI<0b0001000, 0b11, (outs GPR:$dst),
(ins GPR:$a, GPR:$b, GPR:$acc),
IIC_iMAC16, !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
[(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
(sra GPR:$b, (i32 16)))))]>,
Requires<[IsARM, HasV5TE]> {
}
def TT : AMulxyI<0b0001000, 0b11, (outs GPR:$Rd),
(ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
IIC_iMAC16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra",
[(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)),
(sra GPR:$Rm, (i32 16)))))]>,
Requires<[IsARM, HasV5TE]>;
def WB : AMulxyI<0b0001001, 0b00, (outs GPR:$dst),
(ins GPR:$a, GPR:$b, GPR:$acc),
IIC_iMAC16, !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
[(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
(sext_inreg GPR:$b, i16)), (i32 16))))]>,
Requires<[IsARM, HasV5TE]> {
}
def WB : AMulxyI<0b0001001, 0b00, (outs GPR:$Rd),
(ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
IIC_iMAC16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra",
[(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
(sext_inreg GPR:$Rm, i16)), (i32 16))))]>,
Requires<[IsARM, HasV5TE]>;
def WT : AMulxyI<0b0001001, 0b10, (outs GPR:$dst),
(ins GPR:$a, GPR:$b, GPR:$acc),
IIC_iMAC16, !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
[(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
(sra GPR:$b, (i32 16))), (i32 16))))]>,
Requires<[IsARM, HasV5TE]> {
}
def WT : AMulxyI<0b0001001, 0b10, (outs GPR:$Rd),
(ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
IIC_iMAC16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra",
[(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn,
(sra GPR:$Rm, (i32 16))), (i32 16))))]>,
Requires<[IsARM, HasV5TE]>;
}
defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
// Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
def SMLALBB : AMulxyI<0b0001010, 0b00, (outs GPR:$ldst, GPR:$hdst),
(ins GPR:$a, GPR:$b),
IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
def SMLALBB : AMulxyI64<0b0001010, 0b00, (outs GPR:$RdLo, GPR:$RdHi),
(ins GPR:$Rn, GPR:$Rm),
IIC_iMAC64, "smlalbb", "\t$RdLo, $RdHi, $Rn, $Rm",
[/* For disassembly only; pattern left blank */]>,
Requires<[IsARM, HasV5TE]> {
}
Requires<[IsARM, HasV5TE]>;
def SMLALBT : AMulxyI<0b0001010, 0b10, (outs GPR:$ldst, GPR:$hdst),
(ins GPR:$a, GPR:$b),
IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
def SMLALBT : AMulxyI64<0b0001010, 0b10, (outs GPR:$RdLo, GPR:$RdHi),
(ins GPR:$Rn, GPR:$Rm),
IIC_iMAC64, "smlalbt", "\t$RdLo, $RdHi, $Rn, $Rm",
[/* For disassembly only; pattern left blank */]>,
Requires<[IsARM, HasV5TE]> {
}
Requires<[IsARM, HasV5TE]>;
def SMLALTB : AMulxyI<0b0001010, 0b01, (outs GPR:$ldst, GPR:$hdst),
(ins GPR:$a, GPR:$b),
IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
def SMLALTB : AMulxyI64<0b0001010, 0b01, (outs GPR:$RdLo, GPR:$RdHi),
(ins GPR:$Rn, GPR:$Rm),
IIC_iMAC64, "smlaltb", "\t$RdLo, $RdHi, $Rn, $Rm",
[/* For disassembly only; pattern left blank */]>,
Requires<[IsARM, HasV5TE]> {
}
Requires<[IsARM, HasV5TE]>;
def SMLALTT : AMulxyI<0b0001010, 0b11, (outs GPR:$ldst, GPR:$hdst),
(ins GPR:$a, GPR:$b),
IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
def SMLALTT : AMulxyI64<0b0001010, 0b11, (outs GPR:$RdLo, GPR:$RdHi),
(ins GPR:$Rn, GPR:$Rm),
IIC_iMAC64, "smlaltt", "\t$RdLo, $RdHi, $Rn, $Rm",
[/* For disassembly only; pattern left blank */]>,
Requires<[IsARM, HasV5TE]> {
}
Requires<[IsARM, HasV5TE]>;
// Helper class for AI_smld -- for disassembly only
class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops,

View File

@ -150,4 +150,34 @@ define i32 @f15(i32 %x, i32 %y) {
%tmp3.upgrd.2 = trunc i64 %tmp3 to i32
ret i32 %tmp3.upgrd.2
}
define i32 @f16(i16 %x, i32 %y) {
; CHECK: f16:
; CHECK: smulbt r0, r0, r1 @ encoding: [0xc0,0x01,0x60,0xe1]
%tmp1 = add i16 %x, 2
%tmp2 = sext i16 %tmp1 to i32
%tmp3 = ashr i32 %y, 16
%tmp4 = mul i32 %tmp2, %tmp3
ret i32 %tmp4
}
define i32 @f17(i32 %x, i32 %y) {
; CHECK: f17:
; CHECK: smultt r0, r1, r0 @ encoding: [0xe1,0x00,0x60,0xe1]
%tmp1 = ashr i32 %x, 16
%tmp3 = ashr i32 %y, 16
%tmp4 = mul i32 %tmp3, %tmp1
ret i32 %tmp4
}
define i32 @f18(i32 %a, i16 %x, i32 %y) {
; CHECK: f18:
; CHECK: smlabt r0, r1, r2, r0 @ encoding: [0xc1,0x02,0x00,0xe1]
%tmp = sext i16 %x to i32
%tmp2 = ashr i32 %y, 16
%tmp3 = mul i32 %tmp2, %tmp
%tmp5 = add i32 %tmp3, %a
ret i32 %tmp5
}
declare void @llvm.trap() nounwind