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