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
33namespace v8 {
34namespace internal {
35namespace compiler {
36
37// Modes for ArchStoreWithWriteBarrier below.
38enum class RecordWriteMode {
39 kValueIsMap,
40 kValueIsPointer,
41 kValueIsEphemeronKey,
42 kValueIsAny,
43};
44
45inline 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
167enum 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
176V8_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
187enum 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
196V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
197 const AddressingMode& am);
198
199// The mode of the flags continuation (see below).
200enum 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
210V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
211 const FlagsMode& fm);
212
213// The condition of flags continuation (see below).
214enum 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
241inline FlagsCondition NegateFlagsCondition(FlagsCondition condition) {
242 return static_cast<FlagsCondition>(condition ^ 1);
243}
244
245FlagsCondition CommuteFlagsCondition(FlagsCondition condition);
246
247V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
248 const FlagsCondition& fc);
249
250enum 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.
260using 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.
266using ArchOpcodeField = BitField<ArchOpcode, 0, 9>;
267using AddressingModeField = BitField<AddressingMode, 9, 5>;
268using FlagsModeField = BitField<FlagsMode, 14, 3>;
269using FlagsConditionField = BitField<FlagsCondition, 17, 5>;
270using 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