xref: /aosp_15_r20/art/compiler/optimizing/nodes_x86.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1 /*
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 
20 namespace art HIDDEN {
21 
22 // Compute the address of the method for X86 Constant area support.
23 class HX86ComputeBaseMethodAddress final : public HExpression<0> {
24  public:
25   // Treat the value as an int32_t, but it is really a 32 bit native pointer.
HX86ComputeBaseMethodAddress()26   HX86ComputeBaseMethodAddress()
27       : HExpression(kX86ComputeBaseMethodAddress,
28                     DataType::Type::kInt32,
29                     SideEffects::None(),
30                     kNoDexPc) {
31   }
32 
CanBeMoved()33   bool CanBeMoved() const override { return true; }
34 
35   DECLARE_INSTRUCTION(X86ComputeBaseMethodAddress);
36 
37  protected:
38   DEFAULT_COPY_CONSTRUCTOR(X86ComputeBaseMethodAddress);
39 };
40 
41 // Load a constant value from the constant table.
42 class HX86LoadFromConstantTable final : public HExpression<2> {
43  public:
HX86LoadFromConstantTable(HX86ComputeBaseMethodAddress * method_base,HConstant * constant)44   HX86LoadFromConstantTable(HX86ComputeBaseMethodAddress* method_base,
45                             HConstant* constant)
46       : HExpression(kX86LoadFromConstantTable,
47                     constant->GetType(),
48                     SideEffects::None(),
49                     kNoDexPc) {
50     SetRawInputAt(0, method_base);
51     SetRawInputAt(1, constant);
52   }
53 
GetBaseMethodAddress()54   HX86ComputeBaseMethodAddress* GetBaseMethodAddress() const {
55     return InputAt(0)->AsX86ComputeBaseMethodAddress();
56   }
57 
GetConstant()58   HConstant* GetConstant() const {
59     return InputAt(1)->AsConstant();
60   }
61 
62   DECLARE_INSTRUCTION(X86LoadFromConstantTable);
63 
64  protected:
65   DEFAULT_COPY_CONSTRUCTOR(X86LoadFromConstantTable);
66 };
67 
68 // Version of HNeg with access to the constant table for FP types.
69 class HX86FPNeg final : public HExpression<2> {
70  public:
HX86FPNeg(DataType::Type result_type,HInstruction * input,HX86ComputeBaseMethodAddress * method_base,uint32_t dex_pc)71   HX86FPNeg(DataType::Type result_type,
72             HInstruction* input,
73             HX86ComputeBaseMethodAddress* method_base,
74             uint32_t dex_pc)
75       : HExpression(kX86FPNeg, result_type, SideEffects::None(), dex_pc) {
76     DCHECK(DataType::IsFloatingPointType(result_type));
77     SetRawInputAt(0, input);
78     SetRawInputAt(1, method_base);
79   }
80 
GetBaseMethodAddress()81   HX86ComputeBaseMethodAddress* GetBaseMethodAddress() const {
82     return InputAt(1)->AsX86ComputeBaseMethodAddress();
83   }
84 
85   DECLARE_INSTRUCTION(X86FPNeg);
86 
87  protected:
88   DEFAULT_COPY_CONSTRUCTOR(X86FPNeg);
89 };
90 
91 // X86 version of HPackedSwitch that holds a pointer to the base method address.
92 class HX86PackedSwitch final : public HExpression<2> {
93  public:
HX86PackedSwitch(int32_t start_value,int32_t num_entries,HInstruction * input,HX86ComputeBaseMethodAddress * method_base,uint32_t dex_pc)94   HX86PackedSwitch(int32_t start_value,
95                    int32_t num_entries,
96                    HInstruction* input,
97                    HX86ComputeBaseMethodAddress* method_base,
98                    uint32_t dex_pc)
99     : HExpression(kX86PackedSwitch, SideEffects::None(), dex_pc),
100       start_value_(start_value),
101       num_entries_(num_entries) {
102     SetRawInputAt(0, input);
103     SetRawInputAt(1, method_base);
104   }
105 
IsControlFlow()106   bool IsControlFlow() const override { return true; }
107 
GetStartValue()108   int32_t GetStartValue() const { return start_value_; }
109 
GetNumEntries()110   int32_t GetNumEntries() const { return num_entries_; }
111 
GetBaseMethodAddress()112   HX86ComputeBaseMethodAddress* GetBaseMethodAddress() const {
113     return InputAt(1)->AsX86ComputeBaseMethodAddress();
114   }
115 
GetDefaultBlock()116   HBasicBlock* GetDefaultBlock() const {
117     // Last entry is the default block.
118     return GetBlock()->GetSuccessors()[num_entries_];
119   }
120 
121   DECLARE_INSTRUCTION(X86PackedSwitch);
122 
123  protected:
124   DEFAULT_COPY_CONSTRUCTOR(X86PackedSwitch);
125 
126  private:
127   const int32_t start_value_;
128   const int32_t num_entries_;
129 };
130 
131 class HX86AndNot final : public HBinaryOperation {
132  public:
133   HX86AndNot(DataType::Type result_type,
134        HInstruction* left,
135        HInstruction* right,
136        uint32_t dex_pc = kNoDexPc)
HBinaryOperation(kX86AndNot,result_type,left,right,SideEffects::None (),dex_pc)137       : HBinaryOperation(kX86AndNot, result_type, left, right, SideEffects::None(), dex_pc) {
138   }
139 
IsCommutative()140   bool IsCommutative() const override { return false; }
141 
Compute(T x,T y)142   template <typename T> static T Compute(T x, T y) { return ~x & y; }
143 
Evaluate(HIntConstant * x,HIntConstant * y)144   HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override {
145     return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
146   }
Evaluate(HLongConstant * x,HLongConstant * y)147   HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override {
148     return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue()));
149   }
150 
151   DECLARE_INSTRUCTION(X86AndNot);
152 
153  protected:
154   DEFAULT_COPY_CONSTRUCTOR(X86AndNot);
155 };
156 
157 class HX86MaskOrResetLeastSetBit final : public HUnaryOperation {
158  public:
159   HX86MaskOrResetLeastSetBit(DataType::Type result_type, InstructionKind op,
160                              HInstruction* input, uint32_t dex_pc = kNoDexPc)
HUnaryOperation(kX86MaskOrResetLeastSetBit,result_type,input,dex_pc)161       : HUnaryOperation(kX86MaskOrResetLeastSetBit, result_type, input, dex_pc),
162         op_kind_(op) {
163     DCHECK_EQ(result_type, DataType::Kind(input->GetType()));
164     DCHECK(op == HInstruction::kAnd || op == HInstruction::kXor) << op;
165   }
166   template <typename T>
167   auto Compute(T x) const -> decltype(x & (x-1)) {
168     static_assert(std::is_same<decltype(x & (x-1)), decltype(x ^(x-1))>::value,
169                   "Inconsistent  bitwise types");
170     switch (op_kind_) {
171       case HInstruction::kAnd:
172         return x & (x-1);
173       case HInstruction::kXor:
174         return x ^ (x-1);
175       default:
176         LOG(FATAL) << "Unreachable";
177         UNREACHABLE();
178     }
179   }
180 
Evaluate(HIntConstant * x)181   HConstant* Evaluate(HIntConstant* x) const override {
182     return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue()));
183   }
Evaluate(HLongConstant * x)184   HConstant* Evaluate(HLongConstant* x) const override {
185     return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue()));
186   }
187 
GetOpKind()188   InstructionKind GetOpKind() const { return op_kind_; }
189 
190   DECLARE_INSTRUCTION(X86MaskOrResetLeastSetBit);
191 
192  protected:
193   const InstructionKind op_kind_;
194 
195   DEFAULT_COPY_CONSTRUCTOR(X86MaskOrResetLeastSetBit);
196 };
197 
198 }  // namespace art
199 
200 #endif  // ART_COMPILER_OPTIMIZING_NODES_X86_H_
201