vectornode.hpp revision 3447:8c92982cbbc4
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 */
23
24#ifndef SHARE_VM_OPTO_VECTORNODE_HPP
25#define SHARE_VM_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  const TypeVect* vect_type() const { return type()->is_vect(); }
48  uint length() const { return vect_type()->length(); } // Vector length
49
50  virtual int Opcode() const;
51
52  virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(vect_type()->length_in_bytes()); }
53
54  static VectorNode* scalar2vector(Compile* C, Node* s, uint vlen, const Type* opd_t);
55
56  static VectorNode* make(Compile* C, int opc, Node* n1, Node* n2, uint vlen, BasicType bt);
57
58  static int  opcode(int opc, uint vlen, BasicType bt);
59  static bool implemented(int opc, uint vlen, BasicType bt);
60
61};
62
63//===========================Vector=ALU=Operations====================================
64
65//------------------------------AddVBNode---------------------------------------
66// Vector add byte
67class AddVBNode : public VectorNode {
68 public:
69  AddVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
70  virtual int Opcode() const;
71};
72
73//------------------------------AddVSNode---------------------------------------
74// Vector add char/short
75class AddVSNode : public VectorNode {
76 public:
77  AddVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
78  virtual int Opcode() const;
79};
80
81//------------------------------AddVINode---------------------------------------
82// Vector add int
83class AddVINode : public VectorNode {
84 public:
85  AddVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
86  virtual int Opcode() const;
87};
88
89//------------------------------AddVLNode---------------------------------------
90// Vector add long
91class AddVLNode : public VectorNode {
92 public:
93  AddVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
94  virtual int Opcode() const;
95};
96
97//------------------------------AddVFNode---------------------------------------
98// Vector add float
99class AddVFNode : public VectorNode {
100 public:
101  AddVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
102  virtual int Opcode() const;
103};
104
105//------------------------------AddVDNode---------------------------------------
106// Vector add double
107class AddVDNode : public VectorNode {
108 public:
109  AddVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
110  virtual int Opcode() const;
111};
112
113//------------------------------SubVBNode---------------------------------------
114// Vector subtract byte
115class SubVBNode : public VectorNode {
116 public:
117  SubVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
118  virtual int Opcode() const;
119};
120
121//------------------------------SubVSNode---------------------------------------
122// Vector subtract short
123class SubVSNode : public VectorNode {
124 public:
125  SubVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
126  virtual int Opcode() const;
127};
128
129//------------------------------SubVINode---------------------------------------
130// Vector subtract int
131class SubVINode : public VectorNode {
132 public:
133  SubVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
134  virtual int Opcode() const;
135};
136
137//------------------------------SubVLNode---------------------------------------
138// Vector subtract long
139class SubVLNode : public VectorNode {
140 public:
141  SubVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
142  virtual int Opcode() const;
143};
144
145//------------------------------SubVFNode---------------------------------------
146// Vector subtract float
147class SubVFNode : public VectorNode {
148 public:
149  SubVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
150  virtual int Opcode() const;
151};
152
153//------------------------------SubVDNode---------------------------------------
154// Vector subtract double
155class SubVDNode : public VectorNode {
156 public:
157  SubVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
158  virtual int Opcode() const;
159};
160
161//------------------------------MulVFNode---------------------------------------
162// Vector multiply float
163class MulVFNode : public VectorNode {
164 public:
165  MulVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
166  virtual int Opcode() const;
167};
168
169//------------------------------MulVDNode---------------------------------------
170// Vector multiply double
171class MulVDNode : public VectorNode {
172 public:
173  MulVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
174  virtual int Opcode() const;
175};
176
177//------------------------------DivVFNode---------------------------------------
178// Vector divide float
179class DivVFNode : public VectorNode {
180 public:
181  DivVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
182  virtual int Opcode() const;
183};
184
185//------------------------------DivVDNode---------------------------------------
186// Vector Divide double
187class DivVDNode : public VectorNode {
188 public:
189  DivVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
190  virtual int Opcode() const;
191};
192
193//------------------------------LShiftVBNode---------------------------------------
194// Vector lshift byte
195class LShiftVBNode : public VectorNode {
196 public:
197  LShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
198  virtual int Opcode() const;
199};
200
201//------------------------------LShiftVSNode---------------------------------------
202// Vector lshift shorts
203class LShiftVSNode : public VectorNode {
204 public:
205  LShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
206  virtual int Opcode() const;
207};
208
209//------------------------------LShiftVINode---------------------------------------
210// Vector lshift ints
211class LShiftVINode : public VectorNode {
212 public:
213  LShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
214  virtual int Opcode() const;
215};
216
217//------------------------------URShiftVBNode---------------------------------------
218// Vector urshift bytes
219class RShiftVBNode : public VectorNode {
220 public:
221  RShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
222  virtual int Opcode() const;
223};
224
225//------------------------------URShiftVSNode---------------------------------------
226// Vector urshift shorts
227class RShiftVSNode : public VectorNode {
228 public:
229  RShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
230  virtual int Opcode() const;
231};
232
233//------------------------------URShiftVINode---------------------------------------
234// Vector urshift ints
235class RShiftVINode : public VectorNode {
236 public:
237  RShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
238  virtual int Opcode() const;
239};
240
241//------------------------------AndVNode---------------------------------------
242// Vector and
243class AndVNode : public VectorNode {
244 public:
245  AndVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
246  virtual int Opcode() const;
247};
248
249//------------------------------OrVNode---------------------------------------
250// Vector or
251class OrVNode : public VectorNode {
252 public:
253  OrVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
254  virtual int Opcode() const;
255};
256
257//------------------------------XorVNode---------------------------------------
258// Vector xor
259class XorVNode : public VectorNode {
260 public:
261  XorVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
262  virtual int Opcode() const;
263};
264
265//================================= M E M O R Y ===============================
266
267//------------------------------LoadVectorNode---------------------------------
268// Load Vector from memory
269class 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  }
275
276  const TypeVect* vect_type() const { return type()->is_vect(); }
277  uint length() const { return vect_type()->length(); } // Vector length
278
279  virtual int Opcode() const;
280
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(); }
284
285  virtual int store_Opcode() const { return Op_StoreVector; }
286
287  static LoadVectorNode* make(Compile* C, int opc, Node* ctl, Node* mem,
288                              Node* adr, const TypePtr* atyp, uint vlen, BasicType bt);
289};
290
291//------------------------------StoreVectorNode--------------------------------
292// Store Vector to memory
293class 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  }
300
301  const TypeVect* vect_type() const { return in(MemNode::ValueIn)->bottom_type()->is_vect(); }
302  uint length() const { return vect_type()->length(); } // Vector length
303
304  virtual int Opcode() const;
305
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(); }
309
310  static StoreVectorNode* make(Compile* C, int opc, Node* ctl, Node* mem,
311                               Node* adr, const TypePtr* atyp, Node* val,
312                               uint vlen);
313};
314
315
316//=========================Promote_Scalar_to_Vector============================
317
318//------------------------------ReplicateBNode---------------------------------
319// Replicate byte scalar to be vector
320class ReplicateBNode : public VectorNode {
321 public:
322  ReplicateBNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
323  virtual int Opcode() const;
324};
325
326//------------------------------ReplicateSNode---------------------------------
327// Replicate short scalar to be vector
328class ReplicateSNode : public VectorNode {
329 public:
330  ReplicateSNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
331  virtual int Opcode() const;
332};
333
334//------------------------------ReplicateINode---------------------------------
335// Replicate int scalar to be vector
336class ReplicateINode : public VectorNode {
337 public:
338  ReplicateINode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
339  virtual int Opcode() const;
340};
341
342//------------------------------ReplicateLNode---------------------------------
343// Replicate long scalar to be vector
344class ReplicateLNode : public VectorNode {
345 public:
346  ReplicateLNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
347  virtual int Opcode() const;
348};
349
350//------------------------------ReplicateFNode---------------------------------
351// Replicate float scalar to be vector
352class ReplicateFNode : public VectorNode {
353 public:
354  ReplicateFNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
355  virtual int Opcode() const;
356};
357
358//------------------------------ReplicateDNode---------------------------------
359// Replicate double scalar to be vector
360class ReplicateDNode : public VectorNode {
361 public:
362  ReplicateDNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
363  virtual int Opcode() const;
364};
365
366//========================Pack_Scalars_into_a_Vector===========================
367
368//------------------------------PackNode---------------------------------------
369// Pack parent class (not for code generation).
370class 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;
375
376  void add_opd(uint i, Node* n) {
377    init_req(i+1, n);
378  }
379
380  // Create a binary tree form for Packs. [lo, hi) (half-open) range
381  Node* binaryTreePack(Compile* C, int lo, int hi);
382
383  static PackNode* make(Compile* C, Node* s, uint vlen, BasicType bt);
384};
385
386//------------------------------PackBNode---------------------------------------
387// Pack byte scalars into vector
388class PackBNode : public PackNode {
389 public:
390  PackBNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
391  virtual int Opcode() const;
392};
393
394//------------------------------PackSNode---------------------------------------
395// Pack short scalars into a vector
396class 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};
402
403//------------------------------PackINode---------------------------------------
404// Pack integer scalars into a vector
405class 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};
411
412//------------------------------PackLNode---------------------------------------
413// Pack long scalars into a vector
414class 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};
420
421//------------------------------Pack2LNode--------------------------------------
422// Pack 2 long scalars into a vector
423class Pack2LNode : public PackNode {
424 public:
425  Pack2LNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
426  virtual int Opcode() const;
427};
428
429//------------------------------PackFNode---------------------------------------
430// Pack float scalars into vector
431class 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};
437
438//------------------------------PackDNode---------------------------------------
439// Pack double scalars into a vector
440class 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};
446
447//------------------------------Pack2DNode--------------------------------------
448// Pack 2 double scalars into a vector
449class Pack2DNode : public PackNode {
450 public:
451  Pack2DNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
452  virtual int Opcode() const;
453};
454
455
456//========================Extract_Scalar_from_Vector===============================
457
458//------------------------------ExtractNode---------------------------------------
459// Extract a scalar from a vector at position "pos"
460class 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(); }
467
468  static Node* make(Compile* C, Node* v, uint position, BasicType bt);
469};
470
471//------------------------------ExtractBNode---------------------------------------
472// Extract a byte from a vector at position "pos"
473class 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};
480
481//------------------------------ExtractUBNode--------------------------------------
482// Extract a boolean from a vector at position "pos"
483class 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};
490
491//------------------------------ExtractCNode---------------------------------------
492// Extract a char from a vector at position "pos"
493class 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};
500
501//------------------------------ExtractSNode---------------------------------------
502// Extract a short from a vector at position "pos"
503class 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};
510
511//------------------------------ExtractINode---------------------------------------
512// Extract an int from a vector at position "pos"
513class 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};
520
521//------------------------------ExtractLNode---------------------------------------
522// Extract a long from a vector at position "pos"
523class 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};
530
531//------------------------------ExtractFNode---------------------------------------
532// Extract a float from a vector at position "pos"
533class 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};
540
541//------------------------------ExtractDNode---------------------------------------
542// Extract a double from a vector at position "pos"
543class 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};
550
551#endif // SHARE_VM_OPTO_VECTORNODE_HPP
552