llvm.org GIT mirror llvm / 4ea2505
Add support for MC assembling and disassembling of vsel{ge, gt, eq, vs} instructions. This adds a new decoder table/namespace 'VFPV8', as these instructions have their top 4 bits as 0b1111, while other Thumb instructions have 0b1110. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185642 91177308-0d34-0410-b5e6-96231b3b80d8 Joey Gouly 7 years ago
6 changed file(s) with 137 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
15471547 let Inst{4} = op4;
15481548 }
15491549
1550 // FP, binary, not predicated
1551 class ADbInp opcod1, bits<2> opcod2, dag oops, dag iops,
1552 InstrItinClass itin, string asm, list pattern>
1553 : VFPXI
1554 VFPBinaryFrm, itin, asm, "", pattern>
1555 {
1556 // Instruction operands.
1557 bits<5> Dd;
1558 bits<5> Dn;
1559 bits<5> Dm;
1560
1561 let Inst{31-28} = 0b1111;
1562
1563 // Encode instruction operands.
1564 let Inst{3-0} = Dm{3-0};
1565 let Inst{5} = Dm{4};
1566 let Inst{19-16} = Dn{3-0};
1567 let Inst{7} = Dn{4};
1568 let Inst{15-12} = Dd{3-0};
1569 let Inst{22} = Dd{4};
1570
1571 let Inst{27-23} = opcod1;
1572 let Inst{21-20} = opcod2;
1573 let Inst{11-9} = 0b101;
1574 let Inst{8} = 1; // double precision
1575 let Inst{6} = 0;
1576 let Inst{4} = 0;
1577 }
1578
15501579 // Single precision, unary
15511580 class ASuI opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
15521581 bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
16041633 let Inst{8} = 0; // Single precision
16051634 let Inst{6} = op6;
16061635 let Inst{4} = op4;
1636 }
1637
1638 // Single precision, binary, not predicated
1639 class ASbInp opcod1, bits<2> opcod2, dag oops, dag iops,
1640 InstrItinClass itin, string asm, list pattern>
1641 : VFPXI
1642 VFPBinaryFrm, itin, asm, "", pattern>
1643 {
1644 // Instruction operands.
1645 bits<5> Sd;
1646 bits<5> Sn;
1647 bits<5> Sm;
1648
1649 let Inst{31-28} = 0b1111;
1650
1651 // Encode instruction operands.
1652 let Inst{3-0} = Sm{4-1};
1653 let Inst{5} = Sm{0};
1654 let Inst{19-16} = Sn{4-1};
1655 let Inst{7} = Sn{0};
1656 let Inst{15-12} = Sd{4-1};
1657 let Inst{22} = Sd{0};
1658
1659 let Inst{27-23} = opcod1;
1660 let Inst{21-20} = opcod2;
1661 let Inst{11-9} = 0b101;
1662 let Inst{8} = 0; // Single precision
1663 let Inst{6} = 0;
1664 let Inst{4} = 0;
16071665 }
16081666
16091667 // Single precision binary, if no NEON. Same as ASbI except not available if
331331 // VFP pipelines on A8.
332332 let D = VFPNeonA8Domain;
333333 }
334
335 multiclass vsel_inst opc> {
336 let DecoderNamespace = "VFPV8", PostEncoderMethod = "" in {
337 def S : ASbInp<0b11100, opc,
338 (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
339 NoItinerary, !strconcat("vsel", op, ".f32\t$Sd, $Sn, $Sm"),
340 []>, Requires<[HasV8FP]>;
341
342 def D : ADbInp<0b11100, opc,
343 (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
344 NoItinerary, !strconcat("vsel", op, ".f64\t$Dd, $Dn, $Dm"),
345 []>, Requires<[HasV8FP]>;
346 }
347 }
348
349 defm VSELGT : vsel_inst<"gt", 0b11>;
350 defm VSELGE : vsel_inst<"ge", 0b10>;
351 defm VSELEQ : vsel_inst<"eq", 0b00>;
352 defm VSELVS : vsel_inst<"vs", 0b01>;
334353
335354 // Match reassociated forms only if not sign dependent rounding.
336355 def : Pat<(fmul (fneg DPR:$a), (f64 DPR:$b)),
49044904 Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" ||
49054905 Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" ||
49064906 Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal" ||
4907 Mnemonic == "fmuls")
4907 Mnemonic == "fmuls" || Mnemonic.startswith("vsel"))
49084908 return Mnemonic;
49094909
49104910 // First, split out any predication code. Ignore mnemonics we know aren't
50045004 if (Mnemonic == "bkpt" || Mnemonic == "cbnz" || Mnemonic == "setend" ||
50055005 Mnemonic == "cps" || Mnemonic == "it" || Mnemonic == "cbz" ||
50065006 Mnemonic == "trap" || Mnemonic == "setend" ||
5007 Mnemonic.startswith("cps")) {
5007 Mnemonic.startswith("cps") || Mnemonic.startswith("vsel")) {
50085008 // These mnemonics are never predicable
50095009 CanAcceptPredicationCode = false;
50105010 } else if (!isThumb()) {
455455 }
456456
457457 MI.clear();
458 result = decodeInstruction(DecoderTableVFPV832, MI, insn, Address, this, STI);
459 if (result != MCDisassembler::Fail) {
460 Size = 4;
461 return result;
462 }
463
464 MI.clear();
458465 result = decodeInstruction(DecoderTableNEONData32, MI, insn, Address,
459466 this, STI);
460467 if (result != MCDisassembler::Fail) {
761768 UpdateThumbVFPPredicate(MI);
762769 return result;
763770 }
771 }
772
773 MI.clear();
774 result = decodeInstruction(DecoderTableVFPV832, MI, insn32, Address, this, STI);
775 if (result != MCDisassembler::Fail) {
776 Size = 4;
777 UpdateThumbVFPPredicate(MI);
778 return result;
764779 }
765780
766781 if (fieldFromInstruction(insn32, 28, 4) == 0xE) {
2020 @ CHECK: vcvtbeq.f64.f16 d3, s1 @ encoding: [0x60,0x3b,0xb2,0x0e]
2121 vcvtblt.f16.f64 s4, d1
2222 @ CHECK: vcvtblt.f16.f64 s4, d1 @ encoding: [0x41,0x2b,0xb3,0xbe]
23
24 @ VSEL
25 vselge.f32 s4, s1, s23
26 @ CHECK: vselge.f32 s4, s1, s23 @ encoding: [0xab,0x2a,0x20,0xfe]
27 vselge.f64 d30, d31, d23
28 @ CHECK: vselge.f64 d30, d31, d23 @ encoding: [0xa7,0xeb,0x6f,0xfe]
29 vselgt.f32 s0, s1, s0
30 @ CHECK: vselgt.f32 s0, s1, s0 @ encoding: [0x80,0x0a,0x30,0xfe]
31 vselgt.f64 d5, d10, d20
32 @ CHECK: vselgt.f64 d5, d10, d20 @ encoding: [0x24,0x5b,0x3a,0xfe]
33 vseleq.f32 s30, s28, s23
34 @ CHECK: vseleq.f32 s30, s28, s23 @ encoding: [0x2b,0xfa,0x0e,0xfe]
35 vseleq.f64 d2, d4, d8
36 @ CHECK: vseleq.f64 d2, d4, d8 @ encoding: [0x08,0x2b,0x04,0xfe]
37 vselvs.f32 s21, s16, s14
38 @ CHECK: vselvs.f32 s21, s16, s14 @ encoding: [0x07,0xaa,0x58,0xfe]
39 vselvs.f64 d0, d1, d31
40 @ CHECK: vselvs.f64 d0, d1, d31 @ encoding: [0x2f,0x0b,0x11,0xfe]
2222
2323 0x41 0x2b 0xb3 0xbe
2424 # CHECK: vcvtblt.f16.f64 s4, d1
25
26
27 0xab 0x2a 0x20 0xfe
28 # CHECK: vselge.f32 s4, s1, s23
29
30 0xa7 0xeb 0x6f 0xfe
31 # CHECK: vselge.f64 d30, d31, d23
32
33 0x80 0x0a 0x30 0xfe
34 # CHECK: vselgt.f32 s0, s1, s0
35
36 0x24 0x5b 0x3a 0xfe
37 # CHECK: vselgt.f64 d5, d10, d20
38
39 0x2b 0xfa 0x0e 0xfe
40 # CHECK: vseleq.f32 s30, s28, s23
41
42 0x08 0x2b 0x04 0xfe
43 # CHECK: vseleq.f64 d2, d4, d8
44
45 0x07 0xaa 0x58 0xfe
46 # CHECK: vselvs.f32 s21, s16, s14
47
48 0x2f 0x0b 0x11 0xfe
49 # CHECK: vselvs.f64 d0, d1, d31