blob: eabdbad13c7d567c0dc3b1f67e845f65712b7c90 [file] [log] [blame]
Scott Wakelingfe885462016-09-22 10:24:38 +01001/*
2 * Copyright (C) 2016 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#ifndef ART_COMPILER_OPTIMIZING_COMMON_ARM_H_
18#define ART_COMPILER_OPTIMIZING_COMMON_ARM_H_
19
Artem Serovd4cc5b22016-11-04 11:19:09 +000020#include "debug/dwarf/register.h"
21#include "locations.h"
22#include "nodes.h"
23#include "utils/arm/constants_arm.h"
24
Scott Wakelingfe885462016-09-22 10:24:38 +010025// TODO(VIXL): Make VIXL compile with -Wshadow.
26#pragma GCC diagnostic push
27#pragma GCC diagnostic ignored "-Wshadow"
28#include "aarch32/macro-assembler-aarch32.h"
29#pragma GCC diagnostic pop
30
31namespace art {
32namespace arm {
33namespace helpers {
34
35static_assert(vixl::aarch32::kSpCode == SP, "vixl::aarch32::kSpCode must equal ART's SP");
36
37inline dwarf::Reg DWARFReg(vixl::aarch32::Register reg) {
38 return dwarf::Reg::ArmCore(static_cast<int>(reg.GetCode()));
39}
40
41inline dwarf::Reg DWARFReg(vixl::aarch32::SRegister reg) {
42 return dwarf::Reg::ArmFp(static_cast<int>(reg.GetCode()));
43}
44
Scott Wakelinga7812ae2016-10-17 10:03:36 +010045inline vixl::aarch32::Register HighRegisterFrom(Location location) {
46 DCHECK(location.IsRegisterPair()) << location;
Artem Serovcfbe9132016-10-14 15:58:56 +010047 return vixl::aarch32::Register(location.AsRegisterPairHigh<vixl::aarch32::Register>());
Scott Wakelinga7812ae2016-10-17 10:03:36 +010048}
49
50inline vixl::aarch32::DRegister HighDRegisterFrom(Location location) {
51 DCHECK(location.IsFpuRegisterPair()) << location;
Artem Serovcfbe9132016-10-14 15:58:56 +010052 return vixl::aarch32::DRegister(location.AsFpuRegisterPairHigh<vixl::aarch32::DRegister>());
Scott Wakelinga7812ae2016-10-17 10:03:36 +010053}
54
55inline vixl::aarch32::Register LowRegisterFrom(Location location) {
56 DCHECK(location.IsRegisterPair()) << location;
Artem Serovcfbe9132016-10-14 15:58:56 +010057 return vixl::aarch32::Register(location.AsRegisterPairLow<vixl::aarch32::Register>());
Scott Wakelinga7812ae2016-10-17 10:03:36 +010058}
59
60inline vixl::aarch32::SRegister LowSRegisterFrom(Location location) {
61 DCHECK(location.IsFpuRegisterPair()) << location;
Artem Serovcfbe9132016-10-14 15:58:56 +010062 return vixl::aarch32::SRegister(location.AsFpuRegisterPairLow<vixl::aarch32::SRegister>());
Scott Wakelinga7812ae2016-10-17 10:03:36 +010063}
64
Scott Wakelingfe885462016-09-22 10:24:38 +010065inline vixl::aarch32::Register RegisterFrom(Location location) {
66 DCHECK(location.IsRegister()) << location;
67 return vixl::aarch32::Register(location.reg());
68}
69
70inline vixl::aarch32::Register RegisterFrom(Location location, Primitive::Type type) {
71 DCHECK(type != Primitive::kPrimVoid && !Primitive::IsFloatingPointType(type)) << type;
72 return RegisterFrom(location);
73}
74
75inline vixl::aarch32::DRegister DRegisterFrom(Location location) {
Scott Wakelinga7812ae2016-10-17 10:03:36 +010076 DCHECK(location.IsFpuRegisterPair()) << location;
77 int reg_code = location.low();
78 DCHECK_EQ(reg_code % 2, 0) << reg_code;
79 return vixl::aarch32::DRegister(reg_code / 2);
Scott Wakelingfe885462016-09-22 10:24:38 +010080}
81
82inline vixl::aarch32::SRegister SRegisterFrom(Location location) {
83 DCHECK(location.IsFpuRegister()) << location;
84 return vixl::aarch32::SRegister(location.reg());
85}
86
87inline vixl::aarch32::SRegister OutputSRegister(HInstruction* instr) {
88 Primitive::Type type = instr->GetType();
89 DCHECK_EQ(type, Primitive::kPrimFloat) << type;
90 return SRegisterFrom(instr->GetLocations()->Out());
91}
92
93inline vixl::aarch32::DRegister OutputDRegister(HInstruction* instr) {
94 Primitive::Type type = instr->GetType();
95 DCHECK_EQ(type, Primitive::kPrimDouble) << type;
96 return DRegisterFrom(instr->GetLocations()->Out());
97}
98
Scott Wakelinga7812ae2016-10-17 10:03:36 +010099inline vixl::aarch32::VRegister OutputVRegister(HInstruction* instr) {
100 Primitive::Type type = instr->GetType();
101 if (type == Primitive::kPrimFloat) {
102 return OutputSRegister(instr);
103 } else {
104 return OutputDRegister(instr);
105 }
106}
107
Scott Wakelingfe885462016-09-22 10:24:38 +0100108inline vixl::aarch32::SRegister InputSRegisterAt(HInstruction* instr, int input_index) {
109 Primitive::Type type = instr->InputAt(input_index)->GetType();
110 DCHECK_EQ(type, Primitive::kPrimFloat) << type;
111 return SRegisterFrom(instr->GetLocations()->InAt(input_index));
112}
113
114inline vixl::aarch32::DRegister InputDRegisterAt(HInstruction* instr, int input_index) {
115 Primitive::Type type = instr->InputAt(input_index)->GetType();
116 DCHECK_EQ(type, Primitive::kPrimDouble) << type;
117 return DRegisterFrom(instr->GetLocations()->InAt(input_index));
118}
119
Scott Wakelinga7812ae2016-10-17 10:03:36 +0100120inline vixl::aarch32::VRegister InputVRegisterAt(HInstruction* instr, int input_index) {
121 Primitive::Type type = instr->InputAt(input_index)->GetType();
122 if (type == Primitive::kPrimFloat) {
123 return InputSRegisterAt(instr, input_index);
124 } else {
125 return InputDRegisterAt(instr, input_index);
126 }
127}
128
Scott Wakelingfe885462016-09-22 10:24:38 +0100129inline vixl::aarch32::Register OutputRegister(HInstruction* instr) {
130 return RegisterFrom(instr->GetLocations()->Out(), instr->GetType());
131}
132
133inline vixl::aarch32::Register InputRegisterAt(HInstruction* instr, int input_index) {
134 return RegisterFrom(instr->GetLocations()->InAt(input_index),
135 instr->InputAt(input_index)->GetType());
136}
137
Scott Wakelingc34dba72016-10-03 10:14:44 +0100138inline vixl::aarch32::Register InputRegister(HInstruction* instr) {
139 DCHECK_EQ(instr->InputCount(), 1u);
140 return InputRegisterAt(instr, 0);
141}
142
Anton Kirilove28d9ae2016-10-25 18:17:23 +0100143inline int32_t Int32ConstantFrom(Location location) {
144 HConstant* instr = location.GetConstant();
145 if (instr->IsIntConstant()) {
146 return instr->AsIntConstant()->GetValue();
Scott Wakelingb77051e2016-11-21 19:46:00 +0000147 } else if (instr->IsNullConstant()) {
Anton Kirilove28d9ae2016-10-25 18:17:23 +0100148 return 0;
Scott Wakelingb77051e2016-11-21 19:46:00 +0000149 } else {
150 DCHECK(instr->IsLongConstant()) << instr->DebugName();
151 const int64_t ret = instr->AsLongConstant()->GetValue();
152 DCHECK_GE(ret, std::numeric_limits<int32_t>::min());
153 DCHECK_LE(ret, std::numeric_limits<int32_t>::max());
154 return ret;
Anton Kirilove28d9ae2016-10-25 18:17:23 +0100155 }
156}
157
Scott Wakelingfe885462016-09-22 10:24:38 +0100158inline int64_t Int64ConstantFrom(Location location) {
159 HConstant* instr = location.GetConstant();
160 if (instr->IsIntConstant()) {
161 return instr->AsIntConstant()->GetValue();
162 } else if (instr->IsNullConstant()) {
163 return 0;
164 } else {
165 DCHECK(instr->IsLongConstant()) << instr->DebugName();
166 return instr->AsLongConstant()->GetValue();
167 }
168}
169
170inline vixl::aarch32::Operand OperandFrom(Location location, Primitive::Type type) {
171 if (location.IsRegister()) {
172 return vixl::aarch32::Operand(RegisterFrom(location, type));
173 } else {
Scott Wakelingb77051e2016-11-21 19:46:00 +0000174 return vixl::aarch32::Operand(Int32ConstantFrom(location));
Scott Wakelingfe885462016-09-22 10:24:38 +0100175 }
176}
177
178inline vixl::aarch32::Operand InputOperandAt(HInstruction* instr, int input_index) {
179 return OperandFrom(instr->GetLocations()->InAt(input_index),
180 instr->InputAt(input_index)->GetType());
181}
182
Scott Wakelinga7812ae2016-10-17 10:03:36 +0100183inline Location LocationFrom(const vixl::aarch32::Register& reg) {
184 return Location::RegisterLocation(reg.GetCode());
185}
186
187inline Location LocationFrom(const vixl::aarch32::SRegister& reg) {
188 return Location::FpuRegisterLocation(reg.GetCode());
189}
190
191inline Location LocationFrom(const vixl::aarch32::Register& low,
192 const vixl::aarch32::Register& high) {
193 return Location::RegisterPairLocation(low.GetCode(), high.GetCode());
194}
195
196inline Location LocationFrom(const vixl::aarch32::SRegister& low,
197 const vixl::aarch32::SRegister& high) {
198 return Location::FpuRegisterPairLocation(low.GetCode(), high.GetCode());
199}
200
Scott Wakelingfe885462016-09-22 10:24:38 +0100201} // namespace helpers
202} // namespace arm
203} // namespace art
204
205#endif // ART_COMPILER_OPTIMIZING_COMMON_ARM_H_