blob: 63a69f1699af136f2b666f3f3695d830d7dd51a8 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// Copyright 2015 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_INTERPRETER_BYTECODES_H_
6#define V8_INTERPRETER_BYTECODES_H_
7
8#include <iosfwd>
9
10// Clients of this interface shouldn't depend on lots of interpreter internals.
11// Do not include anything from src/interpreter here!
Ben Murdochc5610432016-08-08 18:44:38 +010012#include "src/frames.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000013#include "src/utils.h"
14
15namespace v8 {
16namespace internal {
17namespace interpreter {
18
Ben Murdochda12d292016-06-02 14:46:10 +010019#define INVALID_OPERAND_TYPE_LIST(V) V(None, OperandTypeInfo::kNone)
Ben Murdoch097c5b22016-05-18 11:27:45 +010020
Ben Murdochda12d292016-06-02 14:46:10 +010021#define REGISTER_INPUT_OPERAND_TYPE_LIST(V) \
22 V(MaybeReg, OperandTypeInfo::kScalableSignedByte) \
23 V(Reg, OperandTypeInfo::kScalableSignedByte) \
24 V(RegPair, OperandTypeInfo::kScalableSignedByte)
Ben Murdoch097c5b22016-05-18 11:27:45 +010025
Ben Murdochda12d292016-06-02 14:46:10 +010026#define REGISTER_OUTPUT_OPERAND_TYPE_LIST(V) \
27 V(RegOut, OperandTypeInfo::kScalableSignedByte) \
28 V(RegOutPair, OperandTypeInfo::kScalableSignedByte) \
29 V(RegOutTriple, OperandTypeInfo::kScalableSignedByte)
Ben Murdoch097c5b22016-05-18 11:27:45 +010030
Ben Murdochda12d292016-06-02 14:46:10 +010031#define SCALAR_OPERAND_TYPE_LIST(V) \
32 V(Flag8, OperandTypeInfo::kFixedUnsignedByte) \
Ben Murdoch61f157c2016-09-16 13:49:30 +010033 V(IntrinsicId, OperandTypeInfo::kFixedUnsignedByte) \
Ben Murdochda12d292016-06-02 14:46:10 +010034 V(Idx, OperandTypeInfo::kScalableUnsignedByte) \
35 V(Imm, OperandTypeInfo::kScalableSignedByte) \
36 V(RegCount, OperandTypeInfo::kScalableUnsignedByte) \
37 V(RuntimeId, OperandTypeInfo::kFixedUnsignedShort)
Ben Murdoch097c5b22016-05-18 11:27:45 +010038
39#define REGISTER_OPERAND_TYPE_LIST(V) \
40 REGISTER_INPUT_OPERAND_TYPE_LIST(V) \
41 REGISTER_OUTPUT_OPERAND_TYPE_LIST(V)
42
43#define NON_REGISTER_OPERAND_TYPE_LIST(V) \
44 INVALID_OPERAND_TYPE_LIST(V) \
45 SCALAR_OPERAND_TYPE_LIST(V)
46
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000047// The list of operand types used by bytecodes.
Ben Murdoch097c5b22016-05-18 11:27:45 +010048#define OPERAND_TYPE_LIST(V) \
49 NON_REGISTER_OPERAND_TYPE_LIST(V) \
50 REGISTER_OPERAND_TYPE_LIST(V)
51
Ben Murdochda12d292016-06-02 14:46:10 +010052// Define one debug break bytecode for each possible size of unscaled
53// bytecodes. Format is V(<bytecode>, <accumulator_use>, <operands>).
54#define DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \
55 V(DebugBreak0, AccumulatorUse::kRead) \
56 V(DebugBreak1, AccumulatorUse::kRead, OperandType::kReg) \
57 V(DebugBreak2, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg) \
58 V(DebugBreak3, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg, \
59 OperandType::kReg) \
60 V(DebugBreak4, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg, \
61 OperandType::kReg, OperandType::kReg) \
62 V(DebugBreak5, AccumulatorUse::kRead, OperandType::kRuntimeId, \
63 OperandType::kReg, OperandType::kReg) \
64 V(DebugBreak6, AccumulatorUse::kRead, OperandType::kRuntimeId, \
65 OperandType::kReg, OperandType::kReg, OperandType::kReg)
66
67// Define one debug break for each widening prefix.
68#define DEBUG_BREAK_PREFIX_BYTECODE_LIST(V) \
69 V(DebugBreakWide, AccumulatorUse::kRead) \
70 V(DebugBreakExtraWide, AccumulatorUse::kRead)
71
72#define DEBUG_BREAK_BYTECODE_LIST(V) \
73 DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \
74 DEBUG_BREAK_PREFIX_BYTECODE_LIST(V)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000075
76// The list of bytecodes which are interpreted by the interpreter.
Ben Murdoch61f157c2016-09-16 13:49:30 +010077#define BYTECODE_LIST(V) \
78 /* Extended width operands */ \
79 V(Wide, AccumulatorUse::kNone) \
80 V(ExtraWide, AccumulatorUse::kNone) \
81 \
82 /* Loading the accumulator */ \
83 V(LdaZero, AccumulatorUse::kWrite) \
84 V(LdaSmi, AccumulatorUse::kWrite, OperandType::kImm) \
85 V(LdaUndefined, AccumulatorUse::kWrite) \
86 V(LdaNull, AccumulatorUse::kWrite) \
87 V(LdaTheHole, AccumulatorUse::kWrite) \
88 V(LdaTrue, AccumulatorUse::kWrite) \
89 V(LdaFalse, AccumulatorUse::kWrite) \
90 V(LdaConstant, AccumulatorUse::kWrite, OperandType::kIdx) \
91 \
92 /* Loading registers */ \
93 V(LdrUndefined, AccumulatorUse::kNone, OperandType::kRegOut) \
94 \
95 /* Globals */ \
96 V(LdaGlobal, AccumulatorUse::kWrite, OperandType::kIdx) \
97 V(LdrGlobal, AccumulatorUse::kNone, OperandType::kIdx, OperandType::kRegOut) \
98 V(LdaGlobalInsideTypeof, AccumulatorUse::kWrite, OperandType::kIdx) \
99 V(StaGlobalSloppy, AccumulatorUse::kRead, OperandType::kIdx, \
100 OperandType::kIdx) \
101 V(StaGlobalStrict, AccumulatorUse::kRead, OperandType::kIdx, \
102 OperandType::kIdx) \
103 \
104 /* Context operations */ \
105 V(PushContext, AccumulatorUse::kRead, OperandType::kRegOut) \
106 V(PopContext, AccumulatorUse::kNone, OperandType::kReg) \
107 V(LdaContextSlot, AccumulatorUse::kWrite, OperandType::kReg, \
108 OperandType::kIdx) \
109 V(LdrContextSlot, AccumulatorUse::kNone, OperandType::kReg, \
110 OperandType::kIdx, OperandType::kRegOut) \
111 V(StaContextSlot, AccumulatorUse::kRead, OperandType::kReg, \
112 OperandType::kIdx) \
113 \
114 /* Load-Store lookup slots */ \
115 V(LdaLookupSlot, AccumulatorUse::kWrite, OperandType::kIdx) \
116 V(LdaLookupSlotInsideTypeof, AccumulatorUse::kWrite, OperandType::kIdx) \
117 V(StaLookupSlotSloppy, AccumulatorUse::kReadWrite, OperandType::kIdx) \
118 V(StaLookupSlotStrict, AccumulatorUse::kReadWrite, OperandType::kIdx) \
119 \
120 /* Register-accumulator transfers */ \
121 V(Ldar, AccumulatorUse::kWrite, OperandType::kReg) \
122 V(Star, AccumulatorUse::kRead, OperandType::kRegOut) \
123 \
124 /* Register-register transfers */ \
125 V(Mov, AccumulatorUse::kNone, OperandType::kReg, OperandType::kRegOut) \
126 \
127 /* Property loads (LoadIC) operations */ \
128 V(LdaNamedProperty, AccumulatorUse::kWrite, OperandType::kReg, \
129 OperandType::kIdx, OperandType::kIdx) \
130 V(LdrNamedProperty, AccumulatorUse::kNone, OperandType::kReg, \
131 OperandType::kIdx, OperandType::kIdx, OperandType::kRegOut) \
132 V(LdaKeyedProperty, AccumulatorUse::kReadWrite, OperandType::kReg, \
133 OperandType::kIdx) \
134 V(LdrKeyedProperty, AccumulatorUse::kRead, OperandType::kReg, \
135 OperandType::kIdx, OperandType::kRegOut) \
136 \
137 /* Propery stores (StoreIC) operations */ \
138 V(StaNamedPropertySloppy, AccumulatorUse::kRead, OperandType::kReg, \
139 OperandType::kIdx, OperandType::kIdx) \
140 V(StaNamedPropertyStrict, AccumulatorUse::kRead, OperandType::kReg, \
141 OperandType::kIdx, OperandType::kIdx) \
142 V(StaKeyedPropertySloppy, AccumulatorUse::kRead, OperandType::kReg, \
143 OperandType::kReg, OperandType::kIdx) \
144 V(StaKeyedPropertyStrict, AccumulatorUse::kRead, OperandType::kReg, \
145 OperandType::kReg, OperandType::kIdx) \
146 \
147 /* Binary Operators */ \
148 V(Add, AccumulatorUse::kReadWrite, OperandType::kReg) \
149 V(Sub, AccumulatorUse::kReadWrite, OperandType::kReg) \
150 V(Mul, AccumulatorUse::kReadWrite, OperandType::kReg) \
151 V(Div, AccumulatorUse::kReadWrite, OperandType::kReg) \
152 V(Mod, AccumulatorUse::kReadWrite, OperandType::kReg) \
153 V(BitwiseOr, AccumulatorUse::kReadWrite, OperandType::kReg) \
154 V(BitwiseXor, AccumulatorUse::kReadWrite, OperandType::kReg) \
155 V(BitwiseAnd, AccumulatorUse::kReadWrite, OperandType::kReg) \
156 V(ShiftLeft, AccumulatorUse::kReadWrite, OperandType::kReg) \
157 V(ShiftRight, AccumulatorUse::kReadWrite, OperandType::kReg) \
158 V(ShiftRightLogical, AccumulatorUse::kReadWrite, OperandType::kReg) \
159 \
160 /* Unary Operators */ \
161 V(Inc, AccumulatorUse::kReadWrite) \
162 V(Dec, AccumulatorUse::kReadWrite) \
163 V(ToBooleanLogicalNot, AccumulatorUse::kReadWrite) \
164 V(LogicalNot, AccumulatorUse::kReadWrite) \
165 V(TypeOf, AccumulatorUse::kReadWrite) \
166 V(DeletePropertyStrict, AccumulatorUse::kReadWrite, OperandType::kReg) \
167 V(DeletePropertySloppy, AccumulatorUse::kReadWrite, OperandType::kReg) \
168 \
169 /* Call operations */ \
170 V(Call, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg, \
171 OperandType::kRegCount, OperandType::kIdx) \
172 V(TailCall, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg, \
173 OperandType::kRegCount, OperandType::kIdx) \
174 V(CallRuntime, AccumulatorUse::kWrite, OperandType::kRuntimeId, \
175 OperandType::kMaybeReg, OperandType::kRegCount) \
176 V(CallRuntimeForPair, AccumulatorUse::kNone, OperandType::kRuntimeId, \
177 OperandType::kMaybeReg, OperandType::kRegCount, OperandType::kRegOutPair) \
178 V(CallJSRuntime, AccumulatorUse::kWrite, OperandType::kIdx, \
179 OperandType::kReg, OperandType::kRegCount) \
180 \
181 /* Intrinsics */ \
182 V(InvokeIntrinsic, AccumulatorUse::kWrite, OperandType::kIntrinsicId, \
183 OperandType::kMaybeReg, OperandType::kRegCount) \
184 \
185 /* New operator */ \
186 V(New, AccumulatorUse::kReadWrite, OperandType::kReg, \
187 OperandType::kMaybeReg, OperandType::kRegCount) \
188 \
189 /* Test Operators */ \
190 V(TestEqual, AccumulatorUse::kReadWrite, OperandType::kReg) \
191 V(TestNotEqual, AccumulatorUse::kReadWrite, OperandType::kReg) \
192 V(TestEqualStrict, AccumulatorUse::kReadWrite, OperandType::kReg) \
193 V(TestLessThan, AccumulatorUse::kReadWrite, OperandType::kReg) \
194 V(TestGreaterThan, AccumulatorUse::kReadWrite, OperandType::kReg) \
195 V(TestLessThanOrEqual, AccumulatorUse::kReadWrite, OperandType::kReg) \
196 V(TestGreaterThanOrEqual, AccumulatorUse::kReadWrite, OperandType::kReg) \
197 V(TestInstanceOf, AccumulatorUse::kReadWrite, OperandType::kReg) \
198 V(TestIn, AccumulatorUse::kReadWrite, OperandType::kReg) \
199 \
200 /* Cast operators */ \
201 V(ToName, AccumulatorUse::kReadWrite) \
202 V(ToNumber, AccumulatorUse::kReadWrite) \
203 V(ToObject, AccumulatorUse::kReadWrite) \
204 \
205 /* Literals */ \
206 V(CreateRegExpLiteral, AccumulatorUse::kWrite, OperandType::kIdx, \
207 OperandType::kIdx, OperandType::kFlag8) \
208 V(CreateArrayLiteral, AccumulatorUse::kWrite, OperandType::kIdx, \
209 OperandType::kIdx, OperandType::kFlag8) \
210 V(CreateObjectLiteral, AccumulatorUse::kWrite, OperandType::kIdx, \
211 OperandType::kIdx, OperandType::kFlag8) \
212 \
213 /* Closure allocation */ \
214 V(CreateClosure, AccumulatorUse::kWrite, OperandType::kIdx, \
215 OperandType::kFlag8) \
216 \
217 /* Arguments allocation */ \
218 V(CreateMappedArguments, AccumulatorUse::kWrite) \
219 V(CreateUnmappedArguments, AccumulatorUse::kWrite) \
220 V(CreateRestParameter, AccumulatorUse::kWrite) \
221 \
222 /* Control Flow */ \
223 V(Jump, AccumulatorUse::kNone, OperandType::kImm) \
224 V(JumpConstant, AccumulatorUse::kNone, OperandType::kIdx) \
225 V(JumpIfTrue, AccumulatorUse::kRead, OperandType::kImm) \
226 V(JumpIfTrueConstant, AccumulatorUse::kRead, OperandType::kIdx) \
227 V(JumpIfFalse, AccumulatorUse::kRead, OperandType::kImm) \
228 V(JumpIfFalseConstant, AccumulatorUse::kRead, OperandType::kIdx) \
229 V(JumpIfToBooleanTrue, AccumulatorUse::kRead, OperandType::kImm) \
230 V(JumpIfToBooleanTrueConstant, AccumulatorUse::kRead, OperandType::kIdx) \
231 V(JumpIfToBooleanFalse, AccumulatorUse::kRead, OperandType::kImm) \
232 V(JumpIfToBooleanFalseConstant, AccumulatorUse::kRead, OperandType::kIdx) \
233 V(JumpIfNull, AccumulatorUse::kRead, OperandType::kImm) \
234 V(JumpIfNullConstant, AccumulatorUse::kRead, OperandType::kIdx) \
235 V(JumpIfUndefined, AccumulatorUse::kRead, OperandType::kImm) \
236 V(JumpIfUndefinedConstant, AccumulatorUse::kRead, OperandType::kIdx) \
237 V(JumpIfNotHole, AccumulatorUse::kRead, OperandType::kImm) \
238 V(JumpIfNotHoleConstant, AccumulatorUse::kRead, OperandType::kIdx) \
239 \
240 /* Complex flow control For..in */ \
241 V(ForInPrepare, AccumulatorUse::kRead, OperandType::kRegOutTriple) \
242 V(ForInDone, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg) \
243 V(ForInNext, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg, \
244 OperandType::kRegPair, OperandType::kIdx) \
245 V(ForInStep, AccumulatorUse::kWrite, OperandType::kReg) \
246 \
247 /* Perform a stack guard check */ \
248 V(StackCheck, AccumulatorUse::kNone) \
249 \
250 /* Non-local flow control */ \
251 V(Throw, AccumulatorUse::kRead) \
252 V(ReThrow, AccumulatorUse::kRead) \
253 V(Return, AccumulatorUse::kRead) \
254 \
255 /* Generators */ \
256 V(SuspendGenerator, AccumulatorUse::kRead, OperandType::kReg) \
257 V(ResumeGenerator, AccumulatorUse::kWrite, OperandType::kReg) \
258 \
259 /* Debugger */ \
260 V(Debugger, AccumulatorUse::kNone) \
261 DEBUG_BREAK_BYTECODE_LIST(V) \
262 \
263 /* Illegal bytecode (terminates execution) */ \
264 V(Illegal, AccumulatorUse::kNone) \
265 \
266 /* No operation (used to maintain source positions for peephole */ \
267 /* eliminated bytecodes). */ \
Ben Murdochc5610432016-08-08 18:44:38 +0100268 V(Nop, AccumulatorUse::kNone)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000269
Ben Murdochda12d292016-06-02 14:46:10 +0100270enum class AccumulatorUse : uint8_t {
271 kNone = 0,
272 kRead = 1 << 0,
273 kWrite = 1 << 1,
274 kReadWrite = kRead | kWrite
275};
276
277V8_INLINE AccumulatorUse operator&(AccumulatorUse lhs, AccumulatorUse rhs) {
278 int result = static_cast<int>(lhs) & static_cast<int>(rhs);
279 return static_cast<AccumulatorUse>(result);
280}
281
282V8_INLINE AccumulatorUse operator|(AccumulatorUse lhs, AccumulatorUse rhs) {
283 int result = static_cast<int>(lhs) | static_cast<int>(rhs);
284 return static_cast<AccumulatorUse>(result);
285}
286
287// Enumeration of scaling factors applicable to scalable operands. Code
288// relies on being able to cast values to integer scaling values.
Ben Murdochc5610432016-08-08 18:44:38 +0100289#define OPERAND_SCALE_LIST(V) \
290 V(Single, 1) \
291 V(Double, 2) \
292 V(Quadruple, 4)
293
Ben Murdochda12d292016-06-02 14:46:10 +0100294enum class OperandScale : uint8_t {
Ben Murdochc5610432016-08-08 18:44:38 +0100295#define DECLARE_OPERAND_SCALE(Name, Scale) k##Name = Scale,
296 OPERAND_SCALE_LIST(DECLARE_OPERAND_SCALE)
297#undef DECLARE_OPERAND_SCALE
298 kLast = kQuadruple
Ben Murdochda12d292016-06-02 14:46:10 +0100299};
300
301// Enumeration of the size classes of operand types used by
302// bytecodes. Code relies on being able to cast values to integer
303// types to get the size in bytes.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000304enum class OperandSize : uint8_t {
305 kNone = 0,
306 kByte = 1,
307 kShort = 2,
Ben Murdochda12d292016-06-02 14:46:10 +0100308 kQuad = 4,
309 kLast = kQuad
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000310};
311
Ben Murdochda12d292016-06-02 14:46:10 +0100312// Primitive operand info used that summarize properties of operands.
313// Columns are Name, IsScalable, IsUnsigned, UnscaledSize.
314#define OPERAND_TYPE_INFO_LIST(V) \
315 V(None, false, false, OperandSize::kNone) \
316 V(ScalableSignedByte, true, false, OperandSize::kByte) \
317 V(ScalableUnsignedByte, true, true, OperandSize::kByte) \
318 V(FixedUnsignedByte, false, true, OperandSize::kByte) \
319 V(FixedUnsignedShort, false, true, OperandSize::kShort)
320
321enum class OperandTypeInfo : uint8_t {
322#define DECLARE_OPERAND_TYPE_INFO(Name, ...) k##Name,
323 OPERAND_TYPE_INFO_LIST(DECLARE_OPERAND_TYPE_INFO)
324#undef DECLARE_OPERAND_TYPE_INFO
325};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000326
327// Enumeration of operand types used by bytecodes.
328enum class OperandType : uint8_t {
329#define DECLARE_OPERAND_TYPE(Name, _) k##Name,
330 OPERAND_TYPE_LIST(DECLARE_OPERAND_TYPE)
331#undef DECLARE_OPERAND_TYPE
332#define COUNT_OPERAND_TYPES(x, _) +1
333 // The COUNT_OPERAND macro will turn this into kLast = -1 +1 +1... which will
334 // evaluate to the same value as the last operand.
335 kLast = -1 OPERAND_TYPE_LIST(COUNT_OPERAND_TYPES)
336#undef COUNT_OPERAND_TYPES
337};
338
339
340// Enumeration of interpreter bytecodes.
341enum class Bytecode : uint8_t {
342#define DECLARE_BYTECODE(Name, ...) k##Name,
343 BYTECODE_LIST(DECLARE_BYTECODE)
344#undef DECLARE_BYTECODE
345#define COUNT_BYTECODE(x, ...) +1
346 // The COUNT_BYTECODE macro will turn this into kLast = -1 +1 +1... which will
347 // evaluate to the same value as the last real bytecode.
348 kLast = -1 BYTECODE_LIST(COUNT_BYTECODE)
349#undef COUNT_BYTECODE
350};
351
352
353// An interpreter Register which is located in the function's Register file
354// in its stack-frame. Register hold parameters, this, and expression values.
Ben Murdochc5610432016-08-08 18:44:38 +0100355class Register final {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000356 public:
Ben Murdoch097c5b22016-05-18 11:27:45 +0100357 explicit Register(int index = kInvalidIndex) : index_(index) {}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000358
Ben Murdoch097c5b22016-05-18 11:27:45 +0100359 int index() const { return index_; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000360 bool is_parameter() const { return index() < 0; }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100361 bool is_valid() const { return index_ != kInvalidIndex; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000362
363 static Register FromParameterIndex(int index, int parameter_count);
364 int ToParameterIndex(int parameter_count) const;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100365
366 // Returns an invalid register.
367 static Register invalid_value() { return Register(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000368
369 // Returns the register for the function's closure object.
370 static Register function_closure();
371 bool is_function_closure() const;
372
Ben Murdoch097c5b22016-05-18 11:27:45 +0100373 // Returns the register which holds the current context object.
374 static Register current_context();
375 bool is_current_context() const;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000376
377 // Returns the register for the incoming new target value.
378 static Register new_target();
379 bool is_new_target() const;
380
Ben Murdochc5610432016-08-08 18:44:38 +0100381 // Returns the register for the bytecode array.
382 static Register bytecode_array();
383 bool is_bytecode_array() const;
384
385 // Returns the register for the saved bytecode offset.
386 static Register bytecode_offset();
387 bool is_bytecode_offset() const;
388
Ben Murdoch61f157c2016-09-16 13:49:30 +0100389 // Returns a register that can be used to represent the accumulator
390 // within code in the interpreter, but should never be emitted in
391 // bytecode.
392 static Register virtual_accumulator();
393
Ben Murdochc5610432016-08-08 18:44:38 +0100394 OperandSize SizeOfOperand() const;
395
396 int32_t ToOperand() const { return kRegisterFileStartOffset - index_; }
397 static Register FromOperand(int32_t operand) {
398 return Register(kRegisterFileStartOffset - operand);
399 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100400
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000401 static bool AreContiguous(Register reg1, Register reg2,
402 Register reg3 = Register(),
403 Register reg4 = Register(),
404 Register reg5 = Register());
405
Ben Murdoch097c5b22016-05-18 11:27:45 +0100406 std::string ToString(int parameter_count);
407
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000408 bool operator==(const Register& other) const {
409 return index() == other.index();
410 }
411 bool operator!=(const Register& other) const {
412 return index() != other.index();
413 }
414 bool operator<(const Register& other) const {
415 return index() < other.index();
416 }
417 bool operator<=(const Register& other) const {
418 return index() <= other.index();
419 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100420 bool operator>(const Register& other) const {
421 return index() > other.index();
422 }
423 bool operator>=(const Register& other) const {
424 return index() >= other.index();
425 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000426
427 private:
Ben Murdoch097c5b22016-05-18 11:27:45 +0100428 static const int kInvalidIndex = kMaxInt;
Ben Murdochc5610432016-08-08 18:44:38 +0100429 static const int kRegisterFileStartOffset =
430 InterpreterFrameConstants::kRegisterFileFromFp / kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000431
432 void* operator new(size_t size);
433 void operator delete(void* p);
434
435 int index_;
436};
437
438
439class Bytecodes {
440 public:
441 // Returns string representation of |bytecode|.
442 static const char* ToString(Bytecode bytecode);
443
Ben Murdochda12d292016-06-02 14:46:10 +0100444 // Returns string representation of |bytecode|.
445 static std::string ToString(Bytecode bytecode, OperandScale operand_scale);
446
447 // Returns string representation of |accumulator_use|.
448 static const char* AccumulatorUseToString(AccumulatorUse accumulator_use);
449
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000450 // Returns string representation of |operand_type|.
451 static const char* OperandTypeToString(OperandType operand_type);
452
Ben Murdochda12d292016-06-02 14:46:10 +0100453 // Returns string representation of |operand_scale|.
454 static const char* OperandScaleToString(OperandScale operand_scale);
455
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000456 // Returns string representation of |operand_size|.
457 static const char* OperandSizeToString(OperandSize operand_size);
458
459 // Returns byte value of bytecode.
Ben Murdoch61f157c2016-09-16 13:49:30 +0100460 static uint8_t ToByte(Bytecode bytecode) {
461 DCHECK_LE(bytecode, Bytecode::kLast);
462 return static_cast<uint8_t>(bytecode);
463 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000464
465 // Returns bytecode for |value|.
466 static Bytecode FromByte(uint8_t value);
467
468 // Returns the number of operands expected by |bytecode|.
469 static int NumberOfOperands(Bytecode bytecode);
470
Ben Murdoch097c5b22016-05-18 11:27:45 +0100471 // Returns the number of register operands expected by |bytecode|.
472 static int NumberOfRegisterOperands(Bytecode bytecode);
473
Ben Murdochda12d292016-06-02 14:46:10 +0100474 // Returns the prefix bytecode representing an operand scale to be
475 // applied to a a bytecode.
476 static Bytecode OperandScaleToPrefixBytecode(OperandScale operand_scale);
477
478 // Returns true if the operand scale requires a prefix bytecode.
479 static bool OperandScaleRequiresPrefixBytecode(OperandScale operand_scale);
480
481 // Returns the scaling applied to scalable operands if bytecode is
482 // is a scaling prefix.
483 static OperandScale PrefixBytecodeToOperandScale(Bytecode bytecode);
484
485 // Returns how accumulator is used by |bytecode|.
486 static AccumulatorUse GetAccumulatorUse(Bytecode bytecode);
487
488 // Returns true if |bytecode| reads the accumulator.
489 static bool ReadsAccumulator(Bytecode bytecode);
490
491 // Returns true if |bytecode| writes the accumulator.
492 static bool WritesAccumulator(Bytecode bytecode);
493
Ben Murdochc5610432016-08-08 18:44:38 +0100494 // Return true if |bytecode| writes the accumulator with a boolean value.
495 static bool WritesBooleanToAccumulator(Bytecode bytecode);
496
Ben Murdoch61f157c2016-09-16 13:49:30 +0100497 // Return true if |bytecode| is an accumulator load without effects,
Ben Murdochc5610432016-08-08 18:44:38 +0100498 // e.g. LdaConstant, LdaTrue, Ldar.
499 static bool IsAccumulatorLoadWithoutEffects(Bytecode bytecode);
500
Ben Murdoch61f157c2016-09-16 13:49:30 +0100501 // Return true if |bytecode| is a jump without effects,
502 // e.g. any jump excluding those that include type coercion like
503 // JumpIfTrueToBoolean.
504 static bool IsJumpWithoutEffects(Bytecode bytecode);
505
506 // Return true if |bytecode| is a register load without effects,
507 // e.g. Mov, Star, LdrUndefined.
508 static bool IsRegisterLoadWithoutEffects(Bytecode bytecode);
509
510 // Returns true if |bytecode| has no effects.
511 static bool IsWithoutExternalSideEffects(Bytecode bytecode);
512
Ben Murdoch097c5b22016-05-18 11:27:45 +0100513 // Returns the i-th operand of |bytecode|.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000514 static OperandType GetOperandType(Bytecode bytecode, int i);
515
Ben Murdochc5610432016-08-08 18:44:38 +0100516 // Returns a pointer to an array of operand types terminated in
517 // OperandType::kNone.
518 static const OperandType* GetOperandTypes(Bytecode bytecode);
519
Ben Murdoch61f157c2016-09-16 13:49:30 +0100520 // Returns a pointer to an array of operand type info terminated in
521 // OperandTypeInfo::kNone.
522 static const OperandTypeInfo* GetOperandTypeInfos(Bytecode bytecode);
523
Ben Murdoch097c5b22016-05-18 11:27:45 +0100524 // Returns the size of the i-th operand of |bytecode|.
Ben Murdochda12d292016-06-02 14:46:10 +0100525 static OperandSize GetOperandSize(Bytecode bytecode, int i,
526 OperandScale operand_scale);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000527
Ben Murdoch61f157c2016-09-16 13:49:30 +0100528 // Returns a pointer to an array of the operand sizes for |bytecode|.
529 static const OperandSize* GetOperandSizes(Bytecode bytecode,
530 OperandScale operand_scale);
531
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000532 // Returns the offset of the i-th operand of |bytecode| relative to the start
533 // of the bytecode.
Ben Murdochda12d292016-06-02 14:46:10 +0100534 static int GetOperandOffset(Bytecode bytecode, int i,
535 OperandScale operand_scale);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000536
Ben Murdoch097c5b22016-05-18 11:27:45 +0100537 // Returns a zero-based bitmap of the register operand positions of
538 // |bytecode|.
539 static int GetRegisterOperandBitmap(Bytecode bytecode);
540
Ben Murdochda12d292016-06-02 14:46:10 +0100541 // Returns a debug break bytecode to replace |bytecode|.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100542 static Bytecode GetDebugBreak(Bytecode bytecode);
543
Ben Murdochda12d292016-06-02 14:46:10 +0100544 // Returns the size of the bytecode including its operands for the
545 // given |operand_scale|.
546 static int Size(Bytecode bytecode, OperandScale operand_scale);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000547
548 // Returns the size of |operand|.
Ben Murdochda12d292016-06-02 14:46:10 +0100549 static OperandSize SizeOfOperand(OperandType operand, OperandScale scale);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000550
Ben Murdochc5610432016-08-08 18:44:38 +0100551 // Returns the number of values which |bytecode| returns.
552 static size_t ReturnCount(Bytecode bytecode);
553
Ben Murdoch097c5b22016-05-18 11:27:45 +0100554 // Returns true if the bytecode is a conditional jump taking
Ben Murdochda12d292016-06-02 14:46:10 +0100555 // an immediate byte operand (OperandType::kImm).
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000556 static bool IsConditionalJumpImmediate(Bytecode bytecode);
557
Ben Murdoch097c5b22016-05-18 11:27:45 +0100558 // Returns true if the bytecode is a conditional jump taking
Ben Murdochda12d292016-06-02 14:46:10 +0100559 // a constant pool entry (OperandType::kIdx).
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000560 static bool IsConditionalJumpConstant(Bytecode bytecode);
561
Ben Murdoch097c5b22016-05-18 11:27:45 +0100562 // Returns true if the bytecode is a conditional jump taking
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000563 // any kind of operand.
564 static bool IsConditionalJump(Bytecode bytecode);
565
Ben Murdoch097c5b22016-05-18 11:27:45 +0100566 // Returns true if the bytecode is a jump or a conditional jump taking
Ben Murdochda12d292016-06-02 14:46:10 +0100567 // an immediate byte operand (OperandType::kImm).
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000568 static bool IsJumpImmediate(Bytecode bytecode);
569
Ben Murdoch097c5b22016-05-18 11:27:45 +0100570 // Returns true if the bytecode is a jump or conditional jump taking a
Ben Murdochda12d292016-06-02 14:46:10 +0100571 // constant pool entry (OperandType::kIdx).
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000572 static bool IsJumpConstant(Bytecode bytecode);
573
Ben Murdoch097c5b22016-05-18 11:27:45 +0100574 // Returns true if the bytecode is a jump or conditional jump taking
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000575 // any kind of operand.
576 static bool IsJump(Bytecode bytecode);
577
Ben Murdochc5610432016-08-08 18:44:38 +0100578 // Returns true if the bytecode is a jump that internally coerces the
579 // accumulator to a boolean.
580 static bool IsJumpIfToBoolean(Bytecode bytecode);
581
582 // Returns the equivalent jump bytecode without the accumulator coercion.
583 static Bytecode GetJumpWithoutToBoolean(Bytecode bytecode);
584
Ben Murdoch097c5b22016-05-18 11:27:45 +0100585 // Returns true if the bytecode is a conditional jump, a jump, or a return.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000586 static bool IsJumpOrReturn(Bytecode bytecode);
587
Ben Murdoch097c5b22016-05-18 11:27:45 +0100588 // Returns true if the bytecode is a call or a constructor call.
589 static bool IsCallOrNew(Bytecode bytecode);
590
Ben Murdochda12d292016-06-02 14:46:10 +0100591 // Returns true if the bytecode is a call to the runtime.
592 static bool IsCallRuntime(Bytecode bytecode);
593
Ben Murdoch097c5b22016-05-18 11:27:45 +0100594 // Returns true if the bytecode is a debug break.
595 static bool IsDebugBreak(Bytecode bytecode);
596
Ben Murdochc5610432016-08-08 18:44:38 +0100597 // Returns true if the bytecode is Ldar or Star.
598 static bool IsLdarOrStar(Bytecode bytecode);
599
Ben Murdochda12d292016-06-02 14:46:10 +0100600 // Returns true if the bytecode has wider operand forms.
601 static bool IsBytecodeWithScalableOperands(Bytecode bytecode);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100602
Ben Murdochda12d292016-06-02 14:46:10 +0100603 // Returns true if the bytecode is a scaling prefix bytecode.
604 static bool IsPrefixScalingBytecode(Bytecode bytecode);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100605
606 // Returns true if |operand_type| is any type of register operand.
607 static bool IsRegisterOperandType(OperandType operand_type);
608
609 // Returns true if |operand_type| represents a register used as an input.
610 static bool IsRegisterInputOperandType(OperandType operand_type);
611
612 // Returns true if |operand_type| represents a register used as an output.
613 static bool IsRegisterOutputOperandType(OperandType operand_type);
614
Ben Murdochc5610432016-08-08 18:44:38 +0100615 // Returns the number of registers represented by a register operand. For
616 // instance, a RegPair represents two registers.
617 static int GetNumberOfRegistersRepresentedBy(OperandType operand_type);
618
Ben Murdoch097c5b22016-05-18 11:27:45 +0100619 // Returns true if |operand_type| is a maybe register operand
Ben Murdochda12d292016-06-02 14:46:10 +0100620 // (kMaybeReg).
Ben Murdoch097c5b22016-05-18 11:27:45 +0100621 static bool IsMaybeRegisterOperandType(OperandType operand_type);
622
Ben Murdochda12d292016-06-02 14:46:10 +0100623 // Returns true if |operand_type| is a runtime-id operand (kRuntimeId).
624 static bool IsRuntimeIdOperandType(OperandType operand_type);
625
626 // Returns true if |operand_type| is unsigned, false if signed.
627 static bool IsUnsignedOperandType(OperandType operand_type);
628
629 // Decodes a register operand in a byte array.
630 static Register DecodeRegisterOperand(const uint8_t* operand_start,
631 OperandType operand_type,
632 OperandScale operand_scale);
633
634 // Decodes a signed operand in a byte array.
635 static int32_t DecodeSignedOperand(const uint8_t* operand_start,
636 OperandType operand_type,
637 OperandScale operand_scale);
638
639 // Decodes an unsigned operand in a byte array.
640 static uint32_t DecodeUnsignedOperand(const uint8_t* operand_start,
641 OperandType operand_type,
642 OperandScale operand_scale);
643
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000644 // Decode a single bytecode and operands to |os|.
645 static std::ostream& Decode(std::ostream& os, const uint8_t* bytecode_start,
646 int number_of_parameters);
647
Ben Murdochda12d292016-06-02 14:46:10 +0100648 // Returns true if a handler is generated for a bytecode at a given
649 // operand scale. All bytecodes have handlers at OperandScale::kSingle,
650 // but only bytecodes with scalable operands have handlers with larger
651 // OperandScale values.
652 static bool BytecodeHasHandler(Bytecode bytecode, OperandScale operand_scale);
653
Ben Murdochc5610432016-08-08 18:44:38 +0100654 // Return the operand size required to hold a signed operand.
655 static OperandSize SizeForSignedOperand(int value);
656
657 // Return the operand size required to hold an unsigned operand.
Ben Murdoch61f157c2016-09-16 13:49:30 +0100658 static OperandSize SizeForUnsignedOperand(uint32_t value);
Ben Murdochda12d292016-06-02 14:46:10 +0100659
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000660 private:
661 DISALLOW_IMPLICIT_CONSTRUCTORS(Bytecodes);
662};
663
Ben Murdochc5610432016-08-08 18:44:38 +0100664class CreateObjectLiteralFlags {
665 public:
666 class FlagsBits : public BitField8<int, 0, 3> {};
667 class FastClonePropertiesCountBits
668 : public BitField8<int, FlagsBits::kNext, 3> {};
669 STATIC_ASSERT((FlagsBits::kMask & FastClonePropertiesCountBits::kMask) == 0);
670};
671
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000672std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode);
Ben Murdochda12d292016-06-02 14:46:10 +0100673std::ostream& operator<<(std::ostream& os, const AccumulatorUse& use);
674std::ostream& operator<<(std::ostream& os, const OperandScale& operand_scale);
675std::ostream& operator<<(std::ostream& os, const OperandSize& operand_size);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000676std::ostream& operator<<(std::ostream& os, const OperandType& operand_type);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000677
678} // namespace interpreter
679} // namespace internal
680} // namespace v8
681
682#endif // V8_INTERPRETER_BYTECODES_H_