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 "nodes.h" 22 #include "code_generator.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 : inputs_(instruction->InputCount(), 33 instruction->GetBlock()->GetGraph()->GetArena()->Adapter(kArenaAllocLocationSummary)), 34 temps_(instruction->GetBlock()->GetGraph()->GetArena()->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 ArenaAllocator* arena = instruction->GetBlock()->GetGraph()->GetArena(); 47 stack_mask_ = ArenaBitVector::Create(arena, 0, true, kArenaAllocLocationSummary); 48 } 49 } 50 51 52 Location Location::RegisterOrConstant(HInstruction* instruction) { 53 return instruction->IsConstant() 54 ? Location::ConstantLocation(instruction->AsConstant()) 55 : Location::RequiresRegister(); 56 } 57 58 Location Location::RegisterOrInt32Constant(HInstruction* instruction) { 59 HConstant* constant = instruction->AsConstant(); 60 if (constant != nullptr) { 61 int64_t value = CodeGenerator::GetInt64ValueOf(constant); 62 if (IsInt<32>(value)) { 63 return Location::ConstantLocation(constant); 64 } 65 } 66 return Location::RequiresRegister(); 67 } 68 69 Location Location::FpuRegisterOrInt32Constant(HInstruction* instruction) { 70 HConstant* constant = instruction->AsConstant(); 71 if (constant != nullptr) { 72 int64_t value = CodeGenerator::GetInt64ValueOf(constant); 73 if (IsInt<32>(value)) { 74 return Location::ConstantLocation(constant); 75 } 76 } 77 return Location::RequiresFpuRegister(); 78 } 79 80 Location Location::ByteRegisterOrConstant(int reg, HInstruction* instruction) { 81 return instruction->IsConstant() 82 ? Location::ConstantLocation(instruction->AsConstant()) 83 : Location::RegisterLocation(reg); 84 } 85 86 Location Location::FpuRegisterOrConstant(HInstruction* instruction) { 87 return instruction->IsConstant() 88 ? Location::ConstantLocation(instruction->AsConstant()) 89 : Location::RequiresFpuRegister(); 90 } 91 92 std::ostream& operator<<(std::ostream& os, const Location& location) { 93 os << location.DebugString(); 94 if (location.IsRegister() || location.IsFpuRegister()) { 95 os << location.reg(); 96 } else if (location.IsPair()) { 97 os << location.low() << ":" << location.high(); 98 } else if (location.IsStackSlot() || location.IsDoubleStackSlot()) { 99 os << location.GetStackIndex(); 100 } 101 return os; 102 } 103 104 } // namespace art 105