| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 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 |  | 
| Vladimir Marko | 0f7dca4 | 2015-11-02 14:36:43 +0000 | [diff] [blame] | 17 | #include "pc_relative_fixups_x86.h" | 
| Vladimir Marko | f3e0ee2 | 2015-12-17 15:23:13 +0000 | [diff] [blame] | 18 | #include "code_generator_x86.h" | 
| Aart Bik | d1c4045 | 2016-03-02 16:06:13 -0800 | [diff] [blame] | 19 | #include "intrinsics_x86.h" | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 20 |  | 
| Vladimir Marko | e272715 | 2019-10-10 10:46:42 +0100 | [diff] [blame^] | 21 | namespace art HIDDEN { | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 22 | namespace x86 { | 
 | 23 |  | 
 | 24 | /** | 
 | 25 |  * Finds instructions that need the constant area base as an input. | 
 | 26 |  */ | 
| Vladimir Marko | 0f7dca4 | 2015-11-02 14:36:43 +0000 | [diff] [blame] | 27 | class PCRelativeHandlerVisitor : public HGraphVisitor { | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 28 |  public: | 
| Aart Bik | d1c4045 | 2016-03-02 16:06:13 -0800 | [diff] [blame] | 29 |   PCRelativeHandlerVisitor(HGraph* graph, CodeGenerator* codegen) | 
 | 30 |       : HGraphVisitor(graph), | 
 | 31 |         codegen_(down_cast<CodeGeneratorX86*>(codegen)), | 
 | 32 |         base_(nullptr) {} | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 33 |  | 
| Vladimir Marko | fb337ea | 2015-11-25 15:25:10 +0000 | [diff] [blame] | 34 |   void MoveBaseIfNeeded() { | 
 | 35 |     if (base_ != nullptr) { | 
 | 36 |       // Bring the base closer to the first use (previously, it was in the | 
 | 37 |       // entry block) and relieve some pressure on the register allocator | 
 | 38 |       // while avoiding recalculation of the base in a loop. | 
 | 39 |       base_->MoveBeforeFirstUserAndOutOfLoops(); | 
 | 40 |     } | 
 | 41 |   } | 
 | 42 |  | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 43 |  private: | 
| Roland Levillain | bbc6e7e | 2018-08-24 16:58:47 +0100 | [diff] [blame] | 44 |   void VisitAdd(HAdd* add) override { | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 45 |     BinaryFP(add); | 
 | 46 |   } | 
 | 47 |  | 
| Roland Levillain | bbc6e7e | 2018-08-24 16:58:47 +0100 | [diff] [blame] | 48 |   void VisitSub(HSub* sub) override { | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 49 |     BinaryFP(sub); | 
 | 50 |   } | 
 | 51 |  | 
| Roland Levillain | bbc6e7e | 2018-08-24 16:58:47 +0100 | [diff] [blame] | 52 |   void VisitMul(HMul* mul) override { | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 53 |     BinaryFP(mul); | 
 | 54 |   } | 
 | 55 |  | 
| Roland Levillain | bbc6e7e | 2018-08-24 16:58:47 +0100 | [diff] [blame] | 56 |   void VisitDiv(HDiv* div) override { | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 57 |     BinaryFP(div); | 
 | 58 |   } | 
 | 59 |  | 
| Roland Levillain | bbc6e7e | 2018-08-24 16:58:47 +0100 | [diff] [blame] | 60 |   void VisitCompare(HCompare* compare) override { | 
| Mark P Mendell | 2f10a5f | 2016-01-25 14:47:50 +0000 | [diff] [blame] | 61 |     BinaryFP(compare); | 
 | 62 |   } | 
 | 63 |  | 
| Roland Levillain | bbc6e7e | 2018-08-24 16:58:47 +0100 | [diff] [blame] | 64 |   void VisitReturn(HReturn* ret) override { | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 65 |     HConstant* value = ret->InputAt(0)->AsConstant(); | 
| Vladimir Marko | 0ebe0d8 | 2017-09-21 22:50:39 +0100 | [diff] [blame] | 66 |     if ((value != nullptr && DataType::IsFloatingPointType(value->GetType()))) { | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 67 |       ReplaceInput(ret, value, 0, true); | 
 | 68 |     } | 
 | 69 |   } | 
 | 70 |  | 
| Roland Levillain | bbc6e7e | 2018-08-24 16:58:47 +0100 | [diff] [blame] | 71 |   void VisitInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke) override { | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 72 |     HandleInvoke(invoke); | 
 | 73 |   } | 
 | 74 |  | 
| Roland Levillain | bbc6e7e | 2018-08-24 16:58:47 +0100 | [diff] [blame] | 75 |   void VisitInvokeVirtual(HInvokeVirtual* invoke) override { | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 76 |     HandleInvoke(invoke); | 
 | 77 |   } | 
 | 78 |  | 
| Roland Levillain | bbc6e7e | 2018-08-24 16:58:47 +0100 | [diff] [blame] | 79 |   void VisitInvokeInterface(HInvokeInterface* invoke) override { | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 80 |     HandleInvoke(invoke); | 
 | 81 |   } | 
 | 82 |  | 
| Roland Levillain | bbc6e7e | 2018-08-24 16:58:47 +0100 | [diff] [blame] | 83 |   void VisitLoadClass(HLoadClass* load_class) override { | 
| Vladimir Marko | e47f60c | 2018-02-21 13:43:28 +0000 | [diff] [blame] | 84 |     if (load_class->HasPcRelativeLoadKind()) { | 
| Nicolas Geoffray | 133719e | 2017-01-22 15:44:39 +0000 | [diff] [blame] | 85 |       HX86ComputeBaseMethodAddress* method_address = GetPCRelativeBasePointer(load_class); | 
 | 86 |       load_class->AddSpecialInput(method_address); | 
| Vladimir Marko | dbb7f5b | 2016-03-30 13:23:58 +0100 | [diff] [blame] | 87 |     } | 
 | 88 |   } | 
 | 89 |  | 
| Roland Levillain | bbc6e7e | 2018-08-24 16:58:47 +0100 | [diff] [blame] | 90 |   void VisitLoadString(HLoadString* load_string) override { | 
| Vladimir Marko | e47f60c | 2018-02-21 13:43:28 +0000 | [diff] [blame] | 91 |     if (load_string->HasPcRelativeLoadKind()) { | 
| Nicolas Geoffray | 133719e | 2017-01-22 15:44:39 +0000 | [diff] [blame] | 92 |       HX86ComputeBaseMethodAddress* method_address = GetPCRelativeBasePointer(load_string); | 
 | 93 |       load_string->AddSpecialInput(method_address); | 
| Vladimir Marko | cac5a7e | 2016-02-22 10:39:50 +0000 | [diff] [blame] | 94 |     } | 
 | 95 |   } | 
 | 96 |  | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 97 |   void BinaryFP(HBinaryOperation* bin) { | 
 | 98 |     HConstant* rhs = bin->InputAt(1)->AsConstant(); | 
| Vladimir Marko | 0ebe0d8 | 2017-09-21 22:50:39 +0100 | [diff] [blame] | 99 |     if (rhs != nullptr && DataType::IsFloatingPointType(rhs->GetType())) { | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 100 |       ReplaceInput(bin, rhs, 1, false); | 
 | 101 |     } | 
 | 102 |   } | 
 | 103 |  | 
| Roland Levillain | bbc6e7e | 2018-08-24 16:58:47 +0100 | [diff] [blame] | 104 |   void VisitEqual(HEqual* cond) override { | 
| Mark P Mendell | 2f10a5f | 2016-01-25 14:47:50 +0000 | [diff] [blame] | 105 |     BinaryFP(cond); | 
 | 106 |   } | 
 | 107 |  | 
| Roland Levillain | bbc6e7e | 2018-08-24 16:58:47 +0100 | [diff] [blame] | 108 |   void VisitNotEqual(HNotEqual* cond) override { | 
| Mark P Mendell | 2f10a5f | 2016-01-25 14:47:50 +0000 | [diff] [blame] | 109 |     BinaryFP(cond); | 
 | 110 |   } | 
 | 111 |  | 
| Roland Levillain | bbc6e7e | 2018-08-24 16:58:47 +0100 | [diff] [blame] | 112 |   void VisitLessThan(HLessThan* cond) override { | 
| Mark P Mendell | 2f10a5f | 2016-01-25 14:47:50 +0000 | [diff] [blame] | 113 |     BinaryFP(cond); | 
 | 114 |   } | 
 | 115 |  | 
| Roland Levillain | bbc6e7e | 2018-08-24 16:58:47 +0100 | [diff] [blame] | 116 |   void VisitLessThanOrEqual(HLessThanOrEqual* cond) override { | 
| Mark P Mendell | 2f10a5f | 2016-01-25 14:47:50 +0000 | [diff] [blame] | 117 |     BinaryFP(cond); | 
 | 118 |   } | 
 | 119 |  | 
| Roland Levillain | bbc6e7e | 2018-08-24 16:58:47 +0100 | [diff] [blame] | 120 |   void VisitGreaterThan(HGreaterThan* cond) override { | 
| Mark P Mendell | 2f10a5f | 2016-01-25 14:47:50 +0000 | [diff] [blame] | 121 |     BinaryFP(cond); | 
 | 122 |   } | 
 | 123 |  | 
| Roland Levillain | bbc6e7e | 2018-08-24 16:58:47 +0100 | [diff] [blame] | 124 |   void VisitGreaterThanOrEqual(HGreaterThanOrEqual* cond) override { | 
| Mark P Mendell | 2f10a5f | 2016-01-25 14:47:50 +0000 | [diff] [blame] | 125 |     BinaryFP(cond); | 
 | 126 |   } | 
 | 127 |  | 
| Roland Levillain | bbc6e7e | 2018-08-24 16:58:47 +0100 | [diff] [blame] | 128 |   void VisitNeg(HNeg* neg) override { | 
| Vladimir Marko | 0ebe0d8 | 2017-09-21 22:50:39 +0100 | [diff] [blame] | 129 |     if (DataType::IsFloatingPointType(neg->GetType())) { | 
| Mark P Mendell | 2f10a5f | 2016-01-25 14:47:50 +0000 | [diff] [blame] | 130 |       // We need to replace the HNeg with a HX86FPNeg in order to address the constant area. | 
| Nicolas Geoffray | 133719e | 2017-01-22 15:44:39 +0000 | [diff] [blame] | 131 |       HX86ComputeBaseMethodAddress* method_address = GetPCRelativeBasePointer(neg); | 
| Mark P Mendell | 2f10a5f | 2016-01-25 14:47:50 +0000 | [diff] [blame] | 132 |       HGraph* graph = GetGraph(); | 
 | 133 |       HBasicBlock* block = neg->GetBlock(); | 
| Vladimir Marko | ca6fff8 | 2017-10-03 14:49:14 +0100 | [diff] [blame] | 134 |       HX86FPNeg* x86_fp_neg = new (graph->GetAllocator()) HX86FPNeg( | 
| Mark P Mendell | 2f10a5f | 2016-01-25 14:47:50 +0000 | [diff] [blame] | 135 |           neg->GetType(), | 
 | 136 |           neg->InputAt(0), | 
| Nicolas Geoffray | 133719e | 2017-01-22 15:44:39 +0000 | [diff] [blame] | 137 |           method_address, | 
| Mark P Mendell | 2f10a5f | 2016-01-25 14:47:50 +0000 | [diff] [blame] | 138 |           neg->GetDexPc()); | 
 | 139 |       block->ReplaceAndRemoveInstructionWith(neg, x86_fp_neg); | 
 | 140 |     } | 
 | 141 |   } | 
 | 142 |  | 
| Roland Levillain | bbc6e7e | 2018-08-24 16:58:47 +0100 | [diff] [blame] | 143 |   void VisitPackedSwitch(HPackedSwitch* switch_insn) override { | 
| Vladimir Marko | f3e0ee2 | 2015-12-17 15:23:13 +0000 | [diff] [blame] | 144 |     if (switch_insn->GetNumEntries() <= | 
 | 145 |         InstructionCodeGeneratorX86::kPackedSwitchJumpTableThreshold) { | 
 | 146 |       return; | 
 | 147 |     } | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 148 |     // We need to replace the HPackedSwitch with a HX86PackedSwitch in order to | 
 | 149 |     // address the constant area. | 
| Nicolas Geoffray | 133719e | 2017-01-22 15:44:39 +0000 | [diff] [blame] | 150 |     HX86ComputeBaseMethodAddress* method_address = GetPCRelativeBasePointer(switch_insn); | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 151 |     HGraph* graph = GetGraph(); | 
 | 152 |     HBasicBlock* block = switch_insn->GetBlock(); | 
| Vladimir Marko | ca6fff8 | 2017-10-03 14:49:14 +0100 | [diff] [blame] | 153 |     HX86PackedSwitch* x86_switch = new (graph->GetAllocator()) HX86PackedSwitch( | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 154 |         switch_insn->GetStartValue(), | 
 | 155 |         switch_insn->GetNumEntries(), | 
 | 156 |         switch_insn->InputAt(0), | 
| Nicolas Geoffray | 133719e | 2017-01-22 15:44:39 +0000 | [diff] [blame] | 157 |         method_address, | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 158 |         switch_insn->GetDexPc()); | 
 | 159 |     block->ReplaceAndRemoveInstructionWith(switch_insn, x86_switch); | 
 | 160 |   } | 
 | 161 |  | 
| Nicolas Geoffray | 133719e | 2017-01-22 15:44:39 +0000 | [diff] [blame] | 162 |   HX86ComputeBaseMethodAddress* GetPCRelativeBasePointer(HInstruction* cursor) { | 
 | 163 |     bool has_irreducible_loops = GetGraph()->HasIrreducibleLoops(); | 
 | 164 |     if (!has_irreducible_loops) { | 
 | 165 |       // Ensure we only initialize the pointer once. | 
 | 166 |       if (base_ != nullptr) { | 
 | 167 |         return base_; | 
 | 168 |       } | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 169 |     } | 
| Vladimir Marko | fb337ea | 2015-11-25 15:25:10 +0000 | [diff] [blame] | 170 |     // Insert the base at the start of the entry block, move it to a better | 
 | 171 |     // position later in MoveBaseIfNeeded(). | 
| Nicolas Geoffray | 133719e | 2017-01-22 15:44:39 +0000 | [diff] [blame] | 172 |     HX86ComputeBaseMethodAddress* method_address = | 
| Vladimir Marko | ca6fff8 | 2017-10-03 14:49:14 +0100 | [diff] [blame] | 173 |         new (GetGraph()->GetAllocator()) HX86ComputeBaseMethodAddress(); | 
| Nicolas Geoffray | 133719e | 2017-01-22 15:44:39 +0000 | [diff] [blame] | 174 |     if (has_irreducible_loops) { | 
 | 175 |       cursor->GetBlock()->InsertInstructionBefore(method_address, cursor); | 
 | 176 |     } else { | 
 | 177 |       HBasicBlock* entry_block = GetGraph()->GetEntryBlock(); | 
 | 178 |       entry_block->InsertInstructionBefore(method_address, entry_block->GetFirstInstruction()); | 
 | 179 |       base_ = method_address; | 
 | 180 |     } | 
 | 181 |     return method_address; | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 182 |   } | 
 | 183 |  | 
 | 184 |   void ReplaceInput(HInstruction* insn, HConstant* value, int input_index, bool materialize) { | 
| Nicolas Geoffray | 133719e | 2017-01-22 15:44:39 +0000 | [diff] [blame] | 185 |     HX86ComputeBaseMethodAddress* method_address = GetPCRelativeBasePointer(insn); | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 186 |     HX86LoadFromConstantTable* load_constant = | 
| Vladimir Marko | ca6fff8 | 2017-10-03 14:49:14 +0100 | [diff] [blame] | 187 |         new (GetGraph()->GetAllocator()) HX86LoadFromConstantTable(method_address, value); | 
| David Brazdil | b3e773e | 2016-01-26 11:28:37 +0000 | [diff] [blame] | 188 |     if (!materialize) { | 
 | 189 |       load_constant->MarkEmittedAtUseSite(); | 
 | 190 |     } | 
| Vladimir Marko | 0f7dca4 | 2015-11-02 14:36:43 +0000 | [diff] [blame] | 191 |     insn->GetBlock()->InsertInstructionBefore(load_constant, insn); | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 192 |     insn->ReplaceInput(load_constant, input_index); | 
 | 193 |   } | 
 | 194 |  | 
 | 195 |   void HandleInvoke(HInvoke* invoke) { | 
| Vladimir Marko | 0f7dca4 | 2015-11-02 14:36:43 +0000 | [diff] [blame] | 196 |     HInvokeStaticOrDirect* invoke_static_or_direct = invoke->AsInvokeStaticOrDirect(); | 
| Vladimir Marko | eebb821 | 2018-06-05 14:57:24 +0100 | [diff] [blame] | 197 |  | 
 | 198 |     // We can't add the method address if we already have a current method pointer. | 
 | 199 |     // This may arise when sharpening doesn't remove the current method pointer from the invoke. | 
 | 200 |     if (invoke_static_or_direct != nullptr && invoke_static_or_direct->HasCurrentMethodInput()) { | 
 | 201 |       // Note: This happens only for recursive calls (including compiling an intrinsic | 
 | 202 |       // by faking a call to itself; we use kRuntimeCall for this case). | 
| Vladimir Marko | 6597946 | 2017-05-19 17:25:12 +0100 | [diff] [blame] | 203 |       DCHECK(!invoke_static_or_direct->HasPcRelativeMethodLoadKind()); | 
| Mark P Mendell | 2f10a5f | 2016-01-25 14:47:50 +0000 | [diff] [blame] | 204 |       return; | 
 | 205 |     } | 
 | 206 |  | 
| Vladimir Marko | eebb821 | 2018-06-05 14:57:24 +0100 | [diff] [blame] | 207 |     // If this is an invoke-static/-direct with PC-relative addressing (within boot image | 
 | 208 |     // or using .bss or .data.bimg.rel.ro), we need the PC-relative address base. | 
| Mark P Mendell | 2f10a5f | 2016-01-25 14:47:50 +0000 | [diff] [blame] | 209 |     bool base_added = false; | 
| Aart Bik | d1c4045 | 2016-03-02 16:06:13 -0800 | [diff] [blame] | 210 |     if (invoke_static_or_direct != nullptr && | 
| Vladimir Marko | 6597946 | 2017-05-19 17:25:12 +0100 | [diff] [blame] | 211 |         invoke_static_or_direct->HasPcRelativeMethodLoadKind() && | 
| Vladimir Marko | 68c981f | 2016-08-26 13:13:33 +0100 | [diff] [blame] | 212 |         !IsCallFreeIntrinsic<IntrinsicLocationsBuilderX86>(invoke, codegen_)) { | 
| Nicolas Geoffray | 133719e | 2017-01-22 15:44:39 +0000 | [diff] [blame] | 213 |       HX86ComputeBaseMethodAddress* method_address = GetPCRelativeBasePointer(invoke); | 
 | 214 |       // Add the extra parameter. | 
 | 215 |       invoke_static_or_direct->AddSpecialInput(method_address); | 
| Mark P Mendell | 2f10a5f | 2016-01-25 14:47:50 +0000 | [diff] [blame] | 216 |       base_added = true; | 
| Vladimir Marko | 0f7dca4 | 2015-11-02 14:36:43 +0000 | [diff] [blame] | 217 |     } | 
| Mark P Mendell | 2f10a5f | 2016-01-25 14:47:50 +0000 | [diff] [blame] | 218 |  | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 219 |     // Ensure that we can load FP arguments from the constant area. | 
| Vladimir Marko | e900491 | 2016-06-16 16:50:52 +0100 | [diff] [blame] | 220 |     HInputsRef inputs = invoke->GetInputs(); | 
| Vladimir Marko | 372f10e | 2016-05-17 16:30:10 +0100 | [diff] [blame] | 221 |     for (size_t i = 0; i < inputs.size(); i++) { | 
 | 222 |       HConstant* input = inputs[i]->AsConstant(); | 
| Vladimir Marko | 0ebe0d8 | 2017-09-21 22:50:39 +0100 | [diff] [blame] | 223 |       if (input != nullptr && DataType::IsFloatingPointType(input->GetType())) { | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 224 |         ReplaceInput(invoke, input, i, true); | 
 | 225 |       } | 
 | 226 |     } | 
| Mark P Mendell | 2f10a5f | 2016-01-25 14:47:50 +0000 | [diff] [blame] | 227 |  | 
| Mark P Mendell | 2f10a5f | 2016-01-25 14:47:50 +0000 | [diff] [blame] | 228 |     switch (invoke->GetIntrinsic()) { | 
| Vladimir Marko | eebb821 | 2018-06-05 14:57:24 +0100 | [diff] [blame] | 229 |       case Intrinsics::kIntegerValueOf: | 
 | 230 |         // This intrinsic can be call free if it loads the address of the boot image object. | 
 | 231 |         // If we're compiling PIC, we need the address base for loading from .data.bimg.rel.ro. | 
| Vladimir Marko | a2da9b9 | 2018-10-10 14:21:55 +0100 | [diff] [blame] | 232 |         if (!codegen_->GetCompilerOptions().GetCompilePic()) { | 
| Vladimir Marko | eebb821 | 2018-06-05 14:57:24 +0100 | [diff] [blame] | 233 |           break; | 
 | 234 |         } | 
 | 235 |         FALLTHROUGH_INTENDED; | 
| Aart Bik | 2c9f495 | 2016-08-01 16:52:27 -0700 | [diff] [blame] | 236 |       case Intrinsics::kMathRoundFloat: | 
| Vladimir Marko | eebb821 | 2018-06-05 14:57:24 +0100 | [diff] [blame] | 237 |         // This intrinsic needs the constant area. | 
| Mark P Mendell | 2f10a5f | 2016-01-25 14:47:50 +0000 | [diff] [blame] | 238 |         if (!base_added) { | 
 | 239 |           DCHECK(invoke_static_or_direct != nullptr); | 
 | 240 |           DCHECK(!invoke_static_or_direct->HasCurrentMethodInput()); | 
| Nicolas Geoffray | 133719e | 2017-01-22 15:44:39 +0000 | [diff] [blame] | 241 |           HX86ComputeBaseMethodAddress* method_address = GetPCRelativeBasePointer(invoke); | 
 | 242 |           invoke_static_or_direct->AddSpecialInput(method_address); | 
| Mark P Mendell | 2f10a5f | 2016-01-25 14:47:50 +0000 | [diff] [blame] | 243 |         } | 
 | 244 |         break; | 
 | 245 |       default: | 
 | 246 |         break; | 
 | 247 |     } | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 248 |   } | 
 | 249 |  | 
| Aart Bik | d1c4045 | 2016-03-02 16:06:13 -0800 | [diff] [blame] | 250 |   CodeGeneratorX86* codegen_; | 
 | 251 |  | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 252 |   // The generated HX86ComputeBaseMethodAddress in the entry block needed as an | 
| Nicolas Geoffray | 133719e | 2017-01-22 15:44:39 +0000 | [diff] [blame] | 253 |   // input to the HX86LoadFromConstantTable instructions. Only set for | 
 | 254 |   // graphs with reducible loops. | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 255 |   HX86ComputeBaseMethodAddress* base_; | 
 | 256 | }; | 
 | 257 |  | 
| Aart Bik | 2477320 | 2018-04-26 10:28:51 -0700 | [diff] [blame] | 258 | bool PcRelativeFixups::Run() { | 
| Aart Bik | d1c4045 | 2016-03-02 16:06:13 -0800 | [diff] [blame] | 259 |   PCRelativeHandlerVisitor visitor(graph_, codegen_); | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 260 |   visitor.VisitInsertionOrder(); | 
| Vladimir Marko | fb337ea | 2015-11-25 15:25:10 +0000 | [diff] [blame] | 261 |   visitor.MoveBaseIfNeeded(); | 
| Aart Bik | 2477320 | 2018-04-26 10:28:51 -0700 | [diff] [blame] | 262 |   return true; | 
| Mark Mendell | 9499107 | 2015-10-06 14:58:32 -0400 | [diff] [blame] | 263 | } | 
 | 264 |  | 
 | 265 | }  // namespace x86 | 
 | 266 | }  // namespace art |