blob: bff58d0910fb81dea8ae79a18f337c4a0fa69a12 [file] [log] [blame]
Aart Bikf8f5a162017-02-06 15:35:29 -08001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_COMPILER_OPTIMIZING_NODES_VECTOR_H_
18#define ART_COMPILER_OPTIMIZING_NODES_VECTOR_H_
19
20// This #include should never be used by compilation, because this header file (nodes_vector.h)
21// is included in the header file nodes.h itself. However it gives editing tools better context.
22#include "nodes.h"
23
24namespace art {
25
26// Memory alignment, represented as an offset relative to a base, where 0 <= offset < base,
27// and base is a power of two. For example, the value Alignment(16, 0) means memory is
28// perfectly aligned at a 16-byte boundary, whereas the value Alignment(16, 4) means
29// memory is always exactly 4 bytes above such a boundary.
30class Alignment {
31 public:
32 Alignment(size_t base, size_t offset) : base_(base), offset_(offset) {
33 DCHECK_LT(offset, base);
34 DCHECK(IsPowerOfTwo(base));
35 }
36
37 // Returns true if memory is "at least" aligned at the given boundary.
38 // Assumes requested base is power of two.
39 bool IsAlignedAt(size_t base) const {
40 DCHECK_NE(0u, base);
41 DCHECK(IsPowerOfTwo(base));
42 return ((offset_ | base_) & (base - 1u)) == 0;
43 }
44
45 std::string ToString() const {
46 return "ALIGN(" + std::to_string(base_) + "," + std::to_string(offset_) + ")";
47 }
48
49 private:
50 size_t base_;
51 size_t offset_;
52};
53
54//
55// Definitions of abstract vector operations in HIR.
56//
57
58// Abstraction of a vector operation, i.e., an operation that performs
59// GetVectorLength() x GetPackedType() operations simultaneously.
60class HVecOperation : public HVariableInputSizeInstruction {
61 public:
62 HVecOperation(ArenaAllocator* arena,
63 Primitive::Type packed_type,
64 SideEffects side_effects,
65 size_t number_of_inputs,
66 size_t vector_length,
67 uint32_t dex_pc)
68 : HVariableInputSizeInstruction(side_effects,
69 dex_pc,
70 arena,
71 number_of_inputs,
72 kArenaAllocVectorNode),
73 vector_length_(vector_length) {
74 SetPackedField<TypeField>(packed_type);
75 DCHECK_LT(1u, vector_length);
76 }
77
78 // Returns the number of elements packed in a vector.
79 size_t GetVectorLength() const {
80 return vector_length_;
81 }
82
83 // Returns the number of bytes in a full vector.
84 size_t GetVectorNumberOfBytes() const {
85 return vector_length_ * Primitive::ComponentSize(GetPackedType());
86 }
87
88 // Returns the type of the vector operation: a SIMD operation looks like a FPU location.
89 // TODO: we could introduce SIMD types in HIR.
90 Primitive::Type GetType() const OVERRIDE {
91 return Primitive::kPrimDouble;
92 }
93
94 // Returns the true component type packed in a vector.
95 Primitive::Type GetPackedType() const {
96 return GetPackedField<TypeField>();
97 }
98
99 DECLARE_ABSTRACT_INSTRUCTION(VecOperation);
100
101 private:
102 // Additional packed bits.
103 static constexpr size_t kFieldType = HInstruction::kNumberOfGenericPackedBits;
104 static constexpr size_t kFieldTypeSize =
105 MinimumBitsToStore(static_cast<size_t>(Primitive::kPrimLast));
106 static constexpr size_t kNumberOfVectorOpPackedBits = kFieldType + kFieldTypeSize;
107 static_assert(kNumberOfVectorOpPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields.");
108 using TypeField = BitField<Primitive::Type, kFieldType, kFieldTypeSize>;
109
110 const size_t vector_length_;
111
112 DISALLOW_COPY_AND_ASSIGN(HVecOperation);
113};
114
115// Abstraction of a unary vector operation.
116class HVecUnaryOperation : public HVecOperation {
117 public:
118 HVecUnaryOperation(ArenaAllocator* arena,
119 Primitive::Type packed_type,
120 size_t vector_length,
121 uint32_t dex_pc)
122 : HVecOperation(arena,
123 packed_type,
124 SideEffects::None(),
125 /*number_of_inputs*/ 1,
126 vector_length,
127 dex_pc) { }
128 DECLARE_ABSTRACT_INSTRUCTION(VecUnaryOperation);
129 private:
130 DISALLOW_COPY_AND_ASSIGN(HVecUnaryOperation);
131};
132
133// Abstraction of a binary vector operation.
134class HVecBinaryOperation : public HVecOperation {
135 public:
136 HVecBinaryOperation(ArenaAllocator* arena,
137 Primitive::Type packed_type,
138 size_t vector_length,
139 uint32_t dex_pc)
140 : HVecOperation(arena,
141 packed_type,
142 SideEffects::None(),
143 /*number_of_inputs*/ 2,
144 vector_length,
145 dex_pc) { }
146 DECLARE_ABSTRACT_INSTRUCTION(VecBinaryOperation);
147 private:
148 DISALLOW_COPY_AND_ASSIGN(HVecBinaryOperation);
149};
150
151// Abstraction of a vector operation that references memory, with an alignment.
152// The Android runtime guarantees at least "component size" alignment for array
153// elements and, thus, vectors.
154class HVecMemoryOperation : public HVecOperation {
155 public:
156 HVecMemoryOperation(ArenaAllocator* arena,
157 Primitive::Type packed_type,
158 SideEffects side_effects,
159 size_t number_of_inputs,
160 size_t vector_length,
161 uint32_t dex_pc)
162 : HVecOperation(arena, packed_type, side_effects, number_of_inputs, vector_length, dex_pc),
163 alignment_(Primitive::ComponentSize(packed_type), 0) { }
164
165 void SetAlignment(Alignment alignment) { alignment_ = alignment; }
166
167 Alignment GetAlignment() const { return alignment_; }
168
169 DECLARE_ABSTRACT_INSTRUCTION(VecMemoryOperation);
170
171 private:
172 Alignment alignment_;
173
174 DISALLOW_COPY_AND_ASSIGN(HVecMemoryOperation);
175};
176
177//
178// Definitions of concrete vector operations in HIR.
179//
180
181// Replicates the given scalar into a vector,
182// viz. replicate(x) = [ x, .. , x ].
183class HVecReplicateScalar FINAL : public HVecUnaryOperation {
184 public:
185 HVecReplicateScalar(ArenaAllocator* arena,
186 HInstruction* scalar,
187 Primitive::Type packed_type,
188 size_t vector_length,
189 uint32_t dex_pc = kNoDexPc)
190 : HVecUnaryOperation(arena, packed_type, vector_length, dex_pc) {
191 SetRawInputAt(0, scalar);
192 }
193 DECLARE_INSTRUCTION(VecReplicateScalar);
194 private:
195 DISALLOW_COPY_AND_ASSIGN(HVecReplicateScalar);
196};
197
198// Assigns the given scalar elements to a vector,
199// viz. set( array(x1, .., xn) ) = [ x1, .. , xn ].
200class HVecSetScalars FINAL : public HVecUnaryOperation {
201 HVecSetScalars(ArenaAllocator* arena,
202 HInstruction** scalars, // array
203 Primitive::Type packed_type,
204 size_t vector_length,
205 uint32_t dex_pc = kNoDexPc)
206 : HVecUnaryOperation(arena, packed_type, vector_length, dex_pc) {
207 for (size_t i = 0; i < vector_length; i++) {
208 SetRawInputAt(0, scalars[i]);
209 }
210 }
211 DECLARE_INSTRUCTION(VecSetScalars);
212 private:
213 DISALLOW_COPY_AND_ASSIGN(HVecSetScalars);
214};
215
216// Sum-reduces the given vector into a shorter vector (m < n) or scalar (m = 1),
217// viz. sum-reduce[ x1, .. , xn ] = [ y1, .., ym ], where yi = sum_j x_j.
218class HVecSumReduce FINAL : public HVecUnaryOperation {
219 HVecSumReduce(ArenaAllocator* arena,
220 HInstruction* input,
221 Primitive::Type packed_type,
222 size_t vector_length,
223 uint32_t dex_pc = kNoDexPc)
224 : HVecUnaryOperation(arena, packed_type, vector_length, dex_pc) {
225 DCHECK(input->IsVecOperation());
226 DCHECK_EQ(input->AsVecOperation()->GetPackedType(), packed_type);
227 SetRawInputAt(0, input);
228 }
229
230 // TODO: probably integral promotion
231 Primitive::Type GetType() const OVERRIDE { return GetPackedType(); }
232
233 DECLARE_INSTRUCTION(VecSumReduce);
234 private:
235 DISALLOW_COPY_AND_ASSIGN(HVecSumReduce);
236};
237
238// Converts every component in the vector,
239// viz. cnv[ x1, .. , xn ] = [ cnv(x1), .. , cnv(xn) ].
240class HVecCnv FINAL : public HVecUnaryOperation {
241 public:
242 HVecCnv(ArenaAllocator* arena,
243 HInstruction* input,
244 Primitive::Type packed_type,
245 size_t vector_length,
246 uint32_t dex_pc = kNoDexPc)
247 : HVecUnaryOperation(arena, packed_type, vector_length, dex_pc) {
248 DCHECK(input->IsVecOperation());
249 DCHECK_NE(input->AsVecOperation()->GetPackedType(), packed_type); // actual convert
250 SetRawInputAt(0, input);
251 }
252
253 Primitive::Type GetInputType() const { return InputAt(0)->AsVecOperation()->GetPackedType(); }
254 Primitive::Type GetResultType() const { return GetPackedType(); }
255
256 DECLARE_INSTRUCTION(VecCnv);
257
258 private:
259 DISALLOW_COPY_AND_ASSIGN(HVecCnv);
260};
261
262// Negates every component in the vector,
263// viz. neg[ x1, .. , xn ] = [ -x1, .. , -xn ].
264class HVecNeg FINAL : public HVecUnaryOperation {
265 public:
266 HVecNeg(ArenaAllocator* arena,
267 HInstruction* input,
268 Primitive::Type packed_type,
269 size_t vector_length,
270 uint32_t dex_pc = kNoDexPc)
271 : HVecUnaryOperation(arena, packed_type, vector_length, dex_pc) {
272 DCHECK(input->IsVecOperation());
273 DCHECK_EQ(input->AsVecOperation()->GetPackedType(), packed_type);
274 SetRawInputAt(0, input);
275 }
276 DECLARE_INSTRUCTION(VecNeg);
277 private:
278 DISALLOW_COPY_AND_ASSIGN(HVecNeg);
279};
280
Aart Bik6daebeb2017-04-03 14:35:41 -0700281// Takes absolute value of every component in the vector,
282// viz. abs[ x1, .. , xn ] = [ |x1|, .. , |xn| ].
283class HVecAbs FINAL : public HVecUnaryOperation {
284 public:
285 HVecAbs(ArenaAllocator* arena,
286 HInstruction* input,
287 Primitive::Type packed_type,
288 size_t vector_length,
289 uint32_t dex_pc = kNoDexPc)
290 : HVecUnaryOperation(arena, packed_type, vector_length, dex_pc) {
291 DCHECK(input->IsVecOperation());
292 DCHECK_EQ(input->AsVecOperation()->GetPackedType(), packed_type);
293 SetRawInputAt(0, input);
294 }
295 DECLARE_INSTRUCTION(VecAbs);
296 private:
297 DISALLOW_COPY_AND_ASSIGN(HVecAbs);
298};
299
Aart Bikf8f5a162017-02-06 15:35:29 -0800300// Bitwise- or boolean-nots every component in the vector,
301// viz. not[ x1, .. , xn ] = [ ~x1, .. , ~xn ], or
302// not[ x1, .. , xn ] = [ !x1, .. , !xn ] for boolean.
303class HVecNot FINAL : public HVecUnaryOperation {
304 public:
305 HVecNot(ArenaAllocator* arena,
306 HInstruction* input,
307 Primitive::Type packed_type,
308 size_t vector_length,
309 uint32_t dex_pc = kNoDexPc)
310 : HVecUnaryOperation(arena, packed_type, vector_length, dex_pc) {
311 DCHECK(input->IsVecOperation());
312 SetRawInputAt(0, input);
313 }
314 DECLARE_INSTRUCTION(VecNot);
315 private:
316 DISALLOW_COPY_AND_ASSIGN(HVecNot);
317};
318
319// Adds every component in the two vectors,
320// viz. [ x1, .. , xn ] + [ y1, .. , yn ] = [ x1 + y1, .. , xn + yn ].
321class HVecAdd FINAL : public HVecBinaryOperation {
322 public:
323 HVecAdd(ArenaAllocator* arena,
324 HInstruction* left,
325 HInstruction* right,
326 Primitive::Type packed_type,
327 size_t vector_length,
328 uint32_t dex_pc = kNoDexPc)
329 : HVecBinaryOperation(arena, packed_type, vector_length, dex_pc) {
330 DCHECK(left->IsVecOperation() && right->IsVecOperation());
331 DCHECK_EQ(left->AsVecOperation()->GetPackedType(), packed_type);
332 DCHECK_EQ(right->AsVecOperation()->GetPackedType(), packed_type);
333 SetRawInputAt(0, left);
334 SetRawInputAt(1, right);
335 }
336 DECLARE_INSTRUCTION(VecAdd);
337 private:
338 DISALLOW_COPY_AND_ASSIGN(HVecAdd);
339};
340
Aart Bikf3e61ee2017-04-12 17:09:20 -0700341// Performs halving add on every component in the two vectors, viz.
342// rounded [ x1, .. , xn ] hradd [ y1, .. , yn ] = [ (x1 + y1 + 1) >> 1, .. , (xn + yn + 1) >> 1 ]
343// or [ x1, .. , xn ] hadd [ y1, .. , yn ] = [ (x1 + y1) >> 1, .. , (xn + yn ) >> 1 ]
344// for signed operands x, y (sign extension) or unsigned operands x, y (zero extension).
345class HVecHalvingAdd FINAL : public HVecBinaryOperation {
346 public:
347 HVecHalvingAdd(ArenaAllocator* arena,
348 HInstruction* left,
349 HInstruction* right,
350 Primitive::Type packed_type,
351 size_t vector_length,
352 bool is_unsigned,
353 bool is_rounded,
354 uint32_t dex_pc = kNoDexPc)
355 : HVecBinaryOperation(arena, packed_type, vector_length, dex_pc),
356 is_unsigned_(is_unsigned),
357 is_rounded_(is_rounded) {
358 DCHECK(left->IsVecOperation() && right->IsVecOperation());
359 DCHECK_EQ(left->AsVecOperation()->GetPackedType(), packed_type);
360 DCHECK_EQ(right->AsVecOperation()->GetPackedType(), packed_type);
361 SetRawInputAt(0, left);
362 SetRawInputAt(1, right);
363 }
364
365 bool IsUnsigned() const { return is_unsigned_; }
366 bool IsRounded() const { return is_rounded_; }
367
368 DECLARE_INSTRUCTION(VecHalvingAdd);
369
370 private:
371 bool is_unsigned_;
372 bool is_rounded_;
373
374 DISALLOW_COPY_AND_ASSIGN(HVecHalvingAdd);
375};
376
Aart Bikf8f5a162017-02-06 15:35:29 -0800377// Subtracts every component in the two vectors,
378// viz. [ x1, .. , xn ] - [ y1, .. , yn ] = [ x1 - y1, .. , xn - yn ].
379class HVecSub FINAL : public HVecBinaryOperation {
380 public:
381 HVecSub(ArenaAllocator* arena,
382 HInstruction* left,
383 HInstruction* right,
384 Primitive::Type packed_type,
385 size_t vector_length,
386 uint32_t dex_pc = kNoDexPc)
387 : HVecBinaryOperation(arena, packed_type, vector_length, dex_pc) {
388 DCHECK(left->IsVecOperation() && right->IsVecOperation());
389 DCHECK_EQ(left->AsVecOperation()->GetPackedType(), packed_type);
390 DCHECK_EQ(right->AsVecOperation()->GetPackedType(), packed_type);
391 SetRawInputAt(0, left);
392 SetRawInputAt(1, right);
393 }
394 DECLARE_INSTRUCTION(VecSub);
395 private:
396 DISALLOW_COPY_AND_ASSIGN(HVecSub);
397};
398
399// Multiplies every component in the two vectors,
400// viz. [ x1, .. , xn ] * [ y1, .. , yn ] = [ x1 * y1, .. , xn * yn ].
401class HVecMul FINAL : public HVecBinaryOperation {
402 public:
403 HVecMul(ArenaAllocator* arena,
404 HInstruction* left,
405 HInstruction* right,
406 Primitive::Type packed_type,
407 size_t vector_length,
408 uint32_t dex_pc = kNoDexPc)
409 : HVecBinaryOperation(arena, packed_type, vector_length, dex_pc) {
410 DCHECK(left->IsVecOperation() && right->IsVecOperation());
411 DCHECK_EQ(left->AsVecOperation()->GetPackedType(), packed_type);
412 DCHECK_EQ(right->AsVecOperation()->GetPackedType(), packed_type);
413 SetRawInputAt(0, left);
414 SetRawInputAt(1, right);
415 }
416 DECLARE_INSTRUCTION(VecMul);
417 private:
418 DISALLOW_COPY_AND_ASSIGN(HVecMul);
419};
420
421// Divides every component in the two vectors,
422// viz. [ x1, .. , xn ] / [ y1, .. , yn ] = [ x1 / y1, .. , xn / yn ].
423class HVecDiv FINAL : public HVecBinaryOperation {
424 public:
425 HVecDiv(ArenaAllocator* arena,
426 HInstruction* left,
427 HInstruction* right,
428 Primitive::Type packed_type,
429 size_t vector_length,
430 uint32_t dex_pc = kNoDexPc)
431 : HVecBinaryOperation(arena, packed_type, vector_length, dex_pc) {
432 DCHECK(left->IsVecOperation() && right->IsVecOperation());
433 DCHECK_EQ(left->AsVecOperation()->GetPackedType(), packed_type);
434 DCHECK_EQ(right->AsVecOperation()->GetPackedType(), packed_type);
435 SetRawInputAt(0, left);
436 SetRawInputAt(1, right);
437 }
438 DECLARE_INSTRUCTION(VecDiv);
439 private:
440 DISALLOW_COPY_AND_ASSIGN(HVecDiv);
441};
442
Aart Bikf3e61ee2017-04-12 17:09:20 -0700443// Takes minimum of every component in the two vectors,
444// viz. MIN( [ x1, .. , xn ] , [ y1, .. , yn ]) = [ min(x1, y1), .. , min(xn, yn) ].
445class HVecMin FINAL : public HVecBinaryOperation {
446 public:
447 HVecMin(ArenaAllocator* arena,
448 HInstruction* left,
449 HInstruction* right,
450 Primitive::Type packed_type,
451 size_t vector_length,
452 uint32_t dex_pc = kNoDexPc)
453 : HVecBinaryOperation(arena, packed_type, vector_length, dex_pc) {
454 DCHECK(left->IsVecOperation() && right->IsVecOperation());
455 DCHECK_EQ(left->AsVecOperation()->GetPackedType(), packed_type);
456 DCHECK_EQ(right->AsVecOperation()->GetPackedType(), packed_type);
457 SetRawInputAt(0, left);
458 SetRawInputAt(1, right);
459 }
460 DECLARE_INSTRUCTION(VecMin);
461 private:
462 DISALLOW_COPY_AND_ASSIGN(HVecMin);
463};
464
465// Takes maximum of every component in the two vectors,
466// viz. MAX( [ x1, .. , xn ] , [ y1, .. , yn ]) = [ max(x1, y1), .. , max(xn, yn) ].
467class HVecMax FINAL : public HVecBinaryOperation {
468 public:
469 HVecMax(ArenaAllocator* arena,
470 HInstruction* left,
471 HInstruction* right,
472 Primitive::Type packed_type,
473 size_t vector_length,
474 uint32_t dex_pc = kNoDexPc)
475 : HVecBinaryOperation(arena, packed_type, vector_length, dex_pc) {
476 DCHECK(left->IsVecOperation() && right->IsVecOperation());
477 DCHECK_EQ(left->AsVecOperation()->GetPackedType(), packed_type);
478 DCHECK_EQ(right->AsVecOperation()->GetPackedType(), packed_type);
479 SetRawInputAt(0, left);
480 SetRawInputAt(1, right);
481 }
482 DECLARE_INSTRUCTION(VecMax);
483 private:
484 DISALLOW_COPY_AND_ASSIGN(HVecMax);
485};
486
Aart Bikf8f5a162017-02-06 15:35:29 -0800487// Bitwise-ands every component in the two vectors,
488// viz. [ x1, .. , xn ] & [ y1, .. , yn ] = [ x1 & y1, .. , xn & yn ].
489class HVecAnd FINAL : public HVecBinaryOperation {
490 public:
491 HVecAnd(ArenaAllocator* arena,
492 HInstruction* left,
493 HInstruction* right,
494 Primitive::Type packed_type,
495 size_t vector_length,
496 uint32_t dex_pc = kNoDexPc)
497 : HVecBinaryOperation(arena, packed_type, vector_length, dex_pc) {
498 DCHECK(left->IsVecOperation() && right->IsVecOperation());
499 SetRawInputAt(0, left);
500 SetRawInputAt(1, right);
501 }
502 DECLARE_INSTRUCTION(VecAnd);
503 private:
504 DISALLOW_COPY_AND_ASSIGN(HVecAnd);
505};
506
507// Bitwise-and-nots every component in the two vectors,
508// viz. [ x1, .. , xn ] and-not [ y1, .. , yn ] = [ ~x1 & y1, .. , ~xn & yn ].
509class HVecAndNot FINAL : public HVecBinaryOperation {
510 public:
511 HVecAndNot(ArenaAllocator* arena,
512 HInstruction* left,
513 HInstruction* right,
514 Primitive::Type packed_type,
515 size_t vector_length,
516 uint32_t dex_pc = kNoDexPc)
517 : HVecBinaryOperation(arena, packed_type, vector_length, dex_pc) {
518 DCHECK(left->IsVecOperation() && right->IsVecOperation());
519 SetRawInputAt(0, left);
520 SetRawInputAt(1, right);
521 }
522 DECLARE_INSTRUCTION(VecAndNot);
523 private:
524 DISALLOW_COPY_AND_ASSIGN(HVecAndNot);
525};
526
527// Bitwise-ors every component in the two vectors,
528// viz. [ x1, .. , xn ] | [ y1, .. , yn ] = [ x1 | y1, .. , xn | yn ].
529class HVecOr FINAL : public HVecBinaryOperation {
530 public:
531 HVecOr(ArenaAllocator* arena,
532 HInstruction* left,
533 HInstruction* right,
534 Primitive::Type packed_type,
535 size_t vector_length,
536 uint32_t dex_pc = kNoDexPc)
537 : HVecBinaryOperation(arena, packed_type, vector_length, dex_pc) {
538 DCHECK(left->IsVecOperation() && right->IsVecOperation());
539 SetRawInputAt(0, left);
540 SetRawInputAt(1, right);
541 }
542 DECLARE_INSTRUCTION(VecOr);
543 private:
544 DISALLOW_COPY_AND_ASSIGN(HVecOr);
545};
546
547// Bitwise-xors every component in the two vectors,
548// viz. [ x1, .. , xn ] ^ [ y1, .. , yn ] = [ x1 ^ y1, .. , xn ^ yn ].
549class HVecXor FINAL : public HVecBinaryOperation {
550 public:
551 HVecXor(ArenaAllocator* arena,
552 HInstruction* left,
553 HInstruction* right,
554 Primitive::Type packed_type,
555 size_t vector_length,
556 uint32_t dex_pc = kNoDexPc)
557 : HVecBinaryOperation(arena, packed_type, vector_length, dex_pc) {
558 DCHECK(left->IsVecOperation() && right->IsVecOperation());
559 SetRawInputAt(0, left);
560 SetRawInputAt(1, right);
561 }
562 DECLARE_INSTRUCTION(VecXor);
563 private:
564 DISALLOW_COPY_AND_ASSIGN(HVecXor);
565};
566
567// Logically shifts every component in the vector left by the given distance,
568// viz. [ x1, .. , xn ] << d = [ x1 << d, .. , xn << d ].
569class HVecShl FINAL : public HVecBinaryOperation {
570 public:
571 HVecShl(ArenaAllocator* arena,
572 HInstruction* left,
573 HInstruction* right,
574 Primitive::Type packed_type,
575 size_t vector_length,
576 uint32_t dex_pc = kNoDexPc)
577 : HVecBinaryOperation(arena, packed_type, vector_length, dex_pc) {
578 DCHECK(left->IsVecOperation());
579 DCHECK_EQ(left->AsVecOperation()->GetPackedType(), packed_type);
580 SetRawInputAt(0, left);
581 SetRawInputAt(1, right);
582 }
583 DECLARE_INSTRUCTION(VecShl);
584 private:
585 DISALLOW_COPY_AND_ASSIGN(HVecShl);
586};
587
588// Arithmetically shifts every component in the vector right by the given distance,
589// viz. [ x1, .. , xn ] >> d = [ x1 >> d, .. , xn >> d ].
590class HVecShr FINAL : public HVecBinaryOperation {
591 public:
592 HVecShr(ArenaAllocator* arena,
593 HInstruction* left,
594 HInstruction* right,
595 Primitive::Type packed_type,
596 size_t vector_length,
597 uint32_t dex_pc = kNoDexPc)
598 : HVecBinaryOperation(arena, packed_type, vector_length, dex_pc) {
599 DCHECK(left->IsVecOperation());
600 DCHECK_EQ(left->AsVecOperation()->GetPackedType(), packed_type);
601 SetRawInputAt(0, left);
602 SetRawInputAt(1, right);
603 }
604 DECLARE_INSTRUCTION(VecShr);
605 private:
606 DISALLOW_COPY_AND_ASSIGN(HVecShr);
607};
608
609// Logically shifts every component in the vector right by the given distance,
610// viz. [ x1, .. , xn ] >>> d = [ x1 >>> d, .. , xn >>> d ].
611class HVecUShr FINAL : public HVecBinaryOperation {
612 public:
613 HVecUShr(ArenaAllocator* arena,
614 HInstruction* left,
615 HInstruction* right,
616 Primitive::Type packed_type,
617 size_t vector_length,
618 uint32_t dex_pc = kNoDexPc)
619 : HVecBinaryOperation(arena, packed_type, vector_length, dex_pc) {
620 DCHECK(left->IsVecOperation());
621 DCHECK_EQ(left->AsVecOperation()->GetPackedType(), packed_type);
622 SetRawInputAt(0, left);
623 SetRawInputAt(1, right);
624 }
625 DECLARE_INSTRUCTION(VecUShr);
626 private:
627 DISALLOW_COPY_AND_ASSIGN(HVecUShr);
628};
629
630// Loads a vector from memory, viz. load(mem, 1)
631// yield the vector [ mem(1), .. , mem(n) ].
632class HVecLoad FINAL : public HVecMemoryOperation {
633 public:
634 HVecLoad(ArenaAllocator* arena,
635 HInstruction* base,
636 HInstruction* index,
637 Primitive::Type packed_type,
638 size_t vector_length,
639 uint32_t dex_pc = kNoDexPc)
640 : HVecMemoryOperation(arena,
641 packed_type,
642 SideEffects::ArrayReadOfType(packed_type),
643 /*number_of_inputs*/ 2,
644 vector_length,
645 dex_pc) {
646 SetRawInputAt(0, base);
647 SetRawInputAt(1, index);
648 }
649 DECLARE_INSTRUCTION(VecLoad);
650 private:
651 DISALLOW_COPY_AND_ASSIGN(HVecLoad);
652};
653
654// Stores a vector to memory, viz. store(m, 1, [x1, .. , xn] )
655// sets mem(1) = x1, .. , mem(n) = xn.
656class HVecStore FINAL : public HVecMemoryOperation {
657 public:
658 HVecStore(ArenaAllocator* arena,
659 HInstruction* base,
660 HInstruction* index,
661 HInstruction* value,
662 Primitive::Type packed_type,
663 size_t vector_length,
664 uint32_t dex_pc = kNoDexPc)
665 : HVecMemoryOperation(arena,
666 packed_type,
667 SideEffects::ArrayWriteOfType(packed_type),
668 /*number_of_inputs*/ 3,
669 vector_length,
670 dex_pc) {
671 DCHECK(value->IsVecOperation());
672 DCHECK_EQ(value->AsVecOperation()->GetPackedType(), packed_type);
673 SetRawInputAt(0, base);
674 SetRawInputAt(1, index);
675 SetRawInputAt(2, value);
676 }
677 DECLARE_INSTRUCTION(VecStore);
678 private:
679 DISALLOW_COPY_AND_ASSIGN(HVecStore);
680};
681
682} // namespace art
683
684#endif // ART_COMPILER_OPTIMIZING_NODES_VECTOR_H_