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