mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-26 13:10:42 +00:00
Added the follwoing 32-bit Thumb instructions for disassembly only:
o Parallel addition and subtraction, signed/unsigned o Miscellaneous operations: QADD, QDADD, QSUB, QDSUB o Unsigned sum of absolute differences [and accumulate]: USAD8, USADA8 o Signed/Unsigned saturate: SSAT, SSAT16, USAT, USAT16 o Signed multiply accumulate long (halfwords): SMLAL<x><y> o Signed multiply accumulate/subtract [long] (dual): SMLAD[x], SMLALD[X], SMLSD[X], SMLSLD[X] o Signed dual multiply add/subtract [long]: SMUAD[X], SMUSD[X] git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97276 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
baafcbb4db
commit
adc7733a64
@ -1203,6 +1203,19 @@ class T2Iidxldst<bit signed, bits<2> opcod, bit load, bit pre,
|
||||
let Inst{8} = 1; // The W bit.
|
||||
}
|
||||
|
||||
// Helper class for disassembly only
|
||||
// A6.3.16 & A6.3.17
|
||||
// T2Imac - Thumb2 multiply [accumulate, and absolute difference] instructions.
|
||||
class T2I_mac<bit long, bits<3> op22_20, bits<4> op7_4, dag oops, dag iops,
|
||||
InstrItinClass itin, string opc, string asm, list<dag> pattern>
|
||||
: T2I<oops, iops, itin, opc, asm, pattern> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-24} = 0b011;
|
||||
let Inst{23} = long;
|
||||
let Inst{22-20} = op22_20;
|
||||
let Inst{7-4} = op7_4;
|
||||
}
|
||||
|
||||
// Tv5Pat - Same as Pat<>, but requires V5T Thumb mode.
|
||||
class Tv5Pat<dag pattern, dag result> : Pat<pattern, result> {
|
||||
list<Predicate> Predicates = [IsThumb1Only, HasV5T];
|
||||
|
@ -1586,9 +1586,9 @@ def UHSAX : AAI<0b01100111, 0b0101, "uhsax">;
|
||||
def UHSUB16 : AAI<0b01100111, 0b0111, "uhsub16">;
|
||||
def UHSUB8 : AAI<0b01100111, 0b1111, "uhsub8">;
|
||||
|
||||
// Unsigned Sum of Absolute Difference [and Accumulate] -- for disassembly only
|
||||
// Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
|
||||
|
||||
def USAD8 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
|
||||
def USAD8 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b),
|
||||
MulFrm /* for convenience */, NoItinerary, "usad8",
|
||||
"\t$dst, $a, $b", []>,
|
||||
Requires<[IsARM, HasV6]> {
|
||||
|
@ -1146,6 +1146,142 @@ def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
|
||||
def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm),
|
||||
(t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
|
||||
|
||||
// A6.3.13, A6.3.14, A6.3.15 Parallel addition and subtraction (signed/unsigned)
|
||||
// And Miscellaneous operations -- for disassembly only
|
||||
class T2I_pam<bits<3> op22_20, bits<4> op7_4, string opc>
|
||||
: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), NoItinerary, opc,
|
||||
"\t$dst, $a, $b", [/* For disassembly only; pattern left blank */]> {
|
||||
let Inst{31-27} = 0b11111;
|
||||
let Inst{26-23} = 0b0101;
|
||||
let Inst{22-20} = op22_20;
|
||||
let Inst{15-12} = 0b1111;
|
||||
let Inst{7-4} = op7_4;
|
||||
}
|
||||
|
||||
// Saturating add/subtract -- for disassembly only
|
||||
|
||||
def t2QADD : T2I_pam<0b000, 0b1000, "qadd">;
|
||||
def t2QADD16 : T2I_pam<0b001, 0b0001, "qadd16">;
|
||||
def t2QADD8 : T2I_pam<0b000, 0b0001, "qadd8">;
|
||||
def t2QASX : T2I_pam<0b010, 0b0001, "qasx">;
|
||||
def t2QDADD : T2I_pam<0b000, 0b1001, "qdadd">;
|
||||
def t2QDSUB : T2I_pam<0b000, 0b1011, "qdsub">;
|
||||
def t2QSAX : T2I_pam<0b110, 0b0001, "qsax">;
|
||||
def t2QSUB : T2I_pam<0b000, 0b1010, "qsub">;
|
||||
def t2QSUB16 : T2I_pam<0b101, 0b0001, "qsub16">;
|
||||
def t2QSUB8 : T2I_pam<0b100, 0b0001, "qsub8">;
|
||||
def t2UQADD16 : T2I_pam<0b001, 0b0101, "uqadd16">;
|
||||
def t2UQADD8 : T2I_pam<0b000, 0b0101, "uqadd8">;
|
||||
def t2UQASX : T2I_pam<0b010, 0b0101, "uqasx">;
|
||||
def t2UQSAX : T2I_pam<0b110, 0b0101, "uqsax">;
|
||||
def t2UQSUB16 : T2I_pam<0b101, 0b0101, "uqsub16">;
|
||||
def t2UQSUB8 : T2I_pam<0b100, 0b0101, "uqsub8">;
|
||||
|
||||
// Signed/Unsigned add/subtract -- for disassembly only
|
||||
|
||||
def t2SASX : T2I_pam<0b010, 0b0000, "sasx">;
|
||||
def t2SADD16 : T2I_pam<0b001, 0b0000, "sadd16">;
|
||||
def t2SADD8 : T2I_pam<0b000, 0b0000, "sadd8">;
|
||||
def t2SSAX : T2I_pam<0b110, 0b0000, "ssax">;
|
||||
def t2SSUB16 : T2I_pam<0b101, 0b0000, "ssub16">;
|
||||
def t2SSUB8 : T2I_pam<0b100, 0b0000, "ssub8">;
|
||||
def t2UASX : T2I_pam<0b010, 0b0100, "uasx">;
|
||||
def t2UADD16 : T2I_pam<0b001, 0b0100, "uadd16">;
|
||||
def t2UADD8 : T2I_pam<0b000, 0b0100, "uadd8">;
|
||||
def t2USAX : T2I_pam<0b110, 0b0100, "usax">;
|
||||
def t2USUB16 : T2I_pam<0b101, 0b0100, "usub16">;
|
||||
def t2USUB8 : T2I_pam<0b100, 0b0100, "usub8">;
|
||||
|
||||
// Signed/Unsigned halving add/subtract -- for disassembly only
|
||||
|
||||
def t2SHASX : T2I_pam<0b010, 0b0010, "shasx">;
|
||||
def t2SHADD16 : T2I_pam<0b001, 0b0010, "shadd16">;
|
||||
def t2SHADD8 : T2I_pam<0b000, 0b0010, "shadd8">;
|
||||
def t2SHSAX : T2I_pam<0b110, 0b0010, "shsax">;
|
||||
def t2SHSUB16 : T2I_pam<0b101, 0b0010, "shsub16">;
|
||||
def t2SHSUB8 : T2I_pam<0b100, 0b0010, "shsub8">;
|
||||
def t2UHASX : T2I_pam<0b010, 0b0110, "uhasx">;
|
||||
def t2UHADD16 : T2I_pam<0b001, 0b0110, "uhadd16">;
|
||||
def t2UHADD8 : T2I_pam<0b000, 0b0110, "uhadd8">;
|
||||
def t2UHSAX : T2I_pam<0b110, 0b0110, "uhsax">;
|
||||
def t2UHSUB16 : T2I_pam<0b101, 0b0110, "uhsub16">;
|
||||
def t2UHSUB8 : T2I_pam<0b100, 0b0110, "uhsub8">;
|
||||
|
||||
// Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only
|
||||
|
||||
def t2USAD8 : T2I_mac<0, 0b111, 0b0000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
|
||||
NoItinerary, "usad8", "\t$dst, $a, $b", []> {
|
||||
let Inst{15-12} = 0b1111;
|
||||
}
|
||||
def t2USADA8 : T2I_mac<0, 0b111, 0b0000, (outs GPR:$dst),
|
||||
(ins GPR:$a, GPR:$b, GPR:$acc), NoItinerary, "usada8",
|
||||
"\t$dst, $a, $b, $acc", []>;
|
||||
|
||||
// Signed/Unsigned saturate -- for disassembly only
|
||||
|
||||
def t2SSATlsl : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos,GPR:$a,i32imm:$shamt),
|
||||
NoItinerary, "ssat", "\t$dst, $bit_pos, $a, LSL $shamt",
|
||||
[/* For disassembly only; pattern left blank */]> {
|
||||
let Inst{31-27} = 0b11110;
|
||||
let Inst{25-22} = 0b1100;
|
||||
let Inst{20} = 0;
|
||||
let Inst{15} = 0;
|
||||
let Inst{21} = 0; // sh = '0'
|
||||
}
|
||||
|
||||
def t2SSATasr : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos,GPR:$a,i32imm:$shamt),
|
||||
NoItinerary, "ssat", "\t$dst, $bit_pos, $a, ASR $shamt",
|
||||
[/* For disassembly only; pattern left blank */]> {
|
||||
let Inst{31-27} = 0b11110;
|
||||
let Inst{25-22} = 0b1100;
|
||||
let Inst{20} = 0;
|
||||
let Inst{15} = 0;
|
||||
let Inst{21} = 1; // sh = '1'
|
||||
}
|
||||
|
||||
def t2SSAT16 : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), NoItinerary,
|
||||
"ssat16", "\t$dst, $bit_pos, $a",
|
||||
[/* For disassembly only; pattern left blank */]> {
|
||||
let Inst{31-27} = 0b11110;
|
||||
let Inst{25-22} = 0b1100;
|
||||
let Inst{20} = 0;
|
||||
let Inst{15} = 0;
|
||||
let Inst{21} = 1; // sh = '1'
|
||||
let Inst{14-12} = 0b000; // imm3 = '000'
|
||||
let Inst{7-6} = 0b00; // imm2 = '00'
|
||||
}
|
||||
|
||||
def t2USATlsl : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos,GPR:$a,i32imm:$shamt),
|
||||
NoItinerary, "usat", "\t$dst, $bit_pos, $a, LSL $shamt",
|
||||
[/* For disassembly only; pattern left blank */]> {
|
||||
let Inst{31-27} = 0b11110;
|
||||
let Inst{25-22} = 0b1110;
|
||||
let Inst{20} = 0;
|
||||
let Inst{15} = 0;
|
||||
let Inst{21} = 0; // sh = '0'
|
||||
}
|
||||
|
||||
def t2USATasr : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos,GPR:$a,i32imm:$shamt),
|
||||
NoItinerary, "usat", "\t$dst, $bit_pos, $a, ASR $shamt",
|
||||
[/* For disassembly only; pattern left blank */]> {
|
||||
let Inst{31-27} = 0b11110;
|
||||
let Inst{25-22} = 0b1110;
|
||||
let Inst{20} = 0;
|
||||
let Inst{15} = 0;
|
||||
let Inst{21} = 1; // sh = '1'
|
||||
}
|
||||
|
||||
def t2USAT16 : T2I<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), NoItinerary,
|
||||
"usat16", "\t$dst, $bit_pos, $a",
|
||||
[/* For disassembly only; pattern left blank */]> {
|
||||
let Inst{31-27} = 0b11110;
|
||||
let Inst{25-22} = 0b1110;
|
||||
let Inst{20} = 0;
|
||||
let Inst{15} = 0;
|
||||
let Inst{21} = 1; // sh = '1'
|
||||
let Inst{14-12} = 0b000; // imm3 = '000'
|
||||
let Inst{7-6} = 0b00; // imm2 = '00'
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Shift and rotate Instructions.
|
||||
@ -1535,9 +1671,63 @@ multiclass T2I_smla<string opc, PatFrag opnode> {
|
||||
defm t2SMUL : T2I_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
|
||||
defm t2SMLA : T2I_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
|
||||
|
||||
// TODO: Halfword multiple accumulate long: SMLAL<x><y>
|
||||
// TODO: Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
|
||||
// Halfword multiple accumulate long: SMLAL<x><y> -- for disassembly only
|
||||
def t2SMLALBB : T2I_mac<1, 0b100, 0b1000, (outs GPR:$ldst,GPR:$hdst),
|
||||
(ins GPR:$a,GPR:$b), IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
|
||||
[/* For disassembly only; pattern left blank */]>;
|
||||
def t2SMLALBT : T2I_mac<1, 0b100, 0b1001, (outs GPR:$ldst,GPR:$hdst),
|
||||
(ins GPR:$a,GPR:$b), IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
|
||||
[/* For disassembly only; pattern left blank */]>;
|
||||
def t2SMLALTB : T2I_mac<1, 0b100, 0b1010, (outs GPR:$ldst,GPR:$hdst),
|
||||
(ins GPR:$a,GPR:$b), IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
|
||||
[/* For disassembly only; pattern left blank */]>;
|
||||
def t2SMLALTT : T2I_mac<1, 0b100, 0b1011, (outs GPR:$ldst,GPR:$hdst),
|
||||
(ins GPR:$a,GPR:$b), IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
|
||||
[/* For disassembly only; pattern left blank */]>;
|
||||
|
||||
// Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
|
||||
// These are for disassembly only.
|
||||
|
||||
def t2SMUAD : T2I_mac<0, 0b010, 0b0000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
|
||||
IIC_iMAC32, "smuad", "\t$dst, $a, $b", []> {
|
||||
let Inst{15-12} = 0b1111;
|
||||
}
|
||||
def t2SMUADX : T2I_mac<0, 0b010, 0b0001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
|
||||
IIC_iMAC32, "smuadx", "\t$dst, $a, $b", []> {
|
||||
let Inst{15-12} = 0b1111;
|
||||
}
|
||||
def t2SMUSD : T2I_mac<0, 0b100, 0b0000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
|
||||
IIC_iMAC32, "smusd", "\t$dst, $a, $b", []> {
|
||||
let Inst{15-12} = 0b1111;
|
||||
}
|
||||
def t2SMUSDX : T2I_mac<0, 0b100, 0b0001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
|
||||
IIC_iMAC32, "smusdx", "\t$dst, $a, $b", []> {
|
||||
let Inst{15-12} = 0b1111;
|
||||
}
|
||||
def t2SMLAD : T2I_mac<0, 0b010, 0b0000, (outs GPR:$dst),
|
||||
(ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC32, "smlad",
|
||||
"\t$dst, $a, $b, $acc", []>;
|
||||
def t2SMLADX : T2I_mac<0, 0b010, 0b0001, (outs GPR:$dst),
|
||||
(ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC32, "smladx",
|
||||
"\t$dst, $a, $b, $acc", []>;
|
||||
def t2SMLSD : T2I_mac<0, 0b100, 0b0000, (outs GPR:$dst),
|
||||
(ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC32, "smlsd",
|
||||
"\t$dst, $a, $b, $acc", []>;
|
||||
def t2SMLSDX : T2I_mac<0, 0b100, 0b0001, (outs GPR:$dst),
|
||||
(ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC32, "smlsdx",
|
||||
"\t$dst, $a, $b, $acc", []>;
|
||||
def t2SMLALD : T2I_mac<1, 0b100, 0b1100, (outs GPR:$ldst,GPR:$hdst),
|
||||
(ins GPR:$a,GPR:$b), IIC_iMAC64, "smlald",
|
||||
"\t$ldst, $hdst, $a, $b", []>;
|
||||
def t2SMLALDX : T2I_mac<1, 0b100, 0b1101, (outs GPR:$ldst,GPR:$hdst),
|
||||
(ins GPR:$a,GPR:$b), IIC_iMAC64, "smlaldx",
|
||||
"\t$ldst, $hdst, $a, $b", []>;
|
||||
def t2SMLSLD : T2I_mac<1, 0b101, 0b1100, (outs GPR:$ldst,GPR:$hdst),
|
||||
(ins GPR:$a,GPR:$b), IIC_iMAC64, "smlsld",
|
||||
"\t$ldst, $hdst, $a, $b", []>;
|
||||
def t2SMLSLDX : T2I_mac<1, 0b101, 0b1101, (outs GPR:$ldst,GPR:$hdst),
|
||||
(ins GPR:$a,GPR:$b), IIC_iMAC64, "smlsldx",
|
||||
"\t$ldst, $hdst, $a, $b", []>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Misc. Arithmetic Instructions.
|
||||
|
Loading…
Reference in New Issue
Block a user