29 //------------------------------VectorNode-------------------------------------- |
29 //------------------------------VectorNode-------------------------------------- |
30 |
30 |
31 // Return the vector operator for the specified scalar operation |
31 // Return the vector operator for the specified scalar operation |
32 // and vector length. Also used to check if the code generator |
32 // and vector length. Also used to check if the code generator |
33 // supports the vector operation. |
33 // supports the vector operation. |
34 int VectorNode::opcode(int sopc, uint vlen, BasicType bt) { |
34 int VectorNode::opcode(int sopc, BasicType bt) { |
35 switch (sopc) { |
35 switch (sopc) { |
36 case Op_AddI: |
36 case Op_AddI: |
37 switch (bt) { |
37 switch (bt) { |
38 case T_BOOLEAN: |
38 case T_BOOLEAN: |
39 case T_BYTE: return Op_AddVB; |
39 case T_BYTE: return Op_AddVB; |
159 |
159 |
160 bool VectorNode::implemented(int opc, uint vlen, BasicType bt) { |
160 bool VectorNode::implemented(int opc, uint vlen, BasicType bt) { |
161 if (is_java_primitive(bt) && |
161 if (is_java_primitive(bt) && |
162 (vlen > 1) && is_power_of_2(vlen) && |
162 (vlen > 1) && is_power_of_2(vlen) && |
163 Matcher::vector_size_supported(bt, vlen)) { |
163 Matcher::vector_size_supported(bt, vlen)) { |
164 int vopc = VectorNode::opcode(opc, vlen, bt); |
164 int vopc = VectorNode::opcode(opc, bt); |
165 return vopc > 0 && Matcher::has_match_rule(vopc); |
165 return vopc > 0 && Matcher::has_match_rule(vopc); |
166 } |
166 } |
167 return false; |
167 return false; |
168 } |
168 } |
169 |
169 |
193 return true; |
193 return true; |
194 } |
194 } |
195 return false; |
195 return false; |
196 } |
196 } |
197 |
197 |
|
198 // [Start, end) half-open range defining which operands are vectors |
|
199 void VectorNode::vector_operands(Node* n, uint* start, uint* end) { |
|
200 switch (n->Opcode()) { |
|
201 case Op_LoadB: case Op_LoadUB: |
|
202 case Op_LoadS: case Op_LoadUS: |
|
203 case Op_LoadI: case Op_LoadL: |
|
204 case Op_LoadF: case Op_LoadD: |
|
205 case Op_LoadP: case Op_LoadN: |
|
206 *start = 0; |
|
207 *end = 0; // no vector operands |
|
208 break; |
|
209 case Op_StoreB: case Op_StoreC: |
|
210 case Op_StoreI: case Op_StoreL: |
|
211 case Op_StoreF: case Op_StoreD: |
|
212 case Op_StoreP: case Op_StoreN: |
|
213 *start = MemNode::ValueIn; |
|
214 *end = MemNode::ValueIn + 1; // 1 vector operand |
|
215 break; |
|
216 case Op_LShiftI: case Op_LShiftL: |
|
217 case Op_RShiftI: case Op_RShiftL: |
|
218 case Op_URShiftI: case Op_URShiftL: |
|
219 *start = 1; |
|
220 *end = 2; // 1 vector operand |
|
221 break; |
|
222 case Op_AddI: case Op_AddL: case Op_AddF: case Op_AddD: |
|
223 case Op_SubI: case Op_SubL: case Op_SubF: case Op_SubD: |
|
224 case Op_MulI: case Op_MulL: case Op_MulF: case Op_MulD: |
|
225 case Op_DivF: case Op_DivD: |
|
226 case Op_AndI: case Op_AndL: |
|
227 case Op_OrI: case Op_OrL: |
|
228 case Op_XorI: case Op_XorL: |
|
229 *start = 1; |
|
230 *end = 3; // 2 vector operands |
|
231 break; |
|
232 case Op_CMoveI: case Op_CMoveL: case Op_CMoveF: case Op_CMoveD: |
|
233 *start = 2; |
|
234 *end = n->req(); |
|
235 break; |
|
236 default: |
|
237 *start = 1; |
|
238 *end = n->req(); // default is all operands |
|
239 } |
|
240 } |
|
241 |
198 // Return the vector version of a scalar operation node. |
242 // Return the vector version of a scalar operation node. |
199 VectorNode* VectorNode::make(Compile* C, int opc, Node* n1, Node* n2, uint vlen, BasicType bt) { |
243 VectorNode* VectorNode::make(Compile* C, int opc, Node* n1, Node* n2, uint vlen, BasicType bt) { |
200 const TypeVect* vt = TypeVect::make(bt, vlen); |
244 const TypeVect* vt = TypeVect::make(bt, vlen); |
201 int vopc = VectorNode::opcode(opc, vlen, bt); |
245 int vopc = VectorNode::opcode(opc, bt); |
202 |
246 |
203 switch (vopc) { |
247 switch (vopc) { |
204 case Op_AddVB: return new (C, 3) AddVBNode(n1, n2, vt); |
248 case Op_AddVB: return new (C, 3) AddVBNode(n1, n2, vt); |
205 case Op_AddVS: return new (C, 3) AddVSNode(n1, n2, vt); |
249 case Op_AddVS: return new (C, 3) AddVSNode(n1, n2, vt); |
206 case Op_AddVI: return new (C, 3) AddVINode(n1, n2, vt); |
250 case Op_AddVI: return new (C, 3) AddVINode(n1, n2, vt); |
276 PackNode* PackNode::make(Compile* C, Node* s, uint vlen, BasicType bt) { |
320 PackNode* PackNode::make(Compile* C, Node* s, uint vlen, BasicType bt) { |
277 const TypeVect* vt = TypeVect::make(bt, vlen); |
321 const TypeVect* vt = TypeVect::make(bt, vlen); |
278 switch (bt) { |
322 switch (bt) { |
279 case T_BOOLEAN: |
323 case T_BOOLEAN: |
280 case T_BYTE: |
324 case T_BYTE: |
281 return new (C, vlen+1) PackBNode(s, vt); |
325 return new (C, 2) PackBNode(s, vt); |
282 case T_CHAR: |
326 case T_CHAR: |
283 case T_SHORT: |
327 case T_SHORT: |
284 return new (C, vlen+1) PackSNode(s, vt); |
328 return new (C, 2) PackSNode(s, vt); |
285 case T_INT: |
329 case T_INT: |
286 return new (C, vlen+1) PackINode(s, vt); |
330 return new (C, 2) PackINode(s, vt); |
287 case T_LONG: |
331 case T_LONG: |
288 return new (C, vlen+1) PackLNode(s, vt); |
332 return new (C, 2) PackLNode(s, vt); |
289 case T_FLOAT: |
333 case T_FLOAT: |
290 return new (C, vlen+1) PackFNode(s, vt); |
334 return new (C, 2) PackFNode(s, vt); |
291 case T_DOUBLE: |
335 case T_DOUBLE: |
292 return new (C, vlen+1) PackDNode(s, vt); |
336 return new (C, 2) PackDNode(s, vt); |
293 } |
337 } |
294 ShouldNotReachHere(); |
338 ShouldNotReachHere(); |
295 return NULL; |
339 return NULL; |
296 } |
340 } |
297 |
341 |
298 // Create a binary tree form for Packs. [lo, hi) (half-open) range |
342 // Create a binary tree form for Packs. [lo, hi) (half-open) range |
299 Node* PackNode::binaryTreePack(Compile* C, int lo, int hi) { |
343 PackNode* PackNode::binary_tree_pack(Compile* C, int lo, int hi) { |
300 int ct = hi - lo; |
344 int ct = hi - lo; |
301 assert(is_power_of_2(ct), "power of 2"); |
345 assert(is_power_of_2(ct), "power of 2"); |
302 if (ct == 2) { |
346 if (ct == 2) { |
303 PackNode* pk = PackNode::make(C, in(lo), 2, vect_type()->element_basic_type()); |
347 PackNode* pk = PackNode::make(C, in(lo), 2, vect_type()->element_basic_type()); |
304 pk->add_opd(1, in(lo+1)); |
348 pk->add_opd(in(lo+1)); |
305 return pk; |
349 return pk; |
306 |
350 |
307 } else { |
351 } else { |
308 int mid = lo + ct/2; |
352 int mid = lo + ct/2; |
309 Node* n1 = binaryTreePack(C, lo, mid); |
353 PackNode* n1 = binary_tree_pack(C, lo, mid); |
310 Node* n2 = binaryTreePack(C, mid, hi ); |
354 PackNode* n2 = binary_tree_pack(C, mid, hi ); |
311 |
355 |
312 BasicType bt = vect_type()->element_basic_type(); |
356 BasicType bt = n1->vect_type()->element_basic_type(); |
|
357 assert(bt == n2->vect_type()->element_basic_type(), "should be the same"); |
313 switch (bt) { |
358 switch (bt) { |
314 case T_BOOLEAN: |
359 case T_BOOLEAN: |
315 case T_BYTE: |
360 case T_BYTE: |
316 return new (C, 3) PackSNode(n1, n2, TypeVect::make(T_SHORT, 2)); |
361 return new (C, 3) PackSNode(n1, n2, TypeVect::make(T_SHORT, 2)); |
317 case T_CHAR: |
362 case T_CHAR: |