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 |
34 | class 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 |
82 | class 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 |
90 | class 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 |
98 | class 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 |
106 | class AddVLNode : public VectorNode { |
107 | public: |
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 |
114 | class AddVFNode : public VectorNode { |
115 | public: |
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 |
122 | class AddVDNode : public VectorNode { |
123 | public: |
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 |
130 | class 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 |
141 | class AddReductionVINode : public ReductionNode { |
142 | public: |
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 |
151 | class AddReductionVLNode : public ReductionNode { |
152 | public: |
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 |
161 | class AddReductionVFNode : public ReductionNode { |
162 | public: |
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 |
171 | class AddReductionVDNode : public ReductionNode { |
172 | public: |
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 |
181 | class 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 |
189 | class 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 |
197 | class 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 |
205 | class 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 |
213 | class 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 |
221 | class 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 |
229 | class 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 |
237 | class 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 |
245 | class 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 |
253 | class MulVLNode : public VectorNode { |
254 | public: |
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 |
261 | class MulVFNode : public VectorNode { |
262 | public: |
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 |
269 | class MulVDNode : public VectorNode { |
270 | public: |
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. |
277 | class 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 |
285 | class FmaVDNode : public VectorNode { |
286 | public: |
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 |
293 | class FmaVFNode : public VectorNode { |
294 | public: |
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 |
301 | class CMoveVFNode : public VectorNode { |
302 | public: |
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 |
309 | class CMoveVDNode : public VectorNode { |
310 | public: |
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 |
317 | class MulReductionVINode : public ReductionNode { |
318 | public: |
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 |
327 | class MulReductionVLNode : public ReductionNode { |
328 | public: |
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 |
337 | class MulReductionVFNode : public ReductionNode { |
338 | public: |
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 |
347 | class MulReductionVDNode : public ReductionNode { |
348 | public: |
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 |
357 | class 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 |
365 | class 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 |
373 | class AbsVBNode : public VectorNode { |
374 | public: |
375 | AbsVBNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} |
376 | virtual int Opcode() const; |
377 | }; |
378 | |
379 | //------------------------------AbsVSNode-------------------------------------- |
380 | // Vector Abs short |
381 | class AbsVSNode : public VectorNode { |
382 | public: |
383 | AbsVSNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} |
384 | virtual int Opcode() const; |
385 | }; |
386 | |
387 | //------------------------------AbsVINode-------------------------------------- |
388 | // Vector Abs int |
389 | class AbsVINode : public VectorNode { |
390 | public: |
391 | AbsVINode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} |
392 | virtual int Opcode() const; |
393 | }; |
394 | |
395 | //------------------------------AbsVLNode-------------------------------------- |
396 | // Vector Abs long |
397 | class AbsVLNode : public VectorNode { |
398 | public: |
399 | AbsVLNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} |
400 | virtual int Opcode() const; |
401 | }; |
402 | |
403 | //------------------------------AbsVFNode-------------------------------------- |
404 | // Vector Abs float |
405 | class 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 |
413 | class 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 |
421 | class 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 |
429 | class 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 |
437 | class 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 |
445 | class 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 |
453 | class 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 |
461 | class 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 |
469 | class 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 |
477 | class 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 |
485 | class 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 |
493 | class 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 |
501 | class 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 |
509 | class 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 |
517 | class 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 |
525 | class 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 |
533 | class 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 |
541 | class 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 |
549 | class 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 |
557 | class 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 |
566 | class 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 |
576 | class 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 |
584 | class 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 |
592 | class 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 |
600 | class MinVNode : public VectorNode { |
601 | public: |
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 |
608 | class MaxVNode : public VectorNode { |
609 | public: |
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 |
616 | class MinReductionVNode : public ReductionNode { |
617 | public: |
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 |
644 | class MaxReductionVNode : public ReductionNode { |
645 | public: |
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 |
674 | class 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 |
702 | class 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 |
732 | class 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 |
740 | class 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 |
748 | class 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 |
756 | class 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 |
764 | class 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 |
772 | class 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). |
782 | class 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 |
800 | class 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 |
808 | class 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 |
817 | class 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 |
826 | class 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 |
835 | class 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 |
843 | class 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 |
852 | class 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 |
861 | class 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" |
872 | class : public Node { |
873 | public: |
874 | (Node* src, ConINode* pos) : Node(NULL, src, (Node*)pos) { |
875 | assert(in(2)->get_int() >= 0, "positive constants" ); |
876 | } |
877 | virtual int () const; |
878 | uint () const { return in(2)->get_int(); } |
879 | |
880 | static Node* (Node* v, uint position, BasicType bt); |
881 | }; |
882 | |
883 | //------------------------------ExtractBNode----------------------------------- |
884 | // Extract a byte from a vector at position "pos" |
885 | class : public ExtractNode { |
886 | public: |
887 | (Node* src, ConINode* pos) : ExtractNode(src, pos) {} |
888 | virtual int () const; |
889 | virtual const Type *() const { return TypeInt::INT; } |
890 | virtual uint () const { return Op_RegI; } |
891 | }; |
892 | |
893 | //------------------------------ExtractUBNode---------------------------------- |
894 | // Extract a boolean from a vector at position "pos" |
895 | class : public ExtractNode { |
896 | public: |
897 | (Node* src, ConINode* pos) : ExtractNode(src, pos) {} |
898 | virtual int () const; |
899 | virtual const Type *() const { return TypeInt::INT; } |
900 | virtual uint () const { return Op_RegI; } |
901 | }; |
902 | |
903 | //------------------------------ExtractCNode----------------------------------- |
904 | // Extract a char from a vector at position "pos" |
905 | class : public ExtractNode { |
906 | public: |
907 | (Node* src, ConINode* pos) : ExtractNode(src, pos) {} |
908 | virtual int () const; |
909 | virtual const Type *() const { return TypeInt::INT; } |
910 | virtual uint () const { return Op_RegI; } |
911 | }; |
912 | |
913 | //------------------------------ExtractSNode----------------------------------- |
914 | // Extract a short from a vector at position "pos" |
915 | class : public ExtractNode { |
916 | public: |
917 | (Node* src, ConINode* pos) : ExtractNode(src, pos) {} |
918 | virtual int () const; |
919 | virtual const Type *() const { return TypeInt::INT; } |
920 | virtual uint () const { return Op_RegI; } |
921 | }; |
922 | |
923 | //------------------------------ExtractINode----------------------------------- |
924 | // Extract an int from a vector at position "pos" |
925 | class : public ExtractNode { |
926 | public: |
927 | (Node* src, ConINode* pos) : ExtractNode(src, pos) {} |
928 | virtual int () const; |
929 | virtual const Type *() const { return TypeInt::INT; } |
930 | virtual uint () const { return Op_RegI; } |
931 | }; |
932 | |
933 | //------------------------------ExtractLNode----------------------------------- |
934 | // Extract a long from a vector at position "pos" |
935 | class : public ExtractNode { |
936 | public: |
937 | (Node* src, ConINode* pos) : ExtractNode(src, pos) {} |
938 | virtual int () const; |
939 | virtual const Type *() const { return TypeLong::LONG; } |
940 | virtual uint () const { return Op_RegL; } |
941 | }; |
942 | |
943 | //------------------------------ExtractFNode----------------------------------- |
944 | // Extract a float from a vector at position "pos" |
945 | class : public ExtractNode { |
946 | public: |
947 | (Node* src, ConINode* pos) : ExtractNode(src, pos) {} |
948 | virtual int () const; |
949 | virtual const Type *() const { return Type::FLOAT; } |
950 | virtual uint () const { return Op_RegF; } |
951 | }; |
952 | |
953 | //------------------------------ExtractDNode----------------------------------- |
954 | // Extract a double from a vector at position "pos" |
955 | class : public ExtractNode { |
956 | public: |
957 | (Node* src, ConINode* pos) : ExtractNode(src, pos) {} |
958 | virtual int () const; |
959 | virtual const Type *() const { return Type::DOUBLE; } |
960 | virtual uint () const { return Op_RegD; } |
961 | }; |
962 | |
963 | //------------------------------SetVectMaskINode------------------------------- |
964 | // Provide a mask for a vector predicate machine |
965 | class SetVectMaskINode : public Node { |
966 | public: |
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 | |