1d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers/* 2d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * Copyright (C) 2011 The Android Open Source Project 3d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * 4d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * Licensed under the Apache License, Version 2.0 (the "License"); 5d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * you may not use this file except in compliance with the License. 6d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * You may obtain a copy of the License at 7d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * 8d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * http://www.apache.org/licenses/LICENSE-2.0 9d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * 10d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * Unless required by applicable law or agreed to in writing, software 11d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * distributed under the License is distributed on an "AS IS" BASIS, 12d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * See the License for the specific language governing permissions and 14d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * limitations under the License. 15d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers */ 16d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 17d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#ifndef ART_RUNTIME_ARCH_INSTRUCTION_SET_H_ 18d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#define ART_RUNTIME_ARCH_INSTRUCTION_SET_H_ 19d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 20d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include <iosfwd> 21d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include <string> 22d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 23d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include "base/logging.h" // Logging is required for FATAL in the helper functions. 24d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 25d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersnamespace art { 26d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 27d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersenum InstructionSet { 28d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers kNone, 29d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers kArm, 30d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers kArm64, 31d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers kThumb2, 32d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers kX86, 33d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers kX86_64, 34d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers kMips, 35d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers kMips64 36d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers}; 37d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstd::ostream& operator<<(std::ostream& os, const InstructionSet& rhs); 38d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 39d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#if defined(__arm__) 40d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstatic constexpr InstructionSet kRuntimeISA = kArm; 41d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#elif defined(__aarch64__) 42d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstatic constexpr InstructionSet kRuntimeISA = kArm64; 4357b34294758e9c00993913ebe43c7ee4698a5cc6Andreas Gampe#elif defined(__mips__) && !defined(__LP64__) 44d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstatic constexpr InstructionSet kRuntimeISA = kMips; 4557b34294758e9c00993913ebe43c7ee4698a5cc6Andreas Gampe#elif defined(__mips__) && defined(__LP64__) 4657b34294758e9c00993913ebe43c7ee4698a5cc6Andreas Gampestatic constexpr InstructionSet kRuntimeISA = kMips64; 47d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#elif defined(__i386__) 48d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstatic constexpr InstructionSet kRuntimeISA = kX86; 49d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#elif defined(__x86_64__) 50d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstatic constexpr InstructionSet kRuntimeISA = kX86_64; 51d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#else 52d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstatic constexpr InstructionSet kRuntimeISA = kNone; 53d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#endif 54d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 55d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// Architecture-specific pointer sizes 56d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstatic constexpr size_t kArmPointerSize = 4; 57d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstatic constexpr size_t kArm64PointerSize = 8; 58d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstatic constexpr size_t kMipsPointerSize = 4; 59d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstatic constexpr size_t kMips64PointerSize = 8; 60d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstatic constexpr size_t kX86PointerSize = 4; 61d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstatic constexpr size_t kX86_64PointerSize = 8; 62d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 63d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// ARM instruction alignment. ARM processors require code to be 4-byte aligned, 64d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// but ARM ELF requires 8.. 65d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstatic constexpr size_t kArmAlignment = 8; 66d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 67d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// ARM64 instruction alignment. This is the recommended alignment for maximum performance. 68d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstatic constexpr size_t kArm64Alignment = 16; 69d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 70d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// MIPS instruction alignment. MIPS processors require code to be 4-byte aligned. 71d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// TODO: Can this be 4? 72d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstatic constexpr size_t kMipsAlignment = 8; 73d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 74d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// X86 instruction alignment. This is the recommended alignment for maximum performance. 75d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstatic constexpr size_t kX86Alignment = 16; 76d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 77d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 78d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersconst char* GetInstructionSetString(InstructionSet isa); 79d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 80d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// Note: Returns kNone when the string cannot be parsed to a known value. 81d582fa4ea62083a7598dded5b82dc2198b3daac7Ian RogersInstructionSet GetInstructionSetFromString(const char* instruction_set); 82d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 836f6114140fbc09c5c7bec441922412635a7f7ff1Andreas GampeInstructionSet GetInstructionSetFromELF(uint16_t e_machine, uint32_t e_flags); 846f6114140fbc09c5c7bec441922412635a7f7ff1Andreas Gampe 85d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstatic inline size_t GetInstructionSetPointerSize(InstructionSet isa) { 86d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers switch (isa) { 87d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kArm: 88d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers // Fall-through. 89d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kThumb2: 90d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return kArmPointerSize; 91d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kArm64: 92d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return kArm64PointerSize; 93d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kX86: 94d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return kX86PointerSize; 95d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kX86_64: 96d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return kX86_64PointerSize; 97d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kMips: 98d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return kMipsPointerSize; 99d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kMips64: 100d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return kMips64PointerSize; 101d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kNone: 102d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers LOG(FATAL) << "ISA kNone does not have pointer size."; 103d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers UNREACHABLE(); 104d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers default: 105d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers LOG(FATAL) << "Unknown ISA " << isa; 106d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers UNREACHABLE(); 107d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 108d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 109d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 11009d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Markostatic inline bool IsValidInstructionSet(InstructionSet isa) { 11109d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko switch (isa) { 11209d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko case kArm: 11309d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko case kThumb2: 11409d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko case kArm64: 11509d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko case kX86: 11609d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko case kX86_64: 11709d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko case kMips: 11809d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko case kMips64: 11909d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko return true; 12009d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko case kNone: 12109d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko default: 12209d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko return false; 12309d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko } 12409d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko} 12509d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko 126d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogerssize_t GetInstructionSetAlignment(InstructionSet isa); 127d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 128d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstatic inline bool Is64BitInstructionSet(InstructionSet isa) { 129d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers switch (isa) { 130d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kArm: 131d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kThumb2: 132d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kX86: 133d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kMips: 134d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return false; 135d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 136d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kArm64: 137d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kX86_64: 138d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kMips64: 139d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return true; 140d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 141d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kNone: 142d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers LOG(FATAL) << "ISA kNone does not have bit width."; 143d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers UNREACHABLE(); 144d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers default: 145d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers LOG(FATAL) << "Unknown ISA " << isa; 146d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers UNREACHABLE(); 147d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 148d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 149d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 1502d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartierstatic inline size_t InstructionSetPointerSize(InstructionSet isa) { 1512d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier return Is64BitInstructionSet(isa) ? 8U : 4U; 1522d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier} 1532d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier 154d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstatic inline size_t GetBytesPerGprSpillLocation(InstructionSet isa) { 155d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers switch (isa) { 156d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kArm: 157d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers // Fall-through. 158d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kThumb2: 159d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return 4; 160d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kArm64: 161d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return 8; 162d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kX86: 163d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return 4; 164d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kX86_64: 165d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return 8; 166d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kMips: 167d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return 4; 16857b34294758e9c00993913ebe43c7ee4698a5cc6Andreas Gampe case kMips64: 16957b34294758e9c00993913ebe43c7ee4698a5cc6Andreas Gampe return 8; 170d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kNone: 171d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers LOG(FATAL) << "ISA kNone does not have spills."; 172d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers UNREACHABLE(); 173d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers default: 174d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers LOG(FATAL) << "Unknown ISA " << isa; 175d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers UNREACHABLE(); 176d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 177d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 178d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 179d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstatic inline size_t GetBytesPerFprSpillLocation(InstructionSet isa) { 180d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers switch (isa) { 181d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kArm: 182d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers // Fall-through. 183d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kThumb2: 184d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return 4; 185d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kArm64: 186d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return 8; 187d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kX86: 188d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return 8; 189d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kX86_64: 190d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return 8; 191d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kMips: 192d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return 4; 19357b34294758e9c00993913ebe43c7ee4698a5cc6Andreas Gampe case kMips64: 19457b34294758e9c00993913ebe43c7ee4698a5cc6Andreas Gampe return 8; 195d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers case kNone: 196d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers LOG(FATAL) << "ISA kNone does not have spills."; 197d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers UNREACHABLE(); 198d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers default: 199d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers LOG(FATAL) << "Unknown ISA " << isa; 200d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers UNREACHABLE(); 201d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 202d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 203d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 204d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogerssize_t GetStackOverflowReservedBytes(InstructionSet isa); 205d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 206d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// The following definitions create return types for two word-sized entities that will be passed 207d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// in registers so that memory operations for the interface trampolines can be avoided. The entities 208d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// are the resolved method and the pointer to the code to be invoked. 209d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// 210d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// On x86, ARM32 and MIPS, this is given for a *scalar* 64bit value. The definition thus *must* be 211d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// uint64_t or long long int. 212d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// 21357b34294758e9c00993913ebe43c7ee4698a5cc6Andreas Gampe// On x86_64, ARM64 and MIPS64, structs are decomposed for allocation, so we can create a structs of 21457b34294758e9c00993913ebe43c7ee4698a5cc6Andreas Gampe// two size_t-sized values. 215d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// 216d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// We need two operations: 217d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// 218d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// 1) A flag value that signals failure. The assembly stubs expect the lower part to be "0". 219d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// GetTwoWordFailureValue() will return a value that has lower part == 0. 220d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// 221d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// 2) A value that combines two word-sized values. 222d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// GetTwoWordSuccessValue() constructs this. 223d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// 224d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// IMPORTANT: If you use this to transfer object pointers, it is your responsibility to ensure 225d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// that the object does not move or the value is updated. Simple use of this is NOT SAFE 226d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// when the garbage collector can move objects concurrently. Ensure that required locks 227d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// are held when using! 228d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 22957b34294758e9c00993913ebe43c7ee4698a5cc6Andreas Gampe#if defined(__i386__) || defined(__arm__) || (defined(__mips__) && !defined(__LP64__)) 230d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogerstypedef uint64_t TwoWordReturn; 231d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 232d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// Encodes method_ptr==nullptr and code_ptr==nullptr 233d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstatic inline constexpr TwoWordReturn GetTwoWordFailureValue() { 234d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return 0; 235d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 236d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 237d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// Use the lower 32b for the method pointer and the upper 32b for the code pointer. 238d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstatic inline TwoWordReturn GetTwoWordSuccessValue(uintptr_t hi, uintptr_t lo) { 239d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers static_assert(sizeof(uint32_t) == sizeof(uintptr_t), "Unexpected size difference"); 240d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers uint32_t lo32 = lo; 241d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers uint64_t hi64 = static_cast<uint64_t>(hi); 242d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return ((hi64 << 32) | lo32); 243d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 244d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 24557b34294758e9c00993913ebe43c7ee4698a5cc6Andreas Gampe#elif defined(__x86_64__) || defined(__aarch64__) || (defined(__mips__) && defined(__LP64__)) 246d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstruct TwoWordReturn { 247d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers uintptr_t lo; 248d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers uintptr_t hi; 249d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers}; 250d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 251d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// Encodes method_ptr==nullptr. Leaves random value in code pointer. 252d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstatic inline TwoWordReturn GetTwoWordFailureValue() { 253d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers TwoWordReturn ret; 254d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers ret.lo = 0; 255d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return ret; 256d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 257d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 258d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers// Write values into their respective members. 259d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstatic inline TwoWordReturn GetTwoWordSuccessValue(uintptr_t hi, uintptr_t lo) { 260d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers TwoWordReturn ret; 261d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers ret.lo = lo; 262d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers ret.hi = hi; 263d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return ret; 264d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 265d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#else 266d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#error "Unsupported architecture" 267d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#endif 268d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 269d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} // namespace art 270d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 271d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#endif // ART_RUNTIME_ARCH_INSTRUCTION_SET_H_ 272