blob: 23612713aaf80563c8e235c90acbea1cef391465 [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!
12#include "src/utils.h"
13
14namespace v8 {
15namespace internal {
16namespace interpreter {
17
Ben Murdochda12d292016-06-02 14:46:10 +010018#define INVALID_OPERAND_TYPE_LIST(V) V(None, OperandTypeInfo::kNone)
Ben Murdoch097c5b22016-05-18 11:27:45 +010019
Ben Murdochda12d292016-06-02 14:46:10 +010020#define REGISTER_INPUT_OPERAND_TYPE_LIST(V) \
21 V(MaybeReg, OperandTypeInfo::kScalableSignedByte) \
22 V(Reg, OperandTypeInfo::kScalableSignedByte) \
23 V(RegPair, OperandTypeInfo::kScalableSignedByte)
Ben Murdoch097c5b22016-05-18 11:27:45 +010024
Ben Murdochda12d292016-06-02 14:46:10 +010025#define REGISTER_OUTPUT_OPERAND_TYPE_LIST(V) \
26 V(RegOut, OperandTypeInfo::kScalableSignedByte) \
27 V(RegOutPair, OperandTypeInfo::kScalableSignedByte) \
28 V(RegOutTriple, OperandTypeInfo::kScalableSignedByte)
Ben Murdoch097c5b22016-05-18 11:27:45 +010029
Ben Murdochda12d292016-06-02 14:46:10 +010030#define SCALAR_OPERAND_TYPE_LIST(V) \
31 V(Flag8, OperandTypeInfo::kFixedUnsignedByte) \
32 V(Idx, OperandTypeInfo::kScalableUnsignedByte) \
33 V(Imm, OperandTypeInfo::kScalableSignedByte) \
34 V(RegCount, OperandTypeInfo::kScalableUnsignedByte) \
35 V(RuntimeId, OperandTypeInfo::kFixedUnsignedShort)
Ben Murdoch097c5b22016-05-18 11:27:45 +010036
37#define REGISTER_OPERAND_TYPE_LIST(V) \
38 REGISTER_INPUT_OPERAND_TYPE_LIST(V) \
39 REGISTER_OUTPUT_OPERAND_TYPE_LIST(V)
40
41#define NON_REGISTER_OPERAND_TYPE_LIST(V) \
42 INVALID_OPERAND_TYPE_LIST(V) \
43 SCALAR_OPERAND_TYPE_LIST(V)
44
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000045// The list of operand types used by bytecodes.
Ben Murdoch097c5b22016-05-18 11:27:45 +010046#define OPERAND_TYPE_LIST(V) \
47 NON_REGISTER_OPERAND_TYPE_LIST(V) \
48 REGISTER_OPERAND_TYPE_LIST(V)
49
Ben Murdochda12d292016-06-02 14:46:10 +010050// Define one debug break bytecode for each possible size of unscaled
51// bytecodes. Format is V(<bytecode>, <accumulator_use>, <operands>).
52#define DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \
53 V(DebugBreak0, AccumulatorUse::kRead) \
54 V(DebugBreak1, AccumulatorUse::kRead, OperandType::kReg) \
55 V(DebugBreak2, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg) \
56 V(DebugBreak3, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg, \
57 OperandType::kReg) \
58 V(DebugBreak4, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg, \
59 OperandType::kReg, OperandType::kReg) \
60 V(DebugBreak5, AccumulatorUse::kRead, OperandType::kRuntimeId, \
61 OperandType::kReg, OperandType::kReg) \
62 V(DebugBreak6, AccumulatorUse::kRead, OperandType::kRuntimeId, \
63 OperandType::kReg, OperandType::kReg, OperandType::kReg)
64
65// Define one debug break for each widening prefix.
66#define DEBUG_BREAK_PREFIX_BYTECODE_LIST(V) \
67 V(DebugBreakWide, AccumulatorUse::kRead) \
68 V(DebugBreakExtraWide, AccumulatorUse::kRead)
69
70#define DEBUG_BREAK_BYTECODE_LIST(V) \
71 DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \
72 DEBUG_BREAK_PREFIX_BYTECODE_LIST(V)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000073
74// The list of bytecodes which are interpreted by the interpreter.
Ben Murdochda12d292016-06-02 14:46:10 +010075#define BYTECODE_LIST(V) \
76 /* Extended width operands */ \
77 V(Wide, AccumulatorUse::kNone) \
78 V(ExtraWide, AccumulatorUse::kNone) \
79 \
80 /* Loading the accumulator */ \
81 V(LdaZero, AccumulatorUse::kWrite) \
82 V(LdaSmi, AccumulatorUse::kWrite, OperandType::kImm) \
83 V(LdaUndefined, AccumulatorUse::kWrite) \
84 V(LdaNull, AccumulatorUse::kWrite) \
85 V(LdaTheHole, AccumulatorUse::kWrite) \
86 V(LdaTrue, AccumulatorUse::kWrite) \
87 V(LdaFalse, AccumulatorUse::kWrite) \
88 V(LdaConstant, AccumulatorUse::kWrite, OperandType::kIdx) \
89 \
90 /* Globals */ \
91 V(LdaGlobal, AccumulatorUse::kWrite, OperandType::kIdx, OperandType::kIdx) \
92 V(LdaGlobalInsideTypeof, AccumulatorUse::kWrite, OperandType::kIdx, \
93 OperandType::kIdx) \
94 V(StaGlobalSloppy, AccumulatorUse::kRead, OperandType::kIdx, \
95 OperandType::kIdx) \
96 V(StaGlobalStrict, AccumulatorUse::kRead, OperandType::kIdx, \
97 OperandType::kIdx) \
98 \
99 /* Context operations */ \
100 V(PushContext, AccumulatorUse::kRead, OperandType::kReg) \
101 V(PopContext, AccumulatorUse::kNone, OperandType::kReg) \
102 V(LdaContextSlot, AccumulatorUse::kWrite, OperandType::kReg, \
103 OperandType::kIdx) \
104 V(StaContextSlot, AccumulatorUse::kRead, OperandType::kReg, \
105 OperandType::kIdx) \
106 \
107 /* Load-Store lookup slots */ \
108 V(LdaLookupSlot, AccumulatorUse::kWrite, OperandType::kIdx) \
109 V(LdaLookupSlotInsideTypeof, AccumulatorUse::kWrite, OperandType::kIdx) \
110 V(StaLookupSlotSloppy, AccumulatorUse::kReadWrite, OperandType::kIdx) \
111 V(StaLookupSlotStrict, AccumulatorUse::kReadWrite, OperandType::kIdx) \
112 \
113 /* Register-accumulator transfers */ \
114 V(Ldar, AccumulatorUse::kWrite, OperandType::kReg) \
115 V(Star, AccumulatorUse::kRead, OperandType::kRegOut) \
116 \
117 /* Register-register transfers */ \
118 V(Mov, AccumulatorUse::kNone, OperandType::kReg, OperandType::kRegOut) \
119 \
120 /* LoadIC operations */ \
121 V(LoadIC, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kIdx, \
122 OperandType::kIdx) \
123 V(KeyedLoadIC, AccumulatorUse::kReadWrite, OperandType::kReg, \
124 OperandType::kIdx) \
125 \
126 /* StoreIC operations */ \
127 V(StoreICSloppy, AccumulatorUse::kRead, OperandType::kReg, \
128 OperandType::kIdx, OperandType::kIdx) \
129 V(StoreICStrict, AccumulatorUse::kRead, OperandType::kReg, \
130 OperandType::kIdx, OperandType::kIdx) \
131 V(KeyedStoreICSloppy, AccumulatorUse::kRead, OperandType::kReg, \
132 OperandType::kReg, OperandType::kIdx) \
133 V(KeyedStoreICStrict, AccumulatorUse::kRead, OperandType::kReg, \
134 OperandType::kReg, OperandType::kIdx) \
135 \
136 /* Binary Operators */ \
137 V(Add, AccumulatorUse::kReadWrite, OperandType::kReg) \
138 V(Sub, AccumulatorUse::kReadWrite, OperandType::kReg) \
139 V(Mul, AccumulatorUse::kReadWrite, OperandType::kReg) \
140 V(Div, AccumulatorUse::kReadWrite, OperandType::kReg) \
141 V(Mod, AccumulatorUse::kReadWrite, OperandType::kReg) \
142 V(BitwiseOr, AccumulatorUse::kReadWrite, OperandType::kReg) \
143 V(BitwiseXor, AccumulatorUse::kReadWrite, OperandType::kReg) \
144 V(BitwiseAnd, AccumulatorUse::kReadWrite, OperandType::kReg) \
145 V(ShiftLeft, AccumulatorUse::kReadWrite, OperandType::kReg) \
146 V(ShiftRight, AccumulatorUse::kReadWrite, OperandType::kReg) \
147 V(ShiftRightLogical, AccumulatorUse::kReadWrite, OperandType::kReg) \
148 \
149 /* Unary Operators */ \
150 V(Inc, AccumulatorUse::kReadWrite) \
151 V(Dec, AccumulatorUse::kReadWrite) \
152 V(LogicalNot, AccumulatorUse::kReadWrite) \
153 V(TypeOf, AccumulatorUse::kReadWrite) \
154 V(DeletePropertyStrict, AccumulatorUse::kReadWrite, OperandType::kReg) \
155 V(DeletePropertySloppy, AccumulatorUse::kReadWrite, OperandType::kReg) \
156 \
157 /* Call operations */ \
158 V(Call, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg, \
159 OperandType::kRegCount, OperandType::kIdx) \
160 V(TailCall, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg, \
161 OperandType::kRegCount, OperandType::kIdx) \
162 V(CallRuntime, AccumulatorUse::kWrite, OperandType::kRuntimeId, \
163 OperandType::kMaybeReg, OperandType::kRegCount) \
164 V(CallRuntimeForPair, AccumulatorUse::kNone, OperandType::kRuntimeId, \
165 OperandType::kMaybeReg, OperandType::kRegCount, OperandType::kRegOutPair) \
166 V(CallJSRuntime, AccumulatorUse::kWrite, OperandType::kIdx, \
167 OperandType::kReg, OperandType::kRegCount) \
168 \
169 /* Intrinsics */ \
170 V(InvokeIntrinsic, AccumulatorUse::kWrite, OperandType::kRuntimeId, \
171 OperandType::kMaybeReg, OperandType::kRegCount) \
172 \
173 /* New operator */ \
174 V(New, AccumulatorUse::kReadWrite, OperandType::kReg, \
175 OperandType::kMaybeReg, OperandType::kRegCount) \
176 \
177 /* Test Operators */ \
178 V(TestEqual, AccumulatorUse::kReadWrite, OperandType::kReg) \
179 V(TestNotEqual, AccumulatorUse::kReadWrite, OperandType::kReg) \
180 V(TestEqualStrict, AccumulatorUse::kReadWrite, OperandType::kReg) \
181 V(TestLessThan, AccumulatorUse::kReadWrite, OperandType::kReg) \
182 V(TestGreaterThan, AccumulatorUse::kReadWrite, OperandType::kReg) \
183 V(TestLessThanOrEqual, AccumulatorUse::kReadWrite, OperandType::kReg) \
184 V(TestGreaterThanOrEqual, AccumulatorUse::kReadWrite, OperandType::kReg) \
185 V(TestInstanceOf, AccumulatorUse::kReadWrite, OperandType::kReg) \
186 V(TestIn, AccumulatorUse::kReadWrite, OperandType::kReg) \
187 \
188 /* Cast operators */ \
189 V(ToName, AccumulatorUse::kReadWrite) \
190 V(ToNumber, AccumulatorUse::kReadWrite) \
191 V(ToObject, AccumulatorUse::kReadWrite) \
192 \
193 /* Literals */ \
194 V(CreateRegExpLiteral, AccumulatorUse::kWrite, OperandType::kIdx, \
195 OperandType::kIdx, OperandType::kFlag8) \
196 V(CreateArrayLiteral, AccumulatorUse::kWrite, OperandType::kIdx, \
197 OperandType::kIdx, OperandType::kFlag8) \
198 V(CreateObjectLiteral, AccumulatorUse::kWrite, OperandType::kIdx, \
199 OperandType::kIdx, OperandType::kFlag8) \
200 \
201 /* Closure allocation */ \
202 V(CreateClosure, AccumulatorUse::kWrite, OperandType::kIdx, \
203 OperandType::kFlag8) \
204 \
205 /* Arguments allocation */ \
206 V(CreateMappedArguments, AccumulatorUse::kWrite) \
207 V(CreateUnmappedArguments, AccumulatorUse::kWrite) \
208 V(CreateRestParameter, AccumulatorUse::kWrite) \
209 \
210 /* Control Flow */ \
211 V(Jump, AccumulatorUse::kNone, OperandType::kImm) \
212 V(JumpConstant, AccumulatorUse::kNone, OperandType::kIdx) \
213 V(JumpIfTrue, AccumulatorUse::kRead, OperandType::kImm) \
214 V(JumpIfTrueConstant, AccumulatorUse::kRead, OperandType::kIdx) \
215 V(JumpIfFalse, AccumulatorUse::kRead, OperandType::kImm) \
216 V(JumpIfFalseConstant, AccumulatorUse::kRead, OperandType::kIdx) \
217 V(JumpIfToBooleanTrue, AccumulatorUse::kRead, OperandType::kImm) \
218 V(JumpIfToBooleanTrueConstant, AccumulatorUse::kRead, OperandType::kIdx) \
219 V(JumpIfToBooleanFalse, AccumulatorUse::kRead, OperandType::kImm) \
220 V(JumpIfToBooleanFalseConstant, AccumulatorUse::kRead, OperandType::kIdx) \
221 V(JumpIfNull, AccumulatorUse::kRead, OperandType::kImm) \
222 V(JumpIfNullConstant, AccumulatorUse::kRead, OperandType::kIdx) \
223 V(JumpIfUndefined, AccumulatorUse::kRead, OperandType::kImm) \
224 V(JumpIfUndefinedConstant, AccumulatorUse::kRead, OperandType::kIdx) \
225 V(JumpIfNotHole, AccumulatorUse::kRead, OperandType::kImm) \
226 V(JumpIfNotHoleConstant, AccumulatorUse::kRead, OperandType::kIdx) \
227 \
228 /* Complex flow control For..in */ \
229 V(ForInPrepare, AccumulatorUse::kRead, OperandType::kRegOutTriple) \
230 V(ForInDone, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg) \
231 V(ForInNext, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg, \
232 OperandType::kRegPair, OperandType::kIdx) \
233 V(ForInStep, AccumulatorUse::kWrite, OperandType::kReg) \
234 \
235 /* Perform a stack guard check */ \
236 V(StackCheck, AccumulatorUse::kNone) \
237 \
238 /* Non-local flow control */ \
239 V(Throw, AccumulatorUse::kRead) \
240 V(ReThrow, AccumulatorUse::kRead) \
241 V(Return, AccumulatorUse::kNone) \
242 \
243 /* Debugger */ \
244 V(Debugger, AccumulatorUse::kNone) \
245 DEBUG_BREAK_BYTECODE_LIST(V) \
246 \
247 /* Illegal bytecode (terminates execution) */ \
248 V(Illegal, AccumulatorUse::kNone)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000249
Ben Murdochda12d292016-06-02 14:46:10 +0100250enum class AccumulatorUse : uint8_t {
251 kNone = 0,
252 kRead = 1 << 0,
253 kWrite = 1 << 1,
254 kReadWrite = kRead | kWrite
255};
256
257V8_INLINE AccumulatorUse operator&(AccumulatorUse lhs, AccumulatorUse rhs) {
258 int result = static_cast<int>(lhs) & static_cast<int>(rhs);
259 return static_cast<AccumulatorUse>(result);
260}
261
262V8_INLINE AccumulatorUse operator|(AccumulatorUse lhs, AccumulatorUse rhs) {
263 int result = static_cast<int>(lhs) | static_cast<int>(rhs);
264 return static_cast<AccumulatorUse>(result);
265}
266
267// Enumeration of scaling factors applicable to scalable operands. Code
268// relies on being able to cast values to integer scaling values.
269enum class OperandScale : uint8_t {
270 kSingle = 1,
271 kDouble = 2,
272 kQuadruple = 4,
273 kMaxValid = kQuadruple,
274 kInvalid = 8,
275};
276
277// Enumeration of the size classes of operand types used by
278// bytecodes. Code relies on being able to cast values to integer
279// types to get the size in bytes.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000280enum class OperandSize : uint8_t {
281 kNone = 0,
282 kByte = 1,
283 kShort = 2,
Ben Murdochda12d292016-06-02 14:46:10 +0100284 kQuad = 4,
285 kLast = kQuad
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000286};
287
Ben Murdochda12d292016-06-02 14:46:10 +0100288// Primitive operand info used that summarize properties of operands.
289// Columns are Name, IsScalable, IsUnsigned, UnscaledSize.
290#define OPERAND_TYPE_INFO_LIST(V) \
291 V(None, false, false, OperandSize::kNone) \
292 V(ScalableSignedByte, true, false, OperandSize::kByte) \
293 V(ScalableUnsignedByte, true, true, OperandSize::kByte) \
294 V(FixedUnsignedByte, false, true, OperandSize::kByte) \
295 V(FixedUnsignedShort, false, true, OperandSize::kShort)
296
297enum class OperandTypeInfo : uint8_t {
298#define DECLARE_OPERAND_TYPE_INFO(Name, ...) k##Name,
299 OPERAND_TYPE_INFO_LIST(DECLARE_OPERAND_TYPE_INFO)
300#undef DECLARE_OPERAND_TYPE_INFO
301};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000302
303// Enumeration of operand types used by bytecodes.
304enum class OperandType : uint8_t {
305#define DECLARE_OPERAND_TYPE(Name, _) k##Name,
306 OPERAND_TYPE_LIST(DECLARE_OPERAND_TYPE)
307#undef DECLARE_OPERAND_TYPE
308#define COUNT_OPERAND_TYPES(x, _) +1
309 // The COUNT_OPERAND macro will turn this into kLast = -1 +1 +1... which will
310 // evaluate to the same value as the last operand.
311 kLast = -1 OPERAND_TYPE_LIST(COUNT_OPERAND_TYPES)
312#undef COUNT_OPERAND_TYPES
313};
314
315
316// Enumeration of interpreter bytecodes.
317enum class Bytecode : uint8_t {
318#define DECLARE_BYTECODE(Name, ...) k##Name,
319 BYTECODE_LIST(DECLARE_BYTECODE)
320#undef DECLARE_BYTECODE
321#define COUNT_BYTECODE(x, ...) +1
322 // The COUNT_BYTECODE macro will turn this into kLast = -1 +1 +1... which will
323 // evaluate to the same value as the last real bytecode.
324 kLast = -1 BYTECODE_LIST(COUNT_BYTECODE)
325#undef COUNT_BYTECODE
326};
327
328
329// An interpreter Register which is located in the function's Register file
330// in its stack-frame. Register hold parameters, this, and expression values.
331class Register {
332 public:
Ben Murdoch097c5b22016-05-18 11:27:45 +0100333 explicit Register(int index = kInvalidIndex) : index_(index) {}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000334
Ben Murdoch097c5b22016-05-18 11:27:45 +0100335 int index() const { return index_; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000336 bool is_parameter() const { return index() < 0; }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100337 bool is_valid() const { return index_ != kInvalidIndex; }
338 bool is_byte_operand() const;
339 bool is_short_operand() const;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000340
341 static Register FromParameterIndex(int index, int parameter_count);
342 int ToParameterIndex(int parameter_count) const;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100343
344 // Returns an invalid register.
345 static Register invalid_value() { return Register(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000346
347 // Returns the register for the function's closure object.
348 static Register function_closure();
349 bool is_function_closure() const;
350
Ben Murdoch097c5b22016-05-18 11:27:45 +0100351 // Returns the register which holds the current context object.
352 static Register current_context();
353 bool is_current_context() const;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000354
355 // Returns the register for the incoming new target value.
356 static Register new_target();
357 bool is_new_target() const;
358
Ben Murdochda12d292016-06-02 14:46:10 +0100359 int32_t ToOperand() const { return -index_; }
360 static Register FromOperand(int32_t operand) { return Register(-operand); }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100361
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000362 static bool AreContiguous(Register reg1, Register reg2,
363 Register reg3 = Register(),
364 Register reg4 = Register(),
365 Register reg5 = Register());
366
Ben Murdoch097c5b22016-05-18 11:27:45 +0100367 std::string ToString(int parameter_count);
368
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000369 bool operator==(const Register& other) const {
370 return index() == other.index();
371 }
372 bool operator!=(const Register& other) const {
373 return index() != other.index();
374 }
375 bool operator<(const Register& other) const {
376 return index() < other.index();
377 }
378 bool operator<=(const Register& other) const {
379 return index() <= other.index();
380 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100381 bool operator>(const Register& other) const {
382 return index() > other.index();
383 }
384 bool operator>=(const Register& other) const {
385 return index() >= other.index();
386 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000387
388 private:
Ben Murdoch097c5b22016-05-18 11:27:45 +0100389 static const int kInvalidIndex = kMaxInt;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000390
391 void* operator new(size_t size);
392 void operator delete(void* p);
393
394 int index_;
395};
396
397
398class Bytecodes {
399 public:
400 // Returns string representation of |bytecode|.
401 static const char* ToString(Bytecode bytecode);
402
Ben Murdochda12d292016-06-02 14:46:10 +0100403 // Returns string representation of |bytecode|.
404 static std::string ToString(Bytecode bytecode, OperandScale operand_scale);
405
406 // Returns string representation of |accumulator_use|.
407 static const char* AccumulatorUseToString(AccumulatorUse accumulator_use);
408
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000409 // Returns string representation of |operand_type|.
410 static const char* OperandTypeToString(OperandType operand_type);
411
Ben Murdochda12d292016-06-02 14:46:10 +0100412 // Returns string representation of |operand_scale|.
413 static const char* OperandScaleToString(OperandScale operand_scale);
414
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000415 // Returns string representation of |operand_size|.
416 static const char* OperandSizeToString(OperandSize operand_size);
417
418 // Returns byte value of bytecode.
419 static uint8_t ToByte(Bytecode bytecode);
420
421 // Returns bytecode for |value|.
422 static Bytecode FromByte(uint8_t value);
423
424 // Returns the number of operands expected by |bytecode|.
425 static int NumberOfOperands(Bytecode bytecode);
426
Ben Murdoch097c5b22016-05-18 11:27:45 +0100427 // Returns the number of register operands expected by |bytecode|.
428 static int NumberOfRegisterOperands(Bytecode bytecode);
429
Ben Murdochda12d292016-06-02 14:46:10 +0100430 // Returns the prefix bytecode representing an operand scale to be
431 // applied to a a bytecode.
432 static Bytecode OperandScaleToPrefixBytecode(OperandScale operand_scale);
433
434 // Returns true if the operand scale requires a prefix bytecode.
435 static bool OperandScaleRequiresPrefixBytecode(OperandScale operand_scale);
436
437 // Returns the scaling applied to scalable operands if bytecode is
438 // is a scaling prefix.
439 static OperandScale PrefixBytecodeToOperandScale(Bytecode bytecode);
440
441 // Returns how accumulator is used by |bytecode|.
442 static AccumulatorUse GetAccumulatorUse(Bytecode bytecode);
443
444 // Returns true if |bytecode| reads the accumulator.
445 static bool ReadsAccumulator(Bytecode bytecode);
446
447 // Returns true if |bytecode| writes the accumulator.
448 static bool WritesAccumulator(Bytecode bytecode);
449
Ben Murdoch097c5b22016-05-18 11:27:45 +0100450 // Returns the i-th operand of |bytecode|.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000451 static OperandType GetOperandType(Bytecode bytecode, int i);
452
Ben Murdoch097c5b22016-05-18 11:27:45 +0100453 // Returns the size of the i-th operand of |bytecode|.
Ben Murdochda12d292016-06-02 14:46:10 +0100454 static OperandSize GetOperandSize(Bytecode bytecode, int i,
455 OperandScale operand_scale);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000456
457 // Returns the offset of the i-th operand of |bytecode| relative to the start
458 // of the bytecode.
Ben Murdochda12d292016-06-02 14:46:10 +0100459 static int GetOperandOffset(Bytecode bytecode, int i,
460 OperandScale operand_scale);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000461
Ben Murdoch097c5b22016-05-18 11:27:45 +0100462 // Returns a zero-based bitmap of the register operand positions of
463 // |bytecode|.
464 static int GetRegisterOperandBitmap(Bytecode bytecode);
465
Ben Murdochda12d292016-06-02 14:46:10 +0100466 // Returns a debug break bytecode to replace |bytecode|.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100467 static Bytecode GetDebugBreak(Bytecode bytecode);
468
Ben Murdochda12d292016-06-02 14:46:10 +0100469 // Returns the size of the bytecode including its operands for the
470 // given |operand_scale|.
471 static int Size(Bytecode bytecode, OperandScale operand_scale);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000472
473 // Returns the size of |operand|.
Ben Murdochda12d292016-06-02 14:46:10 +0100474 static OperandSize SizeOfOperand(OperandType operand, OperandScale scale);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000475
Ben Murdoch097c5b22016-05-18 11:27:45 +0100476 // Returns true if the bytecode is a conditional jump taking
Ben Murdochda12d292016-06-02 14:46:10 +0100477 // an immediate byte operand (OperandType::kImm).
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000478 static bool IsConditionalJumpImmediate(Bytecode bytecode);
479
Ben Murdoch097c5b22016-05-18 11:27:45 +0100480 // Returns true if the bytecode is a conditional jump taking
Ben Murdochda12d292016-06-02 14:46:10 +0100481 // a constant pool entry (OperandType::kIdx).
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000482 static bool IsConditionalJumpConstant(Bytecode bytecode);
483
Ben Murdoch097c5b22016-05-18 11:27:45 +0100484 // Returns true if the bytecode is a conditional jump taking
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000485 // any kind of operand.
486 static bool IsConditionalJump(Bytecode bytecode);
487
Ben Murdoch097c5b22016-05-18 11:27:45 +0100488 // Returns true if the bytecode is a jump or a conditional jump taking
Ben Murdochda12d292016-06-02 14:46:10 +0100489 // an immediate byte operand (OperandType::kImm).
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000490 static bool IsJumpImmediate(Bytecode bytecode);
491
Ben Murdoch097c5b22016-05-18 11:27:45 +0100492 // Returns true if the bytecode is a jump or conditional jump taking a
Ben Murdochda12d292016-06-02 14:46:10 +0100493 // constant pool entry (OperandType::kIdx).
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000494 static bool IsJumpConstant(Bytecode bytecode);
495
Ben Murdoch097c5b22016-05-18 11:27:45 +0100496 // Returns true if the bytecode is a jump or conditional jump taking
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000497 // any kind of operand.
498 static bool IsJump(Bytecode bytecode);
499
Ben Murdoch097c5b22016-05-18 11:27:45 +0100500 // Returns true if the bytecode is a conditional jump, a jump, or a return.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000501 static bool IsJumpOrReturn(Bytecode bytecode);
502
Ben Murdoch097c5b22016-05-18 11:27:45 +0100503 // Returns true if the bytecode is a call or a constructor call.
504 static bool IsCallOrNew(Bytecode bytecode);
505
Ben Murdochda12d292016-06-02 14:46:10 +0100506 // Returns true if the bytecode is a call to the runtime.
507 static bool IsCallRuntime(Bytecode bytecode);
508
Ben Murdoch097c5b22016-05-18 11:27:45 +0100509 // Returns true if the bytecode is a debug break.
510 static bool IsDebugBreak(Bytecode bytecode);
511
Ben Murdochda12d292016-06-02 14:46:10 +0100512 // Returns true if the bytecode has wider operand forms.
513 static bool IsBytecodeWithScalableOperands(Bytecode bytecode);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100514
Ben Murdochda12d292016-06-02 14:46:10 +0100515 // Returns true if the bytecode is a scaling prefix bytecode.
516 static bool IsPrefixScalingBytecode(Bytecode bytecode);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100517
518 // Returns true if |operand_type| is any type of register operand.
519 static bool IsRegisterOperandType(OperandType operand_type);
520
521 // Returns true if |operand_type| represents a register used as an input.
522 static bool IsRegisterInputOperandType(OperandType operand_type);
523
524 // Returns true if |operand_type| represents a register used as an output.
525 static bool IsRegisterOutputOperandType(OperandType operand_type);
526
527 // Returns true if |operand_type| is a maybe register operand
Ben Murdochda12d292016-06-02 14:46:10 +0100528 // (kMaybeReg).
Ben Murdoch097c5b22016-05-18 11:27:45 +0100529 static bool IsMaybeRegisterOperandType(OperandType operand_type);
530
Ben Murdochda12d292016-06-02 14:46:10 +0100531 // Returns true if |operand_type| is a runtime-id operand (kRuntimeId).
532 static bool IsRuntimeIdOperandType(OperandType operand_type);
533
534 // Returns true if |operand_type| is unsigned, false if signed.
535 static bool IsUnsignedOperandType(OperandType operand_type);
536
537 // Decodes a register operand in a byte array.
538 static Register DecodeRegisterOperand(const uint8_t* operand_start,
539 OperandType operand_type,
540 OperandScale operand_scale);
541
542 // Decodes a signed operand in a byte array.
543 static int32_t DecodeSignedOperand(const uint8_t* operand_start,
544 OperandType operand_type,
545 OperandScale operand_scale);
546
547 // Decodes an unsigned operand in a byte array.
548 static uint32_t DecodeUnsignedOperand(const uint8_t* operand_start,
549 OperandType operand_type,
550 OperandScale operand_scale);
551
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000552 // Decode a single bytecode and operands to |os|.
553 static std::ostream& Decode(std::ostream& os, const uint8_t* bytecode_start,
554 int number_of_parameters);
555
Ben Murdochda12d292016-06-02 14:46:10 +0100556 // Returns true if a handler is generated for a bytecode at a given
557 // operand scale. All bytecodes have handlers at OperandScale::kSingle,
558 // but only bytecodes with scalable operands have handlers with larger
559 // OperandScale values.
560 static bool BytecodeHasHandler(Bytecode bytecode, OperandScale operand_scale);
561
562 // Return the next larger operand scale.
563 static OperandScale NextOperandScale(OperandScale operand_scale);
564
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000565 private:
566 DISALLOW_IMPLICIT_CONSTRUCTORS(Bytecodes);
567};
568
569std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode);
Ben Murdochda12d292016-06-02 14:46:10 +0100570std::ostream& operator<<(std::ostream& os, const AccumulatorUse& use);
571std::ostream& operator<<(std::ostream& os, const OperandScale& operand_scale);
572std::ostream& operator<<(std::ostream& os, const OperandSize& operand_size);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000573std::ostream& operator<<(std::ostream& os, const OperandType& operand_type);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000574
575} // namespace interpreter
576} // namespace internal
577} // namespace v8
578
579#endif // V8_INTERPRETER_BYTECODES_H_