1/*
2 * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24#ifndef SHARE_OPTO_VECTORNODE_HPP
25#define SHARE_OPTO_VECTORNODE_HPP
26
27#include "opto/matcher.hpp"
28#include "opto/memnode.hpp"
29#include "opto/node.hpp"
30#include "opto/opcodes.hpp"
31
32//------------------------------VectorNode-------------------------------------
33// Vector Operation
34class VectorNode : public TypeNode {
35 public:
36
37 VectorNode(Node* n1, const TypeVect* vt) : TypeNode(vt, 2) {
38 init_class_id(Class_Vector);
39 init_req(1, n1);
40 }
41 VectorNode(Node* n1, Node* n2, const TypeVect* vt) : TypeNode(vt, 3) {
42 init_class_id(Class_Vector);
43 init_req(1, n1);
44 init_req(2, n2);
45 }
46
47 VectorNode(Node* n1, Node* n2, Node* n3, const TypeVect* vt) : TypeNode(vt, 4) {
48 init_class_id(Class_Vector);
49 init_req(1, n1);
50 init_req(2, n2);
51 init_req(3, n3);
52 }
53
54 const TypeVect* vect_type() const { return type()->is_vect(); }
55 uint length() const { return vect_type()->length(); } // Vector length
56 uint length_in_bytes() const { return vect_type()->length_in_bytes(); }
57
58 virtual int Opcode() const;
59
60 virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(vect_type()->length_in_bytes()); }
61
62 static VectorNode* scalar2vector(Node* s, uint vlen, const Type* opd_t);
63 static VectorNode* shift_count(Node* shift, Node* cnt, uint vlen, BasicType bt);
64 static VectorNode* make(int opc, Node* n1, Node* n2, uint vlen, BasicType bt);
65 static VectorNode* make(int opc, Node* n1, Node* n2, Node* n3, uint vlen, BasicType bt);
66
67 static int opcode(int opc, BasicType bt);
68 static bool implemented(int opc, uint vlen, BasicType bt);
69 static bool is_shift(Node* n);
70 static bool is_type_transition_short_to_int(Node* n);
71 static bool is_type_transition_to_int(Node* n);
72 static bool is_muladds2i(Node* n);
73 static bool is_invariant_vector(Node* n);
74 // [Start, end) half-open range defining which operands are vectors
75 static void vector_operands(Node* n, uint* start, uint* end);
76};
77
78//===========================Vector=ALU=Operations=============================
79
80//------------------------------AddVBNode--------------------------------------
81// Vector add byte
82class AddVBNode : public VectorNode {
83 public:
84 AddVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
85 virtual int Opcode() const;
86};
87
88//------------------------------AddVSNode--------------------------------------
89// Vector add char/short
90class AddVSNode : public VectorNode {
91 public:
92 AddVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
93 virtual int Opcode() const;
94};
95
96//------------------------------AddVINode--------------------------------------
97// Vector add int
98class AddVINode : public VectorNode {
99 public:
100 AddVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
101 virtual int Opcode() const;
102};
103
104//------------------------------AddVLNode--------------------------------------
105// Vector add long
106class AddVLNode : public VectorNode {
107public:
108 AddVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
109 virtual int Opcode() const;
110};
111
112//------------------------------AddVFNode--------------------------------------
113// Vector add float
114class AddVFNode : public VectorNode {
115public:
116 AddVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
117 virtual int Opcode() const;
118};
119
120//------------------------------AddVDNode--------------------------------------
121// Vector add double
122class AddVDNode : public VectorNode {
123public:
124 AddVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
125 virtual int Opcode() const;
126};
127
128//------------------------------ReductionNode------------------------------------
129// Perform reduction of a vector
130class ReductionNode : public Node {
131 public:
132 ReductionNode(Node *ctrl, Node* in1, Node* in2) : Node(ctrl, in1, in2) {}
133
134 static ReductionNode* make(int opc, Node *ctrl, Node* in1, Node* in2, BasicType bt);
135 static int opcode(int opc, BasicType bt);
136 static bool implemented(int opc, uint vlen, BasicType bt);
137};
138
139//------------------------------AddReductionVINode--------------------------------------
140// Vector add int as a reduction
141class AddReductionVINode : public ReductionNode {
142public:
143 AddReductionVINode(Node * ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
144 virtual int Opcode() const;
145 virtual const Type* bottom_type() const { return TypeInt::INT; }
146 virtual uint ideal_reg() const { return Op_RegI; }
147};
148
149//------------------------------AddReductionVLNode--------------------------------------
150// Vector add long as a reduction
151class AddReductionVLNode : public ReductionNode {
152public:
153 AddReductionVLNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
154 virtual int Opcode() const;
155 virtual const Type* bottom_type() const { return TypeLong::LONG; }
156 virtual uint ideal_reg() const { return Op_RegL; }
157};
158
159//------------------------------AddReductionVFNode--------------------------------------
160// Vector add float as a reduction
161class AddReductionVFNode : public ReductionNode {
162public:
163 AddReductionVFNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
164 virtual int Opcode() const;
165 virtual const Type* bottom_type() const { return Type::FLOAT; }
166 virtual uint ideal_reg() const { return Op_RegF; }
167};
168
169//------------------------------AddReductionVDNode--------------------------------------
170// Vector add double as a reduction
171class AddReductionVDNode : public ReductionNode {
172public:
173 AddReductionVDNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
174 virtual int Opcode() const;
175 virtual const Type* bottom_type() const { return Type::DOUBLE; }
176 virtual uint ideal_reg() const { return Op_RegD; }
177};
178
179//------------------------------SubVBNode--------------------------------------
180// Vector subtract byte
181class SubVBNode : public VectorNode {
182 public:
183 SubVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
184 virtual int Opcode() const;
185};
186
187//------------------------------SubVSNode--------------------------------------
188// Vector subtract short
189class SubVSNode : public VectorNode {
190 public:
191 SubVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
192 virtual int Opcode() const;
193};
194
195//------------------------------SubVINode--------------------------------------
196// Vector subtract int
197class SubVINode : public VectorNode {
198 public:
199 SubVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
200 virtual int Opcode() const;
201};
202
203//------------------------------SubVLNode--------------------------------------
204// Vector subtract long
205class SubVLNode : public VectorNode {
206 public:
207 SubVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
208 virtual int Opcode() const;
209};
210
211//------------------------------SubVFNode--------------------------------------
212// Vector subtract float
213class SubVFNode : public VectorNode {
214 public:
215 SubVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
216 virtual int Opcode() const;
217};
218
219//------------------------------SubVDNode--------------------------------------
220// Vector subtract double
221class SubVDNode : public VectorNode {
222 public:
223 SubVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
224 virtual int Opcode() const;
225};
226
227//------------------------------MulVBNode--------------------------------------
228// Vector multiply byte
229class MulVBNode : public VectorNode {
230 public:
231 MulVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
232 virtual int Opcode() const;
233};
234
235//------------------------------MulVSNode--------------------------------------
236// Vector multiply short
237class MulVSNode : public VectorNode {
238 public:
239 MulVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
240 virtual int Opcode() const;
241};
242
243//------------------------------MulVINode--------------------------------------
244// Vector multiply int
245class MulVINode : public VectorNode {
246 public:
247 MulVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
248 virtual int Opcode() const;
249};
250
251//------------------------------MulVLNode--------------------------------------
252// Vector multiply long
253class MulVLNode : public VectorNode {
254public:
255 MulVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
256 virtual int Opcode() const;
257};
258
259//------------------------------MulVFNode--------------------------------------
260// Vector multiply float
261class MulVFNode : public VectorNode {
262public:
263 MulVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
264 virtual int Opcode() const;
265};
266
267//------------------------------MulVDNode--------------------------------------
268// Vector multiply double
269class MulVDNode : public VectorNode {
270public:
271 MulVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
272 virtual int Opcode() const;
273};
274
275//------------------------------MulAddVS2VINode--------------------------------
276// Vector multiply shorts to int and add adjacent ints.
277class MulAddVS2VINode : public VectorNode {
278 public:
279 MulAddVS2VINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
280 virtual int Opcode() const;
281};
282
283//------------------------------FmaVDNode--------------------------------------
284// Vector multiply double
285class FmaVDNode : public VectorNode {
286public:
287 FmaVDNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {}
288 virtual int Opcode() const;
289};
290
291//------------------------------FmaVFNode--------------------------------------
292// Vector multiply float
293class FmaVFNode : public VectorNode {
294public:
295 FmaVFNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {}
296 virtual int Opcode() const;
297};
298
299//------------------------------CMoveVFNode--------------------------------------
300// Vector float conditional move
301class CMoveVFNode : public VectorNode {
302public:
303 CMoveVFNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {}
304 virtual int Opcode() const;
305};
306
307//------------------------------CMoveVDNode--------------------------------------
308// Vector double conditional move
309class CMoveVDNode : public VectorNode {
310public:
311 CMoveVDNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {}
312 virtual int Opcode() const;
313};
314
315//------------------------------MulReductionVINode--------------------------------------
316// Vector multiply int as a reduction
317class MulReductionVINode : public ReductionNode {
318public:
319 MulReductionVINode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
320 virtual int Opcode() const;
321 virtual const Type* bottom_type() const { return TypeInt::INT; }
322 virtual uint ideal_reg() const { return Op_RegI; }
323};
324
325//------------------------------MulReductionVLNode--------------------------------------
326// Vector multiply int as a reduction
327class MulReductionVLNode : public ReductionNode {
328public:
329 MulReductionVLNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
330 virtual int Opcode() const;
331 virtual const Type* bottom_type() const { return TypeLong::LONG; }
332 virtual uint ideal_reg() const { return Op_RegI; }
333};
334
335//------------------------------MulReductionVFNode--------------------------------------
336// Vector multiply float as a reduction
337class MulReductionVFNode : public ReductionNode {
338public:
339 MulReductionVFNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
340 virtual int Opcode() const;
341 virtual const Type* bottom_type() const { return Type::FLOAT; }
342 virtual uint ideal_reg() const { return Op_RegF; }
343};
344
345//------------------------------MulReductionVDNode--------------------------------------
346// Vector multiply double as a reduction
347class MulReductionVDNode : public ReductionNode {
348public:
349 MulReductionVDNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
350 virtual int Opcode() const;
351 virtual const Type* bottom_type() const { return Type::DOUBLE; }
352 virtual uint ideal_reg() const { return Op_RegD; }
353};
354
355//------------------------------DivVFNode--------------------------------------
356// Vector divide float
357class DivVFNode : public VectorNode {
358 public:
359 DivVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
360 virtual int Opcode() const;
361};
362
363//------------------------------DivVDNode--------------------------------------
364// Vector Divide double
365class DivVDNode : public VectorNode {
366 public:
367 DivVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
368 virtual int Opcode() const;
369};
370
371//------------------------------AbsVBNode--------------------------------------
372// Vector Abs byte
373class AbsVBNode : public VectorNode {
374public:
375 AbsVBNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
376 virtual int Opcode() const;
377};
378
379//------------------------------AbsVSNode--------------------------------------
380// Vector Abs short
381class AbsVSNode : public VectorNode {
382public:
383 AbsVSNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
384 virtual int Opcode() const;
385};
386
387//------------------------------AbsVINode--------------------------------------
388// Vector Abs int
389class AbsVINode : public VectorNode {
390public:
391 AbsVINode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
392 virtual int Opcode() const;
393};
394
395//------------------------------AbsVLNode--------------------------------------
396// Vector Abs long
397class AbsVLNode : public VectorNode {
398public:
399 AbsVLNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
400 virtual int Opcode() const;
401};
402
403//------------------------------AbsVFNode--------------------------------------
404// Vector Abs float
405class AbsVFNode : public VectorNode {
406 public:
407 AbsVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
408 virtual int Opcode() const;
409};
410
411//------------------------------AbsVDNode--------------------------------------
412// Vector Abs double
413class AbsVDNode : public VectorNode {
414 public:
415 AbsVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
416 virtual int Opcode() const;
417};
418
419//------------------------------NegVFNode--------------------------------------
420// Vector Neg float
421class NegVFNode : public VectorNode {
422 public:
423 NegVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
424 virtual int Opcode() const;
425};
426
427//------------------------------NegVDNode--------------------------------------
428// Vector Neg double
429class NegVDNode : public VectorNode {
430 public:
431 NegVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
432 virtual int Opcode() const;
433};
434
435//------------------------------PopCountVINode---------------------------------
436// Vector popcount integer bits
437class PopCountVINode : public VectorNode {
438 public:
439 PopCountVINode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
440 virtual int Opcode() const;
441};
442
443//------------------------------SqrtVFNode--------------------------------------
444// Vector Sqrt float
445class SqrtVFNode : public VectorNode {
446 public:
447 SqrtVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
448 virtual int Opcode() const;
449};
450
451//------------------------------SqrtVDNode--------------------------------------
452// Vector Sqrt double
453class SqrtVDNode : public VectorNode {
454 public:
455 SqrtVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
456 virtual int Opcode() const;
457};
458
459//------------------------------LShiftVBNode-----------------------------------
460// Vector left shift bytes
461class LShiftVBNode : public VectorNode {
462 public:
463 LShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
464 virtual int Opcode() const;
465};
466
467//------------------------------LShiftVSNode-----------------------------------
468// Vector left shift shorts
469class LShiftVSNode : public VectorNode {
470 public:
471 LShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
472 virtual int Opcode() const;
473};
474
475//------------------------------LShiftVINode-----------------------------------
476// Vector left shift ints
477class LShiftVINode : public VectorNode {
478 public:
479 LShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
480 virtual int Opcode() const;
481};
482
483//------------------------------LShiftVLNode-----------------------------------
484// Vector left shift longs
485class LShiftVLNode : public VectorNode {
486 public:
487 LShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
488 virtual int Opcode() const;
489};
490
491//------------------------------RShiftVBNode-----------------------------------
492// Vector right arithmetic (signed) shift bytes
493class RShiftVBNode : public VectorNode {
494 public:
495 RShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
496 virtual int Opcode() const;
497};
498
499//------------------------------RShiftVSNode-----------------------------------
500// Vector right arithmetic (signed) shift shorts
501class RShiftVSNode : public VectorNode {
502 public:
503 RShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
504 virtual int Opcode() const;
505};
506
507//------------------------------RShiftVINode-----------------------------------
508// Vector right arithmetic (signed) shift ints
509class RShiftVINode : public VectorNode {
510 public:
511 RShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
512 virtual int Opcode() const;
513};
514
515//------------------------------RShiftVLNode-----------------------------------
516// Vector right arithmetic (signed) shift longs
517class RShiftVLNode : public VectorNode {
518 public:
519 RShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
520 virtual int Opcode() const;
521};
522
523//------------------------------URShiftVBNode----------------------------------
524// Vector right logical (unsigned) shift bytes
525class URShiftVBNode : public VectorNode {
526 public:
527 URShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
528 virtual int Opcode() const;
529};
530
531//------------------------------URShiftVSNode----------------------------------
532// Vector right logical (unsigned) shift shorts
533class URShiftVSNode : public VectorNode {
534 public:
535 URShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
536 virtual int Opcode() const;
537};
538
539//------------------------------URShiftVINode----------------------------------
540// Vector right logical (unsigned) shift ints
541class URShiftVINode : public VectorNode {
542 public:
543 URShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
544 virtual int Opcode() const;
545};
546
547//------------------------------URShiftVLNode----------------------------------
548// Vector right logical (unsigned) shift longs
549class URShiftVLNode : public VectorNode {
550 public:
551 URShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
552 virtual int Opcode() const;
553};
554
555//------------------------------LShiftCntVNode---------------------------------
556// Vector left shift count
557class LShiftCntVNode : public VectorNode {
558 public:
559 LShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {}
560 virtual int Opcode() const;
561 virtual uint ideal_reg() const { return Matcher::vector_shift_count_ideal_reg(vect_type()->length_in_bytes()); }
562};
563
564//------------------------------RShiftCntVNode---------------------------------
565// Vector right shift count
566class RShiftCntVNode : public VectorNode {
567 public:
568 RShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {}
569 virtual int Opcode() const;
570 virtual uint ideal_reg() const { return Matcher::vector_shift_count_ideal_reg(vect_type()->length_in_bytes()); }
571};
572
573
574//------------------------------AndVNode---------------------------------------
575// Vector and integer
576class AndVNode : public VectorNode {
577 public:
578 AndVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
579 virtual int Opcode() const;
580};
581
582//------------------------------OrVNode---------------------------------------
583// Vector or integer
584class OrVNode : public VectorNode {
585 public:
586 OrVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
587 virtual int Opcode() const;
588};
589
590//------------------------------XorVNode---------------------------------------
591// Vector xor integer
592class XorVNode : public VectorNode {
593 public:
594 XorVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
595 virtual int Opcode() const;
596};
597
598//------------------------------MinVNode--------------------------------------
599// Vector min
600class MinVNode : public VectorNode {
601public:
602 MinVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
603 virtual int Opcode() const;
604};
605
606//------------------------------MaxVNode--------------------------------------
607// Vector max
608class MaxVNode : public VectorNode {
609public:
610 MaxVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
611 virtual int Opcode() const;
612};
613
614//------------------------------MinReductionVNode--------------------------------------
615// Vector min as a reduction
616class MinReductionVNode : public ReductionNode {
617public:
618 MinReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
619 virtual int Opcode() const;
620 virtual const Type* bottom_type() const {
621 BasicType bt = in(1)->bottom_type()->basic_type();
622 if (bt == T_FLOAT) {
623 return Type::FLOAT;
624 } else if (bt == T_DOUBLE) {
625 return Type::DOUBLE;
626 }
627 assert(false, "unsupported basic type");
628 return NULL;
629 }
630 virtual uint ideal_reg() const {
631 BasicType bt = in(1)->bottom_type()->basic_type();
632 if (bt == T_FLOAT) {
633 return Op_RegF;
634 } else if (bt == T_DOUBLE) {
635 return Op_RegD;
636 }
637 assert(false, "unsupported basic type");
638 return 0;
639 }
640};
641
642//------------------------------MaxReductionVNode--------------------------------------
643// Vector max as a reduction
644class MaxReductionVNode : public ReductionNode {
645public:
646 MaxReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
647 virtual int Opcode() const;
648 virtual const Type* bottom_type() const {
649 BasicType bt = in(1)->bottom_type()->basic_type();
650 if (bt == T_FLOAT) {
651 return Type::FLOAT;
652 } else {
653 return Type::DOUBLE;
654 }
655 assert(false, "unsupported basic type");
656 return NULL;
657 }
658 virtual uint ideal_reg() const {
659 BasicType bt = in(1)->bottom_type()->basic_type();
660 if (bt == T_FLOAT) {
661 return Op_RegF;
662 } else {
663 return Op_RegD;
664 }
665 assert(false, "unsupported basic type");
666 return 0;
667 }
668};
669
670//================================= M E M O R Y ===============================
671
672//------------------------------LoadVectorNode---------------------------------
673// Load Vector from memory
674class LoadVectorNode : public LoadNode {
675 public:
676 LoadVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeVect* vt, ControlDependency control_dependency = LoadNode::DependsOnlyOnTest)
677 : LoadNode(c, mem, adr, at, vt, MemNode::unordered, control_dependency) {
678 init_class_id(Class_LoadVector);
679 set_mismatched_access();
680 }
681
682 const TypeVect* vect_type() const { return type()->is_vect(); }
683 uint length() const { return vect_type()->length(); } // Vector length
684
685 virtual int Opcode() const;
686
687 virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(memory_size()); }
688 virtual BasicType memory_type() const { return T_VOID; }
689 virtual int memory_size() const { return vect_type()->length_in_bytes(); }
690
691 virtual int store_Opcode() const { return Op_StoreVector; }
692
693 static LoadVectorNode* make(int opc, Node* ctl, Node* mem,
694 Node* adr, const TypePtr* atyp,
695 uint vlen, BasicType bt,
696 ControlDependency control_dependency = LoadNode::DependsOnlyOnTest);
697 uint element_size(void) { return type2aelembytes(vect_type()->element_basic_type()); }
698};
699
700//------------------------------StoreVectorNode--------------------------------
701// Store Vector to memory
702class StoreVectorNode : public StoreNode {
703 public:
704 StoreVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val)
705 : StoreNode(c, mem, adr, at, val, MemNode::unordered) {
706 assert(val->is_Vector() || val->is_LoadVector(), "sanity");
707 init_class_id(Class_StoreVector);
708 set_mismatched_access();
709 }
710
711 const TypeVect* vect_type() const { return in(MemNode::ValueIn)->bottom_type()->is_vect(); }
712 uint length() const { return vect_type()->length(); } // Vector length
713
714 virtual int Opcode() const;
715
716 virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(memory_size()); }
717 virtual BasicType memory_type() const { return T_VOID; }
718 virtual int memory_size() const { return vect_type()->length_in_bytes(); }
719
720 static StoreVectorNode* make(int opc, Node* ctl, Node* mem,
721 Node* adr, const TypePtr* atyp, Node* val,
722 uint vlen);
723
724 uint element_size(void) { return type2aelembytes(vect_type()->element_basic_type()); }
725};
726
727
728//=========================Promote_Scalar_to_Vector============================
729
730//------------------------------ReplicateBNode---------------------------------
731// Replicate byte scalar to be vector
732class ReplicateBNode : public VectorNode {
733 public:
734 ReplicateBNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
735 virtual int Opcode() const;
736};
737
738//------------------------------ReplicateSNode---------------------------------
739// Replicate short scalar to be vector
740class ReplicateSNode : public VectorNode {
741 public:
742 ReplicateSNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
743 virtual int Opcode() const;
744};
745
746//------------------------------ReplicateINode---------------------------------
747// Replicate int scalar to be vector
748class ReplicateINode : public VectorNode {
749 public:
750 ReplicateINode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
751 virtual int Opcode() const;
752};
753
754//------------------------------ReplicateLNode---------------------------------
755// Replicate long scalar to be vector
756class ReplicateLNode : public VectorNode {
757 public:
758 ReplicateLNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
759 virtual int Opcode() const;
760};
761
762//------------------------------ReplicateFNode---------------------------------
763// Replicate float scalar to be vector
764class ReplicateFNode : public VectorNode {
765 public:
766 ReplicateFNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
767 virtual int Opcode() const;
768};
769
770//------------------------------ReplicateDNode---------------------------------
771// Replicate double scalar to be vector
772class ReplicateDNode : public VectorNode {
773 public:
774 ReplicateDNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
775 virtual int Opcode() const;
776};
777
778//========================Pack_Scalars_into_a_Vector===========================
779
780//------------------------------PackNode---------------------------------------
781// Pack parent class (not for code generation).
782class PackNode : public VectorNode {
783 public:
784 PackNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
785 PackNode(Node* in1, Node* n2, const TypeVect* vt) : VectorNode(in1, n2, vt) {}
786 virtual int Opcode() const;
787
788 void add_opd(Node* n) {
789 add_req(n);
790 }
791
792 // Create a binary tree form for Packs. [lo, hi) (half-open) range
793 PackNode* binary_tree_pack(int lo, int hi);
794
795 static PackNode* make(Node* s, uint vlen, BasicType bt);
796};
797
798//------------------------------PackBNode--------------------------------------
799// Pack byte scalars into vector
800class PackBNode : public PackNode {
801 public:
802 PackBNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {}
803 virtual int Opcode() const;
804};
805
806//------------------------------PackSNode--------------------------------------
807// Pack short scalars into a vector
808class PackSNode : public PackNode {
809 public:
810 PackSNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {}
811 PackSNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
812 virtual int Opcode() const;
813};
814
815//------------------------------PackINode--------------------------------------
816// Pack integer scalars into a vector
817class PackINode : public PackNode {
818 public:
819 PackINode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {}
820 PackINode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
821 virtual int Opcode() const;
822};
823
824//------------------------------PackLNode--------------------------------------
825// Pack long scalars into a vector
826class PackLNode : public PackNode {
827 public:
828 PackLNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {}
829 PackLNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
830 virtual int Opcode() const;
831};
832
833//------------------------------Pack2LNode-------------------------------------
834// Pack 2 long scalars into a vector
835class Pack2LNode : public PackNode {
836 public:
837 Pack2LNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
838 virtual int Opcode() const;
839};
840
841//------------------------------PackFNode--------------------------------------
842// Pack float scalars into vector
843class PackFNode : public PackNode {
844 public:
845 PackFNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {}
846 PackFNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
847 virtual int Opcode() const;
848};
849
850//------------------------------PackDNode--------------------------------------
851// Pack double scalars into a vector
852class PackDNode : public PackNode {
853 public:
854 PackDNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {}
855 PackDNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
856 virtual int Opcode() const;
857};
858
859//------------------------------Pack2DNode-------------------------------------
860// Pack 2 double scalars into a vector
861class Pack2DNode : public PackNode {
862 public:
863 Pack2DNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
864 virtual int Opcode() const;
865};
866
867
868//========================Extract_Scalar_from_Vector===========================
869
870//------------------------------ExtractNode------------------------------------
871// Extract a scalar from a vector at position "pos"
872class ExtractNode : public Node {
873 public:
874 ExtractNode(Node* src, ConINode* pos) : Node(NULL, src, (Node*)pos) {
875 assert(in(2)->get_int() >= 0, "positive constants");
876 }
877 virtual int Opcode() const;
878 uint pos() const { return in(2)->get_int(); }
879
880 static Node* make(Node* v, uint position, BasicType bt);
881};
882
883//------------------------------ExtractBNode-----------------------------------
884// Extract a byte from a vector at position "pos"
885class ExtractBNode : public ExtractNode {
886 public:
887 ExtractBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
888 virtual int Opcode() const;
889 virtual const Type *bottom_type() const { return TypeInt::INT; }
890 virtual uint ideal_reg() const { return Op_RegI; }
891};
892
893//------------------------------ExtractUBNode----------------------------------
894// Extract a boolean from a vector at position "pos"
895class ExtractUBNode : public ExtractNode {
896 public:
897 ExtractUBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
898 virtual int Opcode() const;
899 virtual const Type *bottom_type() const { return TypeInt::INT; }
900 virtual uint ideal_reg() const { return Op_RegI; }
901};
902
903//------------------------------ExtractCNode-----------------------------------
904// Extract a char from a vector at position "pos"
905class ExtractCNode : public ExtractNode {
906 public:
907 ExtractCNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
908 virtual int Opcode() const;
909 virtual const Type *bottom_type() const { return TypeInt::INT; }
910 virtual uint ideal_reg() const { return Op_RegI; }
911};
912
913//------------------------------ExtractSNode-----------------------------------
914// Extract a short from a vector at position "pos"
915class ExtractSNode : public ExtractNode {
916 public:
917 ExtractSNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
918 virtual int Opcode() const;
919 virtual const Type *bottom_type() const { return TypeInt::INT; }
920 virtual uint ideal_reg() const { return Op_RegI; }
921};
922
923//------------------------------ExtractINode-----------------------------------
924// Extract an int from a vector at position "pos"
925class ExtractINode : public ExtractNode {
926 public:
927 ExtractINode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
928 virtual int Opcode() const;
929 virtual const Type *bottom_type() const { return TypeInt::INT; }
930 virtual uint ideal_reg() const { return Op_RegI; }
931};
932
933//------------------------------ExtractLNode-----------------------------------
934// Extract a long from a vector at position "pos"
935class ExtractLNode : public ExtractNode {
936 public:
937 ExtractLNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
938 virtual int Opcode() const;
939 virtual const Type *bottom_type() const { return TypeLong::LONG; }
940 virtual uint ideal_reg() const { return Op_RegL; }
941};
942
943//------------------------------ExtractFNode-----------------------------------
944// Extract a float from a vector at position "pos"
945class ExtractFNode : public ExtractNode {
946 public:
947 ExtractFNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
948 virtual int Opcode() const;
949 virtual const Type *bottom_type() const { return Type::FLOAT; }
950 virtual uint ideal_reg() const { return Op_RegF; }
951};
952
953//------------------------------ExtractDNode-----------------------------------
954// Extract a double from a vector at position "pos"
955class ExtractDNode : public ExtractNode {
956 public:
957 ExtractDNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
958 virtual int Opcode() const;
959 virtual const Type *bottom_type() const { return Type::DOUBLE; }
960 virtual uint ideal_reg() const { return Op_RegD; }
961};
962
963//------------------------------SetVectMaskINode-------------------------------
964// Provide a mask for a vector predicate machine
965class SetVectMaskINode : public Node {
966public:
967 SetVectMaskINode(Node *c, Node *in1) : Node(c, in1) {}
968 virtual int Opcode() const;
969 const Type *bottom_type() const { return TypeInt::INT; }
970 virtual uint ideal_reg() const { return Op_RegI; }
971 virtual const Type *Value(PhaseGVN *phase) const { return TypeInt::INT; }
972};
973
974#endif // SHARE_OPTO_VECTORNODE_HPP
975