Skip to content

Commit a6b6a15

Browse files
committedJun 21, 2019
[ARM] Add a batch of similarly encoded MVE instructions.
Summary: This adds the `MVE_qDest_qSrc` superclass and all instructions that inherit from it. It's not the complete class of _everything_ with a q-register as both destination and source; it's a subset of them that all have similar encodings (but it would have been hopelessly unwieldy to call it anything like MVE_111x11100). This category includes add/sub with carry; long multiplies; halving multiplies; multiply and accumulate, and some more complex instructions. Reviewers: dmgreen, samparker, SjoerdMeijer, t.p.northover Subscribers: javed.absar, kristof.beyls, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D62677 llvm-svn: 364037
1 parent 9485b26 commit a6b6a15

File tree

5 files changed

+1277
-1
lines changed

5 files changed

+1277
-1
lines changed
 

‎llvm/lib/Target/ARM/ARMInstrMVE.td

+278
Original file line numberDiff line numberDiff line change
@@ -2404,6 +2404,284 @@ def MVE_VCMPs32r : MVE_VCMPqrs<"s32", 0b10>;
24042404

24052405
// end of MVE compares
24062406

2407+
// start of MVE_qDest_qSrc
2408+
2409+
class MVE_qDest_qSrc<string iname, string suffix, dag oops, dag iops,
2410+
string ops, vpred_ops vpred, string cstr,
2411+
list<dag> pattern=[]>
2412+
: MVE_p<oops, iops, NoItinerary, iname, suffix,
2413+
ops, vpred, cstr, pattern> {
2414+
bits<4> Qd;
2415+
bits<4> Qm;
2416+
2417+
let Inst{25-23} = 0b100;
2418+
let Inst{22} = Qd{3};
2419+
let Inst{15-13} = Qd{2-0};
2420+
let Inst{11-9} = 0b111;
2421+
let Inst{6} = 0b0;
2422+
let Inst{5} = Qm{3};
2423+
let Inst{4} = 0b0;
2424+
let Inst{3-1} = Qm{2-0};
2425+
}
2426+
2427+
class MVE_VQxDMLxDH<string iname, bit exch, bit round, bit subtract,
2428+
string suffix, bits<2> size, list<dag> pattern=[]>
2429+
: MVE_qDest_qSrc<iname, suffix, (outs MQPR:$Qd),
2430+
(ins MQPR:$Qn, MQPR:$Qm), "$Qd, $Qn, $Qm",
2431+
vpred_r, "", pattern> {
2432+
bits<4> Qn;
2433+
2434+
let Inst{28} = subtract;
2435+
let Inst{21-20} = size;
2436+
let Inst{19-17} = Qn{2-0};
2437+
let Inst{16} = 0b0;
2438+
let Inst{12} = exch;
2439+
let Inst{8} = 0b0;
2440+
let Inst{7} = Qn{3};
2441+
let Inst{0} = round;
2442+
}
2443+
2444+
multiclass MVE_VQxDMLxDH_multi<string iname, bit exch,
2445+
bit round, bit subtract> {
2446+
def s8 : MVE_VQxDMLxDH<iname, exch, round, subtract, "s8", 0b00>;
2447+
def s16 : MVE_VQxDMLxDH<iname, exch, round, subtract, "s16", 0b01>;
2448+
def s32 : MVE_VQxDMLxDH<iname, exch, round, subtract, "s32", 0b10>;
2449+
}
2450+
2451+
defm MVE_VQDMLADH : MVE_VQxDMLxDH_multi<"vqdmladh", 0b0, 0b0, 0b0>;
2452+
defm MVE_VQDMLADHX : MVE_VQxDMLxDH_multi<"vqdmladhx", 0b1, 0b0, 0b0>;
2453+
defm MVE_VQRDMLADH : MVE_VQxDMLxDH_multi<"vqrdmladh", 0b0, 0b1, 0b0>;
2454+
defm MVE_VQRDMLADHX : MVE_VQxDMLxDH_multi<"vqrdmladhx", 0b1, 0b1, 0b0>;
2455+
defm MVE_VQDMLSDH : MVE_VQxDMLxDH_multi<"vqdmlsdh", 0b0, 0b0, 0b1>;
2456+
defm MVE_VQDMLSDHX : MVE_VQxDMLxDH_multi<"vqdmlsdhx", 0b1, 0b0, 0b1>;
2457+
defm MVE_VQRDMLSDH : MVE_VQxDMLxDH_multi<"vqrdmlsdh", 0b0, 0b1, 0b1>;
2458+
defm MVE_VQRDMLSDHX : MVE_VQxDMLxDH_multi<"vqrdmlsdhx", 0b1, 0b1, 0b1>;
2459+
2460+
class MVE_VCMUL<string iname, string suffix, bit size, list<dag> pattern=[]>
2461+
: MVE_qDest_qSrc<iname, suffix, (outs MQPR:$Qd),
2462+
(ins MQPR:$Qn, MQPR:$Qm, complexrotateop:$rot),
2463+
"$Qd, $Qn, $Qm, $rot", vpred_r, "", pattern> {
2464+
bits<4> Qn;
2465+
bits<2> rot;
2466+
2467+
let Inst{28} = size;
2468+
let Inst{21-20} = 0b11;
2469+
let Inst{19-17} = Qn{2-0};
2470+
let Inst{16} = 0b0;
2471+
let Inst{12} = rot{1};
2472+
let Inst{8} = 0b0;
2473+
let Inst{7} = Qn{3};
2474+
let Inst{0} = rot{0};
2475+
2476+
let Predicates = [HasMVEFloat];
2477+
}
2478+
2479+
def MVE_VCMULf16 : MVE_VCMUL<"vcmul", "f16", 0b0>;
2480+
def MVE_VCMULf32 : MVE_VCMUL<"vcmul", "f32", 0b1>;
2481+
2482+
class MVE_VMULL<string iname, string suffix, bit bit_28, bits<2> bits_21_20,
2483+
bit T, list<dag> pattern=[]>
2484+
: MVE_qDest_qSrc<iname, suffix, (outs MQPR:$Qd),
2485+
(ins MQPR:$Qn, MQPR:$Qm), "$Qd, $Qn, $Qm",
2486+
vpred_r, "", pattern> {
2487+
bits<4> Qd;
2488+
bits<4> Qn;
2489+
bits<4> Qm;
2490+
2491+
let Inst{28} = bit_28;
2492+
let Inst{21-20} = bits_21_20;
2493+
let Inst{19-17} = Qn{2-0};
2494+
let Inst{16} = 0b1;
2495+
let Inst{12} = T;
2496+
let Inst{8} = 0b0;
2497+
let Inst{7} = Qn{3};
2498+
let Inst{0} = 0b0;
2499+
}
2500+
2501+
multiclass MVE_VMULL_multi<string iname, string suffix,
2502+
bit bit_28, bits<2> bits_21_20> {
2503+
def bh : MVE_VMULL<iname # "b", suffix, bit_28, bits_21_20, 0b0>;
2504+
def th : MVE_VMULL<iname # "t", suffix, bit_28, bits_21_20, 0b1>;
2505+
}
2506+
2507+
// For integer multiplies, bits 21:20 encode size, and bit 28 signedness.
2508+
// For polynomial multiplies, bits 21:20 take the unused value 0b11, and
2509+
// bit 28 switches to encoding the size.
2510+
2511+
defm MVE_VMULLs8 : MVE_VMULL_multi<"vmull", "s8", 0b0, 0b00>;
2512+
defm MVE_VMULLs16 : MVE_VMULL_multi<"vmull", "s16", 0b0, 0b01>;
2513+
defm MVE_VMULLs32 : MVE_VMULL_multi<"vmull", "s32", 0b0, 0b10>;
2514+
defm MVE_VMULLu8 : MVE_VMULL_multi<"vmull", "u8", 0b1, 0b00>;
2515+
defm MVE_VMULLu16 : MVE_VMULL_multi<"vmull", "u16", 0b1, 0b01>;
2516+
defm MVE_VMULLu32 : MVE_VMULL_multi<"vmull", "u32", 0b1, 0b10>;
2517+
defm MVE_VMULLp8 : MVE_VMULL_multi<"vmull", "p8", 0b0, 0b11>;
2518+
defm MVE_VMULLp16 : MVE_VMULL_multi<"vmull", "p16", 0b1, 0b11>;
2519+
2520+
class MVE_VxMULH<string iname, string suffix, bit U, bits<2> size,
2521+
bit round, list<dag> pattern=[]>
2522+
: MVE_qDest_qSrc<iname, suffix, (outs MQPR:$Qd),
2523+
(ins MQPR:$Qn, MQPR:$Qm), "$Qd, $Qn, $Qm",
2524+
vpred_r, "", pattern> {
2525+
bits<4> Qn;
2526+
2527+
let Inst{28} = U;
2528+
let Inst{21-20} = size;
2529+
let Inst{19-17} = Qn{2-0};
2530+
let Inst{16} = 0b1;
2531+
let Inst{12} = round;
2532+
let Inst{8} = 0b0;
2533+
let Inst{7} = Qn{3};
2534+
let Inst{0} = 0b1;
2535+
}
2536+
2537+
def MVE_VMULHs8 : MVE_VxMULH<"vmulh", "s8", 0b0, 0b00, 0b0>;
2538+
def MVE_VMULHs16 : MVE_VxMULH<"vmulh", "s16", 0b0, 0b01, 0b0>;
2539+
def MVE_VMULHs32 : MVE_VxMULH<"vmulh", "s32", 0b0, 0b10, 0b0>;
2540+
def MVE_VMULHu8 : MVE_VxMULH<"vmulh", "u8", 0b1, 0b00, 0b0>;
2541+
def MVE_VMULHu16 : MVE_VxMULH<"vmulh", "u16", 0b1, 0b01, 0b0>;
2542+
def MVE_VMULHu32 : MVE_VxMULH<"vmulh", "u32", 0b1, 0b10, 0b0>;
2543+
2544+
def MVE_VRMULHs8 : MVE_VxMULH<"vrmulh", "s8", 0b0, 0b00, 0b1>;
2545+
def MVE_VRMULHs16 : MVE_VxMULH<"vrmulh", "s16", 0b0, 0b01, 0b1>;
2546+
def MVE_VRMULHs32 : MVE_VxMULH<"vrmulh", "s32", 0b0, 0b10, 0b1>;
2547+
def MVE_VRMULHu8 : MVE_VxMULH<"vrmulh", "u8", 0b1, 0b00, 0b1>;
2548+
def MVE_VRMULHu16 : MVE_VxMULH<"vrmulh", "u16", 0b1, 0b01, 0b1>;
2549+
def MVE_VRMULHu32 : MVE_VxMULH<"vrmulh", "u32", 0b1, 0b10, 0b1>;
2550+
2551+
class MVE_VxMOVxN<string iname, string suffix, bit bit_28, bit bit_17,
2552+
bits<2> size, bit T, list<dag> pattern=[]>
2553+
: MVE_qDest_qSrc<iname, suffix, (outs MQPR:$Qd),
2554+
(ins MQPR:$Qd_src, MQPR:$Qm), "$Qd, $Qm",
2555+
vpred_n, "$Qd = $Qd_src", pattern> {
2556+
2557+
let Inst{28} = bit_28;
2558+
let Inst{21-20} = 0b11;
2559+
let Inst{19-18} = size;
2560+
let Inst{17} = bit_17;
2561+
let Inst{16} = 0b1;
2562+
let Inst{12} = T;
2563+
let Inst{8} = 0b0;
2564+
let Inst{7} = !if(!eq(bit_17, 0), 1, 0);
2565+
let Inst{0} = 0b1;
2566+
}
2567+
2568+
multiclass MVE_VxMOVxN_halves<string iname, string suffix,
2569+
bit bit_28, bit bit_17, bits<2> size> {
2570+
def bh : MVE_VxMOVxN<iname # "b", suffix, bit_28, bit_17, size, 0b0>;
2571+
def th : MVE_VxMOVxN<iname # "t", suffix, bit_28, bit_17, size, 0b1>;
2572+
}
2573+
2574+
defm MVE_VMOVNi16 : MVE_VxMOVxN_halves<"vmovn", "i16", 0b1, 0b0, 0b00>;
2575+
defm MVE_VMOVNi32 : MVE_VxMOVxN_halves<"vmovn", "i32", 0b1, 0b0, 0b01>;
2576+
defm MVE_VQMOVNs16 : MVE_VxMOVxN_halves<"vqmovn", "s16", 0b0, 0b1, 0b00>;
2577+
defm MVE_VQMOVNs32 : MVE_VxMOVxN_halves<"vqmovn", "s32", 0b0, 0b1, 0b01>;
2578+
defm MVE_VQMOVNu16 : MVE_VxMOVxN_halves<"vqmovn", "u16", 0b1, 0b1, 0b00>;
2579+
defm MVE_VQMOVNu32 : MVE_VxMOVxN_halves<"vqmovn", "u32", 0b1, 0b1, 0b01>;
2580+
defm MVE_VQMOVUNs16 : MVE_VxMOVxN_halves<"vqmovun", "s16", 0b0, 0b0, 0b00>;
2581+
defm MVE_VQMOVUNs32 : MVE_VxMOVxN_halves<"vqmovun", "s32", 0b0, 0b0, 0b01>;
2582+
2583+
class MVE_VCVT_ff<string iname, string suffix, bit op, bit T,
2584+
list<dag> pattern=[]>
2585+
: MVE_qDest_qSrc<iname, suffix, (outs MQPR:$Qd), (ins MQPR:$Qd_src, MQPR:$Qm),
2586+
"$Qd, $Qm", vpred_n, "$Qd = $Qd_src", pattern> {
2587+
let Inst{28} = op;
2588+
let Inst{21-16} = 0b111111;
2589+
let Inst{12} = T;
2590+
let Inst{8-7} = 0b00;
2591+
let Inst{0} = 0b1;
2592+
2593+
let Predicates = [HasMVEFloat];
2594+
}
2595+
2596+
multiclass MVE_VCVT_ff_halves<string suffix, bit op> {
2597+
def bh : MVE_VCVT_ff<"vcvtb", suffix, op, 0b0>;
2598+
def th : MVE_VCVT_ff<"vcvtt", suffix, op, 0b1>;
2599+
}
2600+
2601+
defm MVE_VCVTf16f32 : MVE_VCVT_ff_halves<"f16.f32", 0b0>;
2602+
defm MVE_VCVTf32f16 : MVE_VCVT_ff_halves<"f32.f16", 0b1>;
2603+
2604+
class MVE_VxCADD<string iname, string suffix, bits<2> size, bit halve,
2605+
list<dag> pattern=[]>
2606+
: MVE_qDest_qSrc<iname, suffix, (outs MQPR:$Qd),
2607+
(ins MQPR:$Qn, MQPR:$Qm, complexrotateopodd:$rot),
2608+
"$Qd, $Qn, $Qm, $rot", vpred_r, "",
2609+
pattern> {
2610+
bits<4> Qn;
2611+
bit rot;
2612+
2613+
let Inst{28} = halve;
2614+
let Inst{21-20} = size;
2615+
let Inst{19-17} = Qn{2-0};
2616+
let Inst{16} = 0b0;
2617+
let Inst{12} = rot;
2618+
let Inst{8} = 0b1;
2619+
let Inst{7} = Qn{3};
2620+
let Inst{0} = 0b0;
2621+
}
2622+
2623+
def MVE_VCADDi8 : MVE_VxCADD<"vcadd", "i8", 0b00, 0b1>;
2624+
def MVE_VCADDi16 : MVE_VxCADD<"vcadd", "i16", 0b01, 0b1>;
2625+
def MVE_VCADDi32 : MVE_VxCADD<"vcadd", "i32", 0b10, 0b1>;
2626+
2627+
def MVE_VHCADDs8 : MVE_VxCADD<"vhcadd", "s8", 0b00, 0b0>;
2628+
def MVE_VHCADDs16 : MVE_VxCADD<"vhcadd", "s16", 0b01, 0b0>;
2629+
def MVE_VHCADDs32 : MVE_VxCADD<"vhcadd", "s32", 0b10, 0b0>;
2630+
2631+
class MVE_VADCSBC<string iname, bit I, bit subtract,
2632+
dag carryin, list<dag> pattern=[]>
2633+
: MVE_qDest_qSrc<iname, "i32", (outs MQPR:$Qd, cl_FPSCR_NZCV:$carryout),
2634+
!con((ins MQPR:$Qn, MQPR:$Qm), carryin),
2635+
"$Qd, $Qn, $Qm", vpred_r, "", pattern> {
2636+
bits<4> Qn;
2637+
2638+
let Inst{28} = subtract;
2639+
let Inst{21-20} = 0b11;
2640+
let Inst{19-17} = Qn{2-0};
2641+
let Inst{16} = 0b0;
2642+
let Inst{12} = I;
2643+
let Inst{8} = 0b1;
2644+
let Inst{7} = Qn{3};
2645+
let Inst{0} = 0b0;
2646+
2647+
// Custom decoder method in order to add the FPSCR operand(s), which
2648+
// Tablegen won't do right
2649+
let DecoderMethod = "DecodeMVEVADCInstruction";
2650+
}
2651+
2652+
def MVE_VADC : MVE_VADCSBC<"vadc", 0b0, 0b0, (ins cl_FPSCR_NZCV:$carryin)>;
2653+
def MVE_VADCI : MVE_VADCSBC<"vadci", 0b1, 0b0, (ins)>;
2654+
2655+
def MVE_VSBC : MVE_VADCSBC<"vsbc", 0b0, 0b1, (ins cl_FPSCR_NZCV:$carryin)>;
2656+
def MVE_VSBCI : MVE_VADCSBC<"vsbci", 0b1, 0b1, (ins)>;
2657+
2658+
class MVE_VQDMULL<string iname, string suffix, bit size, bit T,
2659+
list<dag> pattern=[]>
2660+
: MVE_qDest_qSrc<iname, suffix, (outs MQPR:$Qd),
2661+
(ins MQPR:$Qn, MQPR:$Qm), "$Qd, $Qn, $Qm",
2662+
vpred_r, "", pattern> {
2663+
bits<4> Qn;
2664+
2665+
let Inst{28} = size;
2666+
let Inst{21-20} = 0b11;
2667+
let Inst{19-17} = Qn{2-0};
2668+
let Inst{16} = 0b0;
2669+
let Inst{12} = T;
2670+
let Inst{8} = 0b1;
2671+
let Inst{7} = Qn{3};
2672+
let Inst{0} = 0b1;
2673+
}
2674+
2675+
multiclass MVE_VQDMULL_halves<string suffix, bit size> {
2676+
def bh : MVE_VQDMULL<"vqdmullb", suffix, size, 0b0>;
2677+
def th : MVE_VQDMULL<"vqdmullt", suffix, size, 0b1>;
2678+
}
2679+
2680+
defm MVE_VQDMULLs16 : MVE_VQDMULL_halves<"s16", 0b0>;
2681+
defm MVE_VQDMULLs32 : MVE_VQDMULL_halves<"s32", 0b1>;
2682+
2683+
// end of mve_qDest_qSrc
2684+
24072685
class MVE_VPT<string suffix, bits<2> size, dag iops, string asm, list<dag> pattern=[]>
24082686
: MVE_MI<(outs ), iops, NoItinerary, !strconcat("vpt", "${Mk}", ".", suffix), asm, "", pattern> {
24092687
bits<3> fc;

‎llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp

+40-1
Original file line numberDiff line numberDiff line change
@@ -5966,6 +5966,7 @@ StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic,
59665966
Mnemonic == "vnege" || Mnemonic == "vnegt" ||
59675967
Mnemonic == "vmule" || Mnemonic == "vmult" ||
59685968
Mnemonic == "vrintne" ||
5969+
Mnemonic == "vcmult" || Mnemonic == "vcmule" ||
59695970
Mnemonic.startswith("vq")))) {
59705971
unsigned CC = ARMCondCodeFromString(Mnemonic.substr(Mnemonic.size()-2));
59715972
if (CC != ~0U) {
@@ -6010,7 +6011,10 @@ StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic,
60106011
if (isMnemonicVPTPredicable(Mnemonic, ExtraToken) && Mnemonic != "vmovlt" &&
60116012
Mnemonic != "vshllt" && Mnemonic != "vrshrnt" && Mnemonic != "vshrnt" &&
60126013
Mnemonic != "vqrshrunt" && Mnemonic != "vqshrunt" &&
6013-
Mnemonic != "vqrshrnt" && Mnemonic != "vqshrnt" && Mnemonic != "vcvt") {
6014+
Mnemonic != "vqrshrnt" && Mnemonic != "vqshrnt" && Mnemonic != "vmullt" &&
6015+
Mnemonic != "vqmovnt" && Mnemonic != "vqmovunt" &&
6016+
Mnemonic != "vqmovnt" && Mnemonic != "vmovnt" && Mnemonic != "vqdmullt" &&
6017+
Mnemonic != "vcvtt" && Mnemonic != "vcvt") {
60146018
unsigned CC = ARMVectorCondCodeFromString(Mnemonic.substr(Mnemonic.size()-1));
60156019
if (CC != ~0U) {
60166020
Mnemonic = Mnemonic.slice(0, Mnemonic.size()-1);
@@ -6683,6 +6687,16 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
66836687
ARMOperand::CreateVPTPred(ARMVCC::Else, PLoc));
66846688
Operands.insert(Operands.begin(),
66856689
ARMOperand::CreateToken(StringRef("vcvtn"), MLoc));
6690+
} else if (Mnemonic == "vmul" && PredicationCode == ARMCC::LT &&
6691+
!shouldOmitVectorPredicateOperand(Mnemonic, Operands)) {
6692+
// Another hack, this time to distinguish between scalar predicated vmul
6693+
// with 'lt' predication code and the vector instruction vmullt with
6694+
// vector predication code "none"
6695+
Operands.erase(Operands.begin() + 1);
6696+
Operands.erase(Operands.begin());
6697+
SMLoc MLoc = SMLoc::getFromPointer(NameLoc.getPointer());
6698+
Operands.insert(Operands.begin(),
6699+
ARMOperand::CreateToken(StringRef("vmullt"), MLoc));
66866700
}
66876701
// For vmov and vcmp, as mentioned earlier, we did not add the vector
66886702
// predication code, since these may contain operands that require
@@ -7541,6 +7555,31 @@ bool ARMAsmParser::validateInstruction(MCInst &Inst,
75417555
"list of registers must be at least 1 and at most 16");
75427556
break;
75437557
}
7558+
case ARM::MVE_VQDMULLs32bh:
7559+
case ARM::MVE_VQDMULLs32th:
7560+
case ARM::MVE_VCMULf32:
7561+
case ARM::MVE_VMULLs32bh:
7562+
case ARM::MVE_VMULLs32th:
7563+
case ARM::MVE_VMULLu32bh:
7564+
case ARM::MVE_VMULLu32th:
7565+
case ARM::MVE_VQDMLADHs32:
7566+
case ARM::MVE_VQDMLADHXs32:
7567+
case ARM::MVE_VQRDMLADHs32:
7568+
case ARM::MVE_VQRDMLADHXs32:
7569+
case ARM::MVE_VQDMLSDHs32:
7570+
case ARM::MVE_VQDMLSDHXs32:
7571+
case ARM::MVE_VQRDMLSDHs32:
7572+
case ARM::MVE_VQRDMLSDHXs32: {
7573+
if (Operands[3]->getReg() == Operands[4]->getReg()) {
7574+
return Error (Operands[3]->getStartLoc(),
7575+
"Qd register and Qn register can't be identical");
7576+
}
7577+
if (Operands[3]->getReg() == Operands[5]->getReg()) {
7578+
return Error (Operands[3]->getStartLoc(),
7579+
"Qd register and Qm register can't be identical");
7580+
}
7581+
break;
7582+
}
75447583
}
75457584

75467585
return false;

‎llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp

+27
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,8 @@ static DecodeStatus DecodeNEONModImmInstruction(MCInst &Inst,unsigned Val,
312312
uint64_t Address, const void *Decoder);
313313
static DecodeStatus DecodeMVEModImmInstruction(MCInst &Inst,unsigned Val,
314314
uint64_t Address, const void *Decoder);
315+
static DecodeStatus DecodeMVEVADCInstruction(MCInst &Inst, unsigned Insn,
316+
uint64_t Address, const void *Decoder);
315317
static DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Val,
316318
uint64_t Address, const void *Decoder);
317319
static DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val,
@@ -3462,6 +3464,31 @@ DecodeMVEModImmInstruction(MCInst &Inst, unsigned Insn,
34623464
return S;
34633465
}
34643466

3467+
static DecodeStatus DecodeMVEVADCInstruction(MCInst &Inst, unsigned Insn,
3468+
uint64_t Address, const void *Decoder) {
3469+
DecodeStatus S = MCDisassembler::Success;
3470+
3471+
unsigned Qd = fieldFromInstruction(Insn, 13, 3);
3472+
Qd |= fieldFromInstruction(Insn, 22, 1) << 3;
3473+
if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
3474+
return MCDisassembler::Fail;
3475+
Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV));
3476+
3477+
unsigned Qn = fieldFromInstruction(Insn, 17, 3);
3478+
Qn |= fieldFromInstruction(Insn, 7, 1) << 3;
3479+
if (!Check(S, DecodeMQPRRegisterClass(Inst, Qn, Address, Decoder)))
3480+
return MCDisassembler::Fail;
3481+
unsigned Qm = fieldFromInstruction(Insn, 1, 3);
3482+
Qm |= fieldFromInstruction(Insn, 5, 1) << 3;
3483+
if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder)))
3484+
return MCDisassembler::Fail;
3485+
if (!fieldFromInstruction(Insn, 12, 1)) // I bit clear => need input FPSCR
3486+
Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV));
3487+
Inst.addOperand(MCOperand::createImm(Qd));
3488+
3489+
return S;
3490+
}
3491+
34653492
static DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Insn,
34663493
uint64_t Address, const void *Decoder) {
34673494
DecodeStatus S = MCDisassembler::Success;

0 commit comments

Comments
 (0)
Please sign in to comment.