xref: /aosp_15_r20/art/libartbase/arch/instruction_set.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
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 "android-base/properties.h"
21 #include "android-base/stringprintf.h"
22 #include "base/bit_utils.h"
23 #include "base/globals.h"
24 
25 namespace art {
26 
InstructionSetAbort(InstructionSet isa)27 void InstructionSetAbort(InstructionSet isa) {
28   switch (isa) {
29     case InstructionSet::kArm:
30     case InstructionSet::kThumb2:
31     case InstructionSet::kArm64:
32     case InstructionSet::kRiscv64:
33     case InstructionSet::kX86:
34     case InstructionSet::kX86_64:
35     case InstructionSet::kNone:
36       LOG(FATAL) << "Unsupported instruction set " << isa;
37       UNREACHABLE();
38   }
39 }
40 
GetInstructionSetString(InstructionSet isa)41 const char* GetInstructionSetString(InstructionSet isa) {
42   switch (isa) {
43     case InstructionSet::kArm:
44     case InstructionSet::kThumb2:
45       return "arm";
46     case InstructionSet::kArm64:
47       return "arm64";
48     case InstructionSet::kRiscv64:
49       return "riscv64";
50     case InstructionSet::kX86:
51       return "x86";
52     case InstructionSet::kX86_64:
53       return "x86_64";
54     case InstructionSet::kNone:
55       return "none";
56   }
57 }
58 
GetInstructionSetFromString(const char * isa_str)59 InstructionSet GetInstructionSetFromString(const char* isa_str) {
60   CHECK(isa_str != nullptr);
61 
62   if (strcmp("arm", isa_str) == 0) {
63     return InstructionSet::kArm;
64   } else if (strcmp("arm64", isa_str) == 0) {
65     return InstructionSet::kArm64;
66   } else if (strcmp("riscv64", isa_str) == 0) {
67     return InstructionSet::kRiscv64;
68   } else if (strcmp("x86", isa_str) == 0) {
69     return InstructionSet::kX86;
70   } else if (strcmp("x86_64", isa_str) == 0) {
71     return InstructionSet::kX86_64;
72   }
73 
74   return InstructionSet::kNone;
75 }
76 
GetSupportedInstructionSets(std::string * error_msg)77 std::vector<InstructionSet> GetSupportedInstructionSets(std::string* error_msg) {
78   std::string zygote_kinds = android::base::GetProperty("ro.zygote", {});
79   if (zygote_kinds.empty()) {
80     *error_msg = "Unable to get Zygote kinds";
81     return {};
82   }
83 
84   switch (kRuntimeISA) {
85     case InstructionSet::kArm:
86     case InstructionSet::kArm64:
87       if (zygote_kinds == "zygote64_32" || zygote_kinds == "zygote32_64") {
88         return {InstructionSet::kArm64, InstructionSet::kArm};
89       } else if (zygote_kinds == "zygote64") {
90         return {InstructionSet::kArm64};
91       } else if (zygote_kinds == "zygote32") {
92         return {InstructionSet::kArm};
93       } else {
94         *error_msg = android::base::StringPrintf("Unknown Zygote kinds '%s'", zygote_kinds.c_str());
95         return {};
96       }
97     case InstructionSet::kRiscv64:
98       return {InstructionSet::kRiscv64};
99     case InstructionSet::kX86:
100     case InstructionSet::kX86_64:
101       if (zygote_kinds == "zygote64_32" || zygote_kinds == "zygote32_64") {
102         return {InstructionSet::kX86_64, InstructionSet::kX86};
103       } else if (zygote_kinds == "zygote64") {
104         return {InstructionSet::kX86_64};
105       } else if (zygote_kinds == "zygote32") {
106         return {InstructionSet::kX86};
107       } else {
108         *error_msg = android::base::StringPrintf("Unknown Zygote kinds '%s'", zygote_kinds.c_str());
109         return {};
110       }
111     default:
112       *error_msg = android::base::StringPrintf("Unknown runtime ISA '%s'",
113                                                GetInstructionSetString(kRuntimeISA));
114       return {};
115   }
116 }
117 
118 namespace instruction_set_details {
119 
120 #if !defined(ART_FRAME_SIZE_LIMIT)
121 #error "ART frame size limit missing"
122 #endif
123 
124 // TODO: Should we require an extra page (RoundUp(SIZE) + gPageSize)?
125 static_assert(ART_FRAME_SIZE_LIMIT < kArmStackOverflowReservedBytes, "Frame size limit too large");
126 static_assert(ART_FRAME_SIZE_LIMIT < kArm64StackOverflowReservedBytes,
127               "Frame size limit too large");
128 static_assert(ART_FRAME_SIZE_LIMIT < kRiscv64StackOverflowReservedBytes,
129               "Frame size limit too large");
130 static_assert(ART_FRAME_SIZE_LIMIT < kX86StackOverflowReservedBytes,
131               "Frame size limit too large");
132 static_assert(ART_FRAME_SIZE_LIMIT < kX86_64StackOverflowReservedBytes,
133               "Frame size limit too large");
134 
GetStackOverflowReservedBytesFailure(const char * error_msg)135 NO_RETURN void GetStackOverflowReservedBytesFailure(const char* error_msg) {
136   LOG(FATAL) << error_msg;
137   UNREACHABLE();
138 }
139 
140 }  // namespace instruction_set_details
141 
142 }  // namespace art
143