Line data Source code
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 319798 : inline RecordWriteMode WriteBarrierKindToRecordWriteMode(
46 : WriteBarrierKind write_barrier_kind) {
47 319798 : switch (write_barrier_kind) {
48 : case kMapWriteBarrier:
49 : return RecordWriteMode::kValueIsMap;
50 : case kPointerWriteBarrier:
51 29745 : return RecordWriteMode::kValueIsPointer;
52 : case kEphemeronKeyWriteBarrier:
53 112 : return RecordWriteMode::kValueIsEphemeronKey;
54 : case kFullWriteBarrier:
55 252809 : return RecordWriteMode::kValueIsAny;
56 : case kNoWriteBarrier:
57 : // Should not be passed as argument.
58 : default:
59 : break;
60 : }
61 0 : 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 2882635 : 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_
|