blob: 8e8fbc15811a097bae0eac4d3d37310ddcec6a3b [file] [log] [blame]
Mark Mendell0616ae02015-04-17 12:49:27 -04001/*
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_X86_H_
18#define ART_COMPILER_OPTIMIZING_NODES_X86_H_
19
Vladimir Marko0a516052019-10-14 13:00:44 +000020namespace art {
Mark Mendell0616ae02015-04-17 12:49:27 -040021
22// Compute the address of the method for X86 Constant area support.
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010023class HX86ComputeBaseMethodAddress final : public HExpression<0> {
Mark Mendell0616ae02015-04-17 12:49:27 -040024 public:
25 // Treat the value as an int32_t, but it is really a 32 bit native pointer.
Calin Juravle154746b2015-10-06 15:46:54 +010026 HX86ComputeBaseMethodAddress()
Gupta Kumar, Sanjivd9e4d732018-02-05 13:35:03 +053027 : HExpression(kX86ComputeBaseMethodAddress,
28 DataType::Type::kInt32,
29 SideEffects::None(),
30 kNoDexPc) {
31 }
Mark Mendell0616ae02015-04-17 12:49:27 -040032
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010033 bool CanBeMoved() const override { return true; }
David Brazdild6c205e2016-06-07 14:20:52 +010034
Mark Mendell0616ae02015-04-17 12:49:27 -040035 DECLARE_INSTRUCTION(X86ComputeBaseMethodAddress);
36
Artem Serovcced8ba2017-07-19 18:18:09 +010037 protected:
38 DEFAULT_COPY_CONSTRUCTOR(X86ComputeBaseMethodAddress);
Mark Mendell0616ae02015-04-17 12:49:27 -040039};
40
41// Load a constant value from the constant table.
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010042class HX86LoadFromConstantTable final : public HExpression<2> {
Mark Mendell0616ae02015-04-17 12:49:27 -040043 public:
44 HX86LoadFromConstantTable(HX86ComputeBaseMethodAddress* method_base,
David Brazdilb3e773e2016-01-26 11:28:37 +000045 HConstant* constant)
Gupta Kumar, Sanjivd9e4d732018-02-05 13:35:03 +053046 : HExpression(kX86LoadFromConstantTable,
47 constant->GetType(),
48 SideEffects::None(),
49 kNoDexPc) {
Mark Mendell0616ae02015-04-17 12:49:27 -040050 SetRawInputAt(0, method_base);
51 SetRawInputAt(1, constant);
52 }
53
Mark Mendell0616ae02015-04-17 12:49:27 -040054 HX86ComputeBaseMethodAddress* GetBaseMethodAddress() const {
55 return InputAt(0)->AsX86ComputeBaseMethodAddress();
56 }
57
58 HConstant* GetConstant() const {
59 return InputAt(1)->AsConstant();
60 }
61
62 DECLARE_INSTRUCTION(X86LoadFromConstantTable);
63
Artem Serovcced8ba2017-07-19 18:18:09 +010064 protected:
65 DEFAULT_COPY_CONSTRUCTOR(X86LoadFromConstantTable);
Mark Mendell0616ae02015-04-17 12:49:27 -040066};
67
Mark P Mendell2f10a5f2016-01-25 14:47:50 +000068// Version of HNeg with access to the constant table for FP types.
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010069class HX86FPNeg final : public HExpression<2> {
Mark P Mendell2f10a5f2016-01-25 14:47:50 +000070 public:
Vladimir Marko0ebe0d82017-09-21 22:50:39 +010071 HX86FPNeg(DataType::Type result_type,
Mark P Mendell2f10a5f2016-01-25 14:47:50 +000072 HInstruction* input,
73 HX86ComputeBaseMethodAddress* method_base,
74 uint32_t dex_pc)
Gupta Kumar, Sanjivd9e4d732018-02-05 13:35:03 +053075 : HExpression(kX86FPNeg, result_type, SideEffects::None(), dex_pc) {
Vladimir Marko0ebe0d82017-09-21 22:50:39 +010076 DCHECK(DataType::IsFloatingPointType(result_type));
Mark P Mendell2f10a5f2016-01-25 14:47:50 +000077 SetRawInputAt(0, input);
78 SetRawInputAt(1, method_base);
79 }
80
Nicolas Geoffray133719e2017-01-22 15:44:39 +000081 HX86ComputeBaseMethodAddress* GetBaseMethodAddress() const {
82 return InputAt(1)->AsX86ComputeBaseMethodAddress();
83 }
84
Mark P Mendell2f10a5f2016-01-25 14:47:50 +000085 DECLARE_INSTRUCTION(X86FPNeg);
86
Artem Serovcced8ba2017-07-19 18:18:09 +010087 protected:
88 DEFAULT_COPY_CONSTRUCTOR(X86FPNeg);
Mark P Mendell2f10a5f2016-01-25 14:47:50 +000089};
90
Mark Mendell805b3b52015-09-18 14:10:29 -040091// X86 version of HPackedSwitch that holds a pointer to the base method address.
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010092class HX86PackedSwitch final : public HExpression<2> {
Mark Mendell805b3b52015-09-18 14:10:29 -040093 public:
94 HX86PackedSwitch(int32_t start_value,
95 int32_t num_entries,
96 HInstruction* input,
97 HX86ComputeBaseMethodAddress* method_base,
98 uint32_t dex_pc)
Vladimir Markobd785672018-05-03 17:09:09 +010099 : HExpression(kX86PackedSwitch, SideEffects::None(), dex_pc),
Mark Mendell805b3b52015-09-18 14:10:29 -0400100 start_value_(start_value),
101 num_entries_(num_entries) {
102 SetRawInputAt(0, input);
103 SetRawInputAt(1, method_base);
104 }
105
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100106 bool IsControlFlow() const override { return true; }
Mark Mendell805b3b52015-09-18 14:10:29 -0400107
108 int32_t GetStartValue() const { return start_value_; }
109
110 int32_t GetNumEntries() const { return num_entries_; }
111
112 HX86ComputeBaseMethodAddress* GetBaseMethodAddress() const {
113 return InputAt(1)->AsX86ComputeBaseMethodAddress();
114 }
115
116 HBasicBlock* GetDefaultBlock() const {
117 // Last entry is the default block.
118 return GetBlock()->GetSuccessors()[num_entries_];
119 }
120
121 DECLARE_INSTRUCTION(X86PackedSwitch);
122
Artem Serovcced8ba2017-07-19 18:18:09 +0100123 protected:
124 DEFAULT_COPY_CONSTRUCTOR(X86PackedSwitch);
125
Mark Mendell805b3b52015-09-18 14:10:29 -0400126 private:
127 const int32_t start_value_;
128 const int32_t num_entries_;
Mark Mendell805b3b52015-09-18 14:10:29 -0400129};
130
Shalini Salomi Bodapatidd121f62018-10-26 15:03:53 +0530131class HX86AndNot final : public HBinaryOperation {
132 public:
133 HX86AndNot(DataType::Type result_type,
134 HInstruction* left,
135 HInstruction* right,
136 uint32_t dex_pc = kNoDexPc)
137 : HBinaryOperation(kX86AndNot, result_type, left, right, SideEffects::None(), dex_pc) {
138 }
139
140 bool IsCommutative() const override { return false; }
141
142 template <typename T> static T Compute(T x, T y) { return ~x & y; }
143
144 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override {
145 return GetBlock()->GetGraph()->GetIntConstant(
146 Compute(x->GetValue(), y->GetValue()), GetDexPc());
147 }
148 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override {
149 return GetBlock()->GetGraph()->GetLongConstant(
150 Compute(x->GetValue(), y->GetValue()), GetDexPc());
151 }
152 HConstant* Evaluate(HFloatConstant* x ATTRIBUTE_UNUSED,
153 HFloatConstant* y ATTRIBUTE_UNUSED) const override {
154 LOG(FATAL) << DebugName() << " is not defined for float values";
155 UNREACHABLE();
156 }
157 HConstant* Evaluate(HDoubleConstant* x ATTRIBUTE_UNUSED,
158 HDoubleConstant* y ATTRIBUTE_UNUSED) const override {
159 LOG(FATAL) << DebugName() << " is not defined for double values";
160 UNREACHABLE();
161 }
162
163 DECLARE_INSTRUCTION(X86AndNot);
164
165 protected:
166 DEFAULT_COPY_CONSTRUCTOR(X86AndNot);
167};
168
169class HX86MaskOrResetLeastSetBit final : public HUnaryOperation {
170 public:
171 HX86MaskOrResetLeastSetBit(DataType::Type result_type, InstructionKind op,
172 HInstruction* input, uint32_t dex_pc = kNoDexPc)
173 : HUnaryOperation(kX86MaskOrResetLeastSetBit, result_type, input, dex_pc),
174 op_kind_(op) {
175 DCHECK_EQ(result_type, DataType::Kind(input->GetType()));
176 DCHECK(op == HInstruction::kAnd || op == HInstruction::kXor) << op;
177 }
178 template <typename T>
179 auto Compute(T x) const -> decltype(x & (x-1)) {
180 static_assert(std::is_same<decltype(x & (x-1)), decltype(x ^(x-1))>::value,
181 "Inconsistent bitwise types");
182 switch (op_kind_) {
183 case HInstruction::kAnd:
184 return x & (x-1);
185 case HInstruction::kXor:
186 return x ^ (x-1);
187 default:
188 LOG(FATAL) << "Unreachable";
189 UNREACHABLE();
190 }
191 }
192
193 HConstant* Evaluate(HIntConstant* x) const override {
194 return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue()), GetDexPc());
195 }
196 HConstant* Evaluate(HLongConstant* x) const override {
197 return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue()), GetDexPc());
198 }
199 HConstant* Evaluate(HFloatConstant* x ATTRIBUTE_UNUSED) const override {
200 LOG(FATAL) << DebugName() << "is not defined for float values";
201 UNREACHABLE();
202 }
203 HConstant* Evaluate(HDoubleConstant* x ATTRIBUTE_UNUSED) const override {
204 LOG(FATAL) << DebugName() << "is not defined for double values";
205 UNREACHABLE();
206 }
207 InstructionKind GetOpKind() const { return op_kind_; }
208
209 DECLARE_INSTRUCTION(X86MaskOrResetLeastSetBit);
210
211 protected:
212 const InstructionKind op_kind_;
213
214 DEFAULT_COPY_CONSTRUCTOR(X86MaskOrResetLeastSetBit);
215};
216
Mark Mendell0616ae02015-04-17 12:49:27 -0400217} // namespace art
218
219#endif // ART_COMPILER_OPTIMIZING_NODES_X86_H_