1 /*
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
19 #include "android-base/logging.h"
20 #include "base/bit_utils.h"
21 #include "base/globals.h"
22
23 namespace art {
24
InstructionSetAbort(InstructionSet isa)25 void InstructionSetAbort(InstructionSet isa) {
26 switch (isa) {
27 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:
35 LOG(FATAL) << "Unsupported instruction set " << isa;
36 UNREACHABLE();
37 }
38 LOG(FATAL) << "Unknown ISA " << isa;
39 UNREACHABLE();
40 }
41
GetInstructionSetString(InstructionSet isa)42 const char* GetInstructionSetString(InstructionSet isa) {
43 switch (isa) {
44 case InstructionSet::kArm:
45 case InstructionSet::kThumb2:
46 return "arm";
47 case InstructionSet::kArm64:
48 return "arm64";
49 case InstructionSet::kX86:
50 return "x86";
51 case InstructionSet::kX86_64:
52 return "x86_64";
53 case InstructionSet::kMips:
54 return "mips";
55 case InstructionSet::kMips64:
56 return "mips64";
57 case InstructionSet::kNone:
58 return "none";
59 }
60 LOG(FATAL) << "Unknown ISA " << isa;
61 UNREACHABLE();
62 }
63
GetInstructionSetFromString(const char * isa_str)64 InstructionSet GetInstructionSetFromString(const char* isa_str) {
65 CHECK(isa_str != nullptr);
66
67 if (strcmp("arm", isa_str) == 0) {
68 return InstructionSet::kArm;
69 } else if (strcmp("arm64", isa_str) == 0) {
70 return InstructionSet::kArm64;
71 } else if (strcmp("x86", isa_str) == 0) {
72 return InstructionSet::kX86;
73 } else if (strcmp("x86_64", isa_str) == 0) {
74 return InstructionSet::kX86_64;
75 } else if (strcmp("mips", isa_str) == 0) {
76 return InstructionSet::kMips;
77 } else if (strcmp("mips64", isa_str) == 0) {
78 return InstructionSet::kMips64;
79 }
80
81 return InstructionSet::kNone;
82 }
83
GetInstructionSetAlignment(InstructionSet isa)84 size_t GetInstructionSetAlignment(InstructionSet isa) {
85 switch (isa) {
86 case InstructionSet::kArm:
87 // Fall-through.
88 case InstructionSet::kThumb2:
89 return kArmAlignment;
90 case InstructionSet::kArm64:
91 return kArm64Alignment;
92 case InstructionSet::kX86:
93 // Fall-through.
94 case InstructionSet::kX86_64:
95 return kX86Alignment;
96 case InstructionSet::kMips:
97 // Fall-through.
98 case InstructionSet::kMips64:
99 return kMipsAlignment;
100 case InstructionSet::kNone:
101 LOG(FATAL) << "ISA kNone does not have alignment.";
102 UNREACHABLE();
103 }
104 LOG(FATAL) << "Unknown ISA " << isa;
105 UNREACHABLE();
106 }
107
108 namespace instruction_set_details {
109
110 static_assert(IsAligned<kPageSize>(kArmStackOverflowReservedBytes), "ARM gap not page aligned");
111 static_assert(IsAligned<kPageSize>(kArm64StackOverflowReservedBytes), "ARM64 gap not page aligned");
112 static_assert(IsAligned<kPageSize>(kMipsStackOverflowReservedBytes), "Mips gap not page aligned");
113 static_assert(IsAligned<kPageSize>(kMips64StackOverflowReservedBytes),
114 "Mips64 gap not page aligned");
115 static_assert(IsAligned<kPageSize>(kX86StackOverflowReservedBytes), "X86 gap not page aligned");
116 static_assert(IsAligned<kPageSize>(kX86_64StackOverflowReservedBytes),
117 "X86_64 gap not page aligned");
118
119 #if !defined(ART_FRAME_SIZE_LIMIT)
120 #error "ART frame size limit missing"
121 #endif
122
123 // TODO: Should we require an extra page (RoundUp(SIZE) + kPageSize)?
124 static_assert(ART_FRAME_SIZE_LIMIT < kArmStackOverflowReservedBytes, "Frame size limit too large");
125 static_assert(ART_FRAME_SIZE_LIMIT < kArm64StackOverflowReservedBytes,
126 "Frame size limit too large");
127 static_assert(ART_FRAME_SIZE_LIMIT < kMipsStackOverflowReservedBytes,
128 "Frame size limit too large");
129 static_assert(ART_FRAME_SIZE_LIMIT < kMips64StackOverflowReservedBytes,
130 "Frame size limit too large");
131 static_assert(ART_FRAME_SIZE_LIMIT < kX86StackOverflowReservedBytes,
132 "Frame size limit too large");
133 static_assert(ART_FRAME_SIZE_LIMIT < kX86_64StackOverflowReservedBytes,
134 "Frame size limit too large");
135
GetStackOverflowReservedBytesFailure(const char * error_msg)136 NO_RETURN void GetStackOverflowReservedBytesFailure(const char* error_msg) {
137 LOG(FATAL) << error_msg;
138 UNREACHABLE();
139 }
140
141 } // namespace instruction_set_details
142
143 } // namespace art
144