blob: a187663062d0177ba91f640fa0cea3772058c4bf [file] [log] [blame]
Ian Rogersd582fa42014-11-05 23:46:43 -08001/*
2 * Copyright (C) 2011 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 "instruction_set.h"
18
Andreas Gampe705543e2017-05-24 13:20:49 -070019#include "android-base/logging.h"
Andreas Gamped1262282016-08-11 18:35:58 -070020#include "base/bit_utils.h"
David Sehr1979c642018-04-26 14:41:18 -070021#include "base/globals.h"
Ian Rogersd582fa42014-11-05 23:46:43 -080022
23namespace art {
24
Andreas Gampebda1d602016-08-29 17:43:45 -070025void InstructionSetAbort(InstructionSet isa) {
26 switch (isa) {
Vladimir Marko33bff252017-11-01 14:35:42 +000027 case InstructionSet::kArm:
28 case InstructionSet::kThumb2:
29 case InstructionSet::kArm64:
30 case InstructionSet::kX86:
31 case InstructionSet::kX86_64:
32 case InstructionSet::kMips:
33 case InstructionSet::kMips64:
34 case InstructionSet::kNone:
Andreas Gampebda1d602016-08-29 17:43:45 -070035 LOG(FATAL) << "Unsupported instruction set " << isa;
36 UNREACHABLE();
Andreas Gampebda1d602016-08-29 17:43:45 -070037 }
Andreas Gampe705543e2017-05-24 13:20:49 -070038 LOG(FATAL) << "Unknown ISA " << isa;
39 UNREACHABLE();
Andreas Gampebda1d602016-08-29 17:43:45 -070040}
41
42const char* GetInstructionSetString(InstructionSet isa) {
Ian Rogersd582fa42014-11-05 23:46:43 -080043 switch (isa) {
Vladimir Marko33bff252017-11-01 14:35:42 +000044 case InstructionSet::kArm:
45 case InstructionSet::kThumb2:
Ian Rogersd582fa42014-11-05 23:46:43 -080046 return "arm";
Vladimir Marko33bff252017-11-01 14:35:42 +000047 case InstructionSet::kArm64:
Ian Rogersd582fa42014-11-05 23:46:43 -080048 return "arm64";
Vladimir Marko33bff252017-11-01 14:35:42 +000049 case InstructionSet::kX86:
Ian Rogersd582fa42014-11-05 23:46:43 -080050 return "x86";
Vladimir Marko33bff252017-11-01 14:35:42 +000051 case InstructionSet::kX86_64:
Ian Rogersd582fa42014-11-05 23:46:43 -080052 return "x86_64";
Vladimir Marko33bff252017-11-01 14:35:42 +000053 case InstructionSet::kMips:
Ian Rogersd582fa42014-11-05 23:46:43 -080054 return "mips";
Vladimir Marko33bff252017-11-01 14:35:42 +000055 case InstructionSet::kMips64:
Ian Rogersd582fa42014-11-05 23:46:43 -080056 return "mips64";
Vladimir Marko33bff252017-11-01 14:35:42 +000057 case InstructionSet::kNone:
Ian Rogersd582fa42014-11-05 23:46:43 -080058 return "none";
Ian Rogersd582fa42014-11-05 23:46:43 -080059 }
Andreas Gampe705543e2017-05-24 13:20:49 -070060 LOG(FATAL) << "Unknown ISA " << isa;
61 UNREACHABLE();
Ian Rogersd582fa42014-11-05 23:46:43 -080062}
63
64InstructionSet GetInstructionSetFromString(const char* isa_str) {
65 CHECK(isa_str != nullptr);
66
67 if (strcmp("arm", isa_str) == 0) {
Vladimir Marko33bff252017-11-01 14:35:42 +000068 return InstructionSet::kArm;
Ian Rogersd582fa42014-11-05 23:46:43 -080069 } else if (strcmp("arm64", isa_str) == 0) {
Vladimir Marko33bff252017-11-01 14:35:42 +000070 return InstructionSet::kArm64;
Ian Rogersd582fa42014-11-05 23:46:43 -080071 } else if (strcmp("x86", isa_str) == 0) {
Vladimir Marko33bff252017-11-01 14:35:42 +000072 return InstructionSet::kX86;
Ian Rogersd582fa42014-11-05 23:46:43 -080073 } else if (strcmp("x86_64", isa_str) == 0) {
Vladimir Marko33bff252017-11-01 14:35:42 +000074 return InstructionSet::kX86_64;
Ian Rogersd582fa42014-11-05 23:46:43 -080075 } else if (strcmp("mips", isa_str) == 0) {
Vladimir Marko33bff252017-11-01 14:35:42 +000076 return InstructionSet::kMips;
Ian Rogersd582fa42014-11-05 23:46:43 -080077 } else if (strcmp("mips64", isa_str) == 0) {
Vladimir Marko33bff252017-11-01 14:35:42 +000078 return InstructionSet::kMips64;
Ian Rogersd582fa42014-11-05 23:46:43 -080079 }
80
Vladimir Marko33bff252017-11-01 14:35:42 +000081 return InstructionSet::kNone;
Ian Rogersd582fa42014-11-05 23:46:43 -080082}
83
84size_t GetInstructionSetAlignment(InstructionSet isa) {
85 switch (isa) {
Vladimir Marko33bff252017-11-01 14:35:42 +000086 case InstructionSet::kArm:
Ian Rogersd582fa42014-11-05 23:46:43 -080087 // Fall-through.
Vladimir Marko33bff252017-11-01 14:35:42 +000088 case InstructionSet::kThumb2:
Ian Rogersd582fa42014-11-05 23:46:43 -080089 return kArmAlignment;
Vladimir Marko33bff252017-11-01 14:35:42 +000090 case InstructionSet::kArm64:
Ian Rogersd582fa42014-11-05 23:46:43 -080091 return kArm64Alignment;
Vladimir Marko33bff252017-11-01 14:35:42 +000092 case InstructionSet::kX86:
Ian Rogersd582fa42014-11-05 23:46:43 -080093 // Fall-through.
Vladimir Marko33bff252017-11-01 14:35:42 +000094 case InstructionSet::kX86_64:
Ian Rogersd582fa42014-11-05 23:46:43 -080095 return kX86Alignment;
Vladimir Marko33bff252017-11-01 14:35:42 +000096 case InstructionSet::kMips:
Andreas Gampe57b34292015-01-14 15:45:59 -080097 // Fall-through.
Vladimir Marko33bff252017-11-01 14:35:42 +000098 case InstructionSet::kMips64:
Ian Rogersd582fa42014-11-05 23:46:43 -080099 return kMipsAlignment;
Vladimir Marko33bff252017-11-01 14:35:42 +0000100 case InstructionSet::kNone:
Ian Rogersd582fa42014-11-05 23:46:43 -0800101 LOG(FATAL) << "ISA kNone does not have alignment.";
102 UNREACHABLE();
Ian Rogersd582fa42014-11-05 23:46:43 -0800103 }
Andreas Gampe705543e2017-05-24 13:20:49 -0700104 LOG(FATAL) << "Unknown ISA " << isa;
105 UNREACHABLE();
Ian Rogersd582fa42014-11-05 23:46:43 -0800106}
107
Andreas Gamped1262282016-08-11 18:35:58 -0700108#if !defined(ART_STACK_OVERFLOW_GAP_arm) || !defined(ART_STACK_OVERFLOW_GAP_arm64) || \
109 !defined(ART_STACK_OVERFLOW_GAP_mips) || !defined(ART_STACK_OVERFLOW_GAP_mips64) || \
110 !defined(ART_STACK_OVERFLOW_GAP_x86) || !defined(ART_STACK_OVERFLOW_GAP_x86_64)
111#error "Missing defines for stack overflow gap"
112#endif
Ian Rogersd582fa42014-11-05 23:46:43 -0800113
Andreas Gamped1262282016-08-11 18:35:58 -0700114static constexpr size_t kArmStackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_arm;
115static constexpr size_t kArm64StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_arm64;
116static constexpr size_t kMipsStackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_mips;
117static constexpr size_t kMips64StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_mips64;
118static constexpr size_t kX86StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_x86;
119static constexpr size_t kX86_64StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_x86_64;
120
121static_assert(IsAligned<kPageSize>(kArmStackOverflowReservedBytes), "ARM gap not page aligned");
122static_assert(IsAligned<kPageSize>(kArm64StackOverflowReservedBytes), "ARM64 gap not page aligned");
123static_assert(IsAligned<kPageSize>(kMipsStackOverflowReservedBytes), "Mips gap not page aligned");
124static_assert(IsAligned<kPageSize>(kMips64StackOverflowReservedBytes),
125 "Mips64 gap not page aligned");
126static_assert(IsAligned<kPageSize>(kX86StackOverflowReservedBytes), "X86 gap not page aligned");
127static_assert(IsAligned<kPageSize>(kX86_64StackOverflowReservedBytes),
128 "X86_64 gap not page aligned");
129
130#if !defined(ART_FRAME_SIZE_LIMIT)
131#error "ART frame size limit missing"
132#endif
133
134// TODO: Should we require an extra page (RoundUp(SIZE) + kPageSize)?
135static_assert(ART_FRAME_SIZE_LIMIT < kArmStackOverflowReservedBytes, "Frame size limit too large");
136static_assert(ART_FRAME_SIZE_LIMIT < kArm64StackOverflowReservedBytes,
137 "Frame size limit too large");
138static_assert(ART_FRAME_SIZE_LIMIT < kMipsStackOverflowReservedBytes,
139 "Frame size limit too large");
140static_assert(ART_FRAME_SIZE_LIMIT < kMips64StackOverflowReservedBytes,
141 "Frame size limit too large");
142static_assert(ART_FRAME_SIZE_LIMIT < kX86StackOverflowReservedBytes,
143 "Frame size limit too large");
144static_assert(ART_FRAME_SIZE_LIMIT < kX86_64StackOverflowReservedBytes,
145 "Frame size limit too large");
Ian Rogersd582fa42014-11-05 23:46:43 -0800146
147size_t GetStackOverflowReservedBytes(InstructionSet isa) {
148 switch (isa) {
Vladimir Marko33bff252017-11-01 14:35:42 +0000149 case InstructionSet::kArm: // Intentional fall-through.
150 case InstructionSet::kThumb2:
Ian Rogersd582fa42014-11-05 23:46:43 -0800151 return kArmStackOverflowReservedBytes;
152
Vladimir Marko33bff252017-11-01 14:35:42 +0000153 case InstructionSet::kArm64:
Ian Rogersd582fa42014-11-05 23:46:43 -0800154 return kArm64StackOverflowReservedBytes;
155
Vladimir Marko33bff252017-11-01 14:35:42 +0000156 case InstructionSet::kMips:
Ian Rogersd582fa42014-11-05 23:46:43 -0800157 return kMipsStackOverflowReservedBytes;
158
Vladimir Marko33bff252017-11-01 14:35:42 +0000159 case InstructionSet::kMips64:
Andreas Gampe57b34292015-01-14 15:45:59 -0800160 return kMips64StackOverflowReservedBytes;
161
Vladimir Marko33bff252017-11-01 14:35:42 +0000162 case InstructionSet::kX86:
Ian Rogersd582fa42014-11-05 23:46:43 -0800163 return kX86StackOverflowReservedBytes;
164
Vladimir Marko33bff252017-11-01 14:35:42 +0000165 case InstructionSet::kX86_64:
Ian Rogersd582fa42014-11-05 23:46:43 -0800166 return kX86_64StackOverflowReservedBytes;
167
Vladimir Marko33bff252017-11-01 14:35:42 +0000168 case InstructionSet::kNone:
Ian Rogersd582fa42014-11-05 23:46:43 -0800169 LOG(FATAL) << "kNone has no stack overflow size";
170 UNREACHABLE();
Ian Rogersd582fa42014-11-05 23:46:43 -0800171 }
Andreas Gampe705543e2017-05-24 13:20:49 -0700172 LOG(FATAL) << "Unknown instruction set" << isa;
173 UNREACHABLE();
Ian Rogersd582fa42014-11-05 23:46:43 -0800174}
175
176} // namespace art