llvm.org GIT mirror llvm / 460a905
ARM NEON assembly parsing and encoding for VDUP(scalar). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141446 91177308-0d34-0410-b5e6-96231b3b80d8 Jim Grosbach 8 years ago
7 changed file(s) with 200 addition(s) and 26 deletion(s). Raw diff Collapse all Expand all
19501950
19511951 bits<5> Vd;
19521952 bits<5> Vm;
1953 bits<4> lane;
19541953
19551954 let Inst{22} = Vd{4};
19561955 let Inst{15-12} = Vd{3-0};
99 // This file describes the ARM NEON instruction set.
1010 //
1111 //===----------------------------------------------------------------------===//
12
13
14 //===----------------------------------------------------------------------===//
15 // NEON-specific Operands.
16 //===----------------------------------------------------------------------===//
17 def VectorIndex8Operand : AsmOperandClass { let Name = "VectorIndex8"; }
18 def VectorIndex16Operand : AsmOperandClass { let Name = "VectorIndex16"; }
19 def VectorIndex32Operand : AsmOperandClass { let Name = "VectorIndex32"; }
20 def VectorIndex8 : Operand, ImmLeaf
21 return ((uint64_t)Imm) < 8;
22 }]> {
23 let ParserMatchClass = VectorIndex8Operand;
24 let PrintMethod = "printVectorIndex";
25 let MIOperandInfo = (ops i32imm);
26 }
27 def VectorIndex16 : Operand, ImmLeaf
28 return ((uint64_t)Imm) < 4;
29 }]> {
30 let ParserMatchClass = VectorIndex16Operand;
31 let PrintMethod = "printVectorIndex";
32 let MIOperandInfo = (ops i32imm);
33 }
34 def VectorIndex32 : Operand, ImmLeaf
35 return ((uint64_t)Imm) < 2;
36 }]> {
37 let ParserMatchClass = VectorIndex32Operand;
38 let PrintMethod = "printVectorIndex";
39 let MIOperandInfo = (ops i32imm);
40 }
1241
1342 //===----------------------------------------------------------------------===//
1443 // NEON-specific DAG Nodes.
45174546 // VDUP : Vector Duplicate Lane (from scalar to all elements)
45184547
45194548 class VDUPLND op19_16, string OpcodeStr, string Dt,
4520 ValueType Ty>
4521 : NVDupLane
4522 IIC_VMOVD, OpcodeStr, Dt, "$Vd, $Vm[$lane]",
4549 ValueType Ty, Operand IdxTy>
4550 : NVDupLane
4551 IIC_VMOVD, OpcodeStr, Dt, "$Vd, $Vm$lane",
45234552 [(set DPR:$Vd, (Ty (NEONvduplane (Ty DPR:$Vm), imm:$lane)))]>;
45244553
45254554 class VDUPLNQ op19_16, string OpcodeStr, string Dt,
4526 ValueType ResTy, ValueType OpTy>
4527 : NVDupLane
4528 IIC_VMOVQ, OpcodeStr, Dt, "$Vd, $Vm[$lane]",
4555 ValueType ResTy, ValueType OpTy, Operand IdxTy>
4556 : NVDupLane
4557 IIC_VMOVQ, OpcodeStr, Dt, "$Vd, $Vm$lane",
45294558 [(set QPR:$Vd, (ResTy (NEONvduplane (OpTy DPR:$Vm),
4530 imm:$lane)))]>;
4559 VectorIndex32:$lane)))]>;
45314560
45324561 // Inst{19-16} is partially specified depending on the element size.
45334562
4534 def VDUPLN8d : VDUPLND<{?,?,?,1}, "vdup", "8", v8i8> {
4563 def VDUPLN8d : VDUPLND<{?,?,?,1}, "vdup", "8", v8i8, VectorIndex8> {
4564 bits<3> lane;
45354565 let Inst{19-17} = lane{2-0};
45364566 }
4537 def VDUPLN16d : VDUPLND<{?,?,1,0}, "vdup", "16", v4i16> {
4567 def VDUPLN16d : VDUPLND<{?,?,1,0}, "vdup", "16", v4i16, VectorIndex16> {
4568 bits<2> lane;
45384569 let Inst{19-18} = lane{1-0};
45394570 }
4540 def VDUPLN32d : VDUPLND<{?,1,0,0}, "vdup", "32", v2i32> {
4571 def VDUPLN32d : VDUPLND<{?,1,0,0}, "vdup", "32", v2i32, VectorIndex32> {
4572 bits<1> lane;
45414573 let Inst{19} = lane{0};
45424574 }
4543 def VDUPLN8q : VDUPLNQ<{?,?,?,1}, "vdup", "8", v16i8, v8i8> {
4575 def VDUPLN8q : VDUPLNQ<{?,?,?,1}, "vdup", "8", v16i8, v8i8, VectorIndex8> {
4576 bits<3> lane;
45444577 let Inst{19-17} = lane{2-0};
45454578 }
4546 def VDUPLN16q : VDUPLNQ<{?,?,1,0}, "vdup", "16", v8i16, v4i16> {
4579 def VDUPLN16q : VDUPLNQ<{?,?,1,0}, "vdup", "16", v8i16, v4i16, VectorIndex16> {
4580 bits<2> lane;
45474581 let Inst{19-18} = lane{1-0};
45484582 }
4549 def VDUPLN32q : VDUPLNQ<{?,1,0,0}, "vdup", "32", v4i32, v2i32> {
4583 def VDUPLN32q : VDUPLNQ<{?,1,0,0}, "vdup", "32", v4i32, v2i32, VectorIndex32> {
4584 bits<1> lane;
45504585 let Inst{19} = lane{0};
45514586 }
45524587
253253 k_PostIndexRegister,
254254 k_MSRMask,
255255 k_ProcIFlags,
256 k_VectorIndex,
256257 k_Register,
257258 k_RegisterList,
258259 k_DPRRegisterList,
301302 struct {
302303 unsigned RegNum;
303304 } Reg;
305
306 struct {
307 unsigned Val;
308 } VectorIndex;
304309
305310 struct {
306311 const MCExpr *Val;
418423 case k_BitfieldDescriptor:
419424 Bitfield = o.Bitfield;
420425 break;
426 case k_VectorIndex:
427 VectorIndex = o.VectorIndex;
428 break;
421429 }
422430 }
423431
460468 unsigned getFPImm() const {
461469 assert(Kind == k_FPImmediate && "Invalid access!");
462470 return FPImm.Val;
471 }
472
473 unsigned getVectorIndex() const {
474 assert(Kind == k_VectorIndex && "Invalid access!");
475 return VectorIndex.Val;
463476 }
464477
465478 ARM_MB::MemBOpt getMemBarrierOpt() const {
858871 bool isMSRMask() const { return Kind == k_MSRMask; }
859872 bool isProcIFlags() const { return Kind == k_ProcIFlags; }
860873
874 bool isVectorIndex8() const {
875 if (Kind != k_VectorIndex) return false;
876 return VectorIndex.Val < 8;
877 }
878 bool isVectorIndex16() const {
879 if (Kind != k_VectorIndex) return false;
880 return VectorIndex.Val < 4;
881 }
882 bool isVectorIndex32() const {
883 if (Kind != k_VectorIndex) return false;
884 return VectorIndex.Val < 2;
885 }
886
887
888
861889 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
862890 // Add as immediates when possible. Null MCExpr = 0.
863891 if (Expr == 0)
13421370 Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags())));
13431371 }
13441372
1373 void addVectorIndex8Operands(MCInst &Inst, unsigned N) const {
1374 assert(N == 1 && "Invalid number of operands!");
1375 Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1376 }
1377
1378 void addVectorIndex16Operands(MCInst &Inst, unsigned N) const {
1379 assert(N == 1 && "Invalid number of operands!");
1380 Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1381 }
1382
1383 void addVectorIndex32Operands(MCInst &Inst, unsigned N) const {
1384 assert(N == 1 && "Invalid number of operands!");
1385 Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1386 }
1387
13451388 virtual void print(raw_ostream &OS) const;
13461389
13471390 static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) {
14751518 array_pod_sort(Op->Registers.begin(), Op->Registers.end());
14761519 Op->StartLoc = StartLoc;
14771520 Op->EndLoc = EndLoc;
1521 return Op;
1522 }
1523
1524 static ARMOperand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E,
1525 MCContext &Ctx) {
1526 ARMOperand *Op = new ARMOperand(k_VectorIndex);
1527 Op->VectorIndex.Val = Idx;
1528 Op->StartLoc = S;
1529 Op->EndLoc = E;
14781530 return Op;
14791531 }
14801532
16581710 case k_Token:
16591711 OS << "'" << getToken() << "'";
16601712 break;
1713 case k_VectorIndex:
1714 OS << "";
1715 break;
16611716 }
16621717 }
16631718
16991754 if (!RegNum) return -1;
17001755
17011756 Parser.Lex(); // Eat identifier token.
1757
1758 #if 0
1759 // Also check for an index operand. This is only legal for vector registers,
1760 // but that'll get caught OK in operand matching, so we don't need to
1761 // explicitly filter everything else out here.
1762 if (Parser.getTok().is(AsmToken::LBrac)) {
1763 SMLoc SIdx = Parser.getTok().getLoc();
1764 Parser.Lex(); // Eat left bracket token.
1765
1766 const MCExpr *ImmVal;
1767 SMLoc ExprLoc = Parser.getTok().getLoc();
1768 if (getParser().ParseExpression(ImmVal))
1769 return MatchOperand_ParseFail;
1770 const MCConstantExpr *MCE = dyn_cast(ImmVal);
1771 if (!MCE) {
1772 TokError("immediate value expected for vector index");
1773 return MatchOperand_ParseFail;
1774 }
1775
1776 SMLoc E = Parser.getTok().getLoc();
1777 if (Parser.getTok().isNot(AsmToken::RBrac)) {
1778 Error(E, "']' expected");
1779 return MatchOperand_ParseFail;
1780 }
1781
1782 Parser.Lex(); // Eat right bracket token.
1783
1784 Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(),
1785 SIdx, E,
1786 getContext()));
1787 }
1788 #endif
1789
17021790 return RegNum;
17031791 }
17041792
18141902 Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
18151903 ExclaimTok.getLoc()));
18161904 Parser.Lex(); // Eat exclaim token
1905 return false;
1906 }
1907
1908 // Also check for an index operand. This is only legal for vector registers,
1909 // but that'll get caught OK in operand matching, so we don't need to
1910 // explicitly filter everything else out here.
1911 if (Parser.getTok().is(AsmToken::LBrac)) {
1912 SMLoc SIdx = Parser.getTok().getLoc();
1913 Parser.Lex(); // Eat left bracket token.
1914
1915 const MCExpr *ImmVal;
1916 SMLoc ExprLoc = Parser.getTok().getLoc();
1917 if (getParser().ParseExpression(ImmVal))
1918 return MatchOperand_ParseFail;
1919 const MCConstantExpr *MCE = dyn_cast(ImmVal);
1920 if (!MCE) {
1921 TokError("immediate value expected for vector index");
1922 return MatchOperand_ParseFail;
1923 }
1924
1925 SMLoc E = Parser.getTok().getLoc();
1926 if (Parser.getTok().isNot(AsmToken::RBrac)) {
1927 Error(E, "']' expected");
1928 return MatchOperand_ParseFail;
1929 }
1930
1931 Parser.Lex(); // Eat right bracket token.
1932
1933 Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(),
1934 SIdx, E,
1935 getContext()));
18171936 }
18181937
18191938 return false;
980980 case 3: O << "24"; break;
981981 }
982982 }
983
984 void ARMInstPrinter::printVectorIndex(const MCInst *MI, unsigned OpNum,
985 raw_ostream &O) {
986 O << "[" << MI->getOperand(OpNum).getImm() << "]";
987 }
126126
127127 void printPCLabel(const MCInst *MI, unsigned OpNum, raw_ostream &O);
128128 void printT2LdrLabelOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
129 void printVectorIndex(const MCInst *MI, unsigned OpNum, raw_ostream &O);
129130 };
130131
131132 } // end namespace llvm
1515 @ CHECK: vdup.16 q8, r5 @ encoding: [0xa0,0xee,0xb0,0x5b]
1616 @ CHECK: vdup.32 q7, r6 @ encoding: [0xae,0xee,0x10,0x6b]
1717
18 @ vdup.8 d16, d16[1]
19 @ vdup.16 d16, d16[1]
20 @ vdup.32 d16, d16[1]
21 @ vdup.8 q8, d16[1]
22 @ vdup.16 q8, d16[1]
23 @ vdup.32 q8, d16[1]
18 vdup.8 d16, d11[0]
19 vdup.16 d17, d12[0]
20 vdup.32 d18, d13[0]
21 vdup.8 q3, d10[0]
22 vdup.16 q9, d9[0]
23 vdup.32 q8, d8[0]
24 vdup.8 d16, d11[1]
25 vdup.16 d17, d12[1]
26 vdup.32 d18, d13[1]
27 vdup.8 q3, d10[1]
28 vdup.16 q9, d9[1]
29 vdup.32 q8, d8[1]
2430
25 @ FIXME: vdup.8 d16, d16[1] @ encoding: [0x20,0x0c,0xf3,0xff]
26 @ FIXME: vdup.16 d16, d16[1] @ encoding: [0x20,0x0c,0xf6,0xff]
27 @ FIXME: vdup.32 d16, d16[1] @ encoding: [0x20,0x0c,0xfc,0xff]
28 @ FIXME: vdup.8 q8, d16[1] @ encoding: [0x60,0x0c,0xf3,0xff]
29 @ FIXME: vdup.16 q8, d16[1] @ encoding: [0x60,0x0c,0xf6,0xff]
30 @ FIXME: vdup.32 q8, d16[1] @ encoding: [0x60,0x0c,0xfc,0xff]
31 @ CHECK: vdup.8 d16, d11[0] @ encoding: [0xf1,0xff,0x0b,0x0c]
32 @ CHECK: vdup.16 d17, d12[0] @ encoding: [0xf2,0xff,0x0c,0x1c]
33 @ CHECK: vdup.32 d18, d13[0] @ encoding: [0xf4,0xff,0x0d,0x2c]
34 @ CHECK: vdup.8 q3, d10[0] @ encoding: [0xb1,0xff,0x4a,0x6c]
35 @ CHECK: vdup.16 q9, d9[0] @ encoding: [0xf2,0xff,0x49,0x2c]
36 @ CHECK: vdup.32 q8, d8[0] @ encoding: [0xf4,0xff,0x48,0x0c]
37 @ CHECK: vdup.8 d16, d11[1] @ encoding: [0xf3,0xff,0x0b,0x0c]
38 @ CHECK: vdup.16 d17, d12[1] @ encoding: [0xf6,0xff,0x0c,0x1c]
39 @ CHECK: vdup.32 d18, d13[1] @ encoding: [0xfc,0xff,0x0d,0x2c]
40 @ CHECK: vdup.8 q3, d10[1] @ encoding: [0xb3,0xff,0x4a,0x6c]
41 @ CHECK: vdup.16 q9, d9[1] @ encoding: [0xf6,0xff,0x49,0x2c]
42 @ CHECK: vdup.32 q8, d8[1] @ encoding: [0xfc,0xff,0x48,0x0c]
623623 IMM("postidx_imm8s4");
624624 IMM("imm_sr");
625625 IMM("imm1_31");
626 IMM("VectorIndex8");
627 IMM("VectorIndex16");
628 IMM("VectorIndex32");
626629
627630 MISC("brtarget", "kOperandTypeARMBranchTarget"); // ?
628631 MISC("uncondbrtarget", "kOperandTypeARMBranchTarget"); // ?