1 | // Copyright 2014 the V8 project authors. All rights reserved. |
2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. |
4 | |
5 | #ifndef V8_COMPILER_BACKEND_INSTRUCTION_CODES_H_ |
6 | #define V8_COMPILER_BACKEND_INSTRUCTION_CODES_H_ |
7 | |
8 | #include <iosfwd> |
9 | |
10 | #if V8_TARGET_ARCH_ARM |
11 | #include "src/compiler/backend/arm/instruction-codes-arm.h" |
12 | #elif V8_TARGET_ARCH_ARM64 |
13 | #include "src/compiler/backend/arm64/instruction-codes-arm64.h" |
14 | #elif V8_TARGET_ARCH_IA32 |
15 | #include "src/compiler/backend/ia32/instruction-codes-ia32.h" |
16 | #elif V8_TARGET_ARCH_MIPS |
17 | #include "src/compiler/backend/mips/instruction-codes-mips.h" |
18 | #elif V8_TARGET_ARCH_MIPS64 |
19 | #include "src/compiler/backend/mips64/instruction-codes-mips64.h" |
20 | #elif V8_TARGET_ARCH_X64 |
21 | #include "src/compiler/backend/x64/instruction-codes-x64.h" |
22 | #elif V8_TARGET_ARCH_PPC |
23 | #include "src/compiler/backend/ppc/instruction-codes-ppc.h" |
24 | #elif V8_TARGET_ARCH_S390 |
25 | #include "src/compiler/backend/s390/instruction-codes-s390.h" |
26 | #else |
27 | #define TARGET_ARCH_OPCODE_LIST(V) |
28 | #define TARGET_ADDRESSING_MODE_LIST(V) |
29 | #endif |
30 | #include "src/globals.h" |
31 | #include "src/utils.h" |
32 | |
33 | namespace v8 { |
34 | namespace internal { |
35 | namespace compiler { |
36 | |
37 | // Modes for ArchStoreWithWriteBarrier below. |
38 | enum class RecordWriteMode { |
39 | kValueIsMap, |
40 | kValueIsPointer, |
41 | kValueIsEphemeronKey, |
42 | kValueIsAny, |
43 | }; |
44 | |
45 | inline RecordWriteMode WriteBarrierKindToRecordWriteMode( |
46 | WriteBarrierKind write_barrier_kind) { |
47 | switch (write_barrier_kind) { |
48 | case kMapWriteBarrier: |
49 | return RecordWriteMode::kValueIsMap; |
50 | case kPointerWriteBarrier: |
51 | return RecordWriteMode::kValueIsPointer; |
52 | case kEphemeronKeyWriteBarrier: |
53 | return RecordWriteMode::kValueIsEphemeronKey; |
54 | case kFullWriteBarrier: |
55 | return RecordWriteMode::kValueIsAny; |
56 | case kNoWriteBarrier: |
57 | // Should not be passed as argument. |
58 | default: |
59 | break; |
60 | } |
61 | UNREACHABLE(); |
62 | } |
63 | |
64 | // Target-specific opcodes that specify which assembly sequence to emit. |
65 | // Most opcodes specify a single instruction. |
66 | #define COMMON_ARCH_OPCODE_LIST(V) \ |
67 | V(ArchCallCodeObject) \ |
68 | V(ArchTailCallCodeObjectFromJSFunction) \ |
69 | V(ArchTailCallCodeObject) \ |
70 | V(ArchCallJSFunction) \ |
71 | V(ArchTailCallAddress) \ |
72 | V(ArchPrepareCallCFunction) \ |
73 | V(ArchSaveCallerRegisters) \ |
74 | V(ArchRestoreCallerRegisters) \ |
75 | V(ArchCallCFunction) \ |
76 | V(ArchPrepareTailCall) \ |
77 | V(ArchCallWasmFunction) \ |
78 | V(ArchTailCallWasm) \ |
79 | V(ArchCallBuiltinPointer) \ |
80 | V(ArchJmp) \ |
81 | V(ArchBinarySearchSwitch) \ |
82 | V(ArchLookupSwitch) \ |
83 | V(ArchTableSwitch) \ |
84 | V(ArchNop) \ |
85 | V(ArchDebugAbort) \ |
86 | V(ArchDebugBreak) \ |
87 | V(ArchComment) \ |
88 | V(ArchThrowTerminator) \ |
89 | V(ArchDeoptimize) \ |
90 | V(ArchRet) \ |
91 | V(ArchStackPointer) \ |
92 | V(ArchFramePointer) \ |
93 | V(ArchParentFramePointer) \ |
94 | V(ArchTruncateDoubleToI) \ |
95 | V(ArchStoreWithWriteBarrier) \ |
96 | V(ArchStackSlot) \ |
97 | V(ArchWordPoisonOnSpeculation) \ |
98 | V(Word32AtomicLoadInt8) \ |
99 | V(Word32AtomicLoadUint8) \ |
100 | V(Word32AtomicLoadInt16) \ |
101 | V(Word32AtomicLoadUint16) \ |
102 | V(Word32AtomicLoadWord32) \ |
103 | V(Word32AtomicStoreWord8) \ |
104 | V(Word32AtomicStoreWord16) \ |
105 | V(Word32AtomicStoreWord32) \ |
106 | V(Word32AtomicExchangeInt8) \ |
107 | V(Word32AtomicExchangeUint8) \ |
108 | V(Word32AtomicExchangeInt16) \ |
109 | V(Word32AtomicExchangeUint16) \ |
110 | V(Word32AtomicExchangeWord32) \ |
111 | V(Word32AtomicCompareExchangeInt8) \ |
112 | V(Word32AtomicCompareExchangeUint8) \ |
113 | V(Word32AtomicCompareExchangeInt16) \ |
114 | V(Word32AtomicCompareExchangeUint16) \ |
115 | V(Word32AtomicCompareExchangeWord32) \ |
116 | V(Word32AtomicAddInt8) \ |
117 | V(Word32AtomicAddUint8) \ |
118 | V(Word32AtomicAddInt16) \ |
119 | V(Word32AtomicAddUint16) \ |
120 | V(Word32AtomicAddWord32) \ |
121 | V(Word32AtomicSubInt8) \ |
122 | V(Word32AtomicSubUint8) \ |
123 | V(Word32AtomicSubInt16) \ |
124 | V(Word32AtomicSubUint16) \ |
125 | V(Word32AtomicSubWord32) \ |
126 | V(Word32AtomicAndInt8) \ |
127 | V(Word32AtomicAndUint8) \ |
128 | V(Word32AtomicAndInt16) \ |
129 | V(Word32AtomicAndUint16) \ |
130 | V(Word32AtomicAndWord32) \ |
131 | V(Word32AtomicOrInt8) \ |
132 | V(Word32AtomicOrUint8) \ |
133 | V(Word32AtomicOrInt16) \ |
134 | V(Word32AtomicOrUint16) \ |
135 | V(Word32AtomicOrWord32) \ |
136 | V(Word32AtomicXorInt8) \ |
137 | V(Word32AtomicXorUint8) \ |
138 | V(Word32AtomicXorInt16) \ |
139 | V(Word32AtomicXorUint16) \ |
140 | V(Word32AtomicXorWord32) \ |
141 | V(Ieee754Float64Acos) \ |
142 | V(Ieee754Float64Acosh) \ |
143 | V(Ieee754Float64Asin) \ |
144 | V(Ieee754Float64Asinh) \ |
145 | V(Ieee754Float64Atan) \ |
146 | V(Ieee754Float64Atanh) \ |
147 | V(Ieee754Float64Atan2) \ |
148 | V(Ieee754Float64Cbrt) \ |
149 | V(Ieee754Float64Cos) \ |
150 | V(Ieee754Float64Cosh) \ |
151 | V(Ieee754Float64Exp) \ |
152 | V(Ieee754Float64Expm1) \ |
153 | V(Ieee754Float64Log) \ |
154 | V(Ieee754Float64Log1p) \ |
155 | V(Ieee754Float64Log10) \ |
156 | V(Ieee754Float64Log2) \ |
157 | V(Ieee754Float64Pow) \ |
158 | V(Ieee754Float64Sin) \ |
159 | V(Ieee754Float64Sinh) \ |
160 | V(Ieee754Float64Tan) \ |
161 | V(Ieee754Float64Tanh) |
162 | |
163 | #define ARCH_OPCODE_LIST(V) \ |
164 | COMMON_ARCH_OPCODE_LIST(V) \ |
165 | TARGET_ARCH_OPCODE_LIST(V) |
166 | |
167 | enum ArchOpcode { |
168 | #define DECLARE_ARCH_OPCODE(Name) k##Name, |
169 | ARCH_OPCODE_LIST(DECLARE_ARCH_OPCODE) |
170 | #undef DECLARE_ARCH_OPCODE |
171 | #define COUNT_ARCH_OPCODE(Name) +1 |
172 | kLastArchOpcode = -1 ARCH_OPCODE_LIST(COUNT_ARCH_OPCODE) |
173 | #undef COUNT_ARCH_OPCODE |
174 | }; |
175 | |
176 | V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, |
177 | const ArchOpcode& ao); |
178 | |
179 | // Addressing modes represent the "shape" of inputs to an instruction. |
180 | // Many instructions support multiple addressing modes. Addressing modes |
181 | // are encoded into the InstructionCode of the instruction and tell the |
182 | // code generator after register allocation which assembler method to call. |
183 | #define ADDRESSING_MODE_LIST(V) \ |
184 | V(None) \ |
185 | TARGET_ADDRESSING_MODE_LIST(V) |
186 | |
187 | enum AddressingMode { |
188 | #define DECLARE_ADDRESSING_MODE(Name) kMode_##Name, |
189 | ADDRESSING_MODE_LIST(DECLARE_ADDRESSING_MODE) |
190 | #undef DECLARE_ADDRESSING_MODE |
191 | #define COUNT_ADDRESSING_MODE(Name) +1 |
192 | kLastAddressingMode = -1 ADDRESSING_MODE_LIST(COUNT_ADDRESSING_MODE) |
193 | #undef COUNT_ADDRESSING_MODE |
194 | }; |
195 | |
196 | V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, |
197 | const AddressingMode& am); |
198 | |
199 | // The mode of the flags continuation (see below). |
200 | enum FlagsMode { |
201 | kFlags_none = 0, |
202 | kFlags_branch = 1, |
203 | kFlags_branch_and_poison = 2, |
204 | kFlags_deoptimize = 3, |
205 | kFlags_deoptimize_and_poison = 4, |
206 | kFlags_set = 5, |
207 | kFlags_trap = 6 |
208 | }; |
209 | |
210 | V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, |
211 | const FlagsMode& fm); |
212 | |
213 | // The condition of flags continuation (see below). |
214 | enum FlagsCondition { |
215 | kEqual, |
216 | kNotEqual, |
217 | kSignedLessThan, |
218 | kSignedGreaterThanOrEqual, |
219 | kSignedLessThanOrEqual, |
220 | kSignedGreaterThan, |
221 | kUnsignedLessThan, |
222 | kUnsignedGreaterThanOrEqual, |
223 | kUnsignedLessThanOrEqual, |
224 | kUnsignedGreaterThan, |
225 | kFloatLessThanOrUnordered, |
226 | kFloatGreaterThanOrEqual, |
227 | kFloatLessThanOrEqual, |
228 | kFloatGreaterThanOrUnordered, |
229 | kFloatLessThan, |
230 | kFloatGreaterThanOrEqualOrUnordered, |
231 | kFloatLessThanOrEqualOrUnordered, |
232 | kFloatGreaterThan, |
233 | kUnorderedEqual, |
234 | kUnorderedNotEqual, |
235 | kOverflow, |
236 | kNotOverflow, |
237 | kPositiveOrZero, |
238 | kNegative |
239 | }; |
240 | |
241 | inline FlagsCondition NegateFlagsCondition(FlagsCondition condition) { |
242 | return static_cast<FlagsCondition>(condition ^ 1); |
243 | } |
244 | |
245 | FlagsCondition CommuteFlagsCondition(FlagsCondition condition); |
246 | |
247 | V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, |
248 | const FlagsCondition& fc); |
249 | |
250 | enum MemoryAccessMode { |
251 | kMemoryAccessDirect = 0, |
252 | kMemoryAccessProtected = 1, |
253 | kMemoryAccessPoisoned = 2 |
254 | }; |
255 | |
256 | // The InstructionCode is an opaque, target-specific integer that encodes |
257 | // what code to emit for an instruction in the code generator. It is not |
258 | // interesting to the register allocator, as the inputs and flags on the |
259 | // instructions specify everything of interest. |
260 | using InstructionCode = int32_t; |
261 | |
262 | // Helpers for encoding / decoding InstructionCode into the fields needed |
263 | // for code generation. We encode the instruction, addressing mode, and flags |
264 | // continuation into a single InstructionCode which is stored as part of |
265 | // the instruction. |
266 | using ArchOpcodeField = BitField<ArchOpcode, 0, 9>; |
267 | using AddressingModeField = BitField<AddressingMode, 9, 5>; |
268 | using FlagsModeField = BitField<FlagsMode, 14, 3>; |
269 | using FlagsConditionField = BitField<FlagsCondition, 17, 5>; |
270 | using MiscField = BitField<int, 22, 10>; |
271 | |
272 | } // namespace compiler |
273 | } // namespace internal |
274 | } // namespace v8 |
275 | |
276 | #endif // V8_COMPILER_BACKEND_INSTRUCTION_CODES_H_ |
277 | |