1 /* 2 * Copyright (C) 2014 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 #include "locations.h" 18 19 #include <type_traits> 20 21 #include "code_generator.h" 22 #include "nodes.h" 23 24 namespace art { 25 26 // Verify that Location is trivially copyable. 27 static_assert(std::is_trivially_copyable<Location>::value, "Location should be trivially copyable"); 28 29 LocationSummary::LocationSummary(HInstruction* instruction, 30 CallKind call_kind, 31 bool intrinsified, 32 ArenaAllocator* allocator) 33 : inputs_(instruction->InputCount(), allocator->Adapter(kArenaAllocLocationSummary)), 34 temps_(allocator->Adapter(kArenaAllocLocationSummary)), 35 call_kind_(call_kind), 36 intrinsified_(intrinsified), 37 has_custom_slow_path_calling_convention_(false), 38 output_overlaps_(Location::kOutputOverlap), 39 stack_mask_(nullptr), 40 register_mask_(0), 41 live_registers_(RegisterSet::Empty()), 42 custom_slow_path_caller_saves_(RegisterSet::Empty()) { 43 instruction->SetLocations(this); 44 45 if (NeedsSafepoint()) { 46 stack_mask_ = ArenaBitVector::Create(allocator, 0, true, kArenaAllocLocationSummary); 47 } 48 } 49 50 LocationSummary::LocationSummary(HInstruction* instruction, 51 CallKind call_kind, 52 bool intrinsified) 53 : LocationSummary(instruction, 54 call_kind, 55 intrinsified, 56 instruction->GetBlock()->GetGraph()->GetAllocator()) {} 57 58 Location Location::RegisterOrConstant(HInstruction* instruction) { 59 return instruction->IsConstant() 60 ? Location::ConstantLocation(instruction->AsConstant()) 61 : Location::RequiresRegister(); 62 } 63 64 Location Location::RegisterOrInt32Constant(HInstruction* instruction) { 65 HConstant* constant = instruction->AsConstant(); 66 if (constant != nullptr) { 67 int64_t value = CodeGenerator::GetInt64ValueOf(constant); 68 if (IsInt<32>(value)) { 69 return Location::ConstantLocation(constant); 70 } 71 } 72 return Location::RequiresRegister(); 73 } 74 75 Location Location::FpuRegisterOrInt32Constant(HInstruction* instruction) { 76 HConstant* constant = instruction->AsConstant(); 77 if (constant != nullptr) { 78 int64_t value = CodeGenerator::GetInt64ValueOf(constant); 79 if (IsInt<32>(value)) { 80 return Location::ConstantLocation(constant); 81 } 82 } 83 return Location::RequiresFpuRegister(); 84 } 85 86 Location Location::ByteRegisterOrConstant(int reg, HInstruction* instruction) { 87 return instruction->IsConstant() 88 ? Location::ConstantLocation(instruction->AsConstant()) 89 : Location::RegisterLocation(reg); 90 } 91 92 Location Location::FpuRegisterOrConstant(HInstruction* instruction) { 93 return instruction->IsConstant() 94 ? Location::ConstantLocation(instruction->AsConstant()) 95 : Location::RequiresFpuRegister(); 96 } 97 98 std::ostream& operator<<(std::ostream& os, const Location& location) { 99 os << location.DebugString(); 100 if (location.IsRegister() || location.IsFpuRegister()) { 101 os << location.reg(); 102 } else if (location.IsPair()) { 103 os << location.low() << ":" << location.high(); 104 } else if (location.IsStackSlot() || location.IsDoubleStackSlot()) { 105 os << location.GetStackIndex(); 106 } 107 return os; 108 } 109 110 } // namespace art 111