Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Side by Side Diff: src/interpreter/bytecodes.cc

Issue 1257543003: [Interpreter] Add more bytecode definitions and add operand types. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #define OPERANDS(x) OperandInfo##x
rmcilroy 2015/07/24 18:34:48 Is this required?
6
5 #include "src/interpreter/bytecodes.h" 7 #include "src/interpreter/bytecodes.h"
6 8
7 namespace v8 { 9 namespace v8 {
8 namespace internal { 10 namespace internal {
9 namespace interpreter { 11 namespace interpreter {
10 12
13 static const int kMaxOperands = 3;
14
15 template <enum Operand O>
16 struct OperandInfo {
17 static const int is_explicit;
rmcilroy 2015/07/24 18:34:48 instead of having is_explicit, could we just speci
18 static const int size;
19 };
20
21 #define OPERAND_INFO(op, sz) \
22 template <> \
23 struct OperandInfo<Operand::k##op> { \
24 static const int is_explicit = (sz == 0) ? 0 : 1; \
25 static const int size = sz; \
26 }
27
28 OPERAND_INFO(None, 0);
29 OPERAND_INFO(Imm0, 0);
rmcilroy 2015/07/24 18:34:48 What is Imm0? Seems unrequired.
30 OPERAND_INFO(Imm8, 1);
31 OPERAND_INFO(Smi, 4);
rmcilroy 2015/07/24 18:34:47 As mentioned offline, this can't be a 4 byte opera
32 OPERAND_INFO(Reg, 1);
33
34
35 template <enum Bytecode B>
36 struct BytecodeInfo {
37 // Size of byte code and operands
38 static const int size;
39 // Number of operands
40 static const int number_of_operands;
41 // Packed operand values
42 static const int operands;
43 };
44
45
46 // Packing operands into a single integer (makes indexing easier)
47 static const int kOperandShift = 4;
48 STATIC_ASSERT(static_cast<int>(Operand::kLast) < ((1 << kOperandShift) - 1));
49 #define PACK_OPERAND(op, i) (static_cast<int>(op) << (i * kOperandShift))
50 #define PACK_OPERANDS(op0, op1, op2) \
51 PACK_OPERAND(op0, 0) | PACK_OPERAND(op1, 1) | PACK_OPERAND(op2, 2)
rmcilroy 2015/07/24 18:34:48 I personally don't think it's worth packing operan
52 #define UNPACK_OPERAND(op, pos) (Operand)(op >> (pos * kOperandShift))
53
54 // Generator of BytecodeInfos for each bytecode.
55 #define BYTECODE_INFO(code, op0, op1, op2) \
rmcilroy 2015/07/24 18:34:48 As much as I like pre-processor magic </sarcasm> -
56 template <> \
57 struct BytecodeInfo<Bytecode::code> { \
58 static const int size = 1 + OperandInfo<op0>::size + \
59 OperandInfo<op1>::size + OperandInfo<op2>::size; \
60 static const int number_of_operands = OperandInfo<op0>::is_explicit + \
61 OperandInfo<op1>::is_explicit + \
62 OperandInfo<op2>::is_explicit; \
63 static const int operands = PACK_OPERANDS(op0, op1, op2); \
64 }
65
66 // Bytecode declarations
67 BYTECODE_INFO(kLoadSmi0, Operand::kReg, Operand::kNone, Operand::kNone);
68 BYTECODE_INFO(kLoadSmi8, Operand::kReg, Operand::kImm8, Operand::kNone);
69 BYTECODE_INFO(kLoadSmi, Operand::kReg, Operand::kSmi, Operand::kNone);
70 BYTECODE_INFO(kMove, Operand::kReg, Operand::kReg, Operand::kNone);
71 BYTECODE_INFO(kAdd, Operand::kReg, Operand::kReg, Operand::kReg);
72 BYTECODE_INFO(kSub, Operand::kReg, Operand::kReg, Operand::kReg);
73 BYTECODE_INFO(kMul, Operand::kReg, Operand::kReg, Operand::kReg);
74 BYTECODE_INFO(kDiv, Operand::kReg, Operand::kReg, Operand::kReg);
75 BYTECODE_INFO(kMod, Operand::kReg, Operand::kReg, Operand::kReg);
76 BYTECODE_INFO(kReturn, Operand::kNone, Operand::kNone, Operand::kNone);
rmcilroy 2015/07/24 18:34:48 I would really like this list of declarations to b
77
78
11 // static 79 // static
12 const char* Bytecodes::ToString(Bytecode bytecode) { 80 const char* Bytecodes::ToString(Bytecode bytecode) {
13 switch (bytecode) { 81 switch (bytecode) {
14 #define CASE(Name, _) \ 82 #define CASE(Name) \
15 case Bytecode::k##Name: \ 83 case Bytecode::k##Name: \
16 return #Name; 84 return #Name;
17 BYTECODE_LIST(CASE) 85 BYTECODE_LIST(CASE)
18 #undef CASE 86 #undef CASE
19 } 87 }
20 UNREACHABLE(); 88 UNREACHABLE();
21 return ""; 89 return "";
22 } 90 }
23 91
24 92
25 // static 93 // static
26 const int Bytecodes::NumberOfArguments(Bytecode bytecode) { 94 Bytecode Bytecodes::FromByte(uint8_t value) {
95 Bytecode code = static_cast<Bytecode>(value);
96 CHECK(code <= Bytecode::kLast);
97 return code;
98 }
99
100
101 // static
102 const int Bytecodes::NumberOfOperands(Bytecode bytecode) {
27 switch (bytecode) { 103 switch (bytecode) {
28 #define CASE(Name, arg_count) \ 104 #define CASE(Name) \
29 case Bytecode::k##Name: \ 105 case Bytecode::k##Name: \
30 return arg_count; 106 return BytecodeInfo<Bytecode::k##Name>::number_of_operands;
31 BYTECODE_LIST(CASE) 107 BYTECODE_LIST(CASE)
32 #undef CASE 108 #undef CASE
33 } 109 }
34 UNREACHABLE(); 110 UNREACHABLE();
35 return 0; 111 return 0;
36 } 112 }
37 113
38 114
39 // static 115 // static
116 const Operand Bytecodes::GetOperand(Bytecode bytecode, int i) {
117 CHECK(i < kMaxOperands);
118
119 int packed = 0;
120 switch (bytecode) {
121 #define CASE(Name) \
122 case Bytecode::k##Name: \
123 packed = BytecodeInfo<Bytecode::k##Name>::operands;
124 BYTECODE_LIST(CASE)
125 #undef CASE
126 }
127 return UNPACK_OPERAND(packed, i);
128 }
129
130
131 // static
132 const int Bytecodes::GetOperandSize(Operand operand) {
133 switch (operand) {
134 #define CASE(Name) \
135 case Operand::k##Name: \
136 return OperandInfo<Operand::k##Name>::size;
137 OPERAND_LIST(CASE)
138 #undef CASE
139 }
140 UNREACHABLE();
141 return 0;
142 }
143
144
145 // static
40 const int Bytecodes::Size(Bytecode bytecode) { 146 const int Bytecodes::Size(Bytecode bytecode) {
41 return NumberOfArguments(bytecode) + 1; 147 switch (bytecode) {
148 #define CASE(Name) \
149 case Bytecode::k##Name: \
150 return BytecodeInfo<Bytecode::k##Name>::size;
151 BYTECODE_LIST(CASE)
152 #undef CASE
153 }
154 UNREACHABLE();
155 return 0;
42 } 156 }
43 157
44 158
45 #define CHECK_SIZE(Name, arg_count) \ 159 // static
46 STATIC_ASSERT(arg_count <= Bytecodes::kMaximumNumberOfArguments); 160 const int Bytecodes::MaximumNumberOfOperands() {
47 BYTECODE_LIST(CHECK_SIZE) 161 // TODO(oth): STATIC_ASSERT on number of operands.
48 #undef CHECK_SIZE 162 return kMaxOperands;
163 }
164
165
166 // static
167 const int Bytecodes::MaximumSize() {
168 // TODO(oth): Maximum size of bytecode and associated operands
169 STATIC_ASSERT(BytecodeInfo<Bytecode::kLoadSmi>::size == 6);
170 return 6;
171 }
49 172
50 173
51 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode) { 174 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode) {
52 return os << Bytecodes::ToString(bytecode); 175 return os << Bytecodes::ToString(bytecode);
53 } 176 }
54 177
55 } // namespace interpreter 178 } // namespace interpreter
56 } // namespace internal 179 } // namespace internal
57 } // namespace v8 180 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698