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