• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
CanBeMoved()62   bool CanBeMoved() const override { return true; }
63 
64   DECLARE_INSTRUCTION(X86LoadFromConstantTable);
65 
66  protected:
67   DEFAULT_COPY_CONSTRUCTOR(X86LoadFromConstantTable);
68 };
69 
70 // Version of HNeg with access to the constant table for FP types.
71 class HX86FPNeg final : public HExpression<2> {
72  public:
HX86FPNeg(DataType::Type result_type,HInstruction * input,HX86ComputeBaseMethodAddress * method_base,uint32_t dex_pc)73   HX86FPNeg(DataType::Type result_type,
74             HInstruction* input,
75             HX86ComputeBaseMethodAddress* method_base,
76             uint32_t dex_pc)
77       : HExpression(kX86FPNeg, result_type, SideEffects::None(), dex_pc) {
78     DCHECK(DataType::IsFloatingPointType(result_type));
79     SetRawInputAt(0, input);
80     SetRawInputAt(1, method_base);
81   }
82 
GetBaseMethodAddress()83   HX86ComputeBaseMethodAddress* GetBaseMethodAddress() const {
84     return InputAt(1)->AsX86ComputeBaseMethodAddress();
85   }
86 
87   DECLARE_INSTRUCTION(X86FPNeg);
88 
89  protected:
90   DEFAULT_COPY_CONSTRUCTOR(X86FPNeg);
91 };
92 
93 // X86 version of HPackedSwitch that holds a pointer to the base method address.
94 class HX86PackedSwitch final : public HExpression<2> {
95  public:
HX86PackedSwitch(int32_t start_value,int32_t num_entries,HInstruction * input,HX86ComputeBaseMethodAddress * method_base,uint32_t dex_pc)96   HX86PackedSwitch(int32_t start_value,
97                    int32_t num_entries,
98                    HInstruction* input,
99                    HX86ComputeBaseMethodAddress* method_base,
100                    uint32_t dex_pc)
101     : HExpression(kX86PackedSwitch, SideEffects::None(), dex_pc),
102       start_value_(start_value),
103       num_entries_(num_entries) {
104     SetRawInputAt(0, input);
105     SetRawInputAt(1, method_base);
106   }
107 
IsControlFlow()108   bool IsControlFlow() const override { return true; }
109 
GetStartValue()110   int32_t GetStartValue() const { return start_value_; }
111 
GetNumEntries()112   int32_t GetNumEntries() const { return num_entries_; }
113 
GetBaseMethodAddress()114   HX86ComputeBaseMethodAddress* GetBaseMethodAddress() const {
115     return InputAt(1)->AsX86ComputeBaseMethodAddress();
116   }
117 
GetDefaultBlock()118   HBasicBlock* GetDefaultBlock() const {
119     // Last entry is the default block.
120     return GetBlock()->GetSuccessors()[num_entries_];
121   }
122 
123   DECLARE_INSTRUCTION(X86PackedSwitch);
124 
125  protected:
126   DEFAULT_COPY_CONSTRUCTOR(X86PackedSwitch);
127 
128  private:
129   const int32_t start_value_;
130   const int32_t num_entries_;
131 };
132 
133 class HX86AndNot final : public HBinaryOperation {
134  public:
135   HX86AndNot(DataType::Type result_type,
136        HInstruction* left,
137        HInstruction* right,
138        uint32_t dex_pc = kNoDexPc)
HBinaryOperation(kX86AndNot,result_type,left,right,SideEffects::None (),dex_pc)139       : HBinaryOperation(kX86AndNot, result_type, left, right, SideEffects::None(), dex_pc) {
140   }
141 
IsCommutative()142   bool IsCommutative() const override { return false; }
143 
Compute(T x,T y)144   template <typename T> static T Compute(T x, T y) { return ~x & y; }
145 
Evaluate(HIntConstant * x,HIntConstant * y)146   HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override {
147     return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
148   }
Evaluate(HLongConstant * x,HLongConstant * y)149   HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override {
150     return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue()));
151   }
152 
153   DECLARE_INSTRUCTION(X86AndNot);
154 
155  protected:
156   DEFAULT_COPY_CONSTRUCTOR(X86AndNot);
157 };
158 
159 class HX86MaskOrResetLeastSetBit final : public HUnaryOperation {
160  public:
161   HX86MaskOrResetLeastSetBit(DataType::Type result_type, InstructionKind op,
162                              HInstruction* input, uint32_t dex_pc = kNoDexPc)
HUnaryOperation(kX86MaskOrResetLeastSetBit,result_type,input,dex_pc)163       : HUnaryOperation(kX86MaskOrResetLeastSetBit, result_type, input, dex_pc),
164         op_kind_(op) {
165     DCHECK_EQ(result_type, DataType::Kind(input->GetType()));
166     DCHECK(op == HInstruction::kAnd || op == HInstruction::kXor) << op;
167   }
168   template <typename T>
169   auto Compute(T x) const -> decltype(x & (x-1)) {
170     static_assert(std::is_same<decltype(x & (x-1)), decltype(x ^(x-1))>::value,
171                   "Inconsistent  bitwise types");
172     switch (op_kind_) {
173       case HInstruction::kAnd:
174         return x & (x-1);
175       case HInstruction::kXor:
176         return x ^ (x-1);
177       default:
178         LOG(FATAL) << "Unreachable";
179         UNREACHABLE();
180     }
181   }
182 
Evaluate(HIntConstant * x)183   HConstant* Evaluate(HIntConstant* x) const override {
184     return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue()));
185   }
Evaluate(HLongConstant * x)186   HConstant* Evaluate(HLongConstant* x) const override {
187     return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue()));
188   }
189 
GetOpKind()190   InstructionKind GetOpKind() const { return op_kind_; }
191 
192   DECLARE_INSTRUCTION(X86MaskOrResetLeastSetBit);
193 
194  protected:
195   const InstructionKind op_kind_;
196 
197   DEFAULT_COPY_CONSTRUCTOR(X86MaskOrResetLeastSetBit);
198 };
199 
200 }  // namespace art
201 
202 #endif  // ART_COMPILER_OPTIMIZING_NODES_X86_H_
203