blob: 5d92bfd9ccb72b3aebd3500ee22feb98b4d4bd9d [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
20// TODO(VIXL): Make VIXL compile with -Wshadow.
21#pragma GCC diagnostic push
22#pragma GCC diagnostic ignored "-Wshadow"
23#include "aarch32/macro-assembler-aarch32.h"
24#pragma GCC diagnostic pop
25
26namespace art {
27namespace arm {
28namespace helpers {
29
30static_assert(vixl::aarch32::kSpCode == SP, "vixl::aarch32::kSpCode must equal ART's SP");
31
32inline dwarf::Reg DWARFReg(vixl::aarch32::Register reg) {
33 return dwarf::Reg::ArmCore(static_cast<int>(reg.GetCode()));
34}
35
36inline dwarf::Reg DWARFReg(vixl::aarch32::SRegister reg) {
37 return dwarf::Reg::ArmFp(static_cast<int>(reg.GetCode()));
38}
39
40inline vixl::aarch32::DRegister FromLowSToD(vixl::aarch32::SRegister reg) {
41 DCHECK_EQ(reg.GetCode() % 2, 0u) << reg;
42 return vixl::aarch32::DRegister(reg.GetCode() / 2);
43}
44
Scott Wakelinga7812ae2016-10-17 10:03:36 +010045inline vixl::aarch32::Register HighRegisterFrom(Location location) {
46 DCHECK(location.IsRegisterPair()) << location;
47 return vixl::aarch32::Register(location.AsRegisterPairHigh<vixl32::Register>());
48}
49
50inline vixl::aarch32::DRegister HighDRegisterFrom(Location location) {
51 DCHECK(location.IsFpuRegisterPair()) << location;
52 return vixl::aarch32::DRegister(location.AsFpuRegisterPairHigh<vixl32::DRegister>());
53}
54
55inline vixl::aarch32::Register LowRegisterFrom(Location location) {
56 DCHECK(location.IsRegisterPair()) << location;
57 return vixl::aarch32::Register(location.AsRegisterPairLow<vixl32::Register>());
58}
59
60inline vixl::aarch32::SRegister LowSRegisterFrom(Location location) {
61 DCHECK(location.IsFpuRegisterPair()) << location;
62 return vixl::aarch32::SRegister(location.AsFpuRegisterPairLow<vixl32::SRegister>());
63}
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
138inline int64_t Int64ConstantFrom(Location location) {
139 HConstant* instr = location.GetConstant();
140 if (instr->IsIntConstant()) {
141 return instr->AsIntConstant()->GetValue();
142 } else if (instr->IsNullConstant()) {
143 return 0;
144 } else {
145 DCHECK(instr->IsLongConstant()) << instr->DebugName();
146 return instr->AsLongConstant()->GetValue();
147 }
148}
149
150inline vixl::aarch32::Operand OperandFrom(Location location, Primitive::Type type) {
151 if (location.IsRegister()) {
152 return vixl::aarch32::Operand(RegisterFrom(location, type));
153 } else {
154 return vixl::aarch32::Operand(Int64ConstantFrom(location));
155 }
156}
157
158inline vixl::aarch32::Operand InputOperandAt(HInstruction* instr, int input_index) {
159 return OperandFrom(instr->GetLocations()->InAt(input_index),
160 instr->InputAt(input_index)->GetType());
161}
162
Scott Wakelinga7812ae2016-10-17 10:03:36 +0100163inline Location LocationFrom(const vixl::aarch32::Register& reg) {
164 return Location::RegisterLocation(reg.GetCode());
165}
166
167inline Location LocationFrom(const vixl::aarch32::SRegister& reg) {
168 return Location::FpuRegisterLocation(reg.GetCode());
169}
170
171inline Location LocationFrom(const vixl::aarch32::Register& low,
172 const vixl::aarch32::Register& high) {
173 return Location::RegisterPairLocation(low.GetCode(), high.GetCode());
174}
175
176inline Location LocationFrom(const vixl::aarch32::SRegister& low,
177 const vixl::aarch32::SRegister& high) {
178 return Location::FpuRegisterPairLocation(low.GetCode(), high.GetCode());
179}
180
Scott Wakelingfe885462016-09-22 10:24:38 +0100181} // namespace helpers
182} // namespace arm
183} // namespace art
184
185#endif // ART_COMPILER_OPTIMIZING_COMMON_ARM_H_