1 /* |
1 /* |
2 * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
37 case T_BOOLEAN: |
37 case T_BOOLEAN: |
38 case T_BYTE: return Op_AddVB; |
38 case T_BYTE: return Op_AddVB; |
39 case T_CHAR: |
39 case T_CHAR: |
40 case T_SHORT: return Op_AddVS; |
40 case T_SHORT: return Op_AddVS; |
41 case T_INT: return Op_AddVI; |
41 case T_INT: return Op_AddVI; |
42 } |
42 default: ShouldNotReachHere(); return 0; |
43 ShouldNotReachHere(); |
43 } |
44 case Op_AddL: |
44 case Op_AddL: |
45 assert(bt == T_LONG, "must be"); |
45 assert(bt == T_LONG, "must be"); |
46 return Op_AddVL; |
46 return Op_AddVL; |
47 case Op_AddF: |
47 case Op_AddF: |
48 assert(bt == T_FLOAT, "must be"); |
48 assert(bt == T_FLOAT, "must be"); |
55 case T_BOOLEAN: |
55 case T_BOOLEAN: |
56 case T_BYTE: return Op_SubVB; |
56 case T_BYTE: return Op_SubVB; |
57 case T_CHAR: |
57 case T_CHAR: |
58 case T_SHORT: return Op_SubVS; |
58 case T_SHORT: return Op_SubVS; |
59 case T_INT: return Op_SubVI; |
59 case T_INT: return Op_SubVI; |
60 } |
60 default: ShouldNotReachHere(); return 0; |
61 ShouldNotReachHere(); |
61 } |
62 case Op_SubL: |
62 case Op_SubL: |
63 assert(bt == T_LONG, "must be"); |
63 assert(bt == T_LONG, "must be"); |
64 return Op_SubVL; |
64 return Op_SubVL; |
65 case Op_SubF: |
65 case Op_SubF: |
66 assert(bt == T_FLOAT, "must be"); |
66 assert(bt == T_FLOAT, "must be"); |
73 case T_BOOLEAN: |
73 case T_BOOLEAN: |
74 case T_BYTE: return 0; // Unimplemented |
74 case T_BYTE: return 0; // Unimplemented |
75 case T_CHAR: |
75 case T_CHAR: |
76 case T_SHORT: return Op_MulVS; |
76 case T_SHORT: return Op_MulVS; |
77 case T_INT: return Op_MulVI; |
77 case T_INT: return Op_MulVI; |
78 } |
78 default: ShouldNotReachHere(); return 0; |
79 ShouldNotReachHere(); |
79 } |
80 case Op_MulL: |
80 case Op_MulL: |
81 assert(bt == T_LONG, "must be"); |
81 assert(bt == T_LONG, "must be"); |
82 return Op_MulVL; |
82 return Op_MulVL; |
83 case Op_MulF: |
83 case Op_MulF: |
84 assert(bt == T_FLOAT, "must be"); |
84 assert(bt == T_FLOAT, "must be"); |
121 case T_BOOLEAN: |
121 case T_BOOLEAN: |
122 case T_BYTE: return Op_LShiftVB; |
122 case T_BYTE: return Op_LShiftVB; |
123 case T_CHAR: |
123 case T_CHAR: |
124 case T_SHORT: return Op_LShiftVS; |
124 case T_SHORT: return Op_LShiftVS; |
125 case T_INT: return Op_LShiftVI; |
125 case T_INT: return Op_LShiftVI; |
126 } |
126 default: ShouldNotReachHere(); return 0; |
127 ShouldNotReachHere(); |
127 } |
128 case Op_LShiftL: |
128 case Op_LShiftL: |
129 assert(bt == T_LONG, "must be"); |
129 assert(bt == T_LONG, "must be"); |
130 return Op_LShiftVL; |
130 return Op_LShiftVL; |
131 case Op_RShiftI: |
131 case Op_RShiftI: |
132 switch (bt) { |
132 switch (bt) { |
133 case T_BOOLEAN:return Op_URShiftVB; // boolean is unsigned value |
133 case T_BOOLEAN:return Op_URShiftVB; // boolean is unsigned value |
134 case T_CHAR: return Op_URShiftVS; // char is unsigned value |
134 case T_CHAR: return Op_URShiftVS; // char is unsigned value |
135 case T_BYTE: return Op_RShiftVB; |
135 case T_BYTE: return Op_RShiftVB; |
136 case T_SHORT: return Op_RShiftVS; |
136 case T_SHORT: return Op_RShiftVS; |
137 case T_INT: return Op_RShiftVI; |
137 case T_INT: return Op_RShiftVI; |
138 } |
138 default: ShouldNotReachHere(); return 0; |
139 ShouldNotReachHere(); |
139 } |
140 case Op_RShiftL: |
140 case Op_RShiftL: |
141 assert(bt == T_LONG, "must be"); |
141 assert(bt == T_LONG, "must be"); |
142 return Op_RShiftVL; |
142 return Op_RShiftVL; |
143 case Op_URShiftI: |
143 case Op_URShiftI: |
144 switch (bt) { |
144 switch (bt) { |
149 // values produces incorrect Java result for |
149 // values produces incorrect Java result for |
150 // negative data because java code should convert |
150 // negative data because java code should convert |
151 // a short value into int value with sign |
151 // a short value into int value with sign |
152 // extension before a shift. |
152 // extension before a shift. |
153 case T_INT: return Op_URShiftVI; |
153 case T_INT: return Op_URShiftVI; |
154 } |
154 default: ShouldNotReachHere(); return 0; |
155 ShouldNotReachHere(); |
155 } |
156 case Op_URShiftL: |
156 case Op_URShiftL: |
157 assert(bt == T_LONG, "must be"); |
157 assert(bt == T_LONG, "must be"); |
158 return Op_URShiftVL; |
158 return Op_URShiftVL; |
159 case Op_AndI: |
159 case Op_AndI: |
160 case Op_AndL: |
160 case Op_AndL: |
181 case Op_StoreI: |
181 case Op_StoreI: |
182 case Op_StoreL: |
182 case Op_StoreL: |
183 case Op_StoreF: |
183 case Op_StoreF: |
184 case Op_StoreD: |
184 case Op_StoreD: |
185 return Op_StoreVector; |
185 return Op_StoreVector; |
186 } |
186 |
187 return 0; // Unimplemented |
187 default: |
|
188 return 0; // Unimplemented |
|
189 } |
188 } |
190 } |
189 |
191 |
190 // Also used to check if the code generator |
192 // Also used to check if the code generator |
191 // supports the vector operation. |
193 // supports the vector operation. |
192 bool VectorNode::implemented(int opc, uint vlen, BasicType bt) { |
194 bool VectorNode::implemented(int opc, uint vlen, BasicType bt) { |
331 case Op_URShiftVL: return new URShiftVLNode(n1, n2, vt); |
335 case Op_URShiftVL: return new URShiftVLNode(n1, n2, vt); |
332 |
336 |
333 case Op_AndV: return new AndVNode(n1, n2, vt); |
337 case Op_AndV: return new AndVNode(n1, n2, vt); |
334 case Op_OrV: return new OrVNode (n1, n2, vt); |
338 case Op_OrV: return new OrVNode (n1, n2, vt); |
335 case Op_XorV: return new XorVNode(n1, n2, vt); |
339 case Op_XorV: return new XorVNode(n1, n2, vt); |
336 } |
340 default: |
337 fatal("Missed vector creation for '%s'", NodeClassNames[vopc]); |
341 fatal("Missed vector creation for '%s'", NodeClassNames[vopc]); |
338 return NULL; |
342 return NULL; |
339 |
343 } |
340 } |
344 } |
341 |
345 |
342 VectorNode* VectorNode::make(int opc, Node* n1, Node* n2, Node* n3, uint vlen, BasicType bt) { |
346 VectorNode* VectorNode::make(int opc, Node* n1, Node* n2, Node* n3, uint vlen, BasicType bt) { |
343 const TypeVect* vt = TypeVect::make(bt, vlen); |
347 const TypeVect* vt = TypeVect::make(bt, vlen); |
344 int vopc = VectorNode::opcode(opc, bt); |
348 int vopc = VectorNode::opcode(opc, bt); |
345 // This method should not be called for unimplemented vectors. |
349 // This method should not be called for unimplemented vectors. |
346 guarantee(vopc > 0, "Vector for '%s' is not implemented", NodeClassNames[opc]); |
350 guarantee(vopc > 0, "Vector for '%s' is not implemented", NodeClassNames[opc]); |
347 switch (vopc) { |
351 switch (vopc) { |
348 case Op_FmaVD: return new FmaVDNode(n1, n2, n3, vt); |
352 case Op_FmaVD: return new FmaVDNode(n1, n2, n3, vt); |
349 case Op_FmaVF: return new FmaVFNode(n1, n2, n3, vt); |
353 case Op_FmaVF: return new FmaVFNode(n1, n2, n3, vt); |
350 } |
354 default: |
351 fatal("Missed vector creation for '%s'", NodeClassNames[vopc]); |
355 fatal("Missed vector creation for '%s'", NodeClassNames[vopc]); |
352 return NULL; |
356 return NULL; |
|
357 } |
353 } |
358 } |
354 |
359 |
355 // Scalar promotion |
360 // Scalar promotion |
356 VectorNode* VectorNode::scalar2vector(Node* s, uint vlen, const Type* opd_t) { |
361 VectorNode* VectorNode::scalar2vector(Node* s, uint vlen, const Type* opd_t) { |
357 BasicType bt = opd_t->array_element_basic_type(); |
362 BasicType bt = opd_t->array_element_basic_type(); |
370 return new ReplicateLNode(s, vt); |
375 return new ReplicateLNode(s, vt); |
371 case T_FLOAT: |
376 case T_FLOAT: |
372 return new ReplicateFNode(s, vt); |
377 return new ReplicateFNode(s, vt); |
373 case T_DOUBLE: |
378 case T_DOUBLE: |
374 return new ReplicateDNode(s, vt); |
379 return new ReplicateDNode(s, vt); |
375 } |
380 default: |
376 fatal("Type '%s' is not supported for vectors", type2name(bt)); |
381 fatal("Type '%s' is not supported for vectors", type2name(bt)); |
377 return NULL; |
382 return NULL; |
|
383 } |
378 } |
384 } |
379 |
385 |
380 VectorNode* VectorNode::shift_count(Node* shift, Node* cnt, uint vlen, BasicType bt) { |
386 VectorNode* VectorNode::shift_count(Node* shift, Node* cnt, uint vlen, BasicType bt) { |
381 assert(VectorNode::is_shift(shift) && !cnt->is_Con(), "only variable shift count"); |
387 assert(VectorNode::is_shift(shift) && !cnt->is_Con(), "only variable shift count"); |
382 // Match shift count type with shift vector type. |
388 // Match shift count type with shift vector type. |
388 case Op_RShiftI: |
394 case Op_RShiftI: |
389 case Op_RShiftL: |
395 case Op_RShiftL: |
390 case Op_URShiftI: |
396 case Op_URShiftI: |
391 case Op_URShiftL: |
397 case Op_URShiftL: |
392 return new RShiftCntVNode(cnt, vt); |
398 return new RShiftCntVNode(cnt, vt); |
393 } |
399 default: |
394 fatal("Missed vector creation for '%s'", NodeClassNames[shift->Opcode()]); |
400 fatal("Missed vector creation for '%s'", NodeClassNames[shift->Opcode()]); |
395 return NULL; |
401 return NULL; |
|
402 } |
396 } |
403 } |
397 |
404 |
398 // Return initial Pack node. Additional operands added with add_opd() calls. |
405 // Return initial Pack node. Additional operands added with add_opd() calls. |
399 PackNode* PackNode::make(Node* s, uint vlen, BasicType bt) { |
406 PackNode* PackNode::make(Node* s, uint vlen, BasicType bt) { |
400 const TypeVect* vt = TypeVect::make(bt, vlen); |
407 const TypeVect* vt = TypeVect::make(bt, vlen); |
411 return new PackLNode(s, vt); |
418 return new PackLNode(s, vt); |
412 case T_FLOAT: |
419 case T_FLOAT: |
413 return new PackFNode(s, vt); |
420 return new PackFNode(s, vt); |
414 case T_DOUBLE: |
421 case T_DOUBLE: |
415 return new PackDNode(s, vt); |
422 return new PackDNode(s, vt); |
416 } |
423 default: |
417 fatal("Type '%s' is not supported for vectors", type2name(bt)); |
424 fatal("Type '%s' is not supported for vectors", type2name(bt)); |
418 return NULL; |
425 return NULL; |
|
426 } |
419 } |
427 } |
420 |
428 |
421 // Create a binary tree form for Packs. [lo, hi) (half-open) range |
429 // Create a binary tree form for Packs. [lo, hi) (half-open) range |
422 PackNode* PackNode::binary_tree_pack(int lo, int hi) { |
430 PackNode* PackNode::binary_tree_pack(int lo, int hi) { |
423 int ct = hi - lo; |
431 int ct = hi - lo; |
424 assert(is_power_of_2(ct), "power of 2"); |
432 assert(is_power_of_2(ct), "power of 2"); |
425 if (ct == 2) { |
433 if (ct == 2) { |
426 PackNode* pk = PackNode::make(in(lo), 2, vect_type()->element_basic_type()); |
434 PackNode* pk = PackNode::make(in(lo), 2, vect_type()->element_basic_type()); |
427 pk->add_opd(in(lo+1)); |
435 pk->add_opd(in(lo+1)); |
428 return pk; |
436 return pk; |
429 |
|
430 } else { |
437 } else { |
431 int mid = lo + ct/2; |
438 int mid = lo + ct/2; |
432 PackNode* n1 = binary_tree_pack(lo, mid); |
439 PackNode* n1 = binary_tree_pack(lo, mid); |
433 PackNode* n2 = binary_tree_pack(mid, hi ); |
440 PackNode* n2 = binary_tree_pack(mid, hi ); |
434 |
441 |
447 return new Pack2LNode(n1, n2, TypeVect::make(T_LONG, 2)); |
454 return new Pack2LNode(n1, n2, TypeVect::make(T_LONG, 2)); |
448 case T_FLOAT: |
455 case T_FLOAT: |
449 return new PackDNode(n1, n2, TypeVect::make(T_DOUBLE, 2)); |
456 return new PackDNode(n1, n2, TypeVect::make(T_DOUBLE, 2)); |
450 case T_DOUBLE: |
457 case T_DOUBLE: |
451 return new Pack2DNode(n1, n2, TypeVect::make(T_DOUBLE, 2)); |
458 return new Pack2DNode(n1, n2, TypeVect::make(T_DOUBLE, 2)); |
452 } |
459 default: |
453 fatal("Type '%s' is not supported for vectors", type2name(bt)); |
460 fatal("Type '%s' is not supported for vectors", type2name(bt)); |
454 } |
461 return NULL; |
455 return NULL; |
462 } |
|
463 } |
456 } |
464 } |
457 |
465 |
458 // Return the vector version of a scalar load node. |
466 // Return the vector version of a scalar load node. |
459 LoadVectorNode* LoadVectorNode::make(int opc, Node* ctl, Node* mem, |
467 LoadVectorNode* LoadVectorNode::make(int opc, Node* ctl, Node* mem, |
460 Node* adr, const TypePtr* atyp, |
468 Node* adr, const TypePtr* atyp, |
490 return new ExtractLNode(v, pos); |
498 return new ExtractLNode(v, pos); |
491 case T_FLOAT: |
499 case T_FLOAT: |
492 return new ExtractFNode(v, pos); |
500 return new ExtractFNode(v, pos); |
493 case T_DOUBLE: |
501 case T_DOUBLE: |
494 return new ExtractDNode(v, pos); |
502 return new ExtractDNode(v, pos); |
495 } |
503 default: |
496 fatal("Type '%s' is not supported for vectors", type2name(bt)); |
504 fatal("Type '%s' is not supported for vectors", type2name(bt)); |
497 return NULL; |
505 return NULL; |
|
506 } |
498 } |
507 } |
499 |
508 |
500 int ReductionNode::opcode(int opc, BasicType bt) { |
509 int ReductionNode::opcode(int opc, BasicType bt) { |
501 int vopc = opc; |
510 int vopc = opc; |
502 switch (opc) { |
511 switch (opc) { |
554 case Op_AddReductionVD: return new AddReductionVDNode(ctrl, n1, n2); |
563 case Op_AddReductionVD: return new AddReductionVDNode(ctrl, n1, n2); |
555 case Op_MulReductionVI: return new MulReductionVINode(ctrl, n1, n2); |
564 case Op_MulReductionVI: return new MulReductionVINode(ctrl, n1, n2); |
556 case Op_MulReductionVL: return new MulReductionVLNode(ctrl, n1, n2); |
565 case Op_MulReductionVL: return new MulReductionVLNode(ctrl, n1, n2); |
557 case Op_MulReductionVF: return new MulReductionVFNode(ctrl, n1, n2); |
566 case Op_MulReductionVF: return new MulReductionVFNode(ctrl, n1, n2); |
558 case Op_MulReductionVD: return new MulReductionVDNode(ctrl, n1, n2); |
567 case Op_MulReductionVD: return new MulReductionVDNode(ctrl, n1, n2); |
559 } |
568 default: |
560 fatal("Missed vector creation for '%s'", NodeClassNames[vopc]); |
569 fatal("Missed vector creation for '%s'", NodeClassNames[vopc]); |
561 return NULL; |
570 return NULL; |
|
571 } |
562 } |
572 } |
563 |
573 |
564 bool ReductionNode::implemented(int opc, uint vlen, BasicType bt) { |
574 bool ReductionNode::implemented(int opc, uint vlen, BasicType bt) { |
565 if (is_java_primitive(bt) && |
575 if (is_java_primitive(bt) && |
566 (vlen > 1) && is_power_of_2(vlen) && |
576 (vlen > 1) && is_power_of_2(vlen) && |