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 
LocationSummary(HInstruction * instruction,CallKind call_kind,bool intrinsified,ArenaAllocator * allocator)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 
LocationSummary(HInstruction * instruction,CallKind call_kind,bool intrinsified)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 
RegisterOrConstant(HInstruction * instruction)58 Location Location::RegisterOrConstant(HInstruction* instruction) {
59   return instruction->IsConstant()
60       ? Location::ConstantLocation(instruction->AsConstant())
61       : Location::RequiresRegister();
62 }
63 
RegisterOrInt32Constant(HInstruction * instruction)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 
FpuRegisterOrInt32Constant(HInstruction * instruction)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 
ByteRegisterOrConstant(int reg,HInstruction * instruction)86 Location Location::ByteRegisterOrConstant(int reg, HInstruction* instruction) {
87   return instruction->IsConstant()
88       ? Location::ConstantLocation(instruction->AsConstant())
89       : Location::RegisterLocation(reg);
90 }
91 
FpuRegisterOrConstant(HInstruction * instruction)92 Location Location::FpuRegisterOrConstant(HInstruction* instruction) {
93   return instruction->IsConstant()
94       ? Location::ConstantLocation(instruction->AsConstant())
95       : Location::RequiresFpuRegister();
96 }
97 
operator <<(std::ostream & os,const Location & location)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