1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2014 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker *
4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker *
8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker *
10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker */
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker #include "locations.h"
18*795d594fSAndroid Build Coastguard Worker
19*795d594fSAndroid Build Coastguard Worker #include <type_traits>
20*795d594fSAndroid Build Coastguard Worker
21*795d594fSAndroid Build Coastguard Worker #include "code_generator.h"
22*795d594fSAndroid Build Coastguard Worker #include "nodes.h"
23*795d594fSAndroid Build Coastguard Worker
24*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
25*795d594fSAndroid Build Coastguard Worker
26*795d594fSAndroid Build Coastguard Worker // Verify that Location is trivially copyable.
27*795d594fSAndroid Build Coastguard Worker static_assert(std::is_trivially_copyable<Location>::value, "Location should be trivially copyable");
28*795d594fSAndroid Build Coastguard Worker
LocationSummary(HInstruction * instruction,CallKind call_kind,bool intrinsified,ArenaAllocator * allocator)29*795d594fSAndroid Build Coastguard Worker LocationSummary::LocationSummary(HInstruction* instruction,
30*795d594fSAndroid Build Coastguard Worker CallKind call_kind,
31*795d594fSAndroid Build Coastguard Worker bool intrinsified,
32*795d594fSAndroid Build Coastguard Worker ArenaAllocator* allocator)
33*795d594fSAndroid Build Coastguard Worker : inputs_(instruction->InputCount(), allocator->Adapter(kArenaAllocLocationSummary)),
34*795d594fSAndroid Build Coastguard Worker temps_(allocator->Adapter(kArenaAllocLocationSummary)),
35*795d594fSAndroid Build Coastguard Worker call_kind_(call_kind),
36*795d594fSAndroid Build Coastguard Worker intrinsified_(intrinsified),
37*795d594fSAndroid Build Coastguard Worker has_custom_slow_path_calling_convention_(false),
38*795d594fSAndroid Build Coastguard Worker output_overlaps_(Location::kOutputOverlap),
39*795d594fSAndroid Build Coastguard Worker stack_mask_(nullptr),
40*795d594fSAndroid Build Coastguard Worker register_mask_(0),
41*795d594fSAndroid Build Coastguard Worker live_registers_(RegisterSet::Empty()),
42*795d594fSAndroid Build Coastguard Worker custom_slow_path_caller_saves_(RegisterSet::Empty()) {
43*795d594fSAndroid Build Coastguard Worker instruction->SetLocations(this);
44*795d594fSAndroid Build Coastguard Worker
45*795d594fSAndroid Build Coastguard Worker if (NeedsSafepoint()) {
46*795d594fSAndroid Build Coastguard Worker stack_mask_ = ArenaBitVector::Create(allocator, 0, true, kArenaAllocLocationSummary);
47*795d594fSAndroid Build Coastguard Worker }
48*795d594fSAndroid Build Coastguard Worker }
49*795d594fSAndroid Build Coastguard Worker
LocationSummary(HInstruction * instruction,CallKind call_kind,bool intrinsified)50*795d594fSAndroid Build Coastguard Worker LocationSummary::LocationSummary(HInstruction* instruction,
51*795d594fSAndroid Build Coastguard Worker CallKind call_kind,
52*795d594fSAndroid Build Coastguard Worker bool intrinsified)
53*795d594fSAndroid Build Coastguard Worker : LocationSummary(instruction,
54*795d594fSAndroid Build Coastguard Worker call_kind,
55*795d594fSAndroid Build Coastguard Worker intrinsified,
56*795d594fSAndroid Build Coastguard Worker instruction->GetBlock()->GetGraph()->GetAllocator()) {}
57*795d594fSAndroid Build Coastguard Worker
RegisterOrConstant(HInstruction * instruction)58*795d594fSAndroid Build Coastguard Worker Location Location::RegisterOrConstant(HInstruction* instruction) {
59*795d594fSAndroid Build Coastguard Worker return instruction->IsConstant()
60*795d594fSAndroid Build Coastguard Worker ? Location::ConstantLocation(instruction)
61*795d594fSAndroid Build Coastguard Worker : Location::RequiresRegister();
62*795d594fSAndroid Build Coastguard Worker }
63*795d594fSAndroid Build Coastguard Worker
RegisterOrInt32Constant(HInstruction * instruction)64*795d594fSAndroid Build Coastguard Worker Location Location::RegisterOrInt32Constant(HInstruction* instruction) {
65*795d594fSAndroid Build Coastguard Worker HConstant* constant = instruction->AsConstantOrNull();
66*795d594fSAndroid Build Coastguard Worker if (constant != nullptr) {
67*795d594fSAndroid Build Coastguard Worker int64_t value = CodeGenerator::GetInt64ValueOf(constant);
68*795d594fSAndroid Build Coastguard Worker if (IsInt<32>(value)) {
69*795d594fSAndroid Build Coastguard Worker return Location::ConstantLocation(constant);
70*795d594fSAndroid Build Coastguard Worker }
71*795d594fSAndroid Build Coastguard Worker }
72*795d594fSAndroid Build Coastguard Worker return Location::RequiresRegister();
73*795d594fSAndroid Build Coastguard Worker }
74*795d594fSAndroid Build Coastguard Worker
FpuRegisterOrInt32Constant(HInstruction * instruction)75*795d594fSAndroid Build Coastguard Worker Location Location::FpuRegisterOrInt32Constant(HInstruction* instruction) {
76*795d594fSAndroid Build Coastguard Worker HConstant* constant = instruction->AsConstantOrNull();
77*795d594fSAndroid Build Coastguard Worker if (constant != nullptr) {
78*795d594fSAndroid Build Coastguard Worker int64_t value = CodeGenerator::GetInt64ValueOf(constant);
79*795d594fSAndroid Build Coastguard Worker if (IsInt<32>(value)) {
80*795d594fSAndroid Build Coastguard Worker return Location::ConstantLocation(constant);
81*795d594fSAndroid Build Coastguard Worker }
82*795d594fSAndroid Build Coastguard Worker }
83*795d594fSAndroid Build Coastguard Worker return Location::RequiresFpuRegister();
84*795d594fSAndroid Build Coastguard Worker }
85*795d594fSAndroid Build Coastguard Worker
ByteRegisterOrConstant(int reg,HInstruction * instruction)86*795d594fSAndroid Build Coastguard Worker Location Location::ByteRegisterOrConstant(int reg, HInstruction* instruction) {
87*795d594fSAndroid Build Coastguard Worker return instruction->IsConstant()
88*795d594fSAndroid Build Coastguard Worker ? Location::ConstantLocation(instruction)
89*795d594fSAndroid Build Coastguard Worker : Location::RegisterLocation(reg);
90*795d594fSAndroid Build Coastguard Worker }
91*795d594fSAndroid Build Coastguard Worker
FpuRegisterOrConstant(HInstruction * instruction)92*795d594fSAndroid Build Coastguard Worker Location Location::FpuRegisterOrConstant(HInstruction* instruction) {
93*795d594fSAndroid Build Coastguard Worker return instruction->IsConstant()
94*795d594fSAndroid Build Coastguard Worker ? Location::ConstantLocation(instruction)
95*795d594fSAndroid Build Coastguard Worker : Location::RequiresFpuRegister();
96*795d594fSAndroid Build Coastguard Worker }
97*795d594fSAndroid Build Coastguard Worker
DCheckInstructionIsConstant(HInstruction * instruction)98*795d594fSAndroid Build Coastguard Worker void Location::DCheckInstructionIsConstant(HInstruction* instruction) {
99*795d594fSAndroid Build Coastguard Worker DCHECK(instruction != nullptr);
100*795d594fSAndroid Build Coastguard Worker DCHECK(instruction->IsConstant());
101*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(reinterpret_cast<uintptr_t>(instruction),
102*795d594fSAndroid Build Coastguard Worker reinterpret_cast<uintptr_t>(instruction->AsConstant()));
103*795d594fSAndroid Build Coastguard Worker }
104*795d594fSAndroid Build Coastguard Worker
operator <<(std::ostream & os,const Location & location)105*795d594fSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, const Location& location) {
106*795d594fSAndroid Build Coastguard Worker os << location.DebugString();
107*795d594fSAndroid Build Coastguard Worker if (location.IsRegister() || location.IsFpuRegister()) {
108*795d594fSAndroid Build Coastguard Worker os << location.reg();
109*795d594fSAndroid Build Coastguard Worker } else if (location.IsPair()) {
110*795d594fSAndroid Build Coastguard Worker os << location.low() << ":" << location.high();
111*795d594fSAndroid Build Coastguard Worker } else if (location.IsStackSlot() || location.IsDoubleStackSlot()) {
112*795d594fSAndroid Build Coastguard Worker os << location.GetStackIndex();
113*795d594fSAndroid Build Coastguard Worker }
114*795d594fSAndroid Build Coastguard Worker return os;
115*795d594fSAndroid Build Coastguard Worker }
116*795d594fSAndroid Build Coastguard Worker
117*795d594fSAndroid Build Coastguard Worker } // namespace art
118