| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1 | //===- ARMInstrNEON.td - NEON support for ARM -----------------------------===// | 
|  | 2 | // | 
|  | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
|  | 5 | // This file is distributed under the University of Illinois Open Source | 
|  | 6 | // License. See LICENSE.TXT for details. | 
|  | 7 | // | 
|  | 8 | //===----------------------------------------------------------------------===// | 
|  | 9 | // | 
|  | 10 | // This file describes the ARM NEON instruction set. | 
|  | 11 | // | 
|  | 12 | //===----------------------------------------------------------------------===// | 
|  | 13 |  | 
|  | 14 | //===----------------------------------------------------------------------===// | 
|  | 15 | // NEON-specific DAG Nodes. | 
|  | 16 | //===----------------------------------------------------------------------===// | 
|  | 17 |  | 
|  | 18 | def SDTARMVCMP    : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisSameAs<1, 2>]>; | 
|  | 19 |  | 
|  | 20 | def NEONvceq      : SDNode<"ARMISD::VCEQ", SDTARMVCMP>; | 
|  | 21 | def NEONvcge      : SDNode<"ARMISD::VCGE", SDTARMVCMP>; | 
|  | 22 | def NEONvcgeu     : SDNode<"ARMISD::VCGEU", SDTARMVCMP>; | 
|  | 23 | def NEONvcgt      : SDNode<"ARMISD::VCGT", SDTARMVCMP>; | 
|  | 24 | def NEONvcgtu     : SDNode<"ARMISD::VCGTU", SDTARMVCMP>; | 
|  | 25 | def NEONvtst      : SDNode<"ARMISD::VTST", SDTARMVCMP>; | 
|  | 26 |  | 
|  | 27 | // Types for vector shift by immediates.  The "SHX" version is for long and | 
|  | 28 | // narrow operations where the source and destination vectors have different | 
|  | 29 | // types.  The "SHINS" version is for shift and insert operations. | 
|  | 30 | def SDTARMVSH     : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>, | 
|  | 31 | SDTCisVT<2, i32>]>; | 
|  | 32 | def SDTARMVSHX    : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisInt<1>, | 
|  | 33 | SDTCisVT<2, i32>]>; | 
|  | 34 | def SDTARMVSHINS  : SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<0, 1>, | 
|  | 35 | SDTCisSameAs<0, 2>, SDTCisVT<3, i32>]>; | 
|  | 36 |  | 
|  | 37 | def NEONvshl      : SDNode<"ARMISD::VSHL", SDTARMVSH>; | 
|  | 38 | def NEONvshrs     : SDNode<"ARMISD::VSHRs", SDTARMVSH>; | 
|  | 39 | def NEONvshru     : SDNode<"ARMISD::VSHRu", SDTARMVSH>; | 
|  | 40 | def NEONvshlls    : SDNode<"ARMISD::VSHLLs", SDTARMVSHX>; | 
|  | 41 | def NEONvshllu    : SDNode<"ARMISD::VSHLLu", SDTARMVSHX>; | 
|  | 42 | def NEONvshlli    : SDNode<"ARMISD::VSHLLi", SDTARMVSHX>; | 
|  | 43 | def NEONvshrn     : SDNode<"ARMISD::VSHRN", SDTARMVSHX>; | 
|  | 44 |  | 
|  | 45 | def NEONvrshrs    : SDNode<"ARMISD::VRSHRs", SDTARMVSH>; | 
|  | 46 | def NEONvrshru    : SDNode<"ARMISD::VRSHRu", SDTARMVSH>; | 
|  | 47 | def NEONvrshrn    : SDNode<"ARMISD::VRSHRN", SDTARMVSHX>; | 
|  | 48 |  | 
|  | 49 | def NEONvqshls    : SDNode<"ARMISD::VQSHLs", SDTARMVSH>; | 
|  | 50 | def NEONvqshlu    : SDNode<"ARMISD::VQSHLu", SDTARMVSH>; | 
|  | 51 | def NEONvqshlsu   : SDNode<"ARMISD::VQSHLsu", SDTARMVSH>; | 
|  | 52 | def NEONvqshrns   : SDNode<"ARMISD::VQSHRNs", SDTARMVSHX>; | 
|  | 53 | def NEONvqshrnu   : SDNode<"ARMISD::VQSHRNu", SDTARMVSHX>; | 
|  | 54 | def NEONvqshrnsu  : SDNode<"ARMISD::VQSHRNsu", SDTARMVSHX>; | 
|  | 55 |  | 
|  | 56 | def NEONvqrshrns  : SDNode<"ARMISD::VQRSHRNs", SDTARMVSHX>; | 
|  | 57 | def NEONvqrshrnu  : SDNode<"ARMISD::VQRSHRNu", SDTARMVSHX>; | 
|  | 58 | def NEONvqrshrnsu : SDNode<"ARMISD::VQRSHRNsu", SDTARMVSHX>; | 
|  | 59 |  | 
|  | 60 | def NEONvsli      : SDNode<"ARMISD::VSLI", SDTARMVSHINS>; | 
|  | 61 | def NEONvsri      : SDNode<"ARMISD::VSRI", SDTARMVSHINS>; | 
|  | 62 |  | 
|  | 63 | def SDTARMVGETLN  : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisInt<1>, | 
|  | 64 | SDTCisVT<2, i32>]>; | 
|  | 65 | def NEONvgetlaneu : SDNode<"ARMISD::VGETLANEu", SDTARMVGETLN>; | 
|  | 66 | def NEONvgetlanes : SDNode<"ARMISD::VGETLANEs", SDTARMVGETLN>; | 
|  | 67 |  | 
|  | 68 | def NEONvduplaneq : SDNode<"ARMISD::VDUPLANEQ", | 
|  | 69 | SDTypeProfile<1, 2, [SDTCisVT<2, i32>]>>; | 
|  | 70 |  | 
| Bob Wilson | 20f79e3 | 2009-08-05 00:49:09 +0000 | [diff] [blame] | 71 | def SDTARMVLD2    : SDTypeProfile<2, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<2>]>; | 
|  | 72 | def SDTARMVLD3    : SDTypeProfile<3, 1, [SDTCisSameAs<0, 1>, | 
|  | 73 | SDTCisSameAs<0, 2>, SDTCisPtrTy<3>]>; | 
|  | 74 | def SDTARMVLD4    : SDTypeProfile<4, 1, [SDTCisSameAs<0, 1>, | 
|  | 75 | SDTCisSameAs<0, 2>, | 
|  | 76 | SDTCisSameAs<0, 3>, SDTCisPtrTy<4>]>; | 
|  | 77 | def NEONvld2d     : SDNode<"ARMISD::VLD2D", SDTARMVLD2, | 
|  | 78 | [SDNPHasChain, SDNPMayLoad]>; | 
|  | 79 | def NEONvld3d     : SDNode<"ARMISD::VLD3D", SDTARMVLD3, | 
|  | 80 | [SDNPHasChain, SDNPMayLoad]>; | 
|  | 81 | def NEONvld4d     : SDNode<"ARMISD::VLD4D", SDTARMVLD4, | 
|  | 82 | [SDNPHasChain, SDNPMayLoad]>; | 
| Bob Wilson | f45dee3 | 2009-08-04 00:36:16 +0000 | [diff] [blame] | 83 |  | 
| Bob Wilson | 0127031 | 2009-08-06 18:47:44 +0000 | [diff] [blame] | 84 | def SDTARMVST2    : SDTypeProfile<0, 3, [SDTCisPtrTy<0>, SDTCisSameAs<1, 2>]>; | 
|  | 85 | def SDTARMVST3    : SDTypeProfile<0, 4, [SDTCisPtrTy<0>, SDTCisSameAs<1, 2>, | 
|  | 86 | SDTCisSameAs<1, 3>]>; | 
|  | 87 | def SDTARMVST4    : SDTypeProfile<0, 5, [SDTCisPtrTy<0>, SDTCisSameAs<1, 2>, | 
|  | 88 | SDTCisSameAs<1, 3>, | 
|  | 89 | SDTCisSameAs<1, 4>]>; | 
|  | 90 |  | 
|  | 91 | def NEONvst2d     : SDNode<"ARMISD::VST2D", SDTARMVST2, | 
|  | 92 | [SDNPHasChain, SDNPMayStore]>; | 
|  | 93 | def NEONvst3d     : SDNode<"ARMISD::VST3D", SDTARMVST3, | 
|  | 94 | [SDNPHasChain, SDNPMayStore]>; | 
|  | 95 | def NEONvst4d     : SDNode<"ARMISD::VST4D", SDTARMVST4, | 
|  | 96 | [SDNPHasChain, SDNPMayStore]>; | 
|  | 97 |  | 
| Bob Wilson | ea3a402 | 2009-08-12 22:31:50 +0000 | [diff] [blame] | 98 | def SDTARMVSHUF   : SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisSameAs<0, 1>]>; | 
|  | 99 | def NEONvrev64    : SDNode<"ARMISD::VREV64", SDTARMVSHUF>; | 
|  | 100 | def NEONvrev32    : SDNode<"ARMISD::VREV32", SDTARMVSHUF>; | 
|  | 101 | def NEONvrev16    : SDNode<"ARMISD::VREV16", SDTARMVSHUF>; | 
| Bob Wilson | ff2db10 | 2009-08-12 22:54:19 +0000 | [diff] [blame] | 102 | def NEONvsplat0   : SDNode<"ARMISD::VSPLAT0", SDTARMVSHUF>; | 
| Bob Wilson | ea3a402 | 2009-08-12 22:31:50 +0000 | [diff] [blame] | 103 |  | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 104 | //===----------------------------------------------------------------------===// | 
|  | 105 | // NEON operand definitions | 
|  | 106 | //===----------------------------------------------------------------------===// | 
|  | 107 |  | 
|  | 108 | // addrmode_neonldstm := reg | 
|  | 109 | // | 
|  | 110 | /* TODO: Take advantage of vldm. | 
|  | 111 | def addrmode_neonldstm : Operand<i32>, | 
|  | 112 | ComplexPattern<i32, 2, "SelectAddrModeNeonLdStM", []> { | 
|  | 113 | let PrintMethod = "printAddrNeonLdStMOperand"; | 
|  | 114 | let MIOperandInfo = (ops GPR, i32imm); | 
|  | 115 | } | 
|  | 116 | */ | 
|  | 117 |  | 
|  | 118 | //===----------------------------------------------------------------------===// | 
|  | 119 | // NEON load / store instructions | 
|  | 120 | //===----------------------------------------------------------------------===// | 
|  | 121 |  | 
| Bob Wilson | f042ead | 2009-08-12 00:49:01 +0000 | [diff] [blame] | 122 | /* TODO: Take advantage of vldm. | 
| Bob Wilson | 25cae66 | 2009-08-12 17:04:56 +0000 | [diff] [blame] | 123 | let mayLoad = 1 in { | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 124 | def VLDMD : NI<(outs), | 
|  | 125 | (ins addrmode_neonldstm:$addr, reglist:$dst1, variable_ops), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 126 | NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 127 | "vldm${addr:submode} ${addr:base}, $dst1", | 
| Evan Cheng | 5edd90c | 2009-07-08 22:51:32 +0000 | [diff] [blame] | 128 | []> { | 
|  | 129 | let Inst{27-25} = 0b110; | 
|  | 130 | let Inst{20}    = 1; | 
|  | 131 | let Inst{11-9}  = 0b101; | 
|  | 132 | } | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 133 |  | 
|  | 134 | def VLDMS : NI<(outs), | 
|  | 135 | (ins addrmode_neonldstm:$addr, reglist:$dst1, variable_ops), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 136 | NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 137 | "vldm${addr:submode} ${addr:base}, $dst1", | 
| Evan Cheng | 5edd90c | 2009-07-08 22:51:32 +0000 | [diff] [blame] | 138 | []> { | 
|  | 139 | let Inst{27-25} = 0b110; | 
|  | 140 | let Inst{20}    = 1; | 
|  | 141 | let Inst{11-9}  = 0b101; | 
|  | 142 | } | 
| Bob Wilson | 25cae66 | 2009-08-12 17:04:56 +0000 | [diff] [blame] | 143 | } | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 144 | */ | 
|  | 145 |  | 
|  | 146 | // Use vldmia to load a Q register as a D register pair. | 
| Anton Korobeynikov | 887d05c | 2009-08-08 13:35:48 +0000 | [diff] [blame] | 147 | def VLDRQ : NI4<(outs QPR:$dst), (ins addrmode4:$addr), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 148 | NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 149 | "vldmia $addr, ${dst:dregpair}", | 
| Anton Korobeynikov | 887d05c | 2009-08-08 13:35:48 +0000 | [diff] [blame] | 150 | [(set QPR:$dst, (v2f64 (load addrmode4:$addr)))]> { | 
| Evan Cheng | 5edd90c | 2009-07-08 22:51:32 +0000 | [diff] [blame] | 151 | let Inst{27-25} = 0b110; | 
|  | 152 | let Inst{24}    = 0; // P bit | 
|  | 153 | let Inst{23}    = 1; // U bit | 
|  | 154 | let Inst{20}    = 1; | 
|  | 155 | let Inst{11-9}  = 0b101; | 
|  | 156 | } | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 157 |  | 
| Bob Wilson | 25cae66 | 2009-08-12 17:04:56 +0000 | [diff] [blame] | 158 | // Use vstmia to store a Q register as a D register pair. | 
|  | 159 | def VSTRQ : NI4<(outs), (ins QPR:$src, addrmode4:$addr), | 
|  | 160 | NoItinerary, | 
|  | 161 | "vstmia $addr, ${src:dregpair}", | 
|  | 162 | [(store (v2f64 QPR:$src), addrmode4:$addr)]> { | 
|  | 163 | let Inst{27-25} = 0b110; | 
|  | 164 | let Inst{24}    = 0; // P bit | 
|  | 165 | let Inst{23}    = 1; // U bit | 
|  | 166 | let Inst{20}    = 0; | 
|  | 167 | let Inst{11-9}  = 0b101; | 
|  | 168 | } | 
|  | 169 |  | 
| Bob Wilson | f731a2d | 2009-07-08 18:11:30 +0000 | [diff] [blame] | 170 | //   VLD1     : Vector Load (multiple single elements) | 
|  | 171 | class VLD1D<string OpcodeStr, ValueType Ty, Intrinsic IntOp> | 
|  | 172 | : NLdSt<(outs DPR:$dst), (ins addrmode6:$addr), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 173 | NoItinerary, | 
| Bob Wilson | a872010 | 2009-08-04 21:39:33 +0000 | [diff] [blame] | 174 | !strconcat(OpcodeStr, "\t\\{$dst\\}, $addr"), | 
| Bob Wilson | cf19885 | 2009-07-29 16:39:22 +0000 | [diff] [blame] | 175 | [(set DPR:$dst, (Ty (IntOp addrmode6:$addr)))]>; | 
| Bob Wilson | f731a2d | 2009-07-08 18:11:30 +0000 | [diff] [blame] | 176 | class VLD1Q<string OpcodeStr, ValueType Ty, Intrinsic IntOp> | 
|  | 177 | : NLdSt<(outs QPR:$dst), (ins addrmode6:$addr), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 178 | NoItinerary, | 
| Bob Wilson | f731a2d | 2009-07-08 18:11:30 +0000 | [diff] [blame] | 179 | !strconcat(OpcodeStr, "\t${dst:dregpair}, $addr"), | 
| Bob Wilson | cf19885 | 2009-07-29 16:39:22 +0000 | [diff] [blame] | 180 | [(set QPR:$dst, (Ty (IntOp addrmode6:$addr)))]>; | 
| Bob Wilson | f731a2d | 2009-07-08 18:11:30 +0000 | [diff] [blame] | 181 |  | 
| Bob Wilson | 12842f9 | 2009-08-11 05:39:44 +0000 | [diff] [blame] | 182 | def  VLD1d8   : VLD1D<"vld1.8",  v8i8,  int_arm_neon_vld1>; | 
|  | 183 | def  VLD1d16  : VLD1D<"vld1.16", v4i16, int_arm_neon_vld1>; | 
|  | 184 | def  VLD1d32  : VLD1D<"vld1.32", v2i32, int_arm_neon_vld1>; | 
|  | 185 | def  VLD1df   : VLD1D<"vld1.32", v2f32, int_arm_neon_vld1>; | 
|  | 186 | def  VLD1d64  : VLD1D<"vld1.64", v1i64, int_arm_neon_vld1>; | 
| Bob Wilson | f731a2d | 2009-07-08 18:11:30 +0000 | [diff] [blame] | 187 |  | 
| Bob Wilson | 12842f9 | 2009-08-11 05:39:44 +0000 | [diff] [blame] | 188 | def  VLD1q8   : VLD1Q<"vld1.8",  v16i8, int_arm_neon_vld1>; | 
|  | 189 | def  VLD1q16  : VLD1Q<"vld1.16", v8i16, int_arm_neon_vld1>; | 
|  | 190 | def  VLD1q32  : VLD1Q<"vld1.32", v4i32, int_arm_neon_vld1>; | 
|  | 191 | def  VLD1qf   : VLD1Q<"vld1.32", v4f32, int_arm_neon_vld1>; | 
|  | 192 | def  VLD1q64  : VLD1Q<"vld1.64", v2i64, int_arm_neon_vld1>; | 
| Bob Wilson | f731a2d | 2009-07-08 18:11:30 +0000 | [diff] [blame] | 193 |  | 
| Bob Wilson | 25cae66 | 2009-08-12 17:04:56 +0000 | [diff] [blame] | 194 | let mayLoad = 1 in { | 
|  | 195 |  | 
| Bob Wilson | 20f79e3 | 2009-08-05 00:49:09 +0000 | [diff] [blame] | 196 | //   VLD2     : Vector Load (multiple 2-element structures) | 
|  | 197 | class VLD2D<string OpcodeStr> | 
|  | 198 | : NLdSt<(outs DPR:$dst1, DPR:$dst2), (ins addrmode6:$addr), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 199 | NoItinerary, | 
| Bob Wilson | 20f79e3 | 2009-08-05 00:49:09 +0000 | [diff] [blame] | 200 | !strconcat(OpcodeStr, "\t\\{$dst1,$dst2\\}, $addr"), []>; | 
|  | 201 |  | 
|  | 202 | def  VLD2d8   : VLD2D<"vld2.8">; | 
|  | 203 | def  VLD2d16  : VLD2D<"vld2.16">; | 
|  | 204 | def  VLD2d32  : VLD2D<"vld2.32">; | 
| Bob Wilson | 20f79e3 | 2009-08-05 00:49:09 +0000 | [diff] [blame] | 205 |  | 
|  | 206 | //   VLD3     : Vector Load (multiple 3-element structures) | 
|  | 207 | class VLD3D<string OpcodeStr> | 
|  | 208 | : NLdSt<(outs DPR:$dst1, DPR:$dst2, DPR:$dst3), (ins addrmode6:$addr), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 209 | NoItinerary, | 
| Bob Wilson | 20f79e3 | 2009-08-05 00:49:09 +0000 | [diff] [blame] | 210 | !strconcat(OpcodeStr, "\t\\{$dst1,$dst2,$dst3\\}, $addr"), []>; | 
|  | 211 |  | 
|  | 212 | def  VLD3d8   : VLD3D<"vld3.8">; | 
|  | 213 | def  VLD3d16  : VLD3D<"vld3.16">; | 
|  | 214 | def  VLD3d32  : VLD3D<"vld3.32">; | 
| Bob Wilson | 20f79e3 | 2009-08-05 00:49:09 +0000 | [diff] [blame] | 215 |  | 
|  | 216 | //   VLD4     : Vector Load (multiple 4-element structures) | 
|  | 217 | class VLD4D<string OpcodeStr> | 
|  | 218 | : NLdSt<(outs DPR:$dst1, DPR:$dst2, DPR:$dst3, DPR:$dst4), | 
|  | 219 | (ins addrmode6:$addr), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 220 | NoItinerary, | 
| Bob Wilson | 20f79e3 | 2009-08-05 00:49:09 +0000 | [diff] [blame] | 221 | !strconcat(OpcodeStr, "\t\\{$dst1,$dst2,$dst3,$dst4\\}, $addr"), []>; | 
|  | 222 |  | 
|  | 223 | def  VLD4d8   : VLD4D<"vld4.8">; | 
|  | 224 | def  VLD4d16  : VLD4D<"vld4.16">; | 
|  | 225 | def  VLD4d32  : VLD4D<"vld4.32">; | 
| Bob Wilson | f042ead | 2009-08-12 00:49:01 +0000 | [diff] [blame] | 226 | } | 
|  | 227 |  | 
| Bob Wilson | 0127031 | 2009-08-06 18:47:44 +0000 | [diff] [blame] | 228 | //   VST1     : Vector Store (multiple single elements) | 
|  | 229 | class VST1D<string OpcodeStr, ValueType Ty, Intrinsic IntOp> | 
|  | 230 | : NLdSt<(outs), (ins addrmode6:$addr, DPR:$src), | 
|  | 231 | NoItinerary, | 
|  | 232 | !strconcat(OpcodeStr, "\t\\{$src\\}, $addr"), | 
|  | 233 | [(IntOp addrmode6:$addr, (Ty DPR:$src))]>; | 
|  | 234 | class VST1Q<string OpcodeStr, ValueType Ty, Intrinsic IntOp> | 
|  | 235 | : NLdSt<(outs), (ins addrmode6:$addr, QPR:$src), | 
|  | 236 | NoItinerary, | 
|  | 237 | !strconcat(OpcodeStr, "\t${src:dregpair}, $addr"), | 
|  | 238 | [(IntOp addrmode6:$addr, (Ty QPR:$src))]>; | 
|  | 239 |  | 
| Bob Wilson | 12842f9 | 2009-08-11 05:39:44 +0000 | [diff] [blame] | 240 | def  VST1d8   : VST1D<"vst1.8",  v8i8,  int_arm_neon_vst1>; | 
|  | 241 | def  VST1d16  : VST1D<"vst1.16", v4i16, int_arm_neon_vst1>; | 
|  | 242 | def  VST1d32  : VST1D<"vst1.32", v2i32, int_arm_neon_vst1>; | 
|  | 243 | def  VST1df   : VST1D<"vst1.32", v2f32, int_arm_neon_vst1>; | 
|  | 244 | def  VST1d64  : VST1D<"vst1.64", v1i64, int_arm_neon_vst1>; | 
| Bob Wilson | 0127031 | 2009-08-06 18:47:44 +0000 | [diff] [blame] | 245 |  | 
| Bob Wilson | 12842f9 | 2009-08-11 05:39:44 +0000 | [diff] [blame] | 246 | def  VST1q8   : VST1Q<"vst1.8",  v16i8, int_arm_neon_vst1>; | 
|  | 247 | def  VST1q16  : VST1Q<"vst1.16", v8i16, int_arm_neon_vst1>; | 
|  | 248 | def  VST1q32  : VST1Q<"vst1.32", v4i32, int_arm_neon_vst1>; | 
|  | 249 | def  VST1qf   : VST1Q<"vst1.32", v4f32, int_arm_neon_vst1>; | 
|  | 250 | def  VST1q64  : VST1Q<"vst1.64", v2i64, int_arm_neon_vst1>; | 
| Bob Wilson | 0127031 | 2009-08-06 18:47:44 +0000 | [diff] [blame] | 251 |  | 
| Bob Wilson | 25cae66 | 2009-08-12 17:04:56 +0000 | [diff] [blame] | 252 | let mayStore = 1 in { | 
|  | 253 |  | 
| Bob Wilson | 0127031 | 2009-08-06 18:47:44 +0000 | [diff] [blame] | 254 | //   VST2     : Vector Store (multiple 2-element structures) | 
|  | 255 | class VST2D<string OpcodeStr> | 
|  | 256 | : NLdSt<(outs), (ins addrmode6:$addr, DPR:$src1, DPR:$src2), NoItinerary, | 
|  | 257 | !strconcat(OpcodeStr, "\t\\{$src1,$src2\\}, $addr"), []>; | 
|  | 258 |  | 
|  | 259 | def  VST2d8   : VST2D<"vst2.8">; | 
|  | 260 | def  VST2d16  : VST2D<"vst2.16">; | 
|  | 261 | def  VST2d32  : VST2D<"vst2.32">; | 
|  | 262 |  | 
|  | 263 | //   VST3     : Vector Store (multiple 3-element structures) | 
|  | 264 | class VST3D<string OpcodeStr> | 
|  | 265 | : NLdSt<(outs), (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3), | 
|  | 266 | NoItinerary, | 
|  | 267 | !strconcat(OpcodeStr, "\t\\{$src1,$src2,$src3\\}, $addr"), []>; | 
|  | 268 |  | 
|  | 269 | def  VST3d8   : VST3D<"vst3.8">; | 
|  | 270 | def  VST3d16  : VST3D<"vst3.16">; | 
|  | 271 | def  VST3d32  : VST3D<"vst3.32">; | 
|  | 272 |  | 
|  | 273 | //   VST4     : Vector Store (multiple 4-element structures) | 
|  | 274 | class VST4D<string OpcodeStr> | 
|  | 275 | : NLdSt<(outs), (ins addrmode6:$addr, | 
|  | 276 | DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4), NoItinerary, | 
|  | 277 | !strconcat(OpcodeStr, "\t\\{$src1,$src2,$src3,$src4\\}, $addr"), []>; | 
|  | 278 |  | 
|  | 279 | def  VST4d8   : VST4D<"vst4.8">; | 
|  | 280 | def  VST4d16  : VST4D<"vst4.16">; | 
|  | 281 | def  VST4d32  : VST4D<"vst4.32">; | 
| Bob Wilson | f042ead | 2009-08-12 00:49:01 +0000 | [diff] [blame] | 282 | } | 
| Bob Wilson | 0127031 | 2009-08-06 18:47:44 +0000 | [diff] [blame] | 283 |  | 
| Bob Wilson | f731a2d | 2009-07-08 18:11:30 +0000 | [diff] [blame] | 284 |  | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 285 | //===----------------------------------------------------------------------===// | 
|  | 286 | // NEON pattern fragments | 
|  | 287 | //===----------------------------------------------------------------------===// | 
|  | 288 |  | 
|  | 289 | // Extract D sub-registers of Q registers. | 
|  | 290 | // (arm_dsubreg_0 is 5; arm_dsubreg_1 is 6) | 
| Anton Korobeynikov | 7167f33 | 2009-08-08 14:06:07 +0000 | [diff] [blame] | 291 | def DSubReg_i8_reg  : SDNodeXForm<imm, [{ | 
| Owen Anderson | 9f94459 | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 292 | return CurDAG->getTargetConstant(5 + N->getZExtValue() / 8, MVT::i32); | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 293 | }]>; | 
| Anton Korobeynikov | 7167f33 | 2009-08-08 14:06:07 +0000 | [diff] [blame] | 294 | def DSubReg_i16_reg : SDNodeXForm<imm, [{ | 
| Owen Anderson | 9f94459 | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 295 | return CurDAG->getTargetConstant(5 + N->getZExtValue() / 4, MVT::i32); | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 296 | }]>; | 
| Anton Korobeynikov | 7167f33 | 2009-08-08 14:06:07 +0000 | [diff] [blame] | 297 | def DSubReg_i32_reg : SDNodeXForm<imm, [{ | 
| Owen Anderson | 9f94459 | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 298 | return CurDAG->getTargetConstant(5 + N->getZExtValue() / 2, MVT::i32); | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 299 | }]>; | 
| Anton Korobeynikov | 7167f33 | 2009-08-08 14:06:07 +0000 | [diff] [blame] | 300 | def DSubReg_f64_reg : SDNodeXForm<imm, [{ | 
| Owen Anderson | 9f94459 | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 301 | return CurDAG->getTargetConstant(5 + N->getZExtValue(), MVT::i32); | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 302 | }]>; | 
|  | 303 |  | 
| Anton Korobeynikov | 7167f33 | 2009-08-08 14:06:07 +0000 | [diff] [blame] | 304 | // Extract S sub-registers of Q registers. | 
|  | 305 | // (arm_ssubreg_0 is 1; arm_ssubreg_1 is 2; etc.) | 
|  | 306 | def SSubReg_f32_reg : SDNodeXForm<imm, [{ | 
| Owen Anderson | 9f94459 | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 307 | return CurDAG->getTargetConstant(1 + N->getZExtValue(), MVT::i32); | 
| Anton Korobeynikov | 7167f33 | 2009-08-08 14:06:07 +0000 | [diff] [blame] | 308 | }]>; | 
|  | 309 |  | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 310 | // Translate lane numbers from Q registers to D subregs. | 
|  | 311 | def SubReg_i8_lane  : SDNodeXForm<imm, [{ | 
| Owen Anderson | 9f94459 | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 312 | return CurDAG->getTargetConstant(N->getZExtValue() & 7, MVT::i32); | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 313 | }]>; | 
|  | 314 | def SubReg_i16_lane : SDNodeXForm<imm, [{ | 
| Owen Anderson | 9f94459 | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 315 | return CurDAG->getTargetConstant(N->getZExtValue() & 3, MVT::i32); | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 316 | }]>; | 
|  | 317 | def SubReg_i32_lane : SDNodeXForm<imm, [{ | 
| Owen Anderson | 9f94459 | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 318 | return CurDAG->getTargetConstant(N->getZExtValue() & 1, MVT::i32); | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 319 | }]>; | 
|  | 320 |  | 
|  | 321 | //===----------------------------------------------------------------------===// | 
|  | 322 | // Instruction Classes | 
|  | 323 | //===----------------------------------------------------------------------===// | 
|  | 324 |  | 
|  | 325 | // Basic 2-register operations, both double- and quad-register. | 
|  | 326 | class N2VD<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, | 
|  | 327 | bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr, | 
|  | 328 | ValueType ResTy, ValueType OpTy, SDNode OpNode> | 
|  | 329 | : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 330 | (ins DPR:$src), NoItinerary, !strconcat(OpcodeStr, "\t$dst, $src"), "", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 331 | [(set DPR:$dst, (ResTy (OpNode (OpTy DPR:$src))))]>; | 
|  | 332 | class N2VQ<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, | 
|  | 333 | bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr, | 
|  | 334 | ValueType ResTy, ValueType OpTy, SDNode OpNode> | 
|  | 335 | : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, (outs QPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 336 | (ins QPR:$src), NoItinerary, !strconcat(OpcodeStr, "\t$dst, $src"), "", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 337 | [(set QPR:$dst, (ResTy (OpNode (OpTy QPR:$src))))]>; | 
|  | 338 |  | 
| David Goodwin | 85b5b02 | 2009-08-10 22:17:39 +0000 | [diff] [blame] | 339 | // Basic 2-register operations, scalar single-precision. | 
|  | 340 | class N2VDs<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, | 
|  | 341 | bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr, | 
|  | 342 | ValueType ResTy, ValueType OpTy, SDNode OpNode> | 
|  | 343 | : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, | 
|  | 344 | (outs DPR_VFP2:$dst), (ins DPR_VFP2:$src), | 
|  | 345 | NoItinerary, !strconcat(OpcodeStr, "\t$dst, $src"), "", []>; | 
|  | 346 |  | 
|  | 347 | class N2VDsPat<SDNode OpNode, ValueType ResTy, ValueType OpTy, NeonI Inst> | 
|  | 348 | : NEONFPPat<(ResTy (OpNode SPR:$a)), | 
|  | 349 | (EXTRACT_SUBREG | 
|  | 350 | (Inst (INSERT_SUBREG (OpTy (IMPLICIT_DEF)), SPR:$a, arm_ssubreg_0)), | 
|  | 351 | arm_ssubreg_0)>; | 
|  | 352 |  | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 353 | // Basic 2-register intrinsics, both double- and quad-register. | 
|  | 354 | class N2VDInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, | 
|  | 355 | bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr, | 
|  | 356 | ValueType ResTy, ValueType OpTy, Intrinsic IntOp> | 
|  | 357 | : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 358 | (ins DPR:$src), NoItinerary, !strconcat(OpcodeStr, "\t$dst, $src"), "", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 359 | [(set DPR:$dst, (ResTy (IntOp (OpTy DPR:$src))))]>; | 
|  | 360 | class N2VQInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, | 
|  | 361 | bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr, | 
|  | 362 | ValueType ResTy, ValueType OpTy, Intrinsic IntOp> | 
|  | 363 | : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, (outs QPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 364 | (ins QPR:$src), NoItinerary, !strconcat(OpcodeStr, "\t$dst, $src"), "", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 365 | [(set QPR:$dst, (ResTy (IntOp (OpTy QPR:$src))))]>; | 
|  | 366 |  | 
| David Goodwin | 85b5b02 | 2009-08-10 22:17:39 +0000 | [diff] [blame] | 367 | // Basic 2-register intrinsics, scalar single-precision | 
| Evan Cheng | 4c3b1ca | 2009-08-07 19:30:41 +0000 | [diff] [blame] | 368 | class N2VDInts<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, | 
|  | 369 | bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr, | 
|  | 370 | ValueType ResTy, ValueType OpTy, Intrinsic IntOp> | 
|  | 371 | : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, | 
|  | 372 | (outs DPR_VFP2:$dst), (ins DPR_VFP2:$src), NoItinerary, | 
|  | 373 | !strconcat(OpcodeStr, "\t$dst, $src"), "", []>; | 
|  | 374 |  | 
|  | 375 | class N2VDIntsPat<SDNode OpNode, NeonI Inst> | 
| David Goodwin | 30bf625 | 2009-08-04 20:39:05 +0000 | [diff] [blame] | 376 | : NEONFPPat<(f32 (OpNode SPR:$a)), | 
| Evan Cheng | 4c3b1ca | 2009-08-07 19:30:41 +0000 | [diff] [blame] | 377 | (EXTRACT_SUBREG | 
|  | 378 | (Inst (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$a, arm_ssubreg_0)), | 
|  | 379 | arm_ssubreg_0)>; | 
| David Goodwin | 30bf625 | 2009-08-04 20:39:05 +0000 | [diff] [blame] | 380 |  | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 381 | // Narrow 2-register intrinsics. | 
|  | 382 | class N2VNInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, | 
|  | 383 | bits<2> op17_16, bits<5> op11_7, bit op6, bit op4, | 
|  | 384 | string OpcodeStr, ValueType TyD, ValueType TyQ, Intrinsic IntOp> | 
|  | 385 | : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, op6, op4, (outs DPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 386 | (ins QPR:$src), NoItinerary, !strconcat(OpcodeStr, "\t$dst, $src"), "", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 387 | [(set DPR:$dst, (TyD (IntOp (TyQ QPR:$src))))]>; | 
|  | 388 |  | 
|  | 389 | // Long 2-register intrinsics.  (This is currently only used for VMOVL and is | 
|  | 390 | // derived from N2VImm instead of N2V because of the way the size is encoded.) | 
|  | 391 | class N2VLInt<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7, | 
|  | 392 | bit op6, bit op4, string OpcodeStr, ValueType TyQ, ValueType TyD, | 
|  | 393 | Intrinsic IntOp> | 
|  | 394 | : N2VImm<op24, op23, op21_16, op11_8, op7, op6, op4, (outs QPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 395 | (ins DPR:$src), NoItinerary, !strconcat(OpcodeStr, "\t$dst, $src"), "", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 396 | [(set QPR:$dst, (TyQ (IntOp (TyD DPR:$src))))]>; | 
|  | 397 |  | 
| Bob Wilson | e223107 | 2009-08-08 06:13:25 +0000 | [diff] [blame] | 398 | // 2-register shuffles (VTRN/VZIP/VUZP), both double- and quad-register. | 
|  | 399 | class N2VDShuffle<bits<2> op19_18, bits<5> op11_7, string OpcodeStr> | 
|  | 400 | : N2V<0b11, 0b11, op19_18, 0b10, op11_7, 0, 0, (outs DPR:$dst1, DPR:$dst2), | 
|  | 401 | (ins DPR:$src1, DPR:$src2), NoItinerary, | 
|  | 402 | !strconcat(OpcodeStr, "\t$dst1, $dst2"), | 
|  | 403 | "$src1 = $dst1, $src2 = $dst2", []>; | 
|  | 404 | class N2VQShuffle<bits<2> op19_18, bits<5> op11_7, string OpcodeStr> | 
|  | 405 | : N2V<0b11, 0b11, op19_18, 0b10, op11_7, 1, 0, (outs QPR:$dst1, QPR:$dst2), | 
|  | 406 | (ins QPR:$src1, QPR:$src2), NoItinerary, | 
|  | 407 | !strconcat(OpcodeStr, "\t$dst1, $dst2"), | 
|  | 408 | "$src1 = $dst1, $src2 = $dst2", []>; | 
|  | 409 |  | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 410 | // Basic 3-register operations, both double- and quad-register. | 
|  | 411 | class N3VD<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, | 
|  | 412 | string OpcodeStr, ValueType ResTy, ValueType OpTy, | 
|  | 413 | SDNode OpNode, bit Commutable> | 
|  | 414 | : N3V<op24, op23, op21_20, op11_8, 0, op4, | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 415 | (outs DPR:$dst), (ins DPR:$src1, DPR:$src2), NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 416 | !strconcat(OpcodeStr, "\t$dst, $src1, $src2"), "", | 
|  | 417 | [(set DPR:$dst, (ResTy (OpNode (OpTy DPR:$src1), (OpTy DPR:$src2))))]> { | 
|  | 418 | let isCommutable = Commutable; | 
|  | 419 | } | 
|  | 420 | class N3VQ<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, | 
|  | 421 | string OpcodeStr, ValueType ResTy, ValueType OpTy, | 
|  | 422 | SDNode OpNode, bit Commutable> | 
|  | 423 | : N3V<op24, op23, op21_20, op11_8, 1, op4, | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 424 | (outs QPR:$dst), (ins QPR:$src1, QPR:$src2), NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 425 | !strconcat(OpcodeStr, "\t$dst, $src1, $src2"), "", | 
|  | 426 | [(set QPR:$dst, (ResTy (OpNode (OpTy QPR:$src1), (OpTy QPR:$src2))))]> { | 
|  | 427 | let isCommutable = Commutable; | 
|  | 428 | } | 
|  | 429 |  | 
| David Goodwin | 3b9c52c | 2009-08-04 17:53:06 +0000 | [diff] [blame] | 430 | // Basic 3-register operations, scalar single-precision | 
| Evan Cheng | 4c3b1ca | 2009-08-07 19:30:41 +0000 | [diff] [blame] | 431 | class N3VDs<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, | 
|  | 432 | string OpcodeStr, ValueType ResTy, ValueType OpTy, | 
|  | 433 | SDNode OpNode, bit Commutable> | 
|  | 434 | : N3V<op24, op23, op21_20, op11_8, 0, op4, | 
|  | 435 | (outs DPR_VFP2:$dst), (ins DPR_VFP2:$src1, DPR_VFP2:$src2), NoItinerary, | 
|  | 436 | !strconcat(OpcodeStr, "\t$dst, $src1, $src2"), "", []> { | 
|  | 437 | let isCommutable = Commutable; | 
|  | 438 | } | 
|  | 439 | class N3VDsPat<SDNode OpNode, NeonI Inst> | 
| David Goodwin | 3b9c52c | 2009-08-04 17:53:06 +0000 | [diff] [blame] | 440 | : NEONFPPat<(f32 (OpNode SPR:$a, SPR:$b)), | 
| Evan Cheng | 4c3b1ca | 2009-08-07 19:30:41 +0000 | [diff] [blame] | 441 | (EXTRACT_SUBREG | 
|  | 442 | (Inst (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$a, arm_ssubreg_0), | 
|  | 443 | (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$b, arm_ssubreg_0)), | 
|  | 444 | arm_ssubreg_0)>; | 
| David Goodwin | 3b9c52c | 2009-08-04 17:53:06 +0000 | [diff] [blame] | 445 |  | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 446 | // Basic 3-register intrinsics, both double- and quad-register. | 
|  | 447 | class N3VDInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, | 
|  | 448 | string OpcodeStr, ValueType ResTy, ValueType OpTy, | 
|  | 449 | Intrinsic IntOp, bit Commutable> | 
|  | 450 | : N3V<op24, op23, op21_20, op11_8, 0, op4, | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 451 | (outs DPR:$dst), (ins DPR:$src1, DPR:$src2), NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 452 | !strconcat(OpcodeStr, "\t$dst, $src1, $src2"), "", | 
|  | 453 | [(set DPR:$dst, (ResTy (IntOp (OpTy DPR:$src1), (OpTy DPR:$src2))))]> { | 
|  | 454 | let isCommutable = Commutable; | 
|  | 455 | } | 
|  | 456 | class N3VQInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, | 
|  | 457 | string OpcodeStr, ValueType ResTy, ValueType OpTy, | 
|  | 458 | Intrinsic IntOp, bit Commutable> | 
|  | 459 | : N3V<op24, op23, op21_20, op11_8, 1, op4, | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 460 | (outs QPR:$dst), (ins QPR:$src1, QPR:$src2), NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 461 | !strconcat(OpcodeStr, "\t$dst, $src1, $src2"), "", | 
|  | 462 | [(set QPR:$dst, (ResTy (IntOp (OpTy QPR:$src1), (OpTy QPR:$src2))))]> { | 
|  | 463 | let isCommutable = Commutable; | 
|  | 464 | } | 
|  | 465 |  | 
|  | 466 | // Multiply-Add/Sub operations, both double- and quad-register. | 
|  | 467 | class N3VDMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, | 
|  | 468 | string OpcodeStr, ValueType Ty, SDNode MulOp, SDNode OpNode> | 
|  | 469 | : N3V<op24, op23, op21_20, op11_8, 0, op4, | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 470 | (outs DPR:$dst), (ins DPR:$src1, DPR:$src2, DPR:$src3), NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 471 | !strconcat(OpcodeStr, "\t$dst, $src2, $src3"), "$src1 = $dst", | 
|  | 472 | [(set DPR:$dst, (Ty (OpNode DPR:$src1, | 
|  | 473 | (Ty (MulOp DPR:$src2, DPR:$src3)))))]>; | 
|  | 474 | class N3VQMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, | 
|  | 475 | string OpcodeStr, ValueType Ty, SDNode MulOp, SDNode OpNode> | 
|  | 476 | : N3V<op24, op23, op21_20, op11_8, 1, op4, | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 477 | (outs QPR:$dst), (ins QPR:$src1, QPR:$src2, QPR:$src3), NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 478 | !strconcat(OpcodeStr, "\t$dst, $src2, $src3"), "$src1 = $dst", | 
|  | 479 | [(set QPR:$dst, (Ty (OpNode QPR:$src1, | 
|  | 480 | (Ty (MulOp QPR:$src2, QPR:$src3)))))]>; | 
|  | 481 |  | 
| David Goodwin | 3b9c52c | 2009-08-04 17:53:06 +0000 | [diff] [blame] | 482 | // Multiply-Add/Sub operations, scalar single-precision | 
| Evan Cheng | 4c3b1ca | 2009-08-07 19:30:41 +0000 | [diff] [blame] | 483 | class N3VDMulOps<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, | 
|  | 484 | string OpcodeStr, ValueType Ty, SDNode MulOp, SDNode OpNode> | 
|  | 485 | : N3V<op24, op23, op21_20, op11_8, 0, op4, | 
|  | 486 | (outs DPR_VFP2:$dst), | 
|  | 487 | (ins DPR_VFP2:$src1, DPR_VFP2:$src2, DPR_VFP2:$src3), NoItinerary, | 
|  | 488 | !strconcat(OpcodeStr, "\t$dst, $src2, $src3"), "$src1 = $dst", []>; | 
|  | 489 |  | 
|  | 490 | class N3VDMulOpsPat<SDNode MulNode, SDNode OpNode, NeonI Inst> | 
|  | 491 | : NEONFPPat<(f32 (OpNode SPR:$acc, (f32 (MulNode SPR:$a, SPR:$b)))), | 
|  | 492 | (EXTRACT_SUBREG | 
|  | 493 | (Inst (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$acc, arm_ssubreg_0), | 
|  | 494 | (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$a,   arm_ssubreg_0), | 
|  | 495 | (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$b,   arm_ssubreg_0)), | 
|  | 496 | arm_ssubreg_0)>; | 
| David Goodwin | 3b9c52c | 2009-08-04 17:53:06 +0000 | [diff] [blame] | 497 |  | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 498 | // Neon 3-argument intrinsics, both double- and quad-register. | 
|  | 499 | // The destination register is also used as the first source operand register. | 
|  | 500 | class N3VDInt3<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, | 
|  | 501 | string OpcodeStr, ValueType ResTy, ValueType OpTy, | 
|  | 502 | Intrinsic IntOp> | 
|  | 503 | : N3V<op24, op23, op21_20, op11_8, 0, op4, | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 504 | (outs DPR:$dst), (ins DPR:$src1, DPR:$src2, DPR:$src3), NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 505 | !strconcat(OpcodeStr, "\t$dst, $src2, $src3"), "$src1 = $dst", | 
|  | 506 | [(set DPR:$dst, (ResTy (IntOp (OpTy DPR:$src1), | 
|  | 507 | (OpTy DPR:$src2), (OpTy DPR:$src3))))]>; | 
|  | 508 | class N3VQInt3<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, | 
|  | 509 | string OpcodeStr, ValueType ResTy, ValueType OpTy, | 
|  | 510 | Intrinsic IntOp> | 
|  | 511 | : N3V<op24, op23, op21_20, op11_8, 1, op4, | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 512 | (outs QPR:$dst), (ins QPR:$src1, QPR:$src2, QPR:$src3), NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 513 | !strconcat(OpcodeStr, "\t$dst, $src2, $src3"), "$src1 = $dst", | 
|  | 514 | [(set QPR:$dst, (ResTy (IntOp (OpTy QPR:$src1), | 
|  | 515 | (OpTy QPR:$src2), (OpTy QPR:$src3))))]>; | 
|  | 516 |  | 
|  | 517 | // Neon Long 3-argument intrinsic.  The destination register is | 
|  | 518 | // a quad-register and is also used as the first source operand register. | 
|  | 519 | class N3VLInt3<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, | 
|  | 520 | string OpcodeStr, ValueType TyQ, ValueType TyD, Intrinsic IntOp> | 
|  | 521 | : N3V<op24, op23, op21_20, op11_8, 0, op4, | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 522 | (outs QPR:$dst), (ins QPR:$src1, DPR:$src2, DPR:$src3), NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 523 | !strconcat(OpcodeStr, "\t$dst, $src2, $src3"), "$src1 = $dst", | 
|  | 524 | [(set QPR:$dst, | 
|  | 525 | (TyQ (IntOp (TyQ QPR:$src1), (TyD DPR:$src2), (TyD DPR:$src3))))]>; | 
|  | 526 |  | 
|  | 527 | // Narrowing 3-register intrinsics. | 
|  | 528 | class N3VNInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, | 
|  | 529 | string OpcodeStr, ValueType TyD, ValueType TyQ, | 
|  | 530 | Intrinsic IntOp, bit Commutable> | 
|  | 531 | : N3V<op24, op23, op21_20, op11_8, 0, op4, | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 532 | (outs DPR:$dst), (ins QPR:$src1, QPR:$src2), NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 533 | !strconcat(OpcodeStr, "\t$dst, $src1, $src2"), "", | 
|  | 534 | [(set DPR:$dst, (TyD (IntOp (TyQ QPR:$src1), (TyQ QPR:$src2))))]> { | 
|  | 535 | let isCommutable = Commutable; | 
|  | 536 | } | 
|  | 537 |  | 
|  | 538 | // Long 3-register intrinsics. | 
|  | 539 | class N3VLInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, | 
|  | 540 | string OpcodeStr, ValueType TyQ, ValueType TyD, | 
|  | 541 | Intrinsic IntOp, bit Commutable> | 
|  | 542 | : N3V<op24, op23, op21_20, op11_8, 0, op4, | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 543 | (outs QPR:$dst), (ins DPR:$src1, DPR:$src2), NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 544 | !strconcat(OpcodeStr, "\t$dst, $src1, $src2"), "", | 
|  | 545 | [(set QPR:$dst, (TyQ (IntOp (TyD DPR:$src1), (TyD DPR:$src2))))]> { | 
|  | 546 | let isCommutable = Commutable; | 
|  | 547 | } | 
|  | 548 |  | 
|  | 549 | // Wide 3-register intrinsics. | 
|  | 550 | class N3VWInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, | 
|  | 551 | string OpcodeStr, ValueType TyQ, ValueType TyD, | 
|  | 552 | Intrinsic IntOp, bit Commutable> | 
|  | 553 | : N3V<op24, op23, op21_20, op11_8, 0, op4, | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 554 | (outs QPR:$dst), (ins QPR:$src1, DPR:$src2), NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 555 | !strconcat(OpcodeStr, "\t$dst, $src1, $src2"), "", | 
|  | 556 | [(set QPR:$dst, (TyQ (IntOp (TyQ QPR:$src1), (TyD DPR:$src2))))]> { | 
|  | 557 | let isCommutable = Commutable; | 
|  | 558 | } | 
|  | 559 |  | 
|  | 560 | // Pairwise long 2-register intrinsics, both double- and quad-register. | 
|  | 561 | class N2VDPLInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, | 
|  | 562 | bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr, | 
|  | 563 | ValueType ResTy, ValueType OpTy, Intrinsic IntOp> | 
|  | 564 | : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 565 | (ins DPR:$src), NoItinerary, !strconcat(OpcodeStr, "\t$dst, $src"), "", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 566 | [(set DPR:$dst, (ResTy (IntOp (OpTy DPR:$src))))]>; | 
|  | 567 | class N2VQPLInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, | 
|  | 568 | bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr, | 
|  | 569 | ValueType ResTy, ValueType OpTy, Intrinsic IntOp> | 
|  | 570 | : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, (outs QPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 571 | (ins QPR:$src), NoItinerary, !strconcat(OpcodeStr, "\t$dst, $src"), "", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 572 | [(set QPR:$dst, (ResTy (IntOp (OpTy QPR:$src))))]>; | 
|  | 573 |  | 
|  | 574 | // Pairwise long 2-register accumulate intrinsics, | 
|  | 575 | // both double- and quad-register. | 
|  | 576 | // The destination register is also used as the first source operand register. | 
|  | 577 | class N2VDPLInt2<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, | 
|  | 578 | bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr, | 
|  | 579 | ValueType ResTy, ValueType OpTy, Intrinsic IntOp> | 
|  | 580 | : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 581 | (outs DPR:$dst), (ins DPR:$src1, DPR:$src2), NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 582 | !strconcat(OpcodeStr, "\t$dst, $src2"), "$src1 = $dst", | 
|  | 583 | [(set DPR:$dst, (ResTy (IntOp (ResTy DPR:$src1), (OpTy DPR:$src2))))]>; | 
|  | 584 | class N2VQPLInt2<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, | 
|  | 585 | bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr, | 
|  | 586 | ValueType ResTy, ValueType OpTy, Intrinsic IntOp> | 
|  | 587 | : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 588 | (outs QPR:$dst), (ins QPR:$src1, QPR:$src2), NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 589 | !strconcat(OpcodeStr, "\t$dst, $src2"), "$src1 = $dst", | 
|  | 590 | [(set QPR:$dst, (ResTy (IntOp (ResTy QPR:$src1), (OpTy QPR:$src2))))]>; | 
|  | 591 |  | 
|  | 592 | // Shift by immediate, | 
|  | 593 | // both double- and quad-register. | 
|  | 594 | class N2VDSh<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7, | 
|  | 595 | bit op4, string OpcodeStr, ValueType Ty, SDNode OpNode> | 
|  | 596 | : N2VImm<op24, op23, op21_16, op11_8, op7, 0, op4, | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 597 | (outs DPR:$dst), (ins DPR:$src, i32imm:$SIMM), NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 598 | !strconcat(OpcodeStr, "\t$dst, $src, $SIMM"), "", | 
|  | 599 | [(set DPR:$dst, (Ty (OpNode (Ty DPR:$src), (i32 imm:$SIMM))))]>; | 
|  | 600 | class N2VQSh<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7, | 
|  | 601 | bit op4, string OpcodeStr, ValueType Ty, SDNode OpNode> | 
|  | 602 | : N2VImm<op24, op23, op21_16, op11_8, op7, 1, op4, | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 603 | (outs QPR:$dst), (ins QPR:$src, i32imm:$SIMM), NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 604 | !strconcat(OpcodeStr, "\t$dst, $src, $SIMM"), "", | 
|  | 605 | [(set QPR:$dst, (Ty (OpNode (Ty QPR:$src), (i32 imm:$SIMM))))]>; | 
|  | 606 |  | 
|  | 607 | // Long shift by immediate. | 
|  | 608 | class N2VLSh<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7, | 
|  | 609 | bit op6, bit op4, string OpcodeStr, ValueType ResTy, | 
|  | 610 | ValueType OpTy, SDNode OpNode> | 
|  | 611 | : N2VImm<op24, op23, op21_16, op11_8, op7, op6, op4, | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 612 | (outs QPR:$dst), (ins DPR:$src, i32imm:$SIMM), NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 613 | !strconcat(OpcodeStr, "\t$dst, $src, $SIMM"), "", | 
|  | 614 | [(set QPR:$dst, (ResTy (OpNode (OpTy DPR:$src), | 
|  | 615 | (i32 imm:$SIMM))))]>; | 
|  | 616 |  | 
|  | 617 | // Narrow shift by immediate. | 
|  | 618 | class N2VNSh<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7, | 
|  | 619 | bit op6, bit op4, string OpcodeStr, ValueType ResTy, | 
|  | 620 | ValueType OpTy, SDNode OpNode> | 
|  | 621 | : N2VImm<op24, op23, op21_16, op11_8, op7, op6, op4, | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 622 | (outs DPR:$dst), (ins QPR:$src, i32imm:$SIMM), NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 623 | !strconcat(OpcodeStr, "\t$dst, $src, $SIMM"), "", | 
|  | 624 | [(set DPR:$dst, (ResTy (OpNode (OpTy QPR:$src), | 
|  | 625 | (i32 imm:$SIMM))))]>; | 
|  | 626 |  | 
|  | 627 | // Shift right by immediate and accumulate, | 
|  | 628 | // both double- and quad-register. | 
|  | 629 | class N2VDShAdd<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7, | 
|  | 630 | bit op4, string OpcodeStr, ValueType Ty, SDNode ShOp> | 
|  | 631 | : N2VImm<op24, op23, op21_16, op11_8, op7, 0, op4, | 
|  | 632 | (outs DPR:$dst), (ins DPR:$src1, DPR:$src2, i32imm:$SIMM), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 633 | NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 634 | !strconcat(OpcodeStr, "\t$dst, $src2, $SIMM"), "$src1 = $dst", | 
|  | 635 | [(set DPR:$dst, (Ty (add DPR:$src1, | 
|  | 636 | (Ty (ShOp DPR:$src2, (i32 imm:$SIMM))))))]>; | 
|  | 637 | class N2VQShAdd<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7, | 
|  | 638 | bit op4, string OpcodeStr, ValueType Ty, SDNode ShOp> | 
|  | 639 | : N2VImm<op24, op23, op21_16, op11_8, op7, 1, op4, | 
|  | 640 | (outs QPR:$dst), (ins QPR:$src1, QPR:$src2, i32imm:$SIMM), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 641 | NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 642 | !strconcat(OpcodeStr, "\t$dst, $src2, $SIMM"), "$src1 = $dst", | 
|  | 643 | [(set QPR:$dst, (Ty (add QPR:$src1, | 
|  | 644 | (Ty (ShOp QPR:$src2, (i32 imm:$SIMM))))))]>; | 
|  | 645 |  | 
|  | 646 | // Shift by immediate and insert, | 
|  | 647 | // both double- and quad-register. | 
|  | 648 | class N2VDShIns<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7, | 
|  | 649 | bit op4, string OpcodeStr, ValueType Ty, SDNode ShOp> | 
|  | 650 | : N2VImm<op24, op23, op21_16, op11_8, op7, 0, op4, | 
|  | 651 | (outs DPR:$dst), (ins DPR:$src1, DPR:$src2, i32imm:$SIMM), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 652 | NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 653 | !strconcat(OpcodeStr, "\t$dst, $src2, $SIMM"), "$src1 = $dst", | 
|  | 654 | [(set DPR:$dst, (Ty (ShOp DPR:$src1, DPR:$src2, (i32 imm:$SIMM))))]>; | 
|  | 655 | class N2VQShIns<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7, | 
|  | 656 | bit op4, string OpcodeStr, ValueType Ty, SDNode ShOp> | 
|  | 657 | : N2VImm<op24, op23, op21_16, op11_8, op7, 1, op4, | 
|  | 658 | (outs QPR:$dst), (ins QPR:$src1, QPR:$src2, i32imm:$SIMM), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 659 | NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 660 | !strconcat(OpcodeStr, "\t$dst, $src2, $SIMM"), "$src1 = $dst", | 
|  | 661 | [(set QPR:$dst, (Ty (ShOp QPR:$src1, QPR:$src2, (i32 imm:$SIMM))))]>; | 
|  | 662 |  | 
|  | 663 | // Convert, with fractional bits immediate, | 
|  | 664 | // both double- and quad-register. | 
|  | 665 | class N2VCvtD<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7, | 
|  | 666 | bit op4, string OpcodeStr, ValueType ResTy, ValueType OpTy, | 
|  | 667 | Intrinsic IntOp> | 
|  | 668 | : N2VImm<op24, op23, op21_16, op11_8, op7, 0, op4, | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 669 | (outs DPR:$dst), (ins DPR:$src, i32imm:$SIMM), NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 670 | !strconcat(OpcodeStr, "\t$dst, $src, $SIMM"), "", | 
|  | 671 | [(set DPR:$dst, (ResTy (IntOp (OpTy DPR:$src), (i32 imm:$SIMM))))]>; | 
|  | 672 | class N2VCvtQ<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7, | 
|  | 673 | bit op4, string OpcodeStr, ValueType ResTy, ValueType OpTy, | 
|  | 674 | Intrinsic IntOp> | 
|  | 675 | : N2VImm<op24, op23, op21_16, op11_8, op7, 1, op4, | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 676 | (outs QPR:$dst), (ins QPR:$src, i32imm:$SIMM), NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 677 | !strconcat(OpcodeStr, "\t$dst, $src, $SIMM"), "", | 
|  | 678 | [(set QPR:$dst, (ResTy (IntOp (OpTy QPR:$src), (i32 imm:$SIMM))))]>; | 
|  | 679 |  | 
|  | 680 | //===----------------------------------------------------------------------===// | 
|  | 681 | // Multiclasses | 
|  | 682 | //===----------------------------------------------------------------------===// | 
|  | 683 |  | 
|  | 684 | // Neon 3-register vector operations. | 
|  | 685 |  | 
|  | 686 | // First with only element sizes of 8, 16 and 32 bits: | 
|  | 687 | multiclass N3V_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, | 
|  | 688 | string OpcodeStr, SDNode OpNode, bit Commutable = 0> { | 
|  | 689 | // 64-bit vector types. | 
|  | 690 | def v8i8  : N3VD<op24, op23, 0b00, op11_8, op4, !strconcat(OpcodeStr, "8"), | 
|  | 691 | v8i8, v8i8, OpNode, Commutable>; | 
|  | 692 | def v4i16 : N3VD<op24, op23, 0b01, op11_8, op4, !strconcat(OpcodeStr, "16"), | 
|  | 693 | v4i16, v4i16, OpNode, Commutable>; | 
|  | 694 | def v2i32 : N3VD<op24, op23, 0b10, op11_8, op4, !strconcat(OpcodeStr, "32"), | 
|  | 695 | v2i32, v2i32, OpNode, Commutable>; | 
|  | 696 |  | 
|  | 697 | // 128-bit vector types. | 
|  | 698 | def v16i8 : N3VQ<op24, op23, 0b00, op11_8, op4, !strconcat(OpcodeStr, "8"), | 
|  | 699 | v16i8, v16i8, OpNode, Commutable>; | 
|  | 700 | def v8i16 : N3VQ<op24, op23, 0b01, op11_8, op4, !strconcat(OpcodeStr, "16"), | 
|  | 701 | v8i16, v8i16, OpNode, Commutable>; | 
|  | 702 | def v4i32 : N3VQ<op24, op23, 0b10, op11_8, op4, !strconcat(OpcodeStr, "32"), | 
|  | 703 | v4i32, v4i32, OpNode, Commutable>; | 
|  | 704 | } | 
|  | 705 |  | 
|  | 706 | // ....then also with element size 64 bits: | 
|  | 707 | multiclass N3V_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4, | 
|  | 708 | string OpcodeStr, SDNode OpNode, bit Commutable = 0> | 
|  | 709 | : N3V_QHS<op24, op23, op11_8, op4, OpcodeStr, OpNode, Commutable> { | 
|  | 710 | def v1i64 : N3VD<op24, op23, 0b11, op11_8, op4, !strconcat(OpcodeStr, "64"), | 
|  | 711 | v1i64, v1i64, OpNode, Commutable>; | 
|  | 712 | def v2i64 : N3VQ<op24, op23, 0b11, op11_8, op4, !strconcat(OpcodeStr, "64"), | 
|  | 713 | v2i64, v2i64, OpNode, Commutable>; | 
|  | 714 | } | 
|  | 715 |  | 
|  | 716 |  | 
|  | 717 | // Neon Narrowing 2-register vector intrinsics, | 
|  | 718 | //   source operand element sizes of 16, 32 and 64 bits: | 
|  | 719 | multiclass N2VNInt_HSD<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16, | 
|  | 720 | bits<5> op11_7, bit op6, bit op4, string OpcodeStr, | 
|  | 721 | Intrinsic IntOp> { | 
|  | 722 | def v8i8  : N2VNInt<op24_23, op21_20, 0b00, op17_16, op11_7, op6, op4, | 
|  | 723 | !strconcat(OpcodeStr, "16"), v8i8, v8i16, IntOp>; | 
|  | 724 | def v4i16 : N2VNInt<op24_23, op21_20, 0b01, op17_16, op11_7, op6, op4, | 
|  | 725 | !strconcat(OpcodeStr, "32"), v4i16, v4i32, IntOp>; | 
|  | 726 | def v2i32 : N2VNInt<op24_23, op21_20, 0b10, op17_16, op11_7, op6, op4, | 
|  | 727 | !strconcat(OpcodeStr, "64"), v2i32, v2i64, IntOp>; | 
|  | 728 | } | 
|  | 729 |  | 
|  | 730 |  | 
|  | 731 | // Neon Lengthening 2-register vector intrinsic (currently specific to VMOVL). | 
|  | 732 | //   source operand element sizes of 16, 32 and 64 bits: | 
|  | 733 | multiclass N2VLInt_QHS<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, | 
|  | 734 | bit op4, string OpcodeStr, Intrinsic IntOp> { | 
|  | 735 | def v8i16 : N2VLInt<op24, op23, 0b001000, op11_8, op7, op6, op4, | 
|  | 736 | !strconcat(OpcodeStr, "8"), v8i16, v8i8, IntOp>; | 
|  | 737 | def v4i32 : N2VLInt<op24, op23, 0b010000, op11_8, op7, op6, op4, | 
|  | 738 | !strconcat(OpcodeStr, "16"), v4i32, v4i16, IntOp>; | 
|  | 739 | def v2i64 : N2VLInt<op24, op23, 0b100000, op11_8, op7, op6, op4, | 
|  | 740 | !strconcat(OpcodeStr, "32"), v2i64, v2i32, IntOp>; | 
|  | 741 | } | 
|  | 742 |  | 
|  | 743 |  | 
|  | 744 | // Neon 3-register vector intrinsics. | 
|  | 745 |  | 
|  | 746 | // First with only element sizes of 16 and 32 bits: | 
|  | 747 | multiclass N3VInt_HS<bit op24, bit op23, bits<4> op11_8, bit op4, | 
|  | 748 | string OpcodeStr, Intrinsic IntOp, bit Commutable = 0> { | 
|  | 749 | // 64-bit vector types. | 
|  | 750 | def v4i16 : N3VDInt<op24, op23, 0b01, op11_8, op4, !strconcat(OpcodeStr,"16"), | 
|  | 751 | v4i16, v4i16, IntOp, Commutable>; | 
|  | 752 | def v2i32 : N3VDInt<op24, op23, 0b10, op11_8, op4, !strconcat(OpcodeStr,"32"), | 
|  | 753 | v2i32, v2i32, IntOp, Commutable>; | 
|  | 754 |  | 
|  | 755 | // 128-bit vector types. | 
|  | 756 | def v8i16 : N3VQInt<op24, op23, 0b01, op11_8, op4, !strconcat(OpcodeStr,"16"), | 
|  | 757 | v8i16, v8i16, IntOp, Commutable>; | 
|  | 758 | def v4i32 : N3VQInt<op24, op23, 0b10, op11_8, op4, !strconcat(OpcodeStr,"32"), | 
|  | 759 | v4i32, v4i32, IntOp, Commutable>; | 
|  | 760 | } | 
|  | 761 |  | 
|  | 762 | // ....then also with element size of 8 bits: | 
|  | 763 | multiclass N3VInt_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, | 
|  | 764 | string OpcodeStr, Intrinsic IntOp, bit Commutable = 0> | 
|  | 765 | : N3VInt_HS<op24, op23, op11_8, op4, OpcodeStr, IntOp, Commutable> { | 
|  | 766 | def v8i8  : N3VDInt<op24, op23, 0b00, op11_8, op4, !strconcat(OpcodeStr, "8"), | 
|  | 767 | v8i8, v8i8, IntOp, Commutable>; | 
|  | 768 | def v16i8 : N3VQInt<op24, op23, 0b00, op11_8, op4, !strconcat(OpcodeStr, "8"), | 
|  | 769 | v16i8, v16i8, IntOp, Commutable>; | 
|  | 770 | } | 
|  | 771 |  | 
|  | 772 | // ....then also with element size of 64 bits: | 
|  | 773 | multiclass N3VInt_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4, | 
|  | 774 | string OpcodeStr, Intrinsic IntOp, bit Commutable = 0> | 
|  | 775 | : N3VInt_QHS<op24, op23, op11_8, op4, OpcodeStr, IntOp, Commutable> { | 
|  | 776 | def v1i64 : N3VDInt<op24, op23, 0b11, op11_8, op4, !strconcat(OpcodeStr,"64"), | 
|  | 777 | v1i64, v1i64, IntOp, Commutable>; | 
|  | 778 | def v2i64 : N3VQInt<op24, op23, 0b11, op11_8, op4, !strconcat(OpcodeStr,"64"), | 
|  | 779 | v2i64, v2i64, IntOp, Commutable>; | 
|  | 780 | } | 
|  | 781 |  | 
|  | 782 |  | 
|  | 783 | // Neon Narrowing 3-register vector intrinsics, | 
|  | 784 | //   source operand element sizes of 16, 32 and 64 bits: | 
|  | 785 | multiclass N3VNInt_HSD<bit op24, bit op23, bits<4> op11_8, bit op4, | 
|  | 786 | string OpcodeStr, Intrinsic IntOp, bit Commutable = 0> { | 
|  | 787 | def v8i8  : N3VNInt<op24, op23, 0b00, op11_8, op4, !strconcat(OpcodeStr,"16"), | 
|  | 788 | v8i8, v8i16, IntOp, Commutable>; | 
|  | 789 | def v4i16 : N3VNInt<op24, op23, 0b01, op11_8, op4, !strconcat(OpcodeStr,"32"), | 
|  | 790 | v4i16, v4i32, IntOp, Commutable>; | 
|  | 791 | def v2i32 : N3VNInt<op24, op23, 0b10, op11_8, op4, !strconcat(OpcodeStr,"64"), | 
|  | 792 | v2i32, v2i64, IntOp, Commutable>; | 
|  | 793 | } | 
|  | 794 |  | 
|  | 795 |  | 
|  | 796 | // Neon Long 3-register vector intrinsics. | 
|  | 797 |  | 
|  | 798 | // First with only element sizes of 16 and 32 bits: | 
|  | 799 | multiclass N3VLInt_HS<bit op24, bit op23, bits<4> op11_8, bit op4, | 
|  | 800 | string OpcodeStr, Intrinsic IntOp, bit Commutable = 0> { | 
|  | 801 | def v4i32 : N3VLInt<op24, op23, 0b01, op11_8, op4, !strconcat(OpcodeStr,"16"), | 
|  | 802 | v4i32, v4i16, IntOp, Commutable>; | 
|  | 803 | def v2i64 : N3VLInt<op24, op23, 0b10, op11_8, op4, !strconcat(OpcodeStr,"32"), | 
|  | 804 | v2i64, v2i32, IntOp, Commutable>; | 
|  | 805 | } | 
|  | 806 |  | 
|  | 807 | // ....then also with element size of 8 bits: | 
|  | 808 | multiclass N3VLInt_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, | 
|  | 809 | string OpcodeStr, Intrinsic IntOp, bit Commutable = 0> | 
|  | 810 | : N3VLInt_HS<op24, op23, op11_8, op4, OpcodeStr, IntOp, Commutable> { | 
|  | 811 | def v8i16 : N3VLInt<op24, op23, 0b00, op11_8, op4, !strconcat(OpcodeStr, "8"), | 
|  | 812 | v8i16, v8i8, IntOp, Commutable>; | 
|  | 813 | } | 
|  | 814 |  | 
|  | 815 |  | 
|  | 816 | // Neon Wide 3-register vector intrinsics, | 
|  | 817 | //   source operand element sizes of 8, 16 and 32 bits: | 
|  | 818 | multiclass N3VWInt_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, | 
|  | 819 | string OpcodeStr, Intrinsic IntOp, bit Commutable = 0> { | 
|  | 820 | def v8i16 : N3VWInt<op24, op23, 0b00, op11_8, op4, !strconcat(OpcodeStr, "8"), | 
|  | 821 | v8i16, v8i8, IntOp, Commutable>; | 
|  | 822 | def v4i32 : N3VWInt<op24, op23, 0b01, op11_8, op4, !strconcat(OpcodeStr,"16"), | 
|  | 823 | v4i32, v4i16, IntOp, Commutable>; | 
|  | 824 | def v2i64 : N3VWInt<op24, op23, 0b10, op11_8, op4, !strconcat(OpcodeStr,"32"), | 
|  | 825 | v2i64, v2i32, IntOp, Commutable>; | 
|  | 826 | } | 
|  | 827 |  | 
|  | 828 |  | 
|  | 829 | // Neon Multiply-Op vector operations, | 
|  | 830 | //   element sizes of 8, 16 and 32 bits: | 
|  | 831 | multiclass N3VMulOp_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, | 
|  | 832 | string OpcodeStr, SDNode OpNode> { | 
|  | 833 | // 64-bit vector types. | 
|  | 834 | def v8i8  : N3VDMulOp<op24, op23, 0b00, op11_8, op4, | 
|  | 835 | !strconcat(OpcodeStr, "8"), v8i8, mul, OpNode>; | 
|  | 836 | def v4i16 : N3VDMulOp<op24, op23, 0b01, op11_8, op4, | 
|  | 837 | !strconcat(OpcodeStr, "16"), v4i16, mul, OpNode>; | 
|  | 838 | def v2i32 : N3VDMulOp<op24, op23, 0b10, op11_8, op4, | 
|  | 839 | !strconcat(OpcodeStr, "32"), v2i32, mul, OpNode>; | 
|  | 840 |  | 
|  | 841 | // 128-bit vector types. | 
|  | 842 | def v16i8 : N3VQMulOp<op24, op23, 0b00, op11_8, op4, | 
|  | 843 | !strconcat(OpcodeStr, "8"), v16i8, mul, OpNode>; | 
|  | 844 | def v8i16 : N3VQMulOp<op24, op23, 0b01, op11_8, op4, | 
|  | 845 | !strconcat(OpcodeStr, "16"), v8i16, mul, OpNode>; | 
|  | 846 | def v4i32 : N3VQMulOp<op24, op23, 0b10, op11_8, op4, | 
|  | 847 | !strconcat(OpcodeStr, "32"), v4i32, mul, OpNode>; | 
|  | 848 | } | 
|  | 849 |  | 
|  | 850 |  | 
|  | 851 | // Neon 3-argument intrinsics, | 
|  | 852 | //   element sizes of 8, 16 and 32 bits: | 
|  | 853 | multiclass N3VInt3_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, | 
|  | 854 | string OpcodeStr, Intrinsic IntOp> { | 
|  | 855 | // 64-bit vector types. | 
|  | 856 | def v8i8  : N3VDInt3<op24, op23, 0b00, op11_8, op4, | 
|  | 857 | !strconcat(OpcodeStr, "8"), v8i8, v8i8, IntOp>; | 
|  | 858 | def v4i16 : N3VDInt3<op24, op23, 0b01, op11_8, op4, | 
|  | 859 | !strconcat(OpcodeStr, "16"), v4i16, v4i16, IntOp>; | 
|  | 860 | def v2i32 : N3VDInt3<op24, op23, 0b10, op11_8, op4, | 
|  | 861 | !strconcat(OpcodeStr, "32"), v2i32, v2i32, IntOp>; | 
|  | 862 |  | 
|  | 863 | // 128-bit vector types. | 
|  | 864 | def v16i8 : N3VQInt3<op24, op23, 0b00, op11_8, op4, | 
|  | 865 | !strconcat(OpcodeStr, "8"), v16i8, v16i8, IntOp>; | 
|  | 866 | def v8i16 : N3VQInt3<op24, op23, 0b01, op11_8, op4, | 
|  | 867 | !strconcat(OpcodeStr, "16"), v8i16, v8i16, IntOp>; | 
|  | 868 | def v4i32 : N3VQInt3<op24, op23, 0b10, op11_8, op4, | 
|  | 869 | !strconcat(OpcodeStr, "32"), v4i32, v4i32, IntOp>; | 
|  | 870 | } | 
|  | 871 |  | 
|  | 872 |  | 
|  | 873 | // Neon Long 3-argument intrinsics. | 
|  | 874 |  | 
|  | 875 | // First with only element sizes of 16 and 32 bits: | 
|  | 876 | multiclass N3VLInt3_HS<bit op24, bit op23, bits<4> op11_8, bit op4, | 
|  | 877 | string OpcodeStr, Intrinsic IntOp> { | 
|  | 878 | def v4i32 : N3VLInt3<op24, op23, 0b01, op11_8, op4, | 
|  | 879 | !strconcat(OpcodeStr, "16"), v4i32, v4i16, IntOp>; | 
|  | 880 | def v2i64 : N3VLInt3<op24, op23, 0b10, op11_8, op4, | 
|  | 881 | !strconcat(OpcodeStr, "32"), v2i64, v2i32, IntOp>; | 
|  | 882 | } | 
|  | 883 |  | 
|  | 884 | // ....then also with element size of 8 bits: | 
|  | 885 | multiclass N3VLInt3_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, | 
|  | 886 | string OpcodeStr, Intrinsic IntOp> | 
|  | 887 | : N3VLInt3_HS<op24, op23, op11_8, op4, OpcodeStr, IntOp> { | 
|  | 888 | def v8i16 : N3VLInt3<op24, op23, 0b01, op11_8, op4, | 
|  | 889 | !strconcat(OpcodeStr, "8"), v8i16, v8i8, IntOp>; | 
|  | 890 | } | 
|  | 891 |  | 
|  | 892 |  | 
|  | 893 | // Neon 2-register vector intrinsics, | 
|  | 894 | //   element sizes of 8, 16 and 32 bits: | 
|  | 895 | multiclass N2VInt_QHS<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16, | 
|  | 896 | bits<5> op11_7, bit op4, string OpcodeStr, | 
|  | 897 | Intrinsic IntOp> { | 
|  | 898 | // 64-bit vector types. | 
|  | 899 | def v8i8  : N2VDInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4, | 
|  | 900 | !strconcat(OpcodeStr, "8"), v8i8, v8i8, IntOp>; | 
|  | 901 | def v4i16 : N2VDInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4, | 
|  | 902 | !strconcat(OpcodeStr, "16"), v4i16, v4i16, IntOp>; | 
|  | 903 | def v2i32 : N2VDInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4, | 
|  | 904 | !strconcat(OpcodeStr, "32"), v2i32, v2i32, IntOp>; | 
|  | 905 |  | 
|  | 906 | // 128-bit vector types. | 
|  | 907 | def v16i8 : N2VQInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4, | 
|  | 908 | !strconcat(OpcodeStr, "8"), v16i8, v16i8, IntOp>; | 
|  | 909 | def v8i16 : N2VQInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4, | 
|  | 910 | !strconcat(OpcodeStr, "16"), v8i16, v8i16, IntOp>; | 
|  | 911 | def v4i32 : N2VQInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4, | 
|  | 912 | !strconcat(OpcodeStr, "32"), v4i32, v4i32, IntOp>; | 
|  | 913 | } | 
|  | 914 |  | 
|  | 915 |  | 
|  | 916 | // Neon Pairwise long 2-register intrinsics, | 
|  | 917 | //   element sizes of 8, 16 and 32 bits: | 
|  | 918 | multiclass N2VPLInt_QHS<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16, | 
|  | 919 | bits<5> op11_7, bit op4, | 
|  | 920 | string OpcodeStr, Intrinsic IntOp> { | 
|  | 921 | // 64-bit vector types. | 
|  | 922 | def v8i8  : N2VDPLInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4, | 
|  | 923 | !strconcat(OpcodeStr, "8"), v4i16, v8i8, IntOp>; | 
|  | 924 | def v4i16 : N2VDPLInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4, | 
|  | 925 | !strconcat(OpcodeStr, "16"), v2i32, v4i16, IntOp>; | 
|  | 926 | def v2i32 : N2VDPLInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4, | 
|  | 927 | !strconcat(OpcodeStr, "32"), v1i64, v2i32, IntOp>; | 
|  | 928 |  | 
|  | 929 | // 128-bit vector types. | 
|  | 930 | def v16i8 : N2VQPLInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4, | 
|  | 931 | !strconcat(OpcodeStr, "8"), v8i16, v16i8, IntOp>; | 
|  | 932 | def v8i16 : N2VQPLInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4, | 
|  | 933 | !strconcat(OpcodeStr, "16"), v4i32, v8i16, IntOp>; | 
|  | 934 | def v4i32 : N2VQPLInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4, | 
|  | 935 | !strconcat(OpcodeStr, "32"), v2i64, v4i32, IntOp>; | 
|  | 936 | } | 
|  | 937 |  | 
|  | 938 |  | 
|  | 939 | // Neon Pairwise long 2-register accumulate intrinsics, | 
|  | 940 | //   element sizes of 8, 16 and 32 bits: | 
|  | 941 | multiclass N2VPLInt2_QHS<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16, | 
|  | 942 | bits<5> op11_7, bit op4, | 
|  | 943 | string OpcodeStr, Intrinsic IntOp> { | 
|  | 944 | // 64-bit vector types. | 
|  | 945 | def v8i8  : N2VDPLInt2<op24_23, op21_20, 0b00, op17_16, op11_7, op4, | 
|  | 946 | !strconcat(OpcodeStr, "8"), v4i16, v8i8, IntOp>; | 
|  | 947 | def v4i16 : N2VDPLInt2<op24_23, op21_20, 0b01, op17_16, op11_7, op4, | 
|  | 948 | !strconcat(OpcodeStr, "16"), v2i32, v4i16, IntOp>; | 
|  | 949 | def v2i32 : N2VDPLInt2<op24_23, op21_20, 0b10, op17_16, op11_7, op4, | 
|  | 950 | !strconcat(OpcodeStr, "32"), v1i64, v2i32, IntOp>; | 
|  | 951 |  | 
|  | 952 | // 128-bit vector types. | 
|  | 953 | def v16i8 : N2VQPLInt2<op24_23, op21_20, 0b00, op17_16, op11_7, op4, | 
|  | 954 | !strconcat(OpcodeStr, "8"), v8i16, v16i8, IntOp>; | 
|  | 955 | def v8i16 : N2VQPLInt2<op24_23, op21_20, 0b01, op17_16, op11_7, op4, | 
|  | 956 | !strconcat(OpcodeStr, "16"), v4i32, v8i16, IntOp>; | 
|  | 957 | def v4i32 : N2VQPLInt2<op24_23, op21_20, 0b10, op17_16, op11_7, op4, | 
|  | 958 | !strconcat(OpcodeStr, "32"), v2i64, v4i32, IntOp>; | 
|  | 959 | } | 
|  | 960 |  | 
|  | 961 |  | 
|  | 962 | // Neon 2-register vector shift by immediate, | 
|  | 963 | //   element sizes of 8, 16, 32 and 64 bits: | 
|  | 964 | multiclass N2VSh_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4, | 
|  | 965 | string OpcodeStr, SDNode OpNode> { | 
|  | 966 | // 64-bit vector types. | 
|  | 967 | def v8i8  : N2VDSh<op24, op23, 0b001000, op11_8, 0, op4, | 
|  | 968 | !strconcat(OpcodeStr, "8"), v8i8, OpNode>; | 
|  | 969 | def v4i16 : N2VDSh<op24, op23, 0b010000, op11_8, 0, op4, | 
|  | 970 | !strconcat(OpcodeStr, "16"), v4i16, OpNode>; | 
|  | 971 | def v2i32 : N2VDSh<op24, op23, 0b100000, op11_8, 0, op4, | 
|  | 972 | !strconcat(OpcodeStr, "32"), v2i32, OpNode>; | 
|  | 973 | def v1i64 : N2VDSh<op24, op23, 0b000000, op11_8, 1, op4, | 
|  | 974 | !strconcat(OpcodeStr, "64"), v1i64, OpNode>; | 
|  | 975 |  | 
|  | 976 | // 128-bit vector types. | 
|  | 977 | def v16i8 : N2VQSh<op24, op23, 0b001000, op11_8, 0, op4, | 
|  | 978 | !strconcat(OpcodeStr, "8"), v16i8, OpNode>; | 
|  | 979 | def v8i16 : N2VQSh<op24, op23, 0b010000, op11_8, 0, op4, | 
|  | 980 | !strconcat(OpcodeStr, "16"), v8i16, OpNode>; | 
|  | 981 | def v4i32 : N2VQSh<op24, op23, 0b100000, op11_8, 0, op4, | 
|  | 982 | !strconcat(OpcodeStr, "32"), v4i32, OpNode>; | 
|  | 983 | def v2i64 : N2VQSh<op24, op23, 0b000000, op11_8, 1, op4, | 
|  | 984 | !strconcat(OpcodeStr, "64"), v2i64, OpNode>; | 
|  | 985 | } | 
|  | 986 |  | 
|  | 987 |  | 
|  | 988 | // Neon Shift-Accumulate vector operations, | 
|  | 989 | //   element sizes of 8, 16, 32 and 64 bits: | 
|  | 990 | multiclass N2VShAdd_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4, | 
|  | 991 | string OpcodeStr, SDNode ShOp> { | 
|  | 992 | // 64-bit vector types. | 
|  | 993 | def v8i8  : N2VDShAdd<op24, op23, 0b001000, op11_8, 0, op4, | 
|  | 994 | !strconcat(OpcodeStr, "8"), v8i8, ShOp>; | 
|  | 995 | def v4i16 : N2VDShAdd<op24, op23, 0b010000, op11_8, 0, op4, | 
|  | 996 | !strconcat(OpcodeStr, "16"), v4i16, ShOp>; | 
|  | 997 | def v2i32 : N2VDShAdd<op24, op23, 0b100000, op11_8, 0, op4, | 
|  | 998 | !strconcat(OpcodeStr, "32"), v2i32, ShOp>; | 
|  | 999 | def v1i64 : N2VDShAdd<op24, op23, 0b000000, op11_8, 1, op4, | 
|  | 1000 | !strconcat(OpcodeStr, "64"), v1i64, ShOp>; | 
|  | 1001 |  | 
|  | 1002 | // 128-bit vector types. | 
|  | 1003 | def v16i8 : N2VQShAdd<op24, op23, 0b001000, op11_8, 0, op4, | 
|  | 1004 | !strconcat(OpcodeStr, "8"), v16i8, ShOp>; | 
|  | 1005 | def v8i16 : N2VQShAdd<op24, op23, 0b010000, op11_8, 0, op4, | 
|  | 1006 | !strconcat(OpcodeStr, "16"), v8i16, ShOp>; | 
|  | 1007 | def v4i32 : N2VQShAdd<op24, op23, 0b100000, op11_8, 0, op4, | 
|  | 1008 | !strconcat(OpcodeStr, "32"), v4i32, ShOp>; | 
|  | 1009 | def v2i64 : N2VQShAdd<op24, op23, 0b000000, op11_8, 1, op4, | 
|  | 1010 | !strconcat(OpcodeStr, "64"), v2i64, ShOp>; | 
|  | 1011 | } | 
|  | 1012 |  | 
|  | 1013 |  | 
|  | 1014 | // Neon Shift-Insert vector operations, | 
|  | 1015 | //   element sizes of 8, 16, 32 and 64 bits: | 
|  | 1016 | multiclass N2VShIns_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4, | 
|  | 1017 | string OpcodeStr, SDNode ShOp> { | 
|  | 1018 | // 64-bit vector types. | 
|  | 1019 | def v8i8  : N2VDShIns<op24, op23, 0b001000, op11_8, 0, op4, | 
|  | 1020 | !strconcat(OpcodeStr, "8"), v8i8, ShOp>; | 
|  | 1021 | def v4i16 : N2VDShIns<op24, op23, 0b010000, op11_8, 0, op4, | 
|  | 1022 | !strconcat(OpcodeStr, "16"), v4i16, ShOp>; | 
|  | 1023 | def v2i32 : N2VDShIns<op24, op23, 0b100000, op11_8, 0, op4, | 
|  | 1024 | !strconcat(OpcodeStr, "32"), v2i32, ShOp>; | 
|  | 1025 | def v1i64 : N2VDShIns<op24, op23, 0b000000, op11_8, 1, op4, | 
|  | 1026 | !strconcat(OpcodeStr, "64"), v1i64, ShOp>; | 
|  | 1027 |  | 
|  | 1028 | // 128-bit vector types. | 
|  | 1029 | def v16i8 : N2VQShIns<op24, op23, 0b001000, op11_8, 0, op4, | 
|  | 1030 | !strconcat(OpcodeStr, "8"), v16i8, ShOp>; | 
|  | 1031 | def v8i16 : N2VQShIns<op24, op23, 0b010000, op11_8, 0, op4, | 
|  | 1032 | !strconcat(OpcodeStr, "16"), v8i16, ShOp>; | 
|  | 1033 | def v4i32 : N2VQShIns<op24, op23, 0b100000, op11_8, 0, op4, | 
|  | 1034 | !strconcat(OpcodeStr, "32"), v4i32, ShOp>; | 
|  | 1035 | def v2i64 : N2VQShIns<op24, op23, 0b000000, op11_8, 1, op4, | 
|  | 1036 | !strconcat(OpcodeStr, "64"), v2i64, ShOp>; | 
|  | 1037 | } | 
|  | 1038 |  | 
|  | 1039 | //===----------------------------------------------------------------------===// | 
|  | 1040 | // Instruction Definitions. | 
|  | 1041 | //===----------------------------------------------------------------------===// | 
|  | 1042 |  | 
|  | 1043 | // Vector Add Operations. | 
|  | 1044 |  | 
|  | 1045 | //   VADD     : Vector Add (integer and floating-point) | 
|  | 1046 | defm VADD     : N3V_QHSD<0, 0, 0b1000, 0, "vadd.i", add, 1>; | 
|  | 1047 | def  VADDfd   : N3VD<0, 0, 0b00, 0b1101, 0, "vadd.f32", v2f32, v2f32, fadd, 1>; | 
|  | 1048 | def  VADDfq   : N3VQ<0, 0, 0b00, 0b1101, 0, "vadd.f32", v4f32, v4f32, fadd, 1>; | 
|  | 1049 | //   VADDL    : Vector Add Long (Q = D + D) | 
|  | 1050 | defm VADDLs   : N3VLInt_QHS<0,1,0b0000,0, "vaddl.s", int_arm_neon_vaddls, 1>; | 
|  | 1051 | defm VADDLu   : N3VLInt_QHS<1,1,0b0000,0, "vaddl.u", int_arm_neon_vaddlu, 1>; | 
|  | 1052 | //   VADDW    : Vector Add Wide (Q = Q + D) | 
|  | 1053 | defm VADDWs   : N3VWInt_QHS<0,1,0b0001,0, "vaddw.s", int_arm_neon_vaddws, 0>; | 
|  | 1054 | defm VADDWu   : N3VWInt_QHS<1,1,0b0001,0, "vaddw.u", int_arm_neon_vaddwu, 0>; | 
|  | 1055 | //   VHADD    : Vector Halving Add | 
|  | 1056 | defm VHADDs   : N3VInt_QHS<0,0,0b0000,0, "vhadd.s", int_arm_neon_vhadds, 1>; | 
|  | 1057 | defm VHADDu   : N3VInt_QHS<1,0,0b0000,0, "vhadd.u", int_arm_neon_vhaddu, 1>; | 
|  | 1058 | //   VRHADD   : Vector Rounding Halving Add | 
|  | 1059 | defm VRHADDs  : N3VInt_QHS<0,0,0b0001,0, "vrhadd.s", int_arm_neon_vrhadds, 1>; | 
|  | 1060 | defm VRHADDu  : N3VInt_QHS<1,0,0b0001,0, "vrhadd.u", int_arm_neon_vrhaddu, 1>; | 
|  | 1061 | //   VQADD    : Vector Saturating Add | 
|  | 1062 | defm VQADDs   : N3VInt_QHSD<0,0,0b0000,1, "vqadd.s", int_arm_neon_vqadds, 1>; | 
|  | 1063 | defm VQADDu   : N3VInt_QHSD<1,0,0b0000,1, "vqadd.u", int_arm_neon_vqaddu, 1>; | 
|  | 1064 | //   VADDHN   : Vector Add and Narrow Returning High Half (D = Q + Q) | 
|  | 1065 | defm VADDHN   : N3VNInt_HSD<0,1,0b0100,0, "vaddhn.i", int_arm_neon_vaddhn, 1>; | 
|  | 1066 | //   VRADDHN  : Vector Rounding Add and Narrow Returning High Half (D = Q + Q) | 
|  | 1067 | defm VRADDHN  : N3VNInt_HSD<1,1,0b0100,0, "vraddhn.i", int_arm_neon_vraddhn, 1>; | 
|  | 1068 |  | 
|  | 1069 | // Vector Multiply Operations. | 
|  | 1070 |  | 
|  | 1071 | //   VMUL     : Vector Multiply (integer, polynomial and floating-point) | 
|  | 1072 | defm VMUL     : N3V_QHS<0, 0, 0b1001, 1, "vmul.i", mul, 1>; | 
|  | 1073 | def  VMULpd   : N3VDInt<1, 0, 0b00, 0b1001, 1, "vmul.p8", v8i8, v8i8, | 
|  | 1074 | int_arm_neon_vmulp, 1>; | 
|  | 1075 | def  VMULpq   : N3VQInt<1, 0, 0b00, 0b1001, 1, "vmul.p8", v16i8, v16i8, | 
|  | 1076 | int_arm_neon_vmulp, 1>; | 
|  | 1077 | def  VMULfd   : N3VD<1, 0, 0b00, 0b1101, 1, "vmul.f32", v2f32, v2f32, fmul, 1>; | 
|  | 1078 | def  VMULfq   : N3VQ<1, 0, 0b00, 0b1101, 1, "vmul.f32", v4f32, v4f32, fmul, 1>; | 
|  | 1079 | //   VQDMULH  : Vector Saturating Doubling Multiply Returning High Half | 
|  | 1080 | defm VQDMULH  : N3VInt_HS<0,0,0b1011,0, "vqdmulh.s", int_arm_neon_vqdmulh, 1>; | 
|  | 1081 | //   VQRDMULH : Vector Rounding Saturating Doubling Multiply Returning High Half | 
|  | 1082 | defm VQRDMULH : N3VInt_HS<1,0,0b1011,0, "vqrdmulh.s", int_arm_neon_vqrdmulh, 1>; | 
|  | 1083 | //   VMULL    : Vector Multiply Long (integer and polynomial) (Q = D * D) | 
|  | 1084 | defm VMULLs   : N3VLInt_QHS<0,1,0b1100,0, "vmull.s", int_arm_neon_vmulls, 1>; | 
|  | 1085 | defm VMULLu   : N3VLInt_QHS<1,1,0b1100,0, "vmull.u", int_arm_neon_vmullu, 1>; | 
|  | 1086 | def  VMULLp   : N3VLInt<0, 1, 0b00, 0b1110, 0, "vmull.p8", v8i16, v8i8, | 
|  | 1087 | int_arm_neon_vmullp, 1>; | 
|  | 1088 | //   VQDMULL  : Vector Saturating Doubling Multiply Long (Q = D * D) | 
|  | 1089 | defm VQDMULL  : N3VLInt_HS<0,1,0b1101,0, "vqdmull.s", int_arm_neon_vqdmull, 1>; | 
|  | 1090 |  | 
|  | 1091 | // Vector Multiply-Accumulate and Multiply-Subtract Operations. | 
|  | 1092 |  | 
|  | 1093 | //   VMLA     : Vector Multiply Accumulate (integer and floating-point) | 
|  | 1094 | defm VMLA     : N3VMulOp_QHS<0, 0, 0b1001, 0, "vmla.i", add>; | 
|  | 1095 | def  VMLAfd   : N3VDMulOp<0, 0, 0b00, 0b1101, 1, "vmla.f32", v2f32, fmul, fadd>; | 
|  | 1096 | def  VMLAfq   : N3VQMulOp<0, 0, 0b00, 0b1101, 1, "vmla.f32", v4f32, fmul, fadd>; | 
|  | 1097 | //   VMLAL    : Vector Multiply Accumulate Long (Q += D * D) | 
|  | 1098 | defm VMLALs   : N3VLInt3_QHS<0,1,0b1000,0, "vmlal.s", int_arm_neon_vmlals>; | 
|  | 1099 | defm VMLALu   : N3VLInt3_QHS<1,1,0b1000,0, "vmlal.u", int_arm_neon_vmlalu>; | 
|  | 1100 | //   VQDMLAL  : Vector Saturating Doubling Multiply Accumulate Long (Q += D * D) | 
|  | 1101 | defm VQDMLAL  : N3VLInt3_HS<0, 1, 0b1001, 0, "vqdmlal.s", int_arm_neon_vqdmlal>; | 
|  | 1102 | //   VMLS     : Vector Multiply Subtract (integer and floating-point) | 
|  | 1103 | defm VMLS     : N3VMulOp_QHS<0, 0, 0b1001, 0, "vmls.i", sub>; | 
|  | 1104 | def  VMLSfd   : N3VDMulOp<0, 0, 0b10, 0b1101, 1, "vmls.f32", v2f32, fmul, fsub>; | 
|  | 1105 | def  VMLSfq   : N3VQMulOp<0, 0, 0b10, 0b1101, 1, "vmls.f32", v4f32, fmul, fsub>; | 
|  | 1106 | //   VMLSL    : Vector Multiply Subtract Long (Q -= D * D) | 
|  | 1107 | defm VMLSLs   : N3VLInt3_QHS<0,1,0b1010,0, "vmlsl.s", int_arm_neon_vmlsls>; | 
|  | 1108 | defm VMLSLu   : N3VLInt3_QHS<1,1,0b1010,0, "vmlsl.u", int_arm_neon_vmlslu>; | 
|  | 1109 | //   VQDMLSL  : Vector Saturating Doubling Multiply Subtract Long (Q -= D * D) | 
|  | 1110 | defm VQDMLSL  : N3VLInt3_HS<0, 1, 0b1011, 0, "vqdmlsl.s", int_arm_neon_vqdmlsl>; | 
|  | 1111 |  | 
|  | 1112 | // Vector Subtract Operations. | 
|  | 1113 |  | 
|  | 1114 | //   VSUB     : Vector Subtract (integer and floating-point) | 
|  | 1115 | defm VSUB     : N3V_QHSD<1, 0, 0b1000, 0, "vsub.i", sub, 0>; | 
|  | 1116 | def  VSUBfd   : N3VD<0, 0, 0b10, 0b1101, 0, "vsub.f32", v2f32, v2f32, fsub, 0>; | 
|  | 1117 | def  VSUBfq   : N3VQ<0, 0, 0b10, 0b1101, 0, "vsub.f32", v4f32, v4f32, fsub, 0>; | 
|  | 1118 | //   VSUBL    : Vector Subtract Long (Q = D - D) | 
|  | 1119 | defm VSUBLs   : N3VLInt_QHS<0,1,0b0010,0, "vsubl.s", int_arm_neon_vsubls, 1>; | 
|  | 1120 | defm VSUBLu   : N3VLInt_QHS<1,1,0b0010,0, "vsubl.u", int_arm_neon_vsublu, 1>; | 
|  | 1121 | //   VSUBW    : Vector Subtract Wide (Q = Q - D) | 
|  | 1122 | defm VSUBWs   : N3VWInt_QHS<0,1,0b0011,0, "vsubw.s", int_arm_neon_vsubws, 0>; | 
|  | 1123 | defm VSUBWu   : N3VWInt_QHS<1,1,0b0011,0, "vsubw.u", int_arm_neon_vsubwu, 0>; | 
|  | 1124 | //   VHSUB    : Vector Halving Subtract | 
|  | 1125 | defm VHSUBs   : N3VInt_QHS<0, 0, 0b0010, 0, "vhsub.s", int_arm_neon_vhsubs, 0>; | 
|  | 1126 | defm VHSUBu   : N3VInt_QHS<1, 0, 0b0010, 0, "vhsub.u", int_arm_neon_vhsubu, 0>; | 
|  | 1127 | //   VQSUB    : Vector Saturing Subtract | 
|  | 1128 | defm VQSUBs   : N3VInt_QHSD<0, 0, 0b0010, 1, "vqsub.s", int_arm_neon_vqsubs, 0>; | 
|  | 1129 | defm VQSUBu   : N3VInt_QHSD<1, 0, 0b0010, 1, "vqsub.u", int_arm_neon_vqsubu, 0>; | 
|  | 1130 | //   VSUBHN   : Vector Subtract and Narrow Returning High Half (D = Q - Q) | 
|  | 1131 | defm VSUBHN   : N3VNInt_HSD<0,1,0b0110,0, "vsubhn.i", int_arm_neon_vsubhn, 0>; | 
|  | 1132 | //   VRSUBHN  : Vector Rounding Subtract and Narrow Returning High Half (D=Q-Q) | 
|  | 1133 | defm VRSUBHN  : N3VNInt_HSD<1,1,0b0110,0, "vrsubhn.i", int_arm_neon_vrsubhn, 0>; | 
|  | 1134 |  | 
|  | 1135 | // Vector Comparisons. | 
|  | 1136 |  | 
|  | 1137 | //   VCEQ     : Vector Compare Equal | 
|  | 1138 | defm VCEQ     : N3V_QHS<1, 0, 0b1000, 1, "vceq.i", NEONvceq, 1>; | 
|  | 1139 | def  VCEQfd   : N3VD<0,0,0b00,0b1110,0, "vceq.f32", v2i32, v2f32, NEONvceq, 1>; | 
|  | 1140 | def  VCEQfq   : N3VQ<0,0,0b00,0b1110,0, "vceq.f32", v4i32, v4f32, NEONvceq, 1>; | 
|  | 1141 | //   VCGE     : Vector Compare Greater Than or Equal | 
|  | 1142 | defm VCGEs    : N3V_QHS<0, 0, 0b0011, 1, "vcge.s", NEONvcge, 0>; | 
|  | 1143 | defm VCGEu    : N3V_QHS<1, 0, 0b0011, 1, "vcge.u", NEONvcgeu, 0>; | 
|  | 1144 | def  VCGEfd   : N3VD<1,0,0b00,0b1110,0, "vcge.f32", v2i32, v2f32, NEONvcge, 0>; | 
|  | 1145 | def  VCGEfq   : N3VQ<1,0,0b00,0b1110,0, "vcge.f32", v4i32, v4f32, NEONvcge, 0>; | 
|  | 1146 | //   VCGT     : Vector Compare Greater Than | 
|  | 1147 | defm VCGTs    : N3V_QHS<0, 0, 0b0011, 0, "vcgt.s", NEONvcgt, 0>; | 
|  | 1148 | defm VCGTu    : N3V_QHS<1, 0, 0b0011, 0, "vcgt.u", NEONvcgtu, 0>; | 
|  | 1149 | def  VCGTfd   : N3VD<1,0,0b10,0b1110,0, "vcgt.f32", v2i32, v2f32, NEONvcgt, 0>; | 
|  | 1150 | def  VCGTfq   : N3VQ<1,0,0b10,0b1110,0, "vcgt.f32", v4i32, v4f32, NEONvcgt, 0>; | 
|  | 1151 | //   VACGE    : Vector Absolute Compare Greater Than or Equal (aka VCAGE) | 
|  | 1152 | def  VACGEd   : N3VDInt<1, 0, 0b00, 0b1110, 1, "vacge.f32", v2i32, v2f32, | 
|  | 1153 | int_arm_neon_vacged, 0>; | 
|  | 1154 | def  VACGEq   : N3VQInt<1, 0, 0b00, 0b1110, 1, "vacge.f32", v4i32, v4f32, | 
|  | 1155 | int_arm_neon_vacgeq, 0>; | 
|  | 1156 | //   VACGT    : Vector Absolute Compare Greater Than (aka VCAGT) | 
|  | 1157 | def  VACGTd   : N3VDInt<1, 0, 0b10, 0b1110, 1, "vacgt.f32", v2i32, v2f32, | 
|  | 1158 | int_arm_neon_vacgtd, 0>; | 
|  | 1159 | def  VACGTq   : N3VQInt<1, 0, 0b10, 0b1110, 1, "vacgt.f32", v4i32, v4f32, | 
|  | 1160 | int_arm_neon_vacgtq, 0>; | 
|  | 1161 | //   VTST     : Vector Test Bits | 
|  | 1162 | defm VTST     : N3V_QHS<0, 0, 0b1000, 1, "vtst.i", NEONvtst, 1>; | 
|  | 1163 |  | 
|  | 1164 | // Vector Bitwise Operations. | 
|  | 1165 |  | 
|  | 1166 | //   VAND     : Vector Bitwise AND | 
|  | 1167 | def  VANDd    : N3VD<0, 0, 0b00, 0b0001, 1, "vand", v2i32, v2i32, and, 1>; | 
|  | 1168 | def  VANDq    : N3VQ<0, 0, 0b00, 0b0001, 1, "vand", v4i32, v4i32, and, 1>; | 
|  | 1169 |  | 
|  | 1170 | //   VEOR     : Vector Bitwise Exclusive OR | 
|  | 1171 | def  VEORd    : N3VD<1, 0, 0b00, 0b0001, 1, "veor", v2i32, v2i32, xor, 1>; | 
|  | 1172 | def  VEORq    : N3VQ<1, 0, 0b00, 0b0001, 1, "veor", v4i32, v4i32, xor, 1>; | 
|  | 1173 |  | 
|  | 1174 | //   VORR     : Vector Bitwise OR | 
|  | 1175 | def  VORRd    : N3VD<0, 0, 0b10, 0b0001, 1, "vorr", v2i32, v2i32, or, 1>; | 
|  | 1176 | def  VORRq    : N3VQ<0, 0, 0b10, 0b0001, 1, "vorr", v4i32, v4i32, or, 1>; | 
|  | 1177 |  | 
|  | 1178 | //   VBIC     : Vector Bitwise Bit Clear (AND NOT) | 
|  | 1179 | def  VBICd    : N3V<0, 0, 0b01, 0b0001, 0, 1, (outs DPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1180 | (ins DPR:$src1, DPR:$src2), NoItinerary, | 
|  | 1181 | "vbic\t$dst, $src1, $src2", "", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1182 | [(set DPR:$dst, (v2i32 (and DPR:$src1,(vnot DPR:$src2))))]>; | 
|  | 1183 | def  VBICq    : N3V<0, 0, 0b01, 0b0001, 1, 1, (outs QPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1184 | (ins QPR:$src1, QPR:$src2), NoItinerary, | 
|  | 1185 | "vbic\t$dst, $src1, $src2", "", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1186 | [(set QPR:$dst, (v4i32 (and QPR:$src1,(vnot QPR:$src2))))]>; | 
|  | 1187 |  | 
|  | 1188 | //   VORN     : Vector Bitwise OR NOT | 
|  | 1189 | def  VORNd    : N3V<0, 0, 0b11, 0b0001, 0, 1, (outs DPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1190 | (ins DPR:$src1, DPR:$src2), NoItinerary, | 
|  | 1191 | "vorn\t$dst, $src1, $src2", "", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1192 | [(set DPR:$dst, (v2i32 (or DPR:$src1, (vnot DPR:$src2))))]>; | 
|  | 1193 | def  VORNq    : N3V<0, 0, 0b11, 0b0001, 1, 1, (outs QPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1194 | (ins QPR:$src1, QPR:$src2), NoItinerary, | 
|  | 1195 | "vorn\t$dst, $src1, $src2", "", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1196 | [(set QPR:$dst, (v4i32 (or QPR:$src1, (vnot QPR:$src2))))]>; | 
|  | 1197 |  | 
|  | 1198 | //   VMVN     : Vector Bitwise NOT | 
|  | 1199 | def  VMVNd    : N2V<0b11, 0b11, 0b00, 0b00, 0b01011, 0, 0, | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1200 | (outs DPR:$dst), (ins DPR:$src), NoItinerary, | 
|  | 1201 | "vmvn\t$dst, $src", "", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1202 | [(set DPR:$dst, (v2i32 (vnot DPR:$src)))]>; | 
|  | 1203 | def  VMVNq    : N2V<0b11, 0b11, 0b00, 0b00, 0b01011, 1, 0, | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1204 | (outs QPR:$dst), (ins QPR:$src), NoItinerary, | 
|  | 1205 | "vmvn\t$dst, $src", "", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1206 | [(set QPR:$dst, (v4i32 (vnot QPR:$src)))]>; | 
|  | 1207 | def : Pat<(v2i32 (vnot_conv DPR:$src)), (VMVNd DPR:$src)>; | 
|  | 1208 | def : Pat<(v4i32 (vnot_conv QPR:$src)), (VMVNq QPR:$src)>; | 
|  | 1209 |  | 
|  | 1210 | //   VBSL     : Vector Bitwise Select | 
|  | 1211 | def  VBSLd    : N3V<1, 0, 0b01, 0b0001, 0, 1, (outs DPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1212 | (ins DPR:$src1, DPR:$src2, DPR:$src3), NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1213 | "vbsl\t$dst, $src2, $src3", "$src1 = $dst", | 
|  | 1214 | [(set DPR:$dst, | 
|  | 1215 | (v2i32 (or (and DPR:$src2, DPR:$src1), | 
|  | 1216 | (and DPR:$src3, (vnot DPR:$src1)))))]>; | 
|  | 1217 | def  VBSLq    : N3V<1, 0, 0b01, 0b0001, 1, 1, (outs QPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1218 | (ins QPR:$src1, QPR:$src2, QPR:$src3), NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1219 | "vbsl\t$dst, $src2, $src3", "$src1 = $dst", | 
|  | 1220 | [(set QPR:$dst, | 
|  | 1221 | (v4i32 (or (and QPR:$src2, QPR:$src1), | 
|  | 1222 | (and QPR:$src3, (vnot QPR:$src1)))))]>; | 
|  | 1223 |  | 
|  | 1224 | //   VBIF     : Vector Bitwise Insert if False | 
|  | 1225 | //              like VBSL but with: "vbif\t$dst, $src3, $src1", "$src2 = $dst", | 
|  | 1226 | //   VBIT     : Vector Bitwise Insert if True | 
|  | 1227 | //              like VBSL but with: "vbit\t$dst, $src2, $src1", "$src3 = $dst", | 
|  | 1228 | // These are not yet implemented.  The TwoAddress pass will not go looking | 
|  | 1229 | // for equivalent operations with different register constraints; it just | 
|  | 1230 | // inserts copies. | 
|  | 1231 |  | 
|  | 1232 | // Vector Absolute Differences. | 
|  | 1233 |  | 
|  | 1234 | //   VABD     : Vector Absolute Difference | 
|  | 1235 | defm VABDs    : N3VInt_QHS<0, 0, 0b0111, 0, "vabd.s", int_arm_neon_vabds, 0>; | 
|  | 1236 | defm VABDu    : N3VInt_QHS<1, 0, 0b0111, 0, "vabd.u", int_arm_neon_vabdu, 0>; | 
|  | 1237 | def  VABDfd   : N3VDInt<1, 0, 0b10, 0b1101, 0, "vabd.f32", v2f32, v2f32, | 
| Bob Wilson | 12842f9 | 2009-08-11 05:39:44 +0000 | [diff] [blame] | 1238 | int_arm_neon_vabds, 0>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1239 | def  VABDfq   : N3VQInt<1, 0, 0b10, 0b1101, 0, "vabd.f32", v4f32, v4f32, | 
| Bob Wilson | 12842f9 | 2009-08-11 05:39:44 +0000 | [diff] [blame] | 1240 | int_arm_neon_vabds, 0>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1241 |  | 
|  | 1242 | //   VABDL    : Vector Absolute Difference Long (Q = | D - D |) | 
|  | 1243 | defm VABDLs   : N3VLInt_QHS<0,1,0b0111,0, "vabdl.s", int_arm_neon_vabdls, 0>; | 
|  | 1244 | defm VABDLu   : N3VLInt_QHS<1,1,0b0111,0, "vabdl.u", int_arm_neon_vabdlu, 0>; | 
|  | 1245 |  | 
|  | 1246 | //   VABA     : Vector Absolute Difference and Accumulate | 
|  | 1247 | defm VABAs    : N3VInt3_QHS<0,1,0b0101,0, "vaba.s", int_arm_neon_vabas>; | 
|  | 1248 | defm VABAu    : N3VInt3_QHS<1,1,0b0101,0, "vaba.u", int_arm_neon_vabau>; | 
|  | 1249 |  | 
|  | 1250 | //   VABAL    : Vector Absolute Difference and Accumulate Long (Q += | D - D |) | 
|  | 1251 | defm VABALs   : N3VLInt3_QHS<0,1,0b0101,0, "vabal.s", int_arm_neon_vabals>; | 
|  | 1252 | defm VABALu   : N3VLInt3_QHS<1,1,0b0101,0, "vabal.u", int_arm_neon_vabalu>; | 
|  | 1253 |  | 
|  | 1254 | // Vector Maximum and Minimum. | 
|  | 1255 |  | 
|  | 1256 | //   VMAX     : Vector Maximum | 
|  | 1257 | defm VMAXs    : N3VInt_QHS<0, 0, 0b0110, 0, "vmax.s", int_arm_neon_vmaxs, 1>; | 
|  | 1258 | defm VMAXu    : N3VInt_QHS<1, 0, 0b0110, 0, "vmax.u", int_arm_neon_vmaxu, 1>; | 
|  | 1259 | def  VMAXfd   : N3VDInt<0, 0, 0b00, 0b1111, 0, "vmax.f32", v2f32, v2f32, | 
| Bob Wilson | 12842f9 | 2009-08-11 05:39:44 +0000 | [diff] [blame] | 1260 | int_arm_neon_vmaxs, 1>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1261 | def  VMAXfq   : N3VQInt<0, 0, 0b00, 0b1111, 0, "vmax.f32", v4f32, v4f32, | 
| Bob Wilson | 12842f9 | 2009-08-11 05:39:44 +0000 | [diff] [blame] | 1262 | int_arm_neon_vmaxs, 1>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1263 |  | 
|  | 1264 | //   VMIN     : Vector Minimum | 
|  | 1265 | defm VMINs    : N3VInt_QHS<0, 0, 0b0110, 1, "vmin.s", int_arm_neon_vmins, 1>; | 
|  | 1266 | defm VMINu    : N3VInt_QHS<1, 0, 0b0110, 1, "vmin.u", int_arm_neon_vminu, 1>; | 
|  | 1267 | def  VMINfd   : N3VDInt<0, 0, 0b10, 0b1111, 0, "vmin.f32", v2f32, v2f32, | 
| Bob Wilson | 12842f9 | 2009-08-11 05:39:44 +0000 | [diff] [blame] | 1268 | int_arm_neon_vmins, 1>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1269 | def  VMINfq   : N3VQInt<0, 0, 0b10, 0b1111, 0, "vmin.f32", v4f32, v4f32, | 
| Bob Wilson | 12842f9 | 2009-08-11 05:39:44 +0000 | [diff] [blame] | 1270 | int_arm_neon_vmins, 1>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1271 |  | 
|  | 1272 | // Vector Pairwise Operations. | 
|  | 1273 |  | 
|  | 1274 | //   VPADD    : Vector Pairwise Add | 
|  | 1275 | def  VPADDi8  : N3VDInt<0, 0, 0b00, 0b1011, 1, "vpadd.i8", v8i8, v8i8, | 
| Bob Wilson | 741a9c7 | 2009-08-11 01:15:26 +0000 | [diff] [blame] | 1276 | int_arm_neon_vpadd, 0>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1277 | def  VPADDi16 : N3VDInt<0, 0, 0b01, 0b1011, 1, "vpadd.i16", v4i16, v4i16, | 
| Bob Wilson | 741a9c7 | 2009-08-11 01:15:26 +0000 | [diff] [blame] | 1278 | int_arm_neon_vpadd, 0>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1279 | def  VPADDi32 : N3VDInt<0, 0, 0b10, 0b1011, 1, "vpadd.i32", v2i32, v2i32, | 
| Bob Wilson | 741a9c7 | 2009-08-11 01:15:26 +0000 | [diff] [blame] | 1280 | int_arm_neon_vpadd, 0>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1281 | def  VPADDf   : N3VDInt<1, 0, 0b00, 0b1101, 0, "vpadd.f32", v2f32, v2f32, | 
| Bob Wilson | 741a9c7 | 2009-08-11 01:15:26 +0000 | [diff] [blame] | 1282 | int_arm_neon_vpadd, 0>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1283 |  | 
|  | 1284 | //   VPADDL   : Vector Pairwise Add Long | 
|  | 1285 | defm VPADDLs  : N2VPLInt_QHS<0b11, 0b11, 0b00, 0b00100, 0, "vpaddl.s", | 
|  | 1286 | int_arm_neon_vpaddls>; | 
|  | 1287 | defm VPADDLu  : N2VPLInt_QHS<0b11, 0b11, 0b00, 0b00101, 0, "vpaddl.u", | 
|  | 1288 | int_arm_neon_vpaddlu>; | 
|  | 1289 |  | 
|  | 1290 | //   VPADAL   : Vector Pairwise Add and Accumulate Long | 
|  | 1291 | defm VPADALs  : N2VPLInt2_QHS<0b11, 0b11, 0b00, 0b00100, 0, "vpadal.s", | 
|  | 1292 | int_arm_neon_vpadals>; | 
|  | 1293 | defm VPADALu  : N2VPLInt2_QHS<0b11, 0b11, 0b00, 0b00101, 0, "vpadal.u", | 
|  | 1294 | int_arm_neon_vpadalu>; | 
|  | 1295 |  | 
|  | 1296 | //   VPMAX    : Vector Pairwise Maximum | 
|  | 1297 | def  VPMAXs8  : N3VDInt<0, 0, 0b00, 0b1010, 0, "vpmax.s8", v8i8, v8i8, | 
|  | 1298 | int_arm_neon_vpmaxs, 0>; | 
|  | 1299 | def  VPMAXs16 : N3VDInt<0, 0, 0b01, 0b1010, 0, "vpmax.s16", v4i16, v4i16, | 
|  | 1300 | int_arm_neon_vpmaxs, 0>; | 
|  | 1301 | def  VPMAXs32 : N3VDInt<0, 0, 0b10, 0b1010, 0, "vpmax.s32", v2i32, v2i32, | 
|  | 1302 | int_arm_neon_vpmaxs, 0>; | 
|  | 1303 | def  VPMAXu8  : N3VDInt<1, 0, 0b00, 0b1010, 0, "vpmax.u8", v8i8, v8i8, | 
|  | 1304 | int_arm_neon_vpmaxu, 0>; | 
|  | 1305 | def  VPMAXu16 : N3VDInt<1, 0, 0b01, 0b1010, 0, "vpmax.u16", v4i16, v4i16, | 
|  | 1306 | int_arm_neon_vpmaxu, 0>; | 
|  | 1307 | def  VPMAXu32 : N3VDInt<1, 0, 0b10, 0b1010, 0, "vpmax.u32", v2i32, v2i32, | 
|  | 1308 | int_arm_neon_vpmaxu, 0>; | 
|  | 1309 | def  VPMAXf   : N3VDInt<1, 0, 0b00, 0b1111, 0, "vpmax.f32", v2f32, v2f32, | 
| Bob Wilson | 12842f9 | 2009-08-11 05:39:44 +0000 | [diff] [blame] | 1310 | int_arm_neon_vpmaxs, 0>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1311 |  | 
|  | 1312 | //   VPMIN    : Vector Pairwise Minimum | 
|  | 1313 | def  VPMINs8  : N3VDInt<0, 0, 0b00, 0b1010, 1, "vpmin.s8", v8i8, v8i8, | 
|  | 1314 | int_arm_neon_vpmins, 0>; | 
|  | 1315 | def  VPMINs16 : N3VDInt<0, 0, 0b01, 0b1010, 1, "vpmin.s16", v4i16, v4i16, | 
|  | 1316 | int_arm_neon_vpmins, 0>; | 
|  | 1317 | def  VPMINs32 : N3VDInt<0, 0, 0b10, 0b1010, 1, "vpmin.s32", v2i32, v2i32, | 
|  | 1318 | int_arm_neon_vpmins, 0>; | 
|  | 1319 | def  VPMINu8  : N3VDInt<1, 0, 0b00, 0b1010, 1, "vpmin.u8", v8i8, v8i8, | 
|  | 1320 | int_arm_neon_vpminu, 0>; | 
|  | 1321 | def  VPMINu16 : N3VDInt<1, 0, 0b01, 0b1010, 1, "vpmin.u16", v4i16, v4i16, | 
|  | 1322 | int_arm_neon_vpminu, 0>; | 
|  | 1323 | def  VPMINu32 : N3VDInt<1, 0, 0b10, 0b1010, 1, "vpmin.u32", v2i32, v2i32, | 
|  | 1324 | int_arm_neon_vpminu, 0>; | 
|  | 1325 | def  VPMINf   : N3VDInt<1, 0, 0b10, 0b1111, 0, "vpmin.f32", v2f32, v2f32, | 
| Bob Wilson | 12842f9 | 2009-08-11 05:39:44 +0000 | [diff] [blame] | 1326 | int_arm_neon_vpmins, 0>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1327 |  | 
|  | 1328 | // Vector Reciprocal and Reciprocal Square Root Estimate and Step. | 
|  | 1329 |  | 
|  | 1330 | //   VRECPE   : Vector Reciprocal Estimate | 
|  | 1331 | def  VRECPEd  : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01000, 0, "vrecpe.u32", | 
|  | 1332 | v2i32, v2i32, int_arm_neon_vrecpe>; | 
|  | 1333 | def  VRECPEq  : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01000, 0, "vrecpe.u32", | 
|  | 1334 | v4i32, v4i32, int_arm_neon_vrecpe>; | 
|  | 1335 | def  VRECPEfd : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01010, 0, "vrecpe.f32", | 
| Bob Wilson | 12842f9 | 2009-08-11 05:39:44 +0000 | [diff] [blame] | 1336 | v2f32, v2f32, int_arm_neon_vrecpe>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1337 | def  VRECPEfq : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01010, 0, "vrecpe.f32", | 
| Bob Wilson | 12842f9 | 2009-08-11 05:39:44 +0000 | [diff] [blame] | 1338 | v4f32, v4f32, int_arm_neon_vrecpe>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1339 |  | 
|  | 1340 | //   VRECPS   : Vector Reciprocal Step | 
|  | 1341 | def  VRECPSfd : N3VDInt<0, 0, 0b00, 0b1111, 1, "vrecps.f32", v2f32, v2f32, | 
|  | 1342 | int_arm_neon_vrecps, 1>; | 
|  | 1343 | def  VRECPSfq : N3VQInt<0, 0, 0b00, 0b1111, 1, "vrecps.f32", v4f32, v4f32, | 
|  | 1344 | int_arm_neon_vrecps, 1>; | 
|  | 1345 |  | 
|  | 1346 | //   VRSQRTE  : Vector Reciprocal Square Root Estimate | 
|  | 1347 | def  VRSQRTEd  : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01001, 0, "vrsqrte.u32", | 
|  | 1348 | v2i32, v2i32, int_arm_neon_vrsqrte>; | 
|  | 1349 | def  VRSQRTEq  : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01001, 0, "vrsqrte.u32", | 
|  | 1350 | v4i32, v4i32, int_arm_neon_vrsqrte>; | 
|  | 1351 | def  VRSQRTEfd : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01011, 0, "vrsqrte.f32", | 
| Bob Wilson | 12842f9 | 2009-08-11 05:39:44 +0000 | [diff] [blame] | 1352 | v2f32, v2f32, int_arm_neon_vrsqrte>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1353 | def  VRSQRTEfq : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01011, 0, "vrsqrte.f32", | 
| Bob Wilson | 12842f9 | 2009-08-11 05:39:44 +0000 | [diff] [blame] | 1354 | v4f32, v4f32, int_arm_neon_vrsqrte>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1355 |  | 
|  | 1356 | //   VRSQRTS  : Vector Reciprocal Square Root Step | 
|  | 1357 | def VRSQRTSfd : N3VDInt<0, 0, 0b10, 0b1111, 1, "vrsqrts.f32", v2f32, v2f32, | 
|  | 1358 | int_arm_neon_vrsqrts, 1>; | 
|  | 1359 | def VRSQRTSfq : N3VQInt<0, 0, 0b10, 0b1111, 1, "vrsqrts.f32", v4f32, v4f32, | 
|  | 1360 | int_arm_neon_vrsqrts, 1>; | 
|  | 1361 |  | 
|  | 1362 | // Vector Shifts. | 
|  | 1363 |  | 
|  | 1364 | //   VSHL     : Vector Shift | 
|  | 1365 | defm VSHLs    : N3VInt_QHSD<0, 0, 0b0100, 0, "vshl.s", int_arm_neon_vshifts, 0>; | 
|  | 1366 | defm VSHLu    : N3VInt_QHSD<1, 0, 0b0100, 0, "vshl.u", int_arm_neon_vshiftu, 0>; | 
|  | 1367 | //   VSHL     : Vector Shift Left (Immediate) | 
|  | 1368 | defm VSHLi    : N2VSh_QHSD<0, 1, 0b0111, 1, "vshl.i", NEONvshl>; | 
|  | 1369 | //   VSHR     : Vector Shift Right (Immediate) | 
|  | 1370 | defm VSHRs    : N2VSh_QHSD<0, 1, 0b0000, 1, "vshr.s", NEONvshrs>; | 
|  | 1371 | defm VSHRu    : N2VSh_QHSD<1, 1, 0b0000, 1, "vshr.u", NEONvshru>; | 
|  | 1372 |  | 
|  | 1373 | //   VSHLL    : Vector Shift Left Long | 
|  | 1374 | def  VSHLLs8  : N2VLSh<0, 1, 0b001000, 0b1010, 0, 0, 1, "vshll.s8", | 
|  | 1375 | v8i16, v8i8, NEONvshlls>; | 
|  | 1376 | def  VSHLLs16 : N2VLSh<0, 1, 0b010000, 0b1010, 0, 0, 1, "vshll.s16", | 
|  | 1377 | v4i32, v4i16, NEONvshlls>; | 
|  | 1378 | def  VSHLLs32 : N2VLSh<0, 1, 0b100000, 0b1010, 0, 0, 1, "vshll.s32", | 
|  | 1379 | v2i64, v2i32, NEONvshlls>; | 
|  | 1380 | def  VSHLLu8  : N2VLSh<1, 1, 0b001000, 0b1010, 0, 0, 1, "vshll.u8", | 
|  | 1381 | v8i16, v8i8, NEONvshllu>; | 
|  | 1382 | def  VSHLLu16 : N2VLSh<1, 1, 0b010000, 0b1010, 0, 0, 1, "vshll.u16", | 
|  | 1383 | v4i32, v4i16, NEONvshllu>; | 
|  | 1384 | def  VSHLLu32 : N2VLSh<1, 1, 0b100000, 0b1010, 0, 0, 1, "vshll.u32", | 
|  | 1385 | v2i64, v2i32, NEONvshllu>; | 
|  | 1386 |  | 
|  | 1387 | //   VSHLL    : Vector Shift Left Long (with maximum shift count) | 
|  | 1388 | def  VSHLLi8  : N2VLSh<1, 1, 0b110010, 0b0011, 0, 0, 0, "vshll.i8", | 
|  | 1389 | v8i16, v8i8, NEONvshlli>; | 
|  | 1390 | def  VSHLLi16 : N2VLSh<1, 1, 0b110110, 0b0011, 0, 0, 0, "vshll.i16", | 
|  | 1391 | v4i32, v4i16, NEONvshlli>; | 
|  | 1392 | def  VSHLLi32 : N2VLSh<1, 1, 0b111010, 0b0011, 0, 0, 0, "vshll.i32", | 
|  | 1393 | v2i64, v2i32, NEONvshlli>; | 
|  | 1394 |  | 
|  | 1395 | //   VSHRN    : Vector Shift Right and Narrow | 
|  | 1396 | def  VSHRN16  : N2VNSh<0, 1, 0b001000, 0b1000, 0, 0, 1, "vshrn.i16", | 
|  | 1397 | v8i8, v8i16, NEONvshrn>; | 
|  | 1398 | def  VSHRN32  : N2VNSh<0, 1, 0b010000, 0b1000, 0, 0, 1, "vshrn.i32", | 
|  | 1399 | v4i16, v4i32, NEONvshrn>; | 
|  | 1400 | def  VSHRN64  : N2VNSh<0, 1, 0b100000, 0b1000, 0, 0, 1, "vshrn.i64", | 
|  | 1401 | v2i32, v2i64, NEONvshrn>; | 
|  | 1402 |  | 
|  | 1403 | //   VRSHL    : Vector Rounding Shift | 
|  | 1404 | defm VRSHLs   : N3VInt_QHSD<0,0,0b0101,0, "vrshl.s", int_arm_neon_vrshifts, 0>; | 
|  | 1405 | defm VRSHLu   : N3VInt_QHSD<1,0,0b0101,0, "vrshl.u", int_arm_neon_vrshiftu, 0>; | 
|  | 1406 | //   VRSHR    : Vector Rounding Shift Right | 
|  | 1407 | defm VRSHRs   : N2VSh_QHSD<0, 1, 0b0010, 1, "vrshr.s", NEONvrshrs>; | 
|  | 1408 | defm VRSHRu   : N2VSh_QHSD<1, 1, 0b0010, 1, "vrshr.u", NEONvrshru>; | 
|  | 1409 |  | 
|  | 1410 | //   VRSHRN   : Vector Rounding Shift Right and Narrow | 
|  | 1411 | def  VRSHRN16 : N2VNSh<0, 1, 0b001000, 0b1000, 0, 1, 1, "vrshrn.i16", | 
|  | 1412 | v8i8, v8i16, NEONvrshrn>; | 
|  | 1413 | def  VRSHRN32 : N2VNSh<0, 1, 0b010000, 0b1000, 0, 1, 1, "vrshrn.i32", | 
|  | 1414 | v4i16, v4i32, NEONvrshrn>; | 
|  | 1415 | def  VRSHRN64 : N2VNSh<0, 1, 0b100000, 0b1000, 0, 1, 1, "vrshrn.i64", | 
|  | 1416 | v2i32, v2i64, NEONvrshrn>; | 
|  | 1417 |  | 
|  | 1418 | //   VQSHL    : Vector Saturating Shift | 
|  | 1419 | defm VQSHLs   : N3VInt_QHSD<0,0,0b0100,1, "vqshl.s", int_arm_neon_vqshifts, 0>; | 
|  | 1420 | defm VQSHLu   : N3VInt_QHSD<1,0,0b0100,1, "vqshl.u", int_arm_neon_vqshiftu, 0>; | 
|  | 1421 | //   VQSHL    : Vector Saturating Shift Left (Immediate) | 
|  | 1422 | defm VQSHLsi  : N2VSh_QHSD<0, 1, 0b0111, 1, "vqshl.s", NEONvqshls>; | 
|  | 1423 | defm VQSHLui  : N2VSh_QHSD<1, 1, 0b0111, 1, "vqshl.u", NEONvqshlu>; | 
|  | 1424 | //   VQSHLU   : Vector Saturating Shift Left (Immediate, Unsigned) | 
|  | 1425 | defm VQSHLsu  : N2VSh_QHSD<1, 1, 0b0110, 1, "vqshlu.s", NEONvqshlsu>; | 
|  | 1426 |  | 
|  | 1427 | //   VQSHRN   : Vector Saturating Shift Right and Narrow | 
|  | 1428 | def VQSHRNs16 : N2VNSh<0, 1, 0b001000, 0b1001, 0, 0, 1, "vqshrn.s16", | 
|  | 1429 | v8i8, v8i16, NEONvqshrns>; | 
|  | 1430 | def VQSHRNs32 : N2VNSh<0, 1, 0b010000, 0b1001, 0, 0, 1, "vqshrn.s32", | 
|  | 1431 | v4i16, v4i32, NEONvqshrns>; | 
|  | 1432 | def VQSHRNs64 : N2VNSh<0, 1, 0b100000, 0b1001, 0, 0, 1, "vqshrn.s64", | 
|  | 1433 | v2i32, v2i64, NEONvqshrns>; | 
|  | 1434 | def VQSHRNu16 : N2VNSh<1, 1, 0b001000, 0b1001, 0, 0, 1, "vqshrn.u16", | 
|  | 1435 | v8i8, v8i16, NEONvqshrnu>; | 
|  | 1436 | def VQSHRNu32 : N2VNSh<1, 1, 0b010000, 0b1001, 0, 0, 1, "vqshrn.u32", | 
|  | 1437 | v4i16, v4i32, NEONvqshrnu>; | 
|  | 1438 | def VQSHRNu64 : N2VNSh<1, 1, 0b100000, 0b1001, 0, 0, 1, "vqshrn.u64", | 
|  | 1439 | v2i32, v2i64, NEONvqshrnu>; | 
|  | 1440 |  | 
|  | 1441 | //   VQSHRUN  : Vector Saturating Shift Right and Narrow (Unsigned) | 
|  | 1442 | def VQSHRUN16 : N2VNSh<1, 1, 0b001000, 0b1000, 0, 0, 1, "vqshrun.s16", | 
|  | 1443 | v8i8, v8i16, NEONvqshrnsu>; | 
|  | 1444 | def VQSHRUN32 : N2VNSh<1, 1, 0b010000, 0b1000, 0, 0, 1, "vqshrun.s32", | 
|  | 1445 | v4i16, v4i32, NEONvqshrnsu>; | 
|  | 1446 | def VQSHRUN64 : N2VNSh<1, 1, 0b100000, 0b1000, 0, 0, 1, "vqshrun.s64", | 
|  | 1447 | v2i32, v2i64, NEONvqshrnsu>; | 
|  | 1448 |  | 
|  | 1449 | //   VQRSHL   : Vector Saturating Rounding Shift | 
|  | 1450 | defm VQRSHLs  : N3VInt_QHSD<0, 0, 0b0101, 1, "vqrshl.s", | 
|  | 1451 | int_arm_neon_vqrshifts, 0>; | 
|  | 1452 | defm VQRSHLu  : N3VInt_QHSD<1, 0, 0b0101, 1, "vqrshl.u", | 
|  | 1453 | int_arm_neon_vqrshiftu, 0>; | 
|  | 1454 |  | 
|  | 1455 | //   VQRSHRN  : Vector Saturating Rounding Shift Right and Narrow | 
|  | 1456 | def VQRSHRNs16: N2VNSh<0, 1, 0b001000, 0b1001, 0, 1, 1, "vqrshrn.s16", | 
|  | 1457 | v8i8, v8i16, NEONvqrshrns>; | 
|  | 1458 | def VQRSHRNs32: N2VNSh<0, 1, 0b010000, 0b1001, 0, 1, 1, "vqrshrn.s32", | 
|  | 1459 | v4i16, v4i32, NEONvqrshrns>; | 
|  | 1460 | def VQRSHRNs64: N2VNSh<0, 1, 0b100000, 0b1001, 0, 1, 1, "vqrshrn.s64", | 
|  | 1461 | v2i32, v2i64, NEONvqrshrns>; | 
|  | 1462 | def VQRSHRNu16: N2VNSh<1, 1, 0b001000, 0b1001, 0, 1, 1, "vqrshrn.u16", | 
|  | 1463 | v8i8, v8i16, NEONvqrshrnu>; | 
|  | 1464 | def VQRSHRNu32: N2VNSh<1, 1, 0b010000, 0b1001, 0, 1, 1, "vqrshrn.u32", | 
|  | 1465 | v4i16, v4i32, NEONvqrshrnu>; | 
|  | 1466 | def VQRSHRNu64: N2VNSh<1, 1, 0b100000, 0b1001, 0, 1, 1, "vqrshrn.u64", | 
|  | 1467 | v2i32, v2i64, NEONvqrshrnu>; | 
|  | 1468 |  | 
|  | 1469 | //   VQRSHRUN : Vector Saturating Rounding Shift Right and Narrow (Unsigned) | 
|  | 1470 | def VQRSHRUN16: N2VNSh<1, 1, 0b001000, 0b1000, 0, 1, 1, "vqrshrun.s16", | 
|  | 1471 | v8i8, v8i16, NEONvqrshrnsu>; | 
|  | 1472 | def VQRSHRUN32: N2VNSh<1, 1, 0b010000, 0b1000, 0, 1, 1, "vqrshrun.s32", | 
|  | 1473 | v4i16, v4i32, NEONvqrshrnsu>; | 
|  | 1474 | def VQRSHRUN64: N2VNSh<1, 1, 0b100000, 0b1000, 0, 1, 1, "vqrshrun.s64", | 
|  | 1475 | v2i32, v2i64, NEONvqrshrnsu>; | 
|  | 1476 |  | 
|  | 1477 | //   VSRA     : Vector Shift Right and Accumulate | 
|  | 1478 | defm VSRAs    : N2VShAdd_QHSD<0, 1, 0b0001, 1, "vsra.s", NEONvshrs>; | 
|  | 1479 | defm VSRAu    : N2VShAdd_QHSD<1, 1, 0b0001, 1, "vsra.u", NEONvshru>; | 
|  | 1480 | //   VRSRA    : Vector Rounding Shift Right and Accumulate | 
|  | 1481 | defm VRSRAs   : N2VShAdd_QHSD<0, 1, 0b0011, 1, "vrsra.s", NEONvrshrs>; | 
|  | 1482 | defm VRSRAu   : N2VShAdd_QHSD<1, 1, 0b0011, 1, "vrsra.u", NEONvrshru>; | 
|  | 1483 |  | 
|  | 1484 | //   VSLI     : Vector Shift Left and Insert | 
|  | 1485 | defm VSLI     : N2VShIns_QHSD<1, 1, 0b0101, 1, "vsli.", NEONvsli>; | 
|  | 1486 | //   VSRI     : Vector Shift Right and Insert | 
|  | 1487 | defm VSRI     : N2VShIns_QHSD<1, 1, 0b0100, 1, "vsri.", NEONvsri>; | 
|  | 1488 |  | 
|  | 1489 | // Vector Absolute and Saturating Absolute. | 
|  | 1490 |  | 
|  | 1491 | //   VABS     : Vector Absolute Value | 
|  | 1492 | defm VABS     : N2VInt_QHS<0b11, 0b11, 0b01, 0b00110, 0, "vabs.s", | 
|  | 1493 | int_arm_neon_vabs>; | 
|  | 1494 | def  VABSfd   : N2VDInt<0b11, 0b11, 0b10, 0b01, 0b01110, 0, "vabs.f32", | 
| Bob Wilson | 12842f9 | 2009-08-11 05:39:44 +0000 | [diff] [blame] | 1495 | v2f32, v2f32, int_arm_neon_vabs>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1496 | def  VABSfq   : N2VQInt<0b11, 0b11, 0b10, 0b01, 0b01110, 0, "vabs.f32", | 
| Bob Wilson | 12842f9 | 2009-08-11 05:39:44 +0000 | [diff] [blame] | 1497 | v4f32, v4f32, int_arm_neon_vabs>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1498 |  | 
|  | 1499 | //   VQABS    : Vector Saturating Absolute Value | 
|  | 1500 | defm VQABS    : N2VInt_QHS<0b11, 0b11, 0b00, 0b01110, 0, "vqabs.s", | 
|  | 1501 | int_arm_neon_vqabs>; | 
|  | 1502 |  | 
|  | 1503 | // Vector Negate. | 
|  | 1504 |  | 
|  | 1505 | def vneg      : PatFrag<(ops node:$in), (sub immAllZerosV, node:$in)>; | 
|  | 1506 | def vneg_conv : PatFrag<(ops node:$in), (sub immAllZerosV_bc, node:$in)>; | 
|  | 1507 |  | 
|  | 1508 | class VNEGD<bits<2> size, string OpcodeStr, ValueType Ty> | 
|  | 1509 | : N2V<0b11, 0b11, size, 0b01, 0b00111, 0, 0, (outs DPR:$dst), (ins DPR:$src), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1510 | NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1511 | !strconcat(OpcodeStr, "\t$dst, $src"), "", | 
|  | 1512 | [(set DPR:$dst, (Ty (vneg DPR:$src)))]>; | 
|  | 1513 | class VNEGQ<bits<2> size, string OpcodeStr, ValueType Ty> | 
|  | 1514 | : N2V<0b11, 0b11, size, 0b01, 0b00111, 1, 0, (outs QPR:$dst), (ins QPR:$src), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1515 | NoItinerary, | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1516 | !strconcat(OpcodeStr, "\t$dst, $src"), "", | 
|  | 1517 | [(set QPR:$dst, (Ty (vneg QPR:$src)))]>; | 
|  | 1518 |  | 
|  | 1519 | //   VNEG     : Vector Negate | 
|  | 1520 | def  VNEGs8d  : VNEGD<0b00, "vneg.s8", v8i8>; | 
|  | 1521 | def  VNEGs16d : VNEGD<0b01, "vneg.s16", v4i16>; | 
|  | 1522 | def  VNEGs32d : VNEGD<0b10, "vneg.s32", v2i32>; | 
|  | 1523 | def  VNEGs8q  : VNEGQ<0b00, "vneg.s8", v16i8>; | 
|  | 1524 | def  VNEGs16q : VNEGQ<0b01, "vneg.s16", v8i16>; | 
|  | 1525 | def  VNEGs32q : VNEGQ<0b10, "vneg.s32", v4i32>; | 
|  | 1526 |  | 
|  | 1527 | //   VNEG     : Vector Negate (floating-point) | 
|  | 1528 | def  VNEGf32d : N2V<0b11, 0b11, 0b10, 0b01, 0b01111, 0, 0, | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1529 | (outs DPR:$dst), (ins DPR:$src), NoItinerary, | 
|  | 1530 | "vneg.f32\t$dst, $src", "", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1531 | [(set DPR:$dst, (v2f32 (fneg DPR:$src)))]>; | 
|  | 1532 | def  VNEGf32q : N2V<0b11, 0b11, 0b10, 0b01, 0b01111, 1, 0, | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1533 | (outs QPR:$dst), (ins QPR:$src), NoItinerary, | 
|  | 1534 | "vneg.f32\t$dst, $src", "", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1535 | [(set QPR:$dst, (v4f32 (fneg QPR:$src)))]>; | 
|  | 1536 |  | 
|  | 1537 | def : Pat<(v8i8 (vneg_conv DPR:$src)), (VNEGs8d DPR:$src)>; | 
|  | 1538 | def : Pat<(v4i16 (vneg_conv DPR:$src)), (VNEGs16d DPR:$src)>; | 
|  | 1539 | def : Pat<(v2i32 (vneg_conv DPR:$src)), (VNEGs32d DPR:$src)>; | 
|  | 1540 | def : Pat<(v16i8 (vneg_conv QPR:$src)), (VNEGs8q QPR:$src)>; | 
|  | 1541 | def : Pat<(v8i16 (vneg_conv QPR:$src)), (VNEGs16q QPR:$src)>; | 
|  | 1542 | def : Pat<(v4i32 (vneg_conv QPR:$src)), (VNEGs32q QPR:$src)>; | 
|  | 1543 |  | 
|  | 1544 | //   VQNEG    : Vector Saturating Negate | 
|  | 1545 | defm VQNEG    : N2VInt_QHS<0b11, 0b11, 0b00, 0b01111, 0, "vqneg.s", | 
|  | 1546 | int_arm_neon_vqneg>; | 
|  | 1547 |  | 
|  | 1548 | // Vector Bit Counting Operations. | 
|  | 1549 |  | 
|  | 1550 | //   VCLS     : Vector Count Leading Sign Bits | 
|  | 1551 | defm VCLS     : N2VInt_QHS<0b11, 0b11, 0b00, 0b01000, 0, "vcls.s", | 
|  | 1552 | int_arm_neon_vcls>; | 
|  | 1553 | //   VCLZ     : Vector Count Leading Zeros | 
|  | 1554 | defm VCLZ     : N2VInt_QHS<0b11, 0b11, 0b00, 0b01001, 0, "vclz.i", | 
|  | 1555 | int_arm_neon_vclz>; | 
|  | 1556 | //   VCNT     : Vector Count One Bits | 
|  | 1557 | def  VCNTd    : N2VDInt<0b11, 0b11, 0b00, 0b00, 0b01010, 0, "vcnt.8", | 
|  | 1558 | v8i8, v8i8, int_arm_neon_vcnt>; | 
|  | 1559 | def  VCNTq    : N2VQInt<0b11, 0b11, 0b00, 0b00, 0b01010, 0, "vcnt.8", | 
|  | 1560 | v16i8, v16i8, int_arm_neon_vcnt>; | 
|  | 1561 |  | 
|  | 1562 | // Vector Move Operations. | 
|  | 1563 |  | 
|  | 1564 | //   VMOV     : Vector Move (Register) | 
|  | 1565 |  | 
|  | 1566 | def  VMOVD    : N3V<0, 0, 0b10, 0b0001, 0, 1, (outs DPR:$dst), (ins DPR:$src), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1567 | NoItinerary, "vmov\t$dst, $src", "", []>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1568 | def  VMOVQ    : N3V<0, 0, 0b10, 0b0001, 1, 1, (outs QPR:$dst), (ins QPR:$src), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1569 | NoItinerary, "vmov\t$dst, $src", "", []>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1570 |  | 
|  | 1571 | //   VMOV     : Vector Move (Immediate) | 
|  | 1572 |  | 
|  | 1573 | // VMOV_get_imm8 xform function: convert build_vector to VMOV.i8 imm. | 
|  | 1574 | def VMOV_get_imm8 : SDNodeXForm<build_vector, [{ | 
|  | 1575 | return ARM::getVMOVImm(N, 1, *CurDAG); | 
|  | 1576 | }]>; | 
|  | 1577 | def vmovImm8 : PatLeaf<(build_vector), [{ | 
|  | 1578 | return ARM::getVMOVImm(N, 1, *CurDAG).getNode() != 0; | 
|  | 1579 | }], VMOV_get_imm8>; | 
|  | 1580 |  | 
|  | 1581 | // VMOV_get_imm16 xform function: convert build_vector to VMOV.i16 imm. | 
|  | 1582 | def VMOV_get_imm16 : SDNodeXForm<build_vector, [{ | 
|  | 1583 | return ARM::getVMOVImm(N, 2, *CurDAG); | 
|  | 1584 | }]>; | 
|  | 1585 | def vmovImm16 : PatLeaf<(build_vector), [{ | 
|  | 1586 | return ARM::getVMOVImm(N, 2, *CurDAG).getNode() != 0; | 
|  | 1587 | }], VMOV_get_imm16>; | 
|  | 1588 |  | 
|  | 1589 | // VMOV_get_imm32 xform function: convert build_vector to VMOV.i32 imm. | 
|  | 1590 | def VMOV_get_imm32 : SDNodeXForm<build_vector, [{ | 
|  | 1591 | return ARM::getVMOVImm(N, 4, *CurDAG); | 
|  | 1592 | }]>; | 
|  | 1593 | def vmovImm32 : PatLeaf<(build_vector), [{ | 
|  | 1594 | return ARM::getVMOVImm(N, 4, *CurDAG).getNode() != 0; | 
|  | 1595 | }], VMOV_get_imm32>; | 
|  | 1596 |  | 
|  | 1597 | // VMOV_get_imm64 xform function: convert build_vector to VMOV.i64 imm. | 
|  | 1598 | def VMOV_get_imm64 : SDNodeXForm<build_vector, [{ | 
|  | 1599 | return ARM::getVMOVImm(N, 8, *CurDAG); | 
|  | 1600 | }]>; | 
|  | 1601 | def vmovImm64 : PatLeaf<(build_vector), [{ | 
|  | 1602 | return ARM::getVMOVImm(N, 8, *CurDAG).getNode() != 0; | 
|  | 1603 | }], VMOV_get_imm64>; | 
|  | 1604 |  | 
|  | 1605 | // Note: Some of the cmode bits in the following VMOV instructions need to | 
|  | 1606 | // be encoded based on the immed values. | 
|  | 1607 |  | 
|  | 1608 | def VMOVv8i8  : N1ModImm<1, 0b000, 0b1110, 0, 0, 0, 1, (outs DPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1609 | (ins i8imm:$SIMM), NoItinerary, | 
|  | 1610 | "vmov.i8\t$dst, $SIMM", "", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1611 | [(set DPR:$dst, (v8i8 vmovImm8:$SIMM))]>; | 
|  | 1612 | def VMOVv16i8 : N1ModImm<1, 0b000, 0b1110, 0, 1, 0, 1, (outs QPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1613 | (ins i8imm:$SIMM), NoItinerary, | 
|  | 1614 | "vmov.i8\t$dst, $SIMM", "", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1615 | [(set QPR:$dst, (v16i8 vmovImm8:$SIMM))]>; | 
|  | 1616 |  | 
|  | 1617 | def VMOVv4i16 : N1ModImm<1, 0b000, 0b1000, 0, 0, 0, 1, (outs DPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1618 | (ins i16imm:$SIMM), NoItinerary, | 
|  | 1619 | "vmov.i16\t$dst, $SIMM", "", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1620 | [(set DPR:$dst, (v4i16 vmovImm16:$SIMM))]>; | 
|  | 1621 | def VMOVv8i16 : N1ModImm<1, 0b000, 0b1000, 0, 1, 0, 1, (outs QPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1622 | (ins i16imm:$SIMM), NoItinerary, | 
|  | 1623 | "vmov.i16\t$dst, $SIMM", "", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1624 | [(set QPR:$dst, (v8i16 vmovImm16:$SIMM))]>; | 
|  | 1625 |  | 
|  | 1626 | def VMOVv2i32 : N1ModImm<1, 0b000, 0b0000, 0, 0, 0, 1, (outs DPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1627 | (ins i32imm:$SIMM), NoItinerary, | 
|  | 1628 | "vmov.i32\t$dst, $SIMM", "", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1629 | [(set DPR:$dst, (v2i32 vmovImm32:$SIMM))]>; | 
|  | 1630 | def VMOVv4i32 : N1ModImm<1, 0b000, 0b0000, 0, 1, 0, 1, (outs QPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1631 | (ins i32imm:$SIMM), NoItinerary, | 
|  | 1632 | "vmov.i32\t$dst, $SIMM", "", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1633 | [(set QPR:$dst, (v4i32 vmovImm32:$SIMM))]>; | 
|  | 1634 |  | 
|  | 1635 | def VMOVv1i64 : N1ModImm<1, 0b000, 0b1110, 0, 0, 1, 1, (outs DPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1636 | (ins i64imm:$SIMM), NoItinerary, | 
|  | 1637 | "vmov.i64\t$dst, $SIMM", "", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1638 | [(set DPR:$dst, (v1i64 vmovImm64:$SIMM))]>; | 
|  | 1639 | def VMOVv2i64 : N1ModImm<1, 0b000, 0b1110, 0, 1, 1, 1, (outs QPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1640 | (ins i64imm:$SIMM), NoItinerary, | 
|  | 1641 | "vmov.i64\t$dst, $SIMM", "", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1642 | [(set QPR:$dst, (v2i64 vmovImm64:$SIMM))]>; | 
|  | 1643 |  | 
|  | 1644 | //   VMOV     : Vector Get Lane (move scalar to ARM core register) | 
|  | 1645 |  | 
|  | 1646 | def VGETLNs8  : NVGetLane<0b11100101, 0b1011, 0b00, | 
| Anton Korobeynikov | cfed300 | 2009-08-08 23:10:41 +0000 | [diff] [blame] | 1647 | (outs GPR:$dst), (ins DPR:$src, lane_cst:$lane), | 
|  | 1648 | NoItinerary, "vmov", ".s8\t$dst, $src[$lane]", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1649 | [(set GPR:$dst, (NEONvgetlanes (v8i8 DPR:$src), | 
|  | 1650 | imm:$lane))]>; | 
|  | 1651 | def VGETLNs16 : NVGetLane<0b11100001, 0b1011, 0b01, | 
| Anton Korobeynikov | cfed300 | 2009-08-08 23:10:41 +0000 | [diff] [blame] | 1652 | (outs GPR:$dst), (ins DPR:$src, lane_cst:$lane), | 
|  | 1653 | NoItinerary, "vmov", ".s16\t$dst, $src[$lane]", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1654 | [(set GPR:$dst, (NEONvgetlanes (v4i16 DPR:$src), | 
|  | 1655 | imm:$lane))]>; | 
|  | 1656 | def VGETLNu8  : NVGetLane<0b11101101, 0b1011, 0b00, | 
| Anton Korobeynikov | cfed300 | 2009-08-08 23:10:41 +0000 | [diff] [blame] | 1657 | (outs GPR:$dst), (ins DPR:$src, lane_cst:$lane), | 
|  | 1658 | NoItinerary, "vmov", ".u8\t$dst, $src[$lane]", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1659 | [(set GPR:$dst, (NEONvgetlaneu (v8i8 DPR:$src), | 
|  | 1660 | imm:$lane))]>; | 
|  | 1661 | def VGETLNu16 : NVGetLane<0b11101001, 0b1011, 0b01, | 
| Anton Korobeynikov | cfed300 | 2009-08-08 23:10:41 +0000 | [diff] [blame] | 1662 | (outs GPR:$dst), (ins DPR:$src, lane_cst:$lane), | 
|  | 1663 | NoItinerary, "vmov", ".u16\t$dst, $src[$lane]", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1664 | [(set GPR:$dst, (NEONvgetlaneu (v4i16 DPR:$src), | 
|  | 1665 | imm:$lane))]>; | 
|  | 1666 | def VGETLNi32 : NVGetLane<0b11100001, 0b1011, 0b00, | 
| Anton Korobeynikov | cfed300 | 2009-08-08 23:10:41 +0000 | [diff] [blame] | 1667 | (outs GPR:$dst), (ins DPR:$src, lane_cst:$lane), | 
|  | 1668 | NoItinerary, "vmov", ".32\t$dst, $src[$lane]", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1669 | [(set GPR:$dst, (extractelt (v2i32 DPR:$src), | 
|  | 1670 | imm:$lane))]>; | 
|  | 1671 | // def VGETLNf32: see FMRDH and FMRDL in ARMInstrVFP.td | 
|  | 1672 | def : Pat<(NEONvgetlanes (v16i8 QPR:$src), imm:$lane), | 
|  | 1673 | (VGETLNs8 (v8i8 (EXTRACT_SUBREG QPR:$src, | 
| Anton Korobeynikov | 7167f33 | 2009-08-08 14:06:07 +0000 | [diff] [blame] | 1674 | (DSubReg_i8_reg imm:$lane))), | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1675 | (SubReg_i8_lane imm:$lane))>; | 
|  | 1676 | def : Pat<(NEONvgetlanes (v8i16 QPR:$src), imm:$lane), | 
|  | 1677 | (VGETLNs16 (v4i16 (EXTRACT_SUBREG QPR:$src, | 
| Anton Korobeynikov | 7167f33 | 2009-08-08 14:06:07 +0000 | [diff] [blame] | 1678 | (DSubReg_i16_reg imm:$lane))), | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1679 | (SubReg_i16_lane imm:$lane))>; | 
|  | 1680 | def : Pat<(NEONvgetlaneu (v16i8 QPR:$src), imm:$lane), | 
|  | 1681 | (VGETLNu8 (v8i8 (EXTRACT_SUBREG QPR:$src, | 
| Anton Korobeynikov | 7167f33 | 2009-08-08 14:06:07 +0000 | [diff] [blame] | 1682 | (DSubReg_i8_reg imm:$lane))), | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1683 | (SubReg_i8_lane imm:$lane))>; | 
|  | 1684 | def : Pat<(NEONvgetlaneu (v8i16 QPR:$src), imm:$lane), | 
|  | 1685 | (VGETLNu16 (v4i16 (EXTRACT_SUBREG QPR:$src, | 
| Anton Korobeynikov | 7167f33 | 2009-08-08 14:06:07 +0000 | [diff] [blame] | 1686 | (DSubReg_i16_reg imm:$lane))), | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1687 | (SubReg_i16_lane imm:$lane))>; | 
|  | 1688 | def : Pat<(extractelt (v4i32 QPR:$src), imm:$lane), | 
|  | 1689 | (VGETLNi32 (v2i32 (EXTRACT_SUBREG QPR:$src, | 
| Anton Korobeynikov | 7167f33 | 2009-08-08 14:06:07 +0000 | [diff] [blame] | 1690 | (DSubReg_i32_reg imm:$lane))), | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1691 | (SubReg_i32_lane imm:$lane))>; | 
| Anton Korobeynikov | 7167f33 | 2009-08-08 14:06:07 +0000 | [diff] [blame] | 1692 | def : Pat<(extractelt (v4f32 QPR:$src1), imm:$src2), | 
|  | 1693 | (EXTRACT_SUBREG QPR:$src1, (SSubReg_f32_reg imm:$src2))>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1694 | //def : Pat<(extractelt (v2i64 QPR:$src1), imm:$src2), | 
| Anton Korobeynikov | 7167f33 | 2009-08-08 14:06:07 +0000 | [diff] [blame] | 1695 | //          (EXTRACT_SUBREG QPR:$src1, (DSubReg_f64_reg imm:$src2))>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1696 | def : Pat<(extractelt (v2f64 QPR:$src1), imm:$src2), | 
| Anton Korobeynikov | 7167f33 | 2009-08-08 14:06:07 +0000 | [diff] [blame] | 1697 | (EXTRACT_SUBREG QPR:$src1, (DSubReg_f64_reg imm:$src2))>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1698 |  | 
|  | 1699 |  | 
|  | 1700 | //   VMOV     : Vector Set Lane (move ARM core register to scalar) | 
|  | 1701 |  | 
|  | 1702 | let Constraints = "$src1 = $dst" in { | 
|  | 1703 | def VSETLNi8  : NVSetLane<0b11100100, 0b1011, 0b00, (outs DPR:$dst), | 
| Anton Korobeynikov | cfed300 | 2009-08-08 23:10:41 +0000 | [diff] [blame] | 1704 | (ins DPR:$src1, GPR:$src2, lane_cst:$lane), | 
|  | 1705 | NoItinerary, "vmov", ".8\t$dst[$lane], $src2", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1706 | [(set DPR:$dst, (vector_insert (v8i8 DPR:$src1), | 
|  | 1707 | GPR:$src2, imm:$lane))]>; | 
|  | 1708 | def VSETLNi16 : NVSetLane<0b11100000, 0b1011, 0b01, (outs DPR:$dst), | 
| Anton Korobeynikov | cfed300 | 2009-08-08 23:10:41 +0000 | [diff] [blame] | 1709 | (ins DPR:$src1, GPR:$src2, lane_cst:$lane), | 
|  | 1710 | NoItinerary, "vmov", ".16\t$dst[$lane], $src2", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1711 | [(set DPR:$dst, (vector_insert (v4i16 DPR:$src1), | 
|  | 1712 | GPR:$src2, imm:$lane))]>; | 
|  | 1713 | def VSETLNi32 : NVSetLane<0b11100000, 0b1011, 0b00, (outs DPR:$dst), | 
| Anton Korobeynikov | cfed300 | 2009-08-08 23:10:41 +0000 | [diff] [blame] | 1714 | (ins DPR:$src1, GPR:$src2, lane_cst:$lane), | 
|  | 1715 | NoItinerary, "vmov", ".32\t$dst[$lane], $src2", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1716 | [(set DPR:$dst, (insertelt (v2i32 DPR:$src1), | 
|  | 1717 | GPR:$src2, imm:$lane))]>; | 
|  | 1718 | } | 
|  | 1719 | def : Pat<(vector_insert (v16i8 QPR:$src1), GPR:$src2, imm:$lane), | 
|  | 1720 | (v16i8 (INSERT_SUBREG QPR:$src1, | 
|  | 1721 | (VSETLNi8 (v8i8 (EXTRACT_SUBREG QPR:$src1, | 
| Anton Korobeynikov | 7167f33 | 2009-08-08 14:06:07 +0000 | [diff] [blame] | 1722 | (DSubReg_i8_reg imm:$lane))), | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1723 | GPR:$src2, (SubReg_i8_lane imm:$lane)), | 
| Anton Korobeynikov | 7167f33 | 2009-08-08 14:06:07 +0000 | [diff] [blame] | 1724 | (DSubReg_i8_reg imm:$lane)))>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1725 | def : Pat<(vector_insert (v8i16 QPR:$src1), GPR:$src2, imm:$lane), | 
|  | 1726 | (v8i16 (INSERT_SUBREG QPR:$src1, | 
|  | 1727 | (VSETLNi16 (v4i16 (EXTRACT_SUBREG QPR:$src1, | 
| Anton Korobeynikov | 7167f33 | 2009-08-08 14:06:07 +0000 | [diff] [blame] | 1728 | (DSubReg_i16_reg imm:$lane))), | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1729 | GPR:$src2, (SubReg_i16_lane imm:$lane)), | 
| Anton Korobeynikov | 7167f33 | 2009-08-08 14:06:07 +0000 | [diff] [blame] | 1730 | (DSubReg_i16_reg imm:$lane)))>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1731 | def : Pat<(insertelt (v4i32 QPR:$src1), GPR:$src2, imm:$lane), | 
|  | 1732 | (v4i32 (INSERT_SUBREG QPR:$src1, | 
|  | 1733 | (VSETLNi32 (v2i32 (EXTRACT_SUBREG QPR:$src1, | 
| Anton Korobeynikov | 7167f33 | 2009-08-08 14:06:07 +0000 | [diff] [blame] | 1734 | (DSubReg_i32_reg imm:$lane))), | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1735 | GPR:$src2, (SubReg_i32_lane imm:$lane)), | 
| Anton Korobeynikov | 7167f33 | 2009-08-08 14:06:07 +0000 | [diff] [blame] | 1736 | (DSubReg_i32_reg imm:$lane)))>; | 
|  | 1737 |  | 
|  | 1738 | def : Pat<(v4f32 (insertelt QPR:$src1, SPR:$src2, imm:$src3)), | 
|  | 1739 | (INSERT_SUBREG QPR:$src1, SPR:$src2, (SSubReg_f32_reg imm:$src3))>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1740 |  | 
|  | 1741 | //def : Pat<(v2i64 (insertelt QPR:$src1, DPR:$src2, imm:$src3)), | 
| Anton Korobeynikov | 7167f33 | 2009-08-08 14:06:07 +0000 | [diff] [blame] | 1742 | //          (INSERT_SUBREG QPR:$src1, DPR:$src2, (DSubReg_f64_reg imm:$src3))>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1743 | def : Pat<(v2f64 (insertelt QPR:$src1, DPR:$src2, imm:$src3)), | 
| Anton Korobeynikov | 7167f33 | 2009-08-08 14:06:07 +0000 | [diff] [blame] | 1744 | (INSERT_SUBREG QPR:$src1, DPR:$src2, (DSubReg_f64_reg imm:$src3))>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1745 |  | 
|  | 1746 | //   VDUP     : Vector Duplicate (from ARM core register to all elements) | 
|  | 1747 |  | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1748 | class VDUPD<bits<8> opcod1, bits<2> opcod3, string asmSize, ValueType Ty> | 
|  | 1749 | : NVDup<opcod1, 0b1011, opcod3, (outs DPR:$dst), (ins GPR:$src), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1750 | NoItinerary, "vdup", !strconcat(asmSize, "\t$dst, $src"), | 
| Bob Wilson | ff2db10 | 2009-08-12 22:54:19 +0000 | [diff] [blame] | 1751 | [(set DPR:$dst, (Ty (NEONvsplat0 (scalar_to_vector GPR:$src))))]>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1752 | class VDUPQ<bits<8> opcod1, bits<2> opcod3, string asmSize, ValueType Ty> | 
|  | 1753 | : NVDup<opcod1, 0b1011, opcod3, (outs QPR:$dst), (ins GPR:$src), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1754 | NoItinerary, "vdup", !strconcat(asmSize, "\t$dst, $src"), | 
| Bob Wilson | ff2db10 | 2009-08-12 22:54:19 +0000 | [diff] [blame] | 1755 | [(set QPR:$dst, (Ty (NEONvsplat0 (scalar_to_vector GPR:$src))))]>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1756 |  | 
|  | 1757 | def  VDUP8d   : VDUPD<0b11101100, 0b00, ".8", v8i8>; | 
|  | 1758 | def  VDUP16d  : VDUPD<0b11101000, 0b01, ".16", v4i16>; | 
|  | 1759 | def  VDUP32d  : VDUPD<0b11101000, 0b00, ".32", v2i32>; | 
|  | 1760 | def  VDUP8q   : VDUPQ<0b11101110, 0b00, ".8", v16i8>; | 
|  | 1761 | def  VDUP16q  : VDUPQ<0b11101010, 0b01, ".16", v8i16>; | 
|  | 1762 | def  VDUP32q  : VDUPQ<0b11101010, 0b00, ".32", v4i32>; | 
|  | 1763 |  | 
|  | 1764 | def  VDUPfd   : NVDup<0b11101000, 0b1011, 0b00, (outs DPR:$dst), (ins GPR:$src), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1765 | NoItinerary, "vdup", ".32\t$dst, $src", | 
| Bob Wilson | ff2db10 | 2009-08-12 22:54:19 +0000 | [diff] [blame] | 1766 | [(set DPR:$dst, | 
|  | 1767 | (v2f32 (NEONvsplat0 (scalar_to_vector | 
|  | 1768 | (f32 (bitconvert GPR:$src))))))]>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1769 | def  VDUPfq   : NVDup<0b11101010, 0b1011, 0b00, (outs QPR:$dst), (ins GPR:$src), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1770 | NoItinerary, "vdup", ".32\t$dst, $src", | 
| Bob Wilson | ff2db10 | 2009-08-12 22:54:19 +0000 | [diff] [blame] | 1771 | [(set QPR:$dst, | 
|  | 1772 | (v4f32 (NEONvsplat0 (scalar_to_vector | 
|  | 1773 | (f32 (bitconvert GPR:$src))))))]>; | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1774 |  | 
|  | 1775 | //   VDUP     : Vector Duplicate Lane (from scalar to all elements) | 
|  | 1776 |  | 
|  | 1777 | def SHUFFLE_get_splat_lane : SDNodeXForm<vector_shuffle, [{ | 
|  | 1778 | ShuffleVectorSDNode *SVOp = cast<ShuffleVectorSDNode>(N); | 
| Owen Anderson | 9f94459 | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 1779 | return CurDAG->getTargetConstant(SVOp->getSplatIndex(), MVT::i32); | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1780 | }]>; | 
|  | 1781 |  | 
|  | 1782 | def splat_lane : PatFrag<(ops node:$lhs, node:$rhs), | 
|  | 1783 | (vector_shuffle node:$lhs, node:$rhs), [{ | 
|  | 1784 | ShuffleVectorSDNode *SVOp = cast<ShuffleVectorSDNode>(N); | 
|  | 1785 | return SVOp->isSplat(); | 
|  | 1786 | }], SHUFFLE_get_splat_lane>; | 
|  | 1787 |  | 
|  | 1788 | class VDUPLND<bits<2> op19_18, bits<2> op17_16, string OpcodeStr, ValueType Ty> | 
|  | 1789 | : N2V<0b11, 0b11, op19_18, op17_16, 0b11000, 0, 0, | 
| Anton Korobeynikov | cfed300 | 2009-08-08 23:10:41 +0000 | [diff] [blame] | 1790 | (outs DPR:$dst), (ins DPR:$src, lane_cst:$lane), NoItinerary, | 
|  | 1791 | !strconcat(OpcodeStr, "\t$dst, $src[$lane]"), "", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1792 | [(set DPR:$dst, (Ty (splat_lane:$lane DPR:$src, undef)))]>; | 
|  | 1793 |  | 
|  | 1794 | // vector_shuffle requires that the source and destination types match, so | 
|  | 1795 | // VDUP to a 128-bit result uses a target-specific VDUPLANEQ node. | 
|  | 1796 | class VDUPLNQ<bits<2> op19_18, bits<2> op17_16, string OpcodeStr, | 
|  | 1797 | ValueType ResTy, ValueType OpTy> | 
|  | 1798 | : N2V<0b11, 0b11, op19_18, op17_16, 0b11000, 1, 0, | 
| Anton Korobeynikov | cfed300 | 2009-08-08 23:10:41 +0000 | [diff] [blame] | 1799 | (outs QPR:$dst), (ins DPR:$src, lane_cst:$lane), NoItinerary, | 
|  | 1800 | !strconcat(OpcodeStr, "\t$dst, $src[$lane]"), "", | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1801 | [(set QPR:$dst, (ResTy (NEONvduplaneq (OpTy DPR:$src), imm:$lane)))]>; | 
|  | 1802 |  | 
|  | 1803 | def VDUPLN8d  : VDUPLND<0b00, 0b01, "vdup.8", v8i8>; | 
|  | 1804 | def VDUPLN16d : VDUPLND<0b00, 0b10, "vdup.16", v4i16>; | 
|  | 1805 | def VDUPLN32d : VDUPLND<0b01, 0b00, "vdup.32", v2i32>; | 
|  | 1806 | def VDUPLNfd  : VDUPLND<0b01, 0b00, "vdup.32", v2f32>; | 
|  | 1807 | def VDUPLN8q  : VDUPLNQ<0b00, 0b01, "vdup.8", v16i8, v8i8>; | 
|  | 1808 | def VDUPLN16q : VDUPLNQ<0b00, 0b10, "vdup.16", v8i16, v4i16>; | 
|  | 1809 | def VDUPLN32q : VDUPLNQ<0b01, 0b00, "vdup.32", v4i32, v2i32>; | 
|  | 1810 | def VDUPLNfq  : VDUPLNQ<0b01, 0b00, "vdup.32", v4f32, v2f32>; | 
|  | 1811 |  | 
| Anton Korobeynikov | 23b28cb | 2009-08-07 22:36:50 +0000 | [diff] [blame] | 1812 | def VDUPfdf   : N2V<0b11, 0b11, 0b01, 0b00, 0b11000, 0, 0, | 
|  | 1813 | (outs DPR:$dst), (ins SPR:$src), | 
| Anton Korobeynikov | d28a26d | 2009-08-07 22:51:13 +0000 | [diff] [blame] | 1814 | NoItinerary, "vdup.32\t$dst, ${src:lane}", "", | 
| Bob Wilson | ff2db10 | 2009-08-12 22:54:19 +0000 | [diff] [blame] | 1815 | [(set DPR:$dst, (v2f32 (NEONvsplat0 | 
|  | 1816 | (scalar_to_vector SPR:$src))))]>; | 
| Anton Korobeynikov | 23b28cb | 2009-08-07 22:36:50 +0000 | [diff] [blame] | 1817 |  | 
|  | 1818 | def VDUPfqf   : N2V<0b11, 0b11, 0b01, 0b00, 0b11000, 1, 0, | 
|  | 1819 | (outs QPR:$dst), (ins SPR:$src), | 
| Anton Korobeynikov | d28a26d | 2009-08-07 22:51:13 +0000 | [diff] [blame] | 1820 | NoItinerary, "vdup.32\t$dst, ${src:lane}", "", | 
| Bob Wilson | ff2db10 | 2009-08-12 22:54:19 +0000 | [diff] [blame] | 1821 | [(set QPR:$dst, (v4f32 (NEONvsplat0 | 
|  | 1822 | (scalar_to_vector SPR:$src))))]>; | 
| Anton Korobeynikov | 23b28cb | 2009-08-07 22:36:50 +0000 | [diff] [blame] | 1823 |  | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 1824 | //   VMOVN    : Vector Narrowing Move | 
|  | 1825 | defm VMOVN    : N2VNInt_HSD<0b11,0b11,0b10,0b00100,0,0, "vmovn.i", | 
|  | 1826 | int_arm_neon_vmovn>; | 
|  | 1827 | //   VQMOVN   : Vector Saturating Narrowing Move | 
|  | 1828 | defm VQMOVNs  : N2VNInt_HSD<0b11,0b11,0b10,0b00101,0,0, "vqmovn.s", | 
|  | 1829 | int_arm_neon_vqmovns>; | 
|  | 1830 | defm VQMOVNu  : N2VNInt_HSD<0b11,0b11,0b10,0b00101,1,0, "vqmovn.u", | 
|  | 1831 | int_arm_neon_vqmovnu>; | 
|  | 1832 | defm VQMOVNsu : N2VNInt_HSD<0b11,0b11,0b10,0b00100,1,0, "vqmovun.s", | 
|  | 1833 | int_arm_neon_vqmovnsu>; | 
|  | 1834 | //   VMOVL    : Vector Lengthening Move | 
|  | 1835 | defm VMOVLs   : N2VLInt_QHS<0,1,0b1010,0,0,1, "vmovl.s", int_arm_neon_vmovls>; | 
|  | 1836 | defm VMOVLu   : N2VLInt_QHS<1,1,0b1010,0,0,1, "vmovl.u", int_arm_neon_vmovlu>; | 
|  | 1837 |  | 
|  | 1838 | // Vector Conversions. | 
|  | 1839 |  | 
|  | 1840 | //   VCVT     : Vector Convert Between Floating-Point and Integers | 
|  | 1841 | def  VCVTf2sd : N2VD<0b11, 0b11, 0b10, 0b11, 0b01110, 0, "vcvt.s32.f32", | 
|  | 1842 | v2i32, v2f32, fp_to_sint>; | 
|  | 1843 | def  VCVTf2ud : N2VD<0b11, 0b11, 0b10, 0b11, 0b01111, 0, "vcvt.u32.f32", | 
|  | 1844 | v2i32, v2f32, fp_to_uint>; | 
|  | 1845 | def  VCVTs2fd : N2VD<0b11, 0b11, 0b10, 0b11, 0b01100, 0, "vcvt.f32.s32", | 
|  | 1846 | v2f32, v2i32, sint_to_fp>; | 
|  | 1847 | def  VCVTu2fd : N2VD<0b11, 0b11, 0b10, 0b11, 0b01101, 0, "vcvt.f32.u32", | 
|  | 1848 | v2f32, v2i32, uint_to_fp>; | 
|  | 1849 |  | 
|  | 1850 | def  VCVTf2sq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01110, 0, "vcvt.s32.f32", | 
|  | 1851 | v4i32, v4f32, fp_to_sint>; | 
|  | 1852 | def  VCVTf2uq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01111, 0, "vcvt.u32.f32", | 
|  | 1853 | v4i32, v4f32, fp_to_uint>; | 
|  | 1854 | def  VCVTs2fq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01100, 0, "vcvt.f32.s32", | 
|  | 1855 | v4f32, v4i32, sint_to_fp>; | 
|  | 1856 | def  VCVTu2fq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01101, 0, "vcvt.f32.u32", | 
|  | 1857 | v4f32, v4i32, uint_to_fp>; | 
|  | 1858 |  | 
|  | 1859 | //   VCVT     : Vector Convert Between Floating-Point and Fixed-Point. | 
|  | 1860 | // Note: Some of the opcode bits in the following VCVT instructions need to | 
|  | 1861 | // be encoded based on the immed values. | 
|  | 1862 | def VCVTf2xsd : N2VCvtD<0, 1, 0b000000, 0b1111, 0, 1, "vcvt.s32.f32", | 
|  | 1863 | v2i32, v2f32, int_arm_neon_vcvtfp2fxs>; | 
|  | 1864 | def VCVTf2xud : N2VCvtD<1, 1, 0b000000, 0b1111, 0, 1, "vcvt.u32.f32", | 
|  | 1865 | v2i32, v2f32, int_arm_neon_vcvtfp2fxu>; | 
|  | 1866 | def VCVTxs2fd : N2VCvtD<0, 1, 0b000000, 0b1110, 0, 1, "vcvt.f32.s32", | 
|  | 1867 | v2f32, v2i32, int_arm_neon_vcvtfxs2fp>; | 
|  | 1868 | def VCVTxu2fd : N2VCvtD<1, 1, 0b000000, 0b1110, 0, 1, "vcvt.f32.u32", | 
|  | 1869 | v2f32, v2i32, int_arm_neon_vcvtfxu2fp>; | 
|  | 1870 |  | 
|  | 1871 | def VCVTf2xsq : N2VCvtQ<0, 1, 0b000000, 0b1111, 0, 1, "vcvt.s32.f32", | 
|  | 1872 | v4i32, v4f32, int_arm_neon_vcvtfp2fxs>; | 
|  | 1873 | def VCVTf2xuq : N2VCvtQ<1, 1, 0b000000, 0b1111, 0, 1, "vcvt.u32.f32", | 
|  | 1874 | v4i32, v4f32, int_arm_neon_vcvtfp2fxu>; | 
|  | 1875 | def VCVTxs2fq : N2VCvtQ<0, 1, 0b000000, 0b1110, 0, 1, "vcvt.f32.s32", | 
|  | 1876 | v4f32, v4i32, int_arm_neon_vcvtfxs2fp>; | 
|  | 1877 | def VCVTxu2fq : N2VCvtQ<1, 1, 0b000000, 0b1110, 0, 1, "vcvt.f32.u32", | 
|  | 1878 | v4f32, v4i32, int_arm_neon_vcvtfxu2fp>; | 
|  | 1879 |  | 
| Bob Wilson | ea3a402 | 2009-08-12 22:31:50 +0000 | [diff] [blame] | 1880 | // Vector Reverse. | 
| Bob Wilson | 8a37bbe | 2009-07-26 00:39:34 +0000 | [diff] [blame] | 1881 |  | 
|  | 1882 | //   VREV64   : Vector Reverse elements within 64-bit doublewords | 
|  | 1883 |  | 
|  | 1884 | class VREV64D<bits<2> op19_18, string OpcodeStr, ValueType Ty> | 
|  | 1885 | : N2V<0b11, 0b11, op19_18, 0b00, 0b00000, 0, 0, (outs DPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1886 | (ins DPR:$src), NoItinerary, | 
|  | 1887 | !strconcat(OpcodeStr, "\t$dst, $src"), "", | 
| Bob Wilson | ea3a402 | 2009-08-12 22:31:50 +0000 | [diff] [blame] | 1888 | [(set DPR:$dst, (Ty (NEONvrev64 (Ty DPR:$src))))]>; | 
| Bob Wilson | 8a37bbe | 2009-07-26 00:39:34 +0000 | [diff] [blame] | 1889 | class VREV64Q<bits<2> op19_18, string OpcodeStr, ValueType Ty> | 
|  | 1890 | : N2V<0b11, 0b11, op19_18, 0b00, 0b00000, 1, 0, (outs QPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1891 | (ins QPR:$src), NoItinerary, | 
|  | 1892 | !strconcat(OpcodeStr, "\t$dst, $src"), "", | 
| Bob Wilson | ea3a402 | 2009-08-12 22:31:50 +0000 | [diff] [blame] | 1893 | [(set QPR:$dst, (Ty (NEONvrev64 (Ty QPR:$src))))]>; | 
| Bob Wilson | 8a37bbe | 2009-07-26 00:39:34 +0000 | [diff] [blame] | 1894 |  | 
|  | 1895 | def VREV64d8  : VREV64D<0b00, "vrev64.8", v8i8>; | 
|  | 1896 | def VREV64d16 : VREV64D<0b01, "vrev64.16", v4i16>; | 
|  | 1897 | def VREV64d32 : VREV64D<0b10, "vrev64.32", v2i32>; | 
|  | 1898 | def VREV64df  : VREV64D<0b10, "vrev64.32", v2f32>; | 
|  | 1899 |  | 
|  | 1900 | def VREV64q8  : VREV64Q<0b00, "vrev64.8", v16i8>; | 
|  | 1901 | def VREV64q16 : VREV64Q<0b01, "vrev64.16", v8i16>; | 
|  | 1902 | def VREV64q32 : VREV64Q<0b10, "vrev64.32", v4i32>; | 
|  | 1903 | def VREV64qf  : VREV64Q<0b10, "vrev64.32", v4f32>; | 
|  | 1904 |  | 
|  | 1905 | //   VREV32   : Vector Reverse elements within 32-bit words | 
|  | 1906 |  | 
|  | 1907 | class VREV32D<bits<2> op19_18, string OpcodeStr, ValueType Ty> | 
|  | 1908 | : N2V<0b11, 0b11, op19_18, 0b00, 0b00001, 0, 0, (outs DPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1909 | (ins DPR:$src), NoItinerary, | 
|  | 1910 | !strconcat(OpcodeStr, "\t$dst, $src"), "", | 
| Bob Wilson | ea3a402 | 2009-08-12 22:31:50 +0000 | [diff] [blame] | 1911 | [(set DPR:$dst, (Ty (NEONvrev32 (Ty DPR:$src))))]>; | 
| Bob Wilson | 8a37bbe | 2009-07-26 00:39:34 +0000 | [diff] [blame] | 1912 | class VREV32Q<bits<2> op19_18, string OpcodeStr, ValueType Ty> | 
|  | 1913 | : N2V<0b11, 0b11, op19_18, 0b00, 0b00001, 1, 0, (outs QPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1914 | (ins QPR:$src), NoItinerary, | 
|  | 1915 | !strconcat(OpcodeStr, "\t$dst, $src"), "", | 
| Bob Wilson | ea3a402 | 2009-08-12 22:31:50 +0000 | [diff] [blame] | 1916 | [(set QPR:$dst, (Ty (NEONvrev32 (Ty QPR:$src))))]>; | 
| Bob Wilson | 8a37bbe | 2009-07-26 00:39:34 +0000 | [diff] [blame] | 1917 |  | 
|  | 1918 | def VREV32d8  : VREV32D<0b00, "vrev32.8", v8i8>; | 
|  | 1919 | def VREV32d16 : VREV32D<0b01, "vrev32.16", v4i16>; | 
|  | 1920 |  | 
|  | 1921 | def VREV32q8  : VREV32Q<0b00, "vrev32.8", v16i8>; | 
|  | 1922 | def VREV32q16 : VREV32Q<0b01, "vrev32.16", v8i16>; | 
|  | 1923 |  | 
|  | 1924 | //   VREV16   : Vector Reverse elements within 16-bit halfwords | 
|  | 1925 |  | 
|  | 1926 | class VREV16D<bits<2> op19_18, string OpcodeStr, ValueType Ty> | 
|  | 1927 | : N2V<0b11, 0b11, op19_18, 0b00, 0b00010, 0, 0, (outs DPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1928 | (ins DPR:$src), NoItinerary, | 
|  | 1929 | !strconcat(OpcodeStr, "\t$dst, $src"), "", | 
| Bob Wilson | ea3a402 | 2009-08-12 22:31:50 +0000 | [diff] [blame] | 1930 | [(set DPR:$dst, (Ty (NEONvrev16 (Ty DPR:$src))))]>; | 
| Bob Wilson | 8a37bbe | 2009-07-26 00:39:34 +0000 | [diff] [blame] | 1931 | class VREV16Q<bits<2> op19_18, string OpcodeStr, ValueType Ty> | 
|  | 1932 | : N2V<0b11, 0b11, op19_18, 0b00, 0b00010, 1, 0, (outs QPR:$dst), | 
| David Goodwin | b062c23 | 2009-08-06 16:52:47 +0000 | [diff] [blame] | 1933 | (ins QPR:$src), NoItinerary, | 
|  | 1934 | !strconcat(OpcodeStr, "\t$dst, $src"), "", | 
| Bob Wilson | ea3a402 | 2009-08-12 22:31:50 +0000 | [diff] [blame] | 1935 | [(set QPR:$dst, (Ty (NEONvrev16 (Ty QPR:$src))))]>; | 
| Bob Wilson | 8a37bbe | 2009-07-26 00:39:34 +0000 | [diff] [blame] | 1936 |  | 
|  | 1937 | def VREV16d8  : VREV16D<0b00, "vrev16.8", v8i8>; | 
|  | 1938 | def VREV16q8  : VREV16Q<0b00, "vrev16.8", v16i8>; | 
|  | 1939 |  | 
| Bob Wilson | db46af0 | 2009-08-08 05:53:00 +0000 | [diff] [blame] | 1940 | //   VTRN     : Vector Transpose | 
|  | 1941 |  | 
| Bob Wilson | e223107 | 2009-08-08 06:13:25 +0000 | [diff] [blame] | 1942 | def  VTRNd8   : N2VDShuffle<0b00, 0b00001, "vtrn.8">; | 
|  | 1943 | def  VTRNd16  : N2VDShuffle<0b01, 0b00001, "vtrn.16">; | 
|  | 1944 | def  VTRNd32  : N2VDShuffle<0b10, 0b00001, "vtrn.32">; | 
| Bob Wilson | db46af0 | 2009-08-08 05:53:00 +0000 | [diff] [blame] | 1945 |  | 
| Bob Wilson | e223107 | 2009-08-08 06:13:25 +0000 | [diff] [blame] | 1946 | def  VTRNq8   : N2VQShuffle<0b00, 0b00001, "vtrn.8">; | 
|  | 1947 | def  VTRNq16  : N2VQShuffle<0b01, 0b00001, "vtrn.16">; | 
|  | 1948 | def  VTRNq32  : N2VQShuffle<0b10, 0b00001, "vtrn.32">; | 
| Bob Wilson | db46af0 | 2009-08-08 05:53:00 +0000 | [diff] [blame] | 1949 |  | 
| Bob Wilson | e223107 | 2009-08-08 06:13:25 +0000 | [diff] [blame] | 1950 | //   VUZP     : Vector Unzip (Deinterleave) | 
|  | 1951 |  | 
|  | 1952 | def  VUZPd8   : N2VDShuffle<0b00, 0b00010, "vuzp.8">; | 
|  | 1953 | def  VUZPd16  : N2VDShuffle<0b01, 0b00010, "vuzp.16">; | 
|  | 1954 | def  VUZPd32  : N2VDShuffle<0b10, 0b00010, "vuzp.32">; | 
|  | 1955 |  | 
|  | 1956 | def  VUZPq8   : N2VQShuffle<0b00, 0b00010, "vuzp.8">; | 
|  | 1957 | def  VUZPq16  : N2VQShuffle<0b01, 0b00010, "vuzp.16">; | 
|  | 1958 | def  VUZPq32  : N2VQShuffle<0b10, 0b00010, "vuzp.32">; | 
|  | 1959 |  | 
|  | 1960 | //   VZIP     : Vector Zip (Interleave) | 
|  | 1961 |  | 
|  | 1962 | def  VZIPd8   : N2VDShuffle<0b00, 0b00011, "vzip.8">; | 
|  | 1963 | def  VZIPd16  : N2VDShuffle<0b01, 0b00011, "vzip.16">; | 
|  | 1964 | def  VZIPd32  : N2VDShuffle<0b10, 0b00011, "vzip.32">; | 
|  | 1965 |  | 
|  | 1966 | def  VZIPq8   : N2VQShuffle<0b00, 0b00011, "vzip.8">; | 
|  | 1967 | def  VZIPq16  : N2VQShuffle<0b01, 0b00011, "vzip.16">; | 
|  | 1968 | def  VZIPq32  : N2VQShuffle<0b10, 0b00011, "vzip.32">; | 
| Bob Wilson | db46af0 | 2009-08-08 05:53:00 +0000 | [diff] [blame] | 1969 |  | 
| Bob Wilson | 4b35448 | 2009-08-12 20:51:55 +0000 | [diff] [blame] | 1970 | // Vector Table Lookup and Table Extension. | 
|  | 1971 |  | 
|  | 1972 | //   VTBL     : Vector Table Lookup | 
|  | 1973 | def  VTBL1 | 
|  | 1974 | : N3V<1,1,0b11,0b1000,0,0, (outs DPR:$dst), | 
|  | 1975 | (ins DPR:$tbl1, DPR:$src), NoItinerary, | 
|  | 1976 | "vtbl.8\t$dst, \\{$tbl1\\}, $src", "", | 
|  | 1977 | [(set DPR:$dst, (v8i8 (int_arm_neon_vtbl1 DPR:$tbl1, DPR:$src)))]>; | 
|  | 1978 | def  VTBL2 | 
|  | 1979 | : N3V<1,1,0b11,0b1001,0,0, (outs DPR:$dst), | 
|  | 1980 | (ins DPR:$tbl1, DPR:$tbl2, DPR:$src), NoItinerary, | 
|  | 1981 | "vtbl.8\t$dst, \\{$tbl1,$tbl2\\}, $src", "", | 
|  | 1982 | [(set DPR:$dst, (v8i8 (int_arm_neon_vtbl2 | 
|  | 1983 | DPR:$tbl1, DPR:$tbl2, DPR:$src)))]>; | 
|  | 1984 | def  VTBL3 | 
|  | 1985 | : N3V<1,1,0b11,0b1010,0,0, (outs DPR:$dst), | 
|  | 1986 | (ins DPR:$tbl1, DPR:$tbl2, DPR:$tbl3, DPR:$src), NoItinerary, | 
|  | 1987 | "vtbl.8\t$dst, \\{$tbl1,$tbl2,$tbl3\\}, $src", "", | 
|  | 1988 | [(set DPR:$dst, (v8i8 (int_arm_neon_vtbl3 | 
|  | 1989 | DPR:$tbl1, DPR:$tbl2, DPR:$tbl3, DPR:$src)))]>; | 
|  | 1990 | def  VTBL4 | 
|  | 1991 | : N3V<1,1,0b11,0b1011,0,0, (outs DPR:$dst), | 
|  | 1992 | (ins DPR:$tbl1, DPR:$tbl2, DPR:$tbl3, DPR:$tbl4, DPR:$src), NoItinerary, | 
|  | 1993 | "vtbl.8\t$dst, \\{$tbl1,$tbl2,$tbl3,$tbl4\\}, $src", "", | 
|  | 1994 | [(set DPR:$dst, (v8i8 (int_arm_neon_vtbl4 DPR:$tbl1, DPR:$tbl2, | 
|  | 1995 | DPR:$tbl3, DPR:$tbl4, DPR:$src)))]>; | 
|  | 1996 |  | 
|  | 1997 | //   VTBX     : Vector Table Extension | 
|  | 1998 | def  VTBX1 | 
|  | 1999 | : N3V<1,1,0b11,0b1000,1,0, (outs DPR:$dst), | 
|  | 2000 | (ins DPR:$orig, DPR:$tbl1, DPR:$src), NoItinerary, | 
|  | 2001 | "vtbx.8\t$dst, \\{$tbl1\\}, $src", "$orig = $dst", | 
|  | 2002 | [(set DPR:$dst, (v8i8 (int_arm_neon_vtbx1 | 
|  | 2003 | DPR:$orig, DPR:$tbl1, DPR:$src)))]>; | 
|  | 2004 | def  VTBX2 | 
|  | 2005 | : N3V<1,1,0b11,0b1001,1,0, (outs DPR:$dst), | 
|  | 2006 | (ins DPR:$orig, DPR:$tbl1, DPR:$tbl2, DPR:$src), NoItinerary, | 
|  | 2007 | "vtbx.8\t$dst, \\{$tbl1,$tbl2\\}, $src", "$orig = $dst", | 
|  | 2008 | [(set DPR:$dst, (v8i8 (int_arm_neon_vtbx2 | 
|  | 2009 | DPR:$orig, DPR:$tbl1, DPR:$tbl2, DPR:$src)))]>; | 
|  | 2010 | def  VTBX3 | 
|  | 2011 | : N3V<1,1,0b11,0b1010,1,0, (outs DPR:$dst), | 
|  | 2012 | (ins DPR:$orig, DPR:$tbl1, DPR:$tbl2, DPR:$tbl3, DPR:$src), NoItinerary, | 
|  | 2013 | "vtbx.8\t$dst, \\{$tbl1,$tbl2,$tbl3\\}, $src", "$orig = $dst", | 
|  | 2014 | [(set DPR:$dst, (v8i8 (int_arm_neon_vtbx3 DPR:$orig, DPR:$tbl1, | 
|  | 2015 | DPR:$tbl2, DPR:$tbl3, DPR:$src)))]>; | 
|  | 2016 | def  VTBX4 | 
|  | 2017 | : N3V<1,1,0b11,0b1011,1,0, (outs DPR:$dst), (ins DPR:$orig, DPR:$tbl1, | 
|  | 2018 | DPR:$tbl2, DPR:$tbl3, DPR:$tbl4, DPR:$src), NoItinerary, | 
|  | 2019 | "vtbx.8\t$dst, \\{$tbl1,$tbl2,$tbl3,$tbl4\\}, $src", "$orig = $dst", | 
|  | 2020 | [(set DPR:$dst, (v8i8 (int_arm_neon_vtbx4 DPR:$orig, DPR:$tbl1, | 
|  | 2021 | DPR:$tbl2, DPR:$tbl3, DPR:$tbl4, DPR:$src)))]>; | 
|  | 2022 |  | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 2023 | //===----------------------------------------------------------------------===// | 
| Evan Cheng | 4c3b1ca | 2009-08-07 19:30:41 +0000 | [diff] [blame] | 2024 | // NEON instructions for single-precision FP math | 
|  | 2025 | //===----------------------------------------------------------------------===// | 
|  | 2026 |  | 
|  | 2027 | // These need separate instructions because they must use DPR_VFP2 register | 
|  | 2028 | // class which have SPR sub-registers. | 
|  | 2029 |  | 
|  | 2030 | // Vector Add Operations used for single-precision FP | 
|  | 2031 | let neverHasSideEffects = 1 in | 
|  | 2032 | def VADDfd_sfp : N3VDs<0, 0, 0b00, 0b1101, 0, "vadd.f32", v2f32, v2f32, fadd,1>; | 
|  | 2033 | def : N3VDsPat<fadd, VADDfd_sfp>; | 
|  | 2034 |  | 
| David Goodwin | 85b5b02 | 2009-08-10 22:17:39 +0000 | [diff] [blame] | 2035 | // Vector Sub Operations used for single-precision FP | 
|  | 2036 | let neverHasSideEffects = 1 in | 
|  | 2037 | def VSUBfd_sfp : N3VDs<0, 0, 0b10, 0b1101, 0, "vsub.f32", v2f32, v2f32, fsub,0>; | 
|  | 2038 | def : N3VDsPat<fsub, VSUBfd_sfp>; | 
|  | 2039 |  | 
| Evan Cheng | 4c3b1ca | 2009-08-07 19:30:41 +0000 | [diff] [blame] | 2040 | // Vector Multiply Operations used for single-precision FP | 
|  | 2041 | let neverHasSideEffects = 1 in | 
|  | 2042 | def VMULfd_sfp : N3VDs<1, 0, 0b00, 0b1101, 1, "vmul.f32", v2f32, v2f32, fmul,1>; | 
|  | 2043 | def : N3VDsPat<fmul, VMULfd_sfp>; | 
|  | 2044 |  | 
|  | 2045 | // Vector Multiply-Accumulate/Subtract used for single-precision FP | 
|  | 2046 | let neverHasSideEffects = 1 in | 
|  | 2047 | def VMLAfd_sfp : N3VDMulOps<0, 0, 0b00, 0b1101, 1, "vmla.f32", v2f32,fmul,fadd>; | 
| David Goodwin | 85b5b02 | 2009-08-10 22:17:39 +0000 | [diff] [blame] | 2048 | def : N3VDMulOpsPat<fmul, fadd, VMLAfd_sfp>; | 
| Evan Cheng | 4c3b1ca | 2009-08-07 19:30:41 +0000 | [diff] [blame] | 2049 |  | 
|  | 2050 | let neverHasSideEffects = 1 in | 
|  | 2051 | def VMLSfd_sfp : N3VDMulOps<0, 0, 0b10, 0b1101, 1, "vmls.f32", v2f32,fmul,fsub>; | 
| David Goodwin | 85b5b02 | 2009-08-10 22:17:39 +0000 | [diff] [blame] | 2052 | def : N3VDMulOpsPat<fmul, fsub, VMLSfd_sfp>; | 
| Evan Cheng | 4c3b1ca | 2009-08-07 19:30:41 +0000 | [diff] [blame] | 2053 |  | 
| David Goodwin | 85b5b02 | 2009-08-10 22:17:39 +0000 | [diff] [blame] | 2054 | // Vector Absolute used for single-precision FP | 
| Evan Cheng | 4c3b1ca | 2009-08-07 19:30:41 +0000 | [diff] [blame] | 2055 | let neverHasSideEffects = 1 in | 
|  | 2056 | def  VABSfd_sfp : N2VDInts<0b11, 0b11, 0b10, 0b01, 0b01110, 0, "vabs.f32", | 
| Bob Wilson | 12842f9 | 2009-08-11 05:39:44 +0000 | [diff] [blame] | 2057 | v2f32, v2f32, int_arm_neon_vabs>; | 
| Evan Cheng | 4c3b1ca | 2009-08-07 19:30:41 +0000 | [diff] [blame] | 2058 | def : N2VDIntsPat<fabs, VABSfd_sfp>; | 
|  | 2059 |  | 
| David Goodwin | 85b5b02 | 2009-08-10 22:17:39 +0000 | [diff] [blame] | 2060 | // Vector Negate used for single-precision FP | 
| Evan Cheng | 4c3b1ca | 2009-08-07 19:30:41 +0000 | [diff] [blame] | 2061 | let neverHasSideEffects = 1 in | 
|  | 2062 | def  VNEGf32d_sfp : N2V<0b11, 0b11, 0b10, 0b01, 0b01111, 0, 0, | 
| David Goodwin | 85b5b02 | 2009-08-10 22:17:39 +0000 | [diff] [blame] | 2063 | (outs DPR_VFP2:$dst), (ins DPR_VFP2:$src), NoItinerary, | 
|  | 2064 | "vneg.f32\t$dst, $src", "", []>; | 
| Evan Cheng | 4c3b1ca | 2009-08-07 19:30:41 +0000 | [diff] [blame] | 2065 | def : N2VDIntsPat<fneg, VNEGf32d_sfp>; | 
|  | 2066 |  | 
| David Goodwin | 85b5b02 | 2009-08-10 22:17:39 +0000 | [diff] [blame] | 2067 | // Vector Convert between single-precision FP and integer | 
|  | 2068 | let neverHasSideEffects = 1 in | 
|  | 2069 | def  VCVTf2sd_sfp : N2VDs<0b11, 0b11, 0b10, 0b11, 0b01110, 0, "vcvt.s32.f32", | 
|  | 2070 | v2i32, v2f32, fp_to_sint>; | 
|  | 2071 | def : N2VDsPat<arm_ftosi, f32, v2f32, VCVTf2sd_sfp>; | 
|  | 2072 |  | 
|  | 2073 | let neverHasSideEffects = 1 in | 
|  | 2074 | def  VCVTf2ud_sfp : N2VDs<0b11, 0b11, 0b10, 0b11, 0b01111, 0, "vcvt.u32.f32", | 
|  | 2075 | v2i32, v2f32, fp_to_uint>; | 
|  | 2076 | def : N2VDsPat<arm_ftoui, f32, v2f32, VCVTf2ud_sfp>; | 
|  | 2077 |  | 
|  | 2078 | let neverHasSideEffects = 1 in | 
| David Goodwin | b80734b | 2009-08-11 01:07:38 +0000 | [diff] [blame] | 2079 | def  VCVTs2fd_sfp : N2VDs<0b11, 0b11, 0b10, 0b11, 0b01100, 0, "vcvt.f32.s32", | 
|  | 2080 | v2f32, v2i32, sint_to_fp>; | 
| David Goodwin | 85b5b02 | 2009-08-10 22:17:39 +0000 | [diff] [blame] | 2081 | def : N2VDsPat<arm_sitof, f32, v2i32, VCVTs2fd_sfp>; | 
|  | 2082 |  | 
|  | 2083 | let neverHasSideEffects = 1 in | 
| David Goodwin | b80734b | 2009-08-11 01:07:38 +0000 | [diff] [blame] | 2084 | def  VCVTu2fd_sfp : N2VDs<0b11, 0b11, 0b10, 0b11, 0b01101, 0, "vcvt.f32.u32", | 
|  | 2085 | v2f32, v2i32, uint_to_fp>; | 
| David Goodwin | 85b5b02 | 2009-08-10 22:17:39 +0000 | [diff] [blame] | 2086 | def : N2VDsPat<arm_uitof, f32, v2i32, VCVTu2fd_sfp>; | 
|  | 2087 |  | 
| Evan Cheng | 4c3b1ca | 2009-08-07 19:30:41 +0000 | [diff] [blame] | 2088 | //===----------------------------------------------------------------------===// | 
| Bob Wilson | 2e076c4 | 2009-06-22 23:27:02 +0000 | [diff] [blame] | 2089 | // Non-Instruction Patterns | 
|  | 2090 | //===----------------------------------------------------------------------===// | 
|  | 2091 |  | 
|  | 2092 | // bit_convert | 
|  | 2093 | def : Pat<(v1i64 (bitconvert (v2i32 DPR:$src))), (v1i64 DPR:$src)>; | 
|  | 2094 | def : Pat<(v1i64 (bitconvert (v4i16 DPR:$src))), (v1i64 DPR:$src)>; | 
|  | 2095 | def : Pat<(v1i64 (bitconvert (v8i8  DPR:$src))), (v1i64 DPR:$src)>; | 
|  | 2096 | def : Pat<(v1i64 (bitconvert (f64   DPR:$src))), (v1i64 DPR:$src)>; | 
|  | 2097 | def : Pat<(v1i64 (bitconvert (v2f32 DPR:$src))), (v1i64 DPR:$src)>; | 
|  | 2098 | def : Pat<(v2i32 (bitconvert (v1i64 DPR:$src))), (v2i32 DPR:$src)>; | 
|  | 2099 | def : Pat<(v2i32 (bitconvert (v4i16 DPR:$src))), (v2i32 DPR:$src)>; | 
|  | 2100 | def : Pat<(v2i32 (bitconvert (v8i8  DPR:$src))), (v2i32 DPR:$src)>; | 
|  | 2101 | def : Pat<(v2i32 (bitconvert (f64   DPR:$src))), (v2i32 DPR:$src)>; | 
|  | 2102 | def : Pat<(v2i32 (bitconvert (v2f32 DPR:$src))), (v2i32 DPR:$src)>; | 
|  | 2103 | def : Pat<(v4i16 (bitconvert (v1i64 DPR:$src))), (v4i16 DPR:$src)>; | 
|  | 2104 | def : Pat<(v4i16 (bitconvert (v2i32 DPR:$src))), (v4i16 DPR:$src)>; | 
|  | 2105 | def : Pat<(v4i16 (bitconvert (v8i8  DPR:$src))), (v4i16 DPR:$src)>; | 
|  | 2106 | def : Pat<(v4i16 (bitconvert (f64   DPR:$src))), (v4i16 DPR:$src)>; | 
|  | 2107 | def : Pat<(v4i16 (bitconvert (v2f32 DPR:$src))), (v4i16 DPR:$src)>; | 
|  | 2108 | def : Pat<(v8i8  (bitconvert (v1i64 DPR:$src))), (v8i8  DPR:$src)>; | 
|  | 2109 | def : Pat<(v8i8  (bitconvert (v2i32 DPR:$src))), (v8i8  DPR:$src)>; | 
|  | 2110 | def : Pat<(v8i8  (bitconvert (v4i16 DPR:$src))), (v8i8  DPR:$src)>; | 
|  | 2111 | def : Pat<(v8i8  (bitconvert (f64   DPR:$src))), (v8i8  DPR:$src)>; | 
|  | 2112 | def : Pat<(v8i8  (bitconvert (v2f32 DPR:$src))), (v8i8  DPR:$src)>; | 
|  | 2113 | def : Pat<(f64   (bitconvert (v1i64 DPR:$src))), (f64   DPR:$src)>; | 
|  | 2114 | def : Pat<(f64   (bitconvert (v2i32 DPR:$src))), (f64   DPR:$src)>; | 
|  | 2115 | def : Pat<(f64   (bitconvert (v4i16 DPR:$src))), (f64   DPR:$src)>; | 
|  | 2116 | def : Pat<(f64   (bitconvert (v8i8  DPR:$src))), (f64   DPR:$src)>; | 
|  | 2117 | def : Pat<(f64   (bitconvert (v2f32 DPR:$src))), (f64   DPR:$src)>; | 
|  | 2118 | def : Pat<(v2f32 (bitconvert (f64   DPR:$src))), (v2f32 DPR:$src)>; | 
|  | 2119 | def : Pat<(v2f32 (bitconvert (v1i64 DPR:$src))), (v2f32 DPR:$src)>; | 
|  | 2120 | def : Pat<(v2f32 (bitconvert (v2i32 DPR:$src))), (v2f32 DPR:$src)>; | 
|  | 2121 | def : Pat<(v2f32 (bitconvert (v4i16 DPR:$src))), (v2f32 DPR:$src)>; | 
|  | 2122 | def : Pat<(v2f32 (bitconvert (v8i8  DPR:$src))), (v2f32 DPR:$src)>; | 
|  | 2123 |  | 
|  | 2124 | def : Pat<(v2i64 (bitconvert (v4i32 QPR:$src))), (v2i64 QPR:$src)>; | 
|  | 2125 | def : Pat<(v2i64 (bitconvert (v8i16 QPR:$src))), (v2i64 QPR:$src)>; | 
|  | 2126 | def : Pat<(v2i64 (bitconvert (v16i8 QPR:$src))), (v2i64 QPR:$src)>; | 
|  | 2127 | def : Pat<(v2i64 (bitconvert (v2f64 QPR:$src))), (v2i64 QPR:$src)>; | 
|  | 2128 | def : Pat<(v2i64 (bitconvert (v4f32 QPR:$src))), (v2i64 QPR:$src)>; | 
|  | 2129 | def : Pat<(v4i32 (bitconvert (v2i64 QPR:$src))), (v4i32 QPR:$src)>; | 
|  | 2130 | def : Pat<(v4i32 (bitconvert (v8i16 QPR:$src))), (v4i32 QPR:$src)>; | 
|  | 2131 | def : Pat<(v4i32 (bitconvert (v16i8 QPR:$src))), (v4i32 QPR:$src)>; | 
|  | 2132 | def : Pat<(v4i32 (bitconvert (v2f64 QPR:$src))), (v4i32 QPR:$src)>; | 
|  | 2133 | def : Pat<(v4i32 (bitconvert (v4f32 QPR:$src))), (v4i32 QPR:$src)>; | 
|  | 2134 | def : Pat<(v8i16 (bitconvert (v2i64 QPR:$src))), (v8i16 QPR:$src)>; | 
|  | 2135 | def : Pat<(v8i16 (bitconvert (v4i32 QPR:$src))), (v8i16 QPR:$src)>; | 
|  | 2136 | def : Pat<(v8i16 (bitconvert (v16i8 QPR:$src))), (v8i16 QPR:$src)>; | 
|  | 2137 | def : Pat<(v8i16 (bitconvert (v2f64 QPR:$src))), (v8i16 QPR:$src)>; | 
|  | 2138 | def : Pat<(v8i16 (bitconvert (v4f32 QPR:$src))), (v8i16 QPR:$src)>; | 
|  | 2139 | def : Pat<(v16i8 (bitconvert (v2i64 QPR:$src))), (v16i8 QPR:$src)>; | 
|  | 2140 | def : Pat<(v16i8 (bitconvert (v4i32 QPR:$src))), (v16i8 QPR:$src)>; | 
|  | 2141 | def : Pat<(v16i8 (bitconvert (v8i16 QPR:$src))), (v16i8 QPR:$src)>; | 
|  | 2142 | def : Pat<(v16i8 (bitconvert (v2f64 QPR:$src))), (v16i8 QPR:$src)>; | 
|  | 2143 | def : Pat<(v16i8 (bitconvert (v4f32 QPR:$src))), (v16i8 QPR:$src)>; | 
|  | 2144 | def : Pat<(v4f32 (bitconvert (v2i64 QPR:$src))), (v4f32 QPR:$src)>; | 
|  | 2145 | def : Pat<(v4f32 (bitconvert (v4i32 QPR:$src))), (v4f32 QPR:$src)>; | 
|  | 2146 | def : Pat<(v4f32 (bitconvert (v8i16 QPR:$src))), (v4f32 QPR:$src)>; | 
|  | 2147 | def : Pat<(v4f32 (bitconvert (v16i8 QPR:$src))), (v4f32 QPR:$src)>; | 
|  | 2148 | def : Pat<(v4f32 (bitconvert (v2f64 QPR:$src))), (v4f32 QPR:$src)>; | 
|  | 2149 | def : Pat<(v2f64 (bitconvert (v2i64 QPR:$src))), (v2f64 QPR:$src)>; | 
|  | 2150 | def : Pat<(v2f64 (bitconvert (v4i32 QPR:$src))), (v2f64 QPR:$src)>; | 
|  | 2151 | def : Pat<(v2f64 (bitconvert (v8i16 QPR:$src))), (v2f64 QPR:$src)>; | 
|  | 2152 | def : Pat<(v2f64 (bitconvert (v16i8 QPR:$src))), (v2f64 QPR:$src)>; | 
|  | 2153 | def : Pat<(v2f64 (bitconvert (v4f32 QPR:$src))), (v2f64 QPR:$src)>; |