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