@@ -2404,6 +2404,284 @@ def MVE_VCMPs32r : MVE_VCMPqrs<"s32", 0b10>;
2404
2404
2405
2405
// end of MVE compares
2406
2406
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
+
2407
2685
class MVE_VPT<string suffix, bits<2> size, dag iops, string asm, list<dag> pattern=[]>
2408
2686
: MVE_MI<(outs ), iops, NoItinerary, !strconcat("vpt", "${Mk}", ".", suffix), asm, "", pattern> {
2409
2687
bits<3> fc;
0 commit comments