blob: 8bd8667f8492951c6fb0c7adea3d65e3006f7fcd [file] [log] [blame]
Artem Udovichenko4a0dad62016-01-26 12:28:31 +03001/*
2 * Copyright (C) 2015 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_SHARED_H_
18#define ART_COMPILER_OPTIMIZING_NODES_SHARED_H_
19
20namespace art {
21
Vladimir Markofcb503c2016-05-18 12:48:17 +010022class HMultiplyAccumulate FINAL : public HExpression<3> {
Artem Udovichenko4a0dad62016-01-26 12:28:31 +030023 public:
24 HMultiplyAccumulate(Primitive::Type type,
25 InstructionKind op,
26 HInstruction* accumulator,
27 HInstruction* mul_left,
28 HInstruction* mul_right,
29 uint32_t dex_pc = kNoDexPc)
30 : HExpression(type, SideEffects::None(), dex_pc), op_kind_(op) {
31 SetRawInputAt(kInputAccumulatorIndex, accumulator);
32 SetRawInputAt(kInputMulLeftIndex, mul_left);
33 SetRawInputAt(kInputMulRightIndex, mul_right);
34 }
35
36 static constexpr int kInputAccumulatorIndex = 0;
37 static constexpr int kInputMulLeftIndex = 1;
38 static constexpr int kInputMulRightIndex = 2;
39
40 bool CanBeMoved() const OVERRIDE { return true; }
Vladimir Marko372f10e2016-05-17 16:30:10 +010041 bool InstructionDataEquals(const HInstruction* other) const OVERRIDE {
Artem Udovichenko4a0dad62016-01-26 12:28:31 +030042 return op_kind_ == other->AsMultiplyAccumulate()->op_kind_;
43 }
44
45 InstructionKind GetOpKind() const { return op_kind_; }
46
47 DECLARE_INSTRUCTION(MultiplyAccumulate);
48
49 private:
50 // Indicates if this is a MADD or MSUB.
51 const InstructionKind op_kind_;
52
53 DISALLOW_COPY_AND_ASSIGN(HMultiplyAccumulate);
54};
55
Vladimir Markofcb503c2016-05-18 12:48:17 +010056class HBitwiseNegatedRight FINAL : public HBinaryOperation {
Artem Serov7fc63502016-02-09 17:15:29 +000057 public:
58 HBitwiseNegatedRight(Primitive::Type result_type,
59 InstructionKind op,
60 HInstruction* left,
61 HInstruction* right,
62 uint32_t dex_pc = kNoDexPc)
63 : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc),
64 op_kind_(op) {
65 DCHECK(op == HInstruction::kAnd || op == HInstruction::kOr || op == HInstruction::kXor) << op;
66 }
67
68 template <typename T, typename U>
69 auto Compute(T x, U y) const -> decltype(x & ~y) {
70 static_assert(std::is_same<decltype(x & ~y), decltype(x | ~y)>::value &&
71 std::is_same<decltype(x & ~y), decltype(x ^ ~y)>::value,
72 "Inconsistent negated bitwise types");
73 switch (op_kind_) {
74 case HInstruction::kAnd:
75 return x & ~y;
76 case HInstruction::kOr:
77 return x | ~y;
78 case HInstruction::kXor:
79 return x ^ ~y;
80 default:
81 LOG(FATAL) << "Unreachable";
82 UNREACHABLE();
83 }
84 }
85
86 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE {
87 return GetBlock()->GetGraph()->GetIntConstant(
88 Compute(x->GetValue(), y->GetValue()), GetDexPc());
89 }
90 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE {
91 return GetBlock()->GetGraph()->GetLongConstant(
92 Compute(x->GetValue(), y->GetValue()), GetDexPc());
93 }
94 HConstant* Evaluate(HFloatConstant* x ATTRIBUTE_UNUSED,
95 HFloatConstant* y ATTRIBUTE_UNUSED) const OVERRIDE {
96 LOG(FATAL) << DebugName() << " is not defined for float values";
97 UNREACHABLE();
98 }
99 HConstant* Evaluate(HDoubleConstant* x ATTRIBUTE_UNUSED,
100 HDoubleConstant* y ATTRIBUTE_UNUSED) const OVERRIDE {
101 LOG(FATAL) << DebugName() << " is not defined for double values";
102 UNREACHABLE();
103 }
104
105 InstructionKind GetOpKind() const { return op_kind_; }
106
107 DECLARE_INSTRUCTION(BitwiseNegatedRight);
108
109 private:
110 // Specifies the bitwise operation, which will be then negated.
111 const InstructionKind op_kind_;
112
113 DISALLOW_COPY_AND_ASSIGN(HBitwiseNegatedRight);
114};
115
Artem Serov328429f2016-07-06 16:23:04 +0100116
117// This instruction computes an intermediate address pointing in the 'middle' of an object. The
118// result pointer cannot be handled by GC, so extra care is taken to make sure that this value is
119// never used across anything that can trigger GC.
120class HIntermediateAddress FINAL : public HExpression<2> {
121 public:
122 HIntermediateAddress(HInstruction* base_address, HInstruction* offset, uint32_t dex_pc)
123 : HExpression(Primitive::kPrimNot, SideEffects::DependsOnGC(), dex_pc) {
124 SetRawInputAt(0, base_address);
125 SetRawInputAt(1, offset);
126 }
127
128 bool CanBeMoved() const OVERRIDE { return true; }
129 bool InstructionDataEquals(const HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE {
130 return true;
131 }
132 bool IsActualObject() const OVERRIDE { return false; }
133
134 HInstruction* GetBaseAddress() const { return InputAt(0); }
135 HInstruction* GetOffset() const { return InputAt(1); }
136
137 DECLARE_INSTRUCTION(IntermediateAddress);
138
139 private:
140 DISALLOW_COPY_AND_ASSIGN(HIntermediateAddress);
141};
142
143
Artem Udovichenko4a0dad62016-01-26 12:28:31 +0300144} // namespace art
145
146#endif // ART_COMPILER_OPTIMIZING_NODES_SHARED_H_