Fri, 15 Jun 2012 01:25:19 -0700
7119644: Increase superword's vector size up to 256 bits
Summary: Increase vector size up to 256-bits for YMM AVX registers on x86.
Reviewed-by: never, twisti, roland
1 /*
2 * Copyright (c) 2007, 2012, 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 */
24 #ifndef SHARE_VM_OPTO_VECTORNODE_HPP
25 #define SHARE_VM_OPTO_VECTORNODE_HPP
27 #include "opto/matcher.hpp"
28 #include "opto/memnode.hpp"
29 #include "opto/node.hpp"
30 #include "opto/opcodes.hpp"
32 //------------------------------VectorNode--------------------------------------
33 // Vector Operation
34 class VectorNode : public TypeNode {
35 public:
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 }
47 const TypeVect* vect_type() const { return type()->is_vect(); }
48 uint length() const { return vect_type()->length(); } // Vector length
50 virtual int Opcode() const;
52 virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(vect_type()->length_in_bytes()); }
54 static VectorNode* scalar2vector(Compile* C, Node* s, uint vlen, const Type* opd_t);
56 static VectorNode* make(Compile* C, int opc, Node* n1, Node* n2, uint vlen, BasicType bt);
58 static int opcode(int opc, uint vlen, BasicType bt);
59 static bool implemented(int opc, uint vlen, BasicType bt);
61 };
63 //===========================Vector=ALU=Operations====================================
65 //------------------------------AddVBNode---------------------------------------
66 // Vector add byte
67 class AddVBNode : public VectorNode {
68 public:
69 AddVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
70 virtual int Opcode() const;
71 };
73 //------------------------------AddVSNode---------------------------------------
74 // Vector add char/short
75 class AddVSNode : public VectorNode {
76 public:
77 AddVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
78 virtual int Opcode() const;
79 };
81 //------------------------------AddVINode---------------------------------------
82 // Vector add int
83 class AddVINode : public VectorNode {
84 public:
85 AddVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
86 virtual int Opcode() const;
87 };
89 //------------------------------AddVLNode---------------------------------------
90 // Vector add long
91 class AddVLNode : public VectorNode {
92 public:
93 AddVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
94 virtual int Opcode() const;
95 };
97 //------------------------------AddVFNode---------------------------------------
98 // Vector add float
99 class AddVFNode : public VectorNode {
100 public:
101 AddVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
102 virtual int Opcode() const;
103 };
105 //------------------------------AddVDNode---------------------------------------
106 // Vector add double
107 class AddVDNode : public VectorNode {
108 public:
109 AddVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
110 virtual int Opcode() const;
111 };
113 //------------------------------SubVBNode---------------------------------------
114 // Vector subtract byte
115 class SubVBNode : public VectorNode {
116 public:
117 SubVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
118 virtual int Opcode() const;
119 };
121 //------------------------------SubVSNode---------------------------------------
122 // Vector subtract short
123 class SubVSNode : public VectorNode {
124 public:
125 SubVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
126 virtual int Opcode() const;
127 };
129 //------------------------------SubVINode---------------------------------------
130 // Vector subtract int
131 class SubVINode : public VectorNode {
132 public:
133 SubVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
134 virtual int Opcode() const;
135 };
137 //------------------------------SubVLNode---------------------------------------
138 // Vector subtract long
139 class SubVLNode : public VectorNode {
140 public:
141 SubVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
142 virtual int Opcode() const;
143 };
145 //------------------------------SubVFNode---------------------------------------
146 // Vector subtract float
147 class SubVFNode : public VectorNode {
148 public:
149 SubVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
150 virtual int Opcode() const;
151 };
153 //------------------------------SubVDNode---------------------------------------
154 // Vector subtract double
155 class SubVDNode : public VectorNode {
156 public:
157 SubVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
158 virtual int Opcode() const;
159 };
161 //------------------------------MulVFNode---------------------------------------
162 // Vector multiply float
163 class MulVFNode : public VectorNode {
164 public:
165 MulVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
166 virtual int Opcode() const;
167 };
169 //------------------------------MulVDNode---------------------------------------
170 // Vector multiply double
171 class MulVDNode : public VectorNode {
172 public:
173 MulVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
174 virtual int Opcode() const;
175 };
177 //------------------------------DivVFNode---------------------------------------
178 // Vector divide float
179 class DivVFNode : public VectorNode {
180 public:
181 DivVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
182 virtual int Opcode() const;
183 };
185 //------------------------------DivVDNode---------------------------------------
186 // Vector Divide double
187 class DivVDNode : public VectorNode {
188 public:
189 DivVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
190 virtual int Opcode() const;
191 };
193 //------------------------------LShiftVBNode---------------------------------------
194 // Vector lshift byte
195 class LShiftVBNode : public VectorNode {
196 public:
197 LShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
198 virtual int Opcode() const;
199 };
201 //------------------------------LShiftVSNode---------------------------------------
202 // Vector lshift shorts
203 class LShiftVSNode : public VectorNode {
204 public:
205 LShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
206 virtual int Opcode() const;
207 };
209 //------------------------------LShiftVINode---------------------------------------
210 // Vector lshift ints
211 class LShiftVINode : public VectorNode {
212 public:
213 LShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
214 virtual int Opcode() const;
215 };
217 //------------------------------URShiftVBNode---------------------------------------
218 // Vector urshift bytes
219 class RShiftVBNode : public VectorNode {
220 public:
221 RShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
222 virtual int Opcode() const;
223 };
225 //------------------------------URShiftVSNode---------------------------------------
226 // Vector urshift shorts
227 class RShiftVSNode : public VectorNode {
228 public:
229 RShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
230 virtual int Opcode() const;
231 };
233 //------------------------------URShiftVINode---------------------------------------
234 // Vector urshift ints
235 class RShiftVINode : public VectorNode {
236 public:
237 RShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
238 virtual int Opcode() const;
239 };
241 //------------------------------AndVNode---------------------------------------
242 // Vector and
243 class AndVNode : public VectorNode {
244 public:
245 AndVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
246 virtual int Opcode() const;
247 };
249 //------------------------------OrVNode---------------------------------------
250 // Vector or
251 class OrVNode : public VectorNode {
252 public:
253 OrVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
254 virtual int Opcode() const;
255 };
257 //------------------------------XorVNode---------------------------------------
258 // Vector xor
259 class XorVNode : public VectorNode {
260 public:
261 XorVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
262 virtual int Opcode() const;
263 };
265 //================================= M E M O R Y ===============================
267 //------------------------------LoadVectorNode---------------------------------
268 // Load Vector from memory
269 class LoadVectorNode : public LoadNode {
270 public:
271 LoadVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeVect* vt)
272 : LoadNode(c, mem, adr, at, vt) {
273 init_class_id(Class_LoadVector);
274 }
276 const TypeVect* vect_type() const { return type()->is_vect(); }
277 uint length() const { return vect_type()->length(); } // Vector length
279 virtual int Opcode() const;
281 virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(memory_size()); }
282 virtual BasicType memory_type() const { return T_VOID; }
283 virtual int memory_size() const { return vect_type()->length_in_bytes(); }
285 virtual int store_Opcode() const { return Op_StoreVector; }
287 static LoadVectorNode* make(Compile* C, int opc, Node* ctl, Node* mem,
288 Node* adr, const TypePtr* atyp, uint vlen, BasicType bt);
289 };
291 //------------------------------StoreVectorNode--------------------------------
292 // Store Vector to memory
293 class StoreVectorNode : public StoreNode {
294 public:
295 StoreVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val)
296 : StoreNode(c, mem, adr, at, val) {
297 assert(val->is_Vector() || val->is_LoadVector(), "sanity");
298 init_class_id(Class_StoreVector);
299 }
301 const TypeVect* vect_type() const { return in(MemNode::ValueIn)->bottom_type()->is_vect(); }
302 uint length() const { return vect_type()->length(); } // Vector length
304 virtual int Opcode() const;
306 virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(memory_size()); }
307 virtual BasicType memory_type() const { return T_VOID; }
308 virtual int memory_size() const { return vect_type()->length_in_bytes(); }
310 static StoreVectorNode* make(Compile* C, int opc, Node* ctl, Node* mem,
311 Node* adr, const TypePtr* atyp, Node* val,
312 uint vlen);
313 };
316 //=========================Promote_Scalar_to_Vector============================
318 //------------------------------ReplicateBNode---------------------------------
319 // Replicate byte scalar to be vector
320 class ReplicateBNode : public VectorNode {
321 public:
322 ReplicateBNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
323 virtual int Opcode() const;
324 };
326 //------------------------------ReplicateSNode---------------------------------
327 // Replicate short scalar to be vector
328 class ReplicateSNode : public VectorNode {
329 public:
330 ReplicateSNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
331 virtual int Opcode() const;
332 };
334 //------------------------------ReplicateINode---------------------------------
335 // Replicate int scalar to be vector
336 class ReplicateINode : public VectorNode {
337 public:
338 ReplicateINode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
339 virtual int Opcode() const;
340 };
342 //------------------------------ReplicateLNode---------------------------------
343 // Replicate long scalar to be vector
344 class ReplicateLNode : public VectorNode {
345 public:
346 ReplicateLNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
347 virtual int Opcode() const;
348 };
350 //------------------------------ReplicateFNode---------------------------------
351 // Replicate float scalar to be vector
352 class ReplicateFNode : public VectorNode {
353 public:
354 ReplicateFNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
355 virtual int Opcode() const;
356 };
358 //------------------------------ReplicateDNode---------------------------------
359 // Replicate double scalar to be vector
360 class ReplicateDNode : public VectorNode {
361 public:
362 ReplicateDNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
363 virtual int Opcode() const;
364 };
366 //========================Pack_Scalars_into_a_Vector===========================
368 //------------------------------PackNode---------------------------------------
369 // Pack parent class (not for code generation).
370 class PackNode : public VectorNode {
371 public:
372 PackNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
373 PackNode(Node* in1, Node* n2, const TypeVect* vt) : VectorNode(in1, n2, vt) {}
374 virtual int Opcode() const;
376 void add_opd(uint i, Node* n) {
377 init_req(i+1, n);
378 }
380 // Create a binary tree form for Packs. [lo, hi) (half-open) range
381 Node* binaryTreePack(Compile* C, int lo, int hi);
383 static PackNode* make(Compile* C, Node* s, uint vlen, BasicType bt);
384 };
386 //------------------------------PackBNode---------------------------------------
387 // Pack byte scalars into vector
388 class PackBNode : public PackNode {
389 public:
390 PackBNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {}
391 virtual int Opcode() const;
392 };
394 //------------------------------PackSNode---------------------------------------
395 // Pack short scalars into a vector
396 class PackSNode : public PackNode {
397 public:
398 PackSNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {}
399 PackSNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
400 virtual int Opcode() const;
401 };
403 //------------------------------PackINode---------------------------------------
404 // Pack integer scalars into a vector
405 class PackINode : public PackNode {
406 public:
407 PackINode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {}
408 PackINode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
409 virtual int Opcode() const;
410 };
412 //------------------------------PackLNode---------------------------------------
413 // Pack long scalars into a vector
414 class PackLNode : public PackNode {
415 public:
416 PackLNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {}
417 PackLNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
418 virtual int Opcode() const;
419 };
421 //------------------------------Pack2LNode--------------------------------------
422 // Pack 2 long scalars into a vector
423 class Pack2LNode : public PackNode {
424 public:
425 Pack2LNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
426 virtual int Opcode() const;
427 };
429 //------------------------------PackFNode---------------------------------------
430 // Pack float scalars into vector
431 class PackFNode : public PackNode {
432 public:
433 PackFNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {}
434 PackFNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
435 virtual int Opcode() const;
436 };
438 //------------------------------PackDNode---------------------------------------
439 // Pack double scalars into a vector
440 class PackDNode : public PackNode {
441 public:
442 PackDNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {}
443 PackDNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
444 virtual int Opcode() const;
445 };
447 //------------------------------Pack2DNode--------------------------------------
448 // Pack 2 double scalars into a vector
449 class Pack2DNode : public PackNode {
450 public:
451 Pack2DNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
452 virtual int Opcode() const;
453 };
456 //========================Extract_Scalar_from_Vector===============================
458 //------------------------------ExtractNode---------------------------------------
459 // Extract a scalar from a vector at position "pos"
460 class ExtractNode : public Node {
461 public:
462 ExtractNode(Node* src, ConINode* pos) : Node(NULL, src, (Node*)pos) {
463 assert(in(2)->get_int() >= 0, "positive constants");
464 }
465 virtual int Opcode() const;
466 uint pos() const { return in(2)->get_int(); }
468 static Node* make(Compile* C, Node* v, uint position, BasicType bt);
469 };
471 //------------------------------ExtractBNode---------------------------------------
472 // Extract a byte from a vector at position "pos"
473 class ExtractBNode : public ExtractNode {
474 public:
475 ExtractBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
476 virtual int Opcode() const;
477 virtual const Type *bottom_type() const { return TypeInt::INT; }
478 virtual uint ideal_reg() const { return Op_RegI; }
479 };
481 //------------------------------ExtractUBNode--------------------------------------
482 // Extract a boolean from a vector at position "pos"
483 class ExtractUBNode : public ExtractNode {
484 public:
485 ExtractUBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
486 virtual int Opcode() const;
487 virtual const Type *bottom_type() const { return TypeInt::INT; }
488 virtual uint ideal_reg() const { return Op_RegI; }
489 };
491 //------------------------------ExtractCNode---------------------------------------
492 // Extract a char from a vector at position "pos"
493 class ExtractCNode : public ExtractNode {
494 public:
495 ExtractCNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
496 virtual int Opcode() const;
497 virtual const Type *bottom_type() const { return TypeInt::INT; }
498 virtual uint ideal_reg() const { return Op_RegI; }
499 };
501 //------------------------------ExtractSNode---------------------------------------
502 // Extract a short from a vector at position "pos"
503 class ExtractSNode : public ExtractNode {
504 public:
505 ExtractSNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
506 virtual int Opcode() const;
507 virtual const Type *bottom_type() const { return TypeInt::INT; }
508 virtual uint ideal_reg() const { return Op_RegI; }
509 };
511 //------------------------------ExtractINode---------------------------------------
512 // Extract an int from a vector at position "pos"
513 class ExtractINode : public ExtractNode {
514 public:
515 ExtractINode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
516 virtual int Opcode() const;
517 virtual const Type *bottom_type() const { return TypeInt::INT; }
518 virtual uint ideal_reg() const { return Op_RegI; }
519 };
521 //------------------------------ExtractLNode---------------------------------------
522 // Extract a long from a vector at position "pos"
523 class ExtractLNode : public ExtractNode {
524 public:
525 ExtractLNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
526 virtual int Opcode() const;
527 virtual const Type *bottom_type() const { return TypeLong::LONG; }
528 virtual uint ideal_reg() const { return Op_RegL; }
529 };
531 //------------------------------ExtractFNode---------------------------------------
532 // Extract a float from a vector at position "pos"
533 class ExtractFNode : public ExtractNode {
534 public:
535 ExtractFNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
536 virtual int Opcode() const;
537 virtual const Type *bottom_type() const { return Type::FLOAT; }
538 virtual uint ideal_reg() const { return Op_RegF; }
539 };
541 //------------------------------ExtractDNode---------------------------------------
542 // Extract a double from a vector at position "pos"
543 class ExtractDNode : public ExtractNode {
544 public:
545 ExtractDNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
546 virtual int Opcode() const;
547 virtual const Type *bottom_type() const { return Type::DOUBLE; }
548 virtual uint ideal_reg() const { return Op_RegD; }
549 };
551 #endif // SHARE_VM_OPTO_VECTORNODE_HPP