diff options
Diffstat (limited to 'include/clang/Basic/arm_neon.td')
-rw-r--r-- | include/clang/Basic/arm_neon.td | 180 |
1 files changed, 117 insertions, 63 deletions
diff --git a/include/clang/Basic/arm_neon.td b/include/clang/Basic/arm_neon.td index 3373e017decb..77bc797c5056 100644 --- a/include/clang/Basic/arm_neon.td +++ b/include/clang/Basic/arm_neon.td @@ -77,9 +77,23 @@ class Inst <string n, string p, string t, Op o> { Op Operand = o; bit isShift = 0; bit isVCVT_N = 0; + + // Certain intrinsics have different names than their representative + // instructions. This field allows us to handle this correctly when we + // are generating tests. + string InstName = ""; + + // Certain intrinsics even though they are not a WOpInst or LOpInst, + // generate a WOpInst/LOpInst instruction (see below for definition + // of a WOpInst/LOpInst). For testing purposes we need to know + // this. Ex: vset_lane which outputs vmov instructions. + bit isHiddenWInst = 0; + bit isHiddenLInst = 0; } -// Used to generate Builtins.def: +// The following instruction classes are implemented via builtins. +// These declarations are used to generate Builtins.def: +// // SInst: Instruction with signed/unsigned suffix (e.g., "s8", "u8", "p8") // IInst: Instruction with generic integer suffix (e.g., "i8") // WInst: Instruction with only bit size suffix (e.g., "8") @@ -87,6 +101,22 @@ class SInst<string n, string p, string t> : Inst<n, p, t, OP_NONE> {} class IInst<string n, string p, string t> : Inst<n, p, t, OP_NONE> {} class WInst<string n, string p, string t> : Inst<n, p, t, OP_NONE> {} +// The following instruction classes are implemented via operators +// instead of builtins. As such these declarations are only used for +// the purpose of generating tests. +// +// SOpInst: Instruction with signed/unsigned suffix (e.g., "s8", +// "u8", "p8"). +// IOpInst: Instruction with generic integer suffix (e.g., "i8"). +// WOpInst: Instruction with bit size only suffix (e.g., "8"). +// LOpInst: Logical instruction with no bit size suffix. +// NoTestOpInst: Intrinsic that has no corresponding instruction. +class SOpInst<string n, string p, string t, Op o> : Inst<n, p, t, o> {} +class IOpInst<string n, string p, string t, Op o> : Inst<n, p, t, o> {} +class WOpInst<string n, string p, string t, Op o> : Inst<n, p, t, o> {} +class LOpInst<string n, string p, string t, Op o> : Inst<n, p, t, o> {} +class NoTestOpInst<string n, string p, string t, Op o> : Inst<n, p, t, o> {} + // prototype: return (arg, arg, ...) // v: void // t: best-fit integer (int/poly args) @@ -123,9 +153,10 @@ class WInst<string n, string p, string t> : Inst<n, p, t, OP_NONE> {} //////////////////////////////////////////////////////////////////////////////// // E.3.1 Addition -def VADD : Inst<"vadd", "ddd", "csilfUcUsUiUlQcQsQiQlQfQUcQUsQUiQUl", OP_ADD>; -def VADDL : Inst<"vaddl", "wdd", "csiUcUsUi", OP_ADDL>; -def VADDW : Inst<"vaddw", "wwd", "csiUcUsUi", OP_ADDW>; +def VADD : IOpInst<"vadd", "ddd", + "csilfUcUsUiUlQcQsQiQlQfQUcQUsQUiQUl", OP_ADD>; +def VADDL : SOpInst<"vaddl", "wdd", "csiUcUsUi", OP_ADDL>; +def VADDW : SOpInst<"vaddw", "wwd", "csiUcUsUi", OP_ADDW>; def VHADD : SInst<"vhadd", "ddd", "csiUcUsUiQcQsQiQUcQUsQUi">; def VRHADD : SInst<"vrhadd", "ddd", "csiUcUsUiQcQsQiQUcQUsQUi">; def VQADD : SInst<"vqadd", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">; @@ -134,12 +165,12 @@ def VRADDHN : IInst<"vraddhn", "hkk", "silUsUiUl">; //////////////////////////////////////////////////////////////////////////////// // E.3.2 Multiplication -def VMUL : Inst<"vmul", "ddd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_MUL>; +def VMUL : IOpInst<"vmul", "ddd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_MUL>; def VMULP : SInst<"vmul", "ddd", "PcQPc">; -def VMLA : Inst<"vmla", "dddd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_MLA>; -def VMLAL : Inst<"vmlal", "wwdd", "csiUcUsUi", OP_MLAL>; -def VMLS : Inst<"vmls", "dddd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_MLS>; -def VMLSL : Inst<"vmlsl", "wwdd", "csiUcUsUi", OP_MLSL>; +def VMLA : IOpInst<"vmla", "dddd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_MLA>; +def VMLAL : SOpInst<"vmlal", "wwdd", "csiUcUsUi", OP_MLAL>; +def VMLS : IOpInst<"vmls", "dddd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_MLS>; +def VMLSL : SOpInst<"vmlsl", "wwdd", "csiUcUsUi", OP_MLSL>; def VQDMULH : SInst<"vqdmulh", "ddd", "siQsQi">; def VQRDMULH : SInst<"vqrdmulh", "ddd", "siQsQi">; def VQDMLAL : SInst<"vqdmlal", "wwdd", "si">; @@ -149,9 +180,10 @@ def VQDMULL : SInst<"vqdmull", "wdd", "si">; //////////////////////////////////////////////////////////////////////////////// // E.3.3 Subtraction -def VSUB : Inst<"vsub", "ddd", "csilfUcUsUiUlQcQsQiQlQfQUcQUsQUiQUl", OP_SUB>; -def VSUBL : Inst<"vsubl", "wdd", "csiUcUsUi", OP_SUBL>; -def VSUBW : Inst<"vsubw", "wwd", "csiUcUsUi", OP_SUBW>; +def VSUB : IOpInst<"vsub", "ddd", + "csilfUcUsUiUlQcQsQiQlQfQUcQUsQUiQUl", OP_SUB>; +def VSUBL : SOpInst<"vsubl", "wdd", "csiUcUsUi", OP_SUBL>; +def VSUBW : SOpInst<"vsubw", "wwd", "csiUcUsUi", OP_SUBW>; def VQSUB : SInst<"vqsub", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">; def VHSUB : SInst<"vhsub", "ddd", "csiUcUsUiQcQsQiQUcQUsQUi">; def VSUBHN : IInst<"vsubhn", "hkk", "silUsUiUl">; @@ -159,23 +191,29 @@ def VRSUBHN : IInst<"vrsubhn", "hkk", "silUsUiUl">; //////////////////////////////////////////////////////////////////////////////// // E.3.4 Comparison -def VCEQ : Inst<"vceq", "udd", "csifUcUsUiPcQcQsQiQfQUcQUsQUiQPc", OP_EQ>; -def VCGE : Inst<"vcge", "udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_GE>; -def VCLE : Inst<"vcle", "udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_LE>; -def VCGT : Inst<"vcgt", "udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_GT>; -def VCLT : Inst<"vclt", "udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_LT>; +def VCEQ : IOpInst<"vceq", "udd", "csifUcUsUiPcQcQsQiQfQUcQUsQUiQPc", OP_EQ>; +def VCGE : SOpInst<"vcge", "udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_GE>; +let InstName = "vcge" in +def VCLE : SOpInst<"vcle", "udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_LE>; +def VCGT : SOpInst<"vcgt", "udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_GT>; +let InstName = "vcgt" in +def VCLT : SOpInst<"vclt", "udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_LT>; +let InstName = "vacge" in { def VCAGE : IInst<"vcage", "udd", "fQf">; def VCALE : IInst<"vcale", "udd", "fQf">; +} +let InstName = "vacgt" in { def VCAGT : IInst<"vcagt", "udd", "fQf">; def VCALT : IInst<"vcalt", "udd", "fQf">; +} def VTST : WInst<"vtst", "udd", "csiUcUsUiPcQcQsQiQUcQUsQUiQPc">; //////////////////////////////////////////////////////////////////////////////// // E.3.5 Absolute Difference def VABD : SInst<"vabd", "ddd", "csiUcUsUifQcQsQiQUcQUsQUiQf">; -def VABDL : Inst<"vabdl", "wdd", "csiUcUsUi", OP_ABDL>; -def VABA : Inst<"vaba", "dddd", "csiUcUsUiQcQsQiQUcQUsQUi", OP_ABA>; -def VABAL : Inst<"vabal", "wwdd", "csiUcUsUi", OP_ABAL>; +def VABDL : SOpInst<"vabdl", "wdd", "csiUcUsUi", OP_ABDL>; +def VABA : SOpInst<"vaba", "dddd", "csiUcUsUiQcQsQiQUcQUsQUi", OP_ABA>; +def VABAL : SOpInst<"vabal", "wwdd", "csiUcUsUi", OP_ABAL>; //////////////////////////////////////////////////////////////////////////////// // E.3.6 Max/Min @@ -264,35 +302,43 @@ def VST4_LANE : WInst<"vst4_lane", "vp4i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">; //////////////////////////////////////////////////////////////////////////////// // E.3.16 Extract lanes from a vector +let InstName = "vmov" in def VGET_LANE : IInst<"vget_lane", "sdi", "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl">; //////////////////////////////////////////////////////////////////////////////// // E.3.17 Set lanes within a vector +let InstName = "vmov" in def VSET_LANE : IInst<"vset_lane", "dsdi", "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl">; //////////////////////////////////////////////////////////////////////////////// // E.3.18 Initialize a vector from bit pattern -def VCREATE: Inst<"vcreate", "dl", "csihfUcUsUiUlPcPsl", OP_CAST>; +def VCREATE : NoTestOpInst<"vcreate", "dl", "csihfUcUsUiUlPcPsl", OP_CAST>; //////////////////////////////////////////////////////////////////////////////// // E.3.19 Set all lanes to same value -def VDUP_N : Inst<"vdup_n", "ds", - "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl", OP_DUP>; -def VMOV_N : Inst<"vmov_n", "ds", - "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl", OP_DUP>; -def VDUP_LANE : Inst<"vdup_lane", "dgi", - "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl",OP_DUP_LN>; +let InstName = "vmov" in { +def VDUP_N : WOpInst<"vdup_n", "ds", + "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl", OP_DUP>; +def VMOV_N : WOpInst<"vmov_n", "ds", + "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl", OP_DUP>; +} +let InstName = "" in +def VDUP_LANE: WOpInst<"vdup_lane", "dgi", + "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl", + OP_DUP_LN>; //////////////////////////////////////////////////////////////////////////////// // E.3.20 Combining vectors -def VCOMBINE : Inst<"vcombine", "kdd", "csilhfUcUsUiUlPcPs", OP_CONC>; +def VCOMBINE : NoTestOpInst<"vcombine", "kdd", "csilhfUcUsUiUlPcPs", OP_CONC>; //////////////////////////////////////////////////////////////////////////////// // E.3.21 Splitting vectors -def VGET_HIGH : Inst<"vget_high", "dk", "csilhfUcUsUiUlPcPs", OP_HI>; -def VGET_LOW : Inst<"vget_low", "dk", "csilhfUcUsUiUlPcPs", OP_LO>; +let InstName = "vmov" in { +def VGET_HIGH : NoTestOpInst<"vget_high", "dk", "csilhfUcUsUiUlPcPs", OP_HI>; +def VGET_LOW : NoTestOpInst<"vget_low", "dk", "csilhfUcUsUiUlPcPs", OP_LO>; +} //////////////////////////////////////////////////////////////////////////////// // E.3.22 Converting vectors @@ -313,39 +359,46 @@ def VQMOVUN : SInst<"vqmovun", "ek", "sil">; //////////////////////////////////////////////////////////////////////////////// // E.3.23-24 Table lookup, Extended table lookup +let InstName = "vtbl" in { def VTBL1 : WInst<"vtbl1", "ddt", "UccPc">; def VTBL2 : WInst<"vtbl2", "d2t", "UccPc">; def VTBL3 : WInst<"vtbl3", "d3t", "UccPc">; def VTBL4 : WInst<"vtbl4", "d4t", "UccPc">; +} +let InstName = "vtbx" in { def VTBX1 : WInst<"vtbx1", "dddt", "UccPc">; def VTBX2 : WInst<"vtbx2", "dd2t", "UccPc">; def VTBX3 : WInst<"vtbx3", "dd3t", "UccPc">; def VTBX4 : WInst<"vtbx4", "dd4t", "UccPc">; +} //////////////////////////////////////////////////////////////////////////////// // E.3.25 Operations with a scalar value -def VMLA_LANE : Inst<"vmla_lane", "dddgi", "siUsUifQsQiQUsQUiQf", OP_MLA_LN>; -def VMLAL_LANE : Inst<"vmlal_lane", "wwddi", "siUsUi", OP_MLAL_LN>; -def VQDMLAL_LANE : Inst<"vqdmlal_lane", "wwddi", "si", OP_QDMLAL_LN>; -def VMLS_LANE : Inst<"vmls_lane", "dddgi", "siUsUifQsQiQUsQUiQf", OP_MLS_LN>; -def VMLSL_LANE : Inst<"vmlsl_lane", "wwddi", "siUsUi", OP_MLSL_LN>; -def VQDMLSL_LANE : Inst<"vqdmlsl_lane", "wwddi", "si", OP_QDMLSL_LN>; -def VMUL_N : Inst<"vmul_n", "dds", "sifUsUiQsQiQfQUsQUi", OP_MUL_N>; -def VMUL_LANE : Inst<"vmul_lane", "ddgi", "sifUsUiQsQiQfQUsQUi", OP_MUL_LN>; -def VMULL_N : SInst<"vmull_n", "wda", "siUsUi">; -def VMULL_LANE : Inst<"vmull_lane", "wddi", "siUsUi", OP_MULL_LN>; -def VQDMULL_N : SInst<"vqdmull_n", "wda", "si">; -def VQDMULL_LANE : Inst<"vqdmull_lane", "wddi", "si", OP_QDMULL_LN>; -def VQDMULH_N : SInst<"vqdmulh_n", "dda", "siQsQi">; -def VQDMULH_LANE : Inst<"vqdmulh_lane", "ddgi", "siQsQi", OP_QDMULH_LN>; -def VQRDMULH_N : SInst<"vqrdmulh_n", "dda", "siQsQi">; -def VQRDMULH_LANE : Inst<"vqrdmulh_lane", "ddgi", "siQsQi", OP_QRDMULH_LN>; -def VMLA_N : Inst<"vmla_n", "ddda", "siUsUifQsQiQUsQUiQf", OP_MLA_N>; -def VMLAL_N : Inst<"vmlal_n", "wwda", "siUsUi", OP_MLAL_N>; -def VQDMLAL_N : SInst<"vqdmlal_n", "wwda", "si">; -def VMLS_N : Inst<"vmls_n", "ddds", "siUsUifQsQiQUsQUiQf", OP_MLS_N>; -def VMLSL_N : Inst<"vmlsl_n", "wwda", "siUsUi", OP_MLSL_N>; -def VQDMLSL_N : SInst<"vqdmlsl_n", "wwda", "si">; +def VMLA_LANE : IOpInst<"vmla_lane", "dddgi", + "siUsUifQsQiQUsQUiQf", OP_MLA_LN>; +def VMLAL_LANE : SOpInst<"vmlal_lane", "wwddi", "siUsUi", OP_MLAL_LN>; +def VQDMLAL_LANE : SOpInst<"vqdmlal_lane", "wwddi", "si", OP_QDMLAL_LN>; +def VMLS_LANE : IOpInst<"vmls_lane", "dddgi", + "siUsUifQsQiQUsQUiQf", OP_MLS_LN>; +def VMLSL_LANE : SOpInst<"vmlsl_lane", "wwddi", "siUsUi", OP_MLSL_LN>; +def VQDMLSL_LANE : SOpInst<"vqdmlsl_lane", "wwddi", "si", OP_QDMLSL_LN>; +def VMUL_N : IOpInst<"vmul_n", "dds", "sifUsUiQsQiQfQUsQUi", OP_MUL_N>; +def VMUL_LANE : IOpInst<"vmul_lane", "ddgi", + "sifUsUiQsQiQfQUsQUi", OP_MUL_LN>; +def VMULL_N : SInst<"vmull_n", "wda", "siUsUi">; +def VMULL_LANE : SOpInst<"vmull_lane", "wddi", "siUsUi", OP_MULL_LN>; +def VQDMULL_N : SInst<"vqdmull_n", "wda", "si">; +def VQDMULL_LANE : SOpInst<"vqdmull_lane", "wddi", "si", OP_QDMULL_LN>; +def VQDMULH_N : SInst<"vqdmulh_n", "dda", "siQsQi">; +def VQDMULH_LANE : SOpInst<"vqdmulh_lane", "ddgi", "siQsQi", OP_QDMULH_LN>; +def VQRDMULH_N : SInst<"vqrdmulh_n", "dda", "siQsQi">; +def VQRDMULH_LANE : SOpInst<"vqrdmulh_lane", "ddgi", "siQsQi", OP_QRDMULH_LN>; +def VMLA_N : IOpInst<"vmla_n", "ddda", "siUsUifQsQiQUsQUiQf", OP_MLA_N>; +def VMLAL_N : SOpInst<"vmlal_n", "wwda", "siUsUi", OP_MLAL_N>; +def VQDMLAL_N : SInst<"vqdmlal_n", "wwda", "si">; +def VMLS_N : IOpInst<"vmls_n", "ddds", "siUsUifQsQiQUsQUiQf", OP_MLS_N>; +def VMLSL_N : SOpInst<"vmlsl_n", "wwda", "siUsUi", OP_MLSL_N>; +def VQDMLSL_N : SInst<"vqdmlsl_n", "wwda", "si">; //////////////////////////////////////////////////////////////////////////////// // E.3.26 Vector Extract @@ -354,16 +407,16 @@ def VEXT : WInst<"vext", "dddi", //////////////////////////////////////////////////////////////////////////////// // E.3.27 Reverse vector elements -def VREV64 : Inst<"vrev64", "dd", "csiUcUsUiPcPsfQcQsQiQUcQUsQUiQPcQPsQf", +def VREV64 : WOpInst<"vrev64", "dd", "csiUcUsUiPcPsfQcQsQiQUcQUsQUiQPcQPsQf", OP_REV64>; -def VREV32 : Inst<"vrev32", "dd", "csUcUsPcPsQcQsQUcQUsQPcQPs", OP_REV32>; -def VREV16 : Inst<"vrev16", "dd", "cUcPcQcQUcQPc", OP_REV16>; +def VREV32 : WOpInst<"vrev32", "dd", "csUcUsPcPsQcQsQUcQUsQPcQPs", OP_REV32>; +def VREV16 : WOpInst<"vrev16", "dd", "cUcPcQcQUcQPc", OP_REV16>; //////////////////////////////////////////////////////////////////////////////// // E.3.28 Other single operand arithmetic def VABS : SInst<"vabs", "dd", "csifQcQsQiQf">; def VQABS : SInst<"vqabs", "dd", "csiQcQsQi">; -def VNEG : Inst<"vneg", "dd", "csifQcQsQiQf", OP_NEG>; +def VNEG : SOpInst<"vneg", "dd", "csifQcQsQiQf", OP_NEG>; def VQNEG : SInst<"vqneg", "dd", "csiQcQsQi">; def VCLS : SInst<"vcls", "dd", "csiQcQsQi">; def VCLZ : IInst<"vclz", "dd", "csiUcUsUiQcQsQiQUcQUsQUi">; @@ -373,12 +426,13 @@ def VRSQRTE : SInst<"vrsqrte", "dd", "fUiQfQUi">; //////////////////////////////////////////////////////////////////////////////// // E.3.29 Logical operations -def VMVN : Inst<"vmvn", "dd", "csiUcUsUiPcQcQsQiQUcQUsQUiQPc", OP_NOT>; -def VAND : Inst<"vand", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_AND>; -def VORR : Inst<"vorr", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_OR>; -def VEOR : Inst<"veor", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_XOR>; -def VBIC : Inst<"vbic", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_ANDN>; -def VORN : Inst<"vorn", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_ORN>; +def VMVN : LOpInst<"vmvn", "dd", "csiUcUsUiPcQcQsQiQUcQUsQUiQPc", OP_NOT>; +def VAND : LOpInst<"vand", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_AND>; +def VORR : LOpInst<"vorr", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_OR>; +def VEOR : LOpInst<"veor", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_XOR>; +def VBIC : LOpInst<"vbic", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_ANDN>; +def VORN : LOpInst<"vorn", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_ORN>; +let isHiddenLInst = 1 in def VBSL : SInst<"vbsl", "dudd", "csilUcUsUiUlfPcPsQcQsQiQlQUcQUsQUiQUlQfQPcQPs">; @@ -391,7 +445,7 @@ def VUZP : WInst<"vuzp", "2dd", "csiUcUsUifPcPsQcQsQiQUcQUsQUiQfQPcQPs">; //////////////////////////////////////////////////////////////////////////////// // E.3.31 Vector reinterpret cast operations def VREINTERPRET - : Inst<"vreinterpret", "dd", + : NoTestOpInst<"vreinterpret", "dd", "csilUcUsUiUlhfPcPsQcQsQiQlQUcQUsQUiQUlQhQfQPcQPs", OP_REINT>; //////////////////////////////////////////////////////////////////////////////// |