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

Side by Side Diff: src/interpreter/register-translator.cc

Issue 1783483002: [interpreter] Add support for scalable operands. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Re-generate golden files. Created 4 years, 9 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
« no previous file with comments | « src/interpreter/register-translator.h ('k') | src/log.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "src/interpreter/register-translator.h"
6
7 #include "src/interpreter/bytecode-array-builder.h"
8
9 namespace v8 {
10 namespace internal {
11 namespace interpreter {
12
13 RegisterTranslator::RegisterTranslator(RegisterMover* mover)
14 : mover_(mover),
15 emitting_moves_(false),
16 window_registers_count_(0),
17 output_moves_count_(0) {}
18
19 void RegisterTranslator::TranslateInputRegisters(Bytecode bytecode,
20 uint32_t* raw_operands,
21 int raw_operand_count) {
22 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), raw_operand_count);
23 if (!emitting_moves_) {
24 emitting_moves_ = true;
25 DCHECK_EQ(window_registers_count_, 0);
26 int register_bitmap = Bytecodes::GetRegisterOperandBitmap(bytecode);
27 for (int i = 0; i < raw_operand_count; i++) {
28 if ((register_bitmap & (1 << i)) == 0) {
29 continue;
30 }
31 Register in_reg = Register::FromRawOperand(raw_operands[i]);
32 Register out_reg = TranslateAndMove(bytecode, i, in_reg);
33 raw_operands[i] = out_reg.ToRawOperand();
34 }
35 window_registers_count_ = 0;
36 emitting_moves_ = false;
37 } else {
38 // When the register translator is translating registers, it will
39 // cause the bytecode generator to emit moves on it's behalf. This
40 // path is reached by these moves.
41 DCHECK(bytecode == Bytecode::kMovWide && raw_operand_count == 2 &&
42 Register::FromRawOperand(raw_operands[0]).is_valid() &&
43 Register::FromRawOperand(raw_operands[1]).is_valid());
44 }
45 }
46
47 Register RegisterTranslator::TranslateAndMove(Bytecode bytecode,
48 int operand_index, Register reg) {
49 if (FitsInReg8Operand(reg)) {
50 return reg;
51 }
52
53 OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index);
54 OperandSize operand_size = Bytecodes::SizeOfOperand(operand_type);
55 if (operand_size == OperandSize::kShort) {
56 CHECK(FitsInReg16Operand(reg));
57 return Translate(reg);
58 }
59
60 CHECK((operand_type == OperandType::kReg8 ||
61 operand_type == OperandType::kRegOut8) &&
62 RegisterIsMovableToWindow(bytecode, operand_index));
63 Register translated_reg = Translate(reg);
64 Register window_reg(kTranslationWindowStart + window_registers_count_);
65 window_registers_count_ += 1;
66 if (Bytecodes::IsRegisterInputOperandType(operand_type)) {
67 DCHECK(!Bytecodes::IsRegisterOutputOperandType(operand_type));
68 mover()->MoveRegisterUntranslated(translated_reg, window_reg);
69 } else if (Bytecodes::IsRegisterOutputOperandType(operand_type)) {
70 DCHECK_LT(output_moves_count_, kTranslationWindowLength);
71 output_moves_[output_moves_count_] =
72 std::make_pair(window_reg, translated_reg);
73 output_moves_count_ += 1;
74 } else {
75 UNREACHABLE();
76 }
77 return window_reg;
78 }
79
80 // static
81 bool RegisterTranslator::RegisterIsMovableToWindow(Bytecode bytecode,
82 int operand_index) {
83 // By design, we only support moving individual registers. There
84 // should be wide variants of such bytecodes instead to avoid the
85 // need for a large translation window.
86 OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index);
87 if (operand_type != OperandType::kReg8 &&
88 operand_type != OperandType::kRegOut8) {
89 return false;
90 } else if (operand_index + 1 == Bytecodes::NumberOfOperands(bytecode)) {
91 return true;
92 } else {
93 OperandType next_operand_type =
94 Bytecodes::GetOperandType(bytecode, operand_index + 1);
95 return (next_operand_type != OperandType::kRegCount8 &&
96 next_operand_type != OperandType::kRegCount16);
97 }
98 }
99
100 void RegisterTranslator::TranslateOutputRegisters() {
101 if (!emitting_moves_) {
102 emitting_moves_ = true;
103 while (output_moves_count_ > 0) {
104 output_moves_count_ -= 1;
105 mover()->MoveRegisterUntranslated(
106 output_moves_[output_moves_count_].first,
107 output_moves_[output_moves_count_].second);
108 }
109 emitting_moves_ = false;
110 }
111 }
112
113 // static
114 Register RegisterTranslator::Translate(Register reg) {
115 if (reg.index() >= kTranslationWindowStart) {
116 return Register(reg.index() + kTranslationWindowLength);
117 } else {
118 return reg;
119 }
120 }
121
122 // static
123 bool RegisterTranslator::InTranslationWindow(Register reg) {
124 return (reg.index() >= kTranslationWindowStart &&
125 reg.index() <= kTranslationWindowLimit);
126 }
127
128 // static
129 Register RegisterTranslator::UntranslateRegister(Register reg) {
130 if (reg.index() >= kTranslationWindowStart) {
131 return Register(reg.index() - kTranslationWindowLength);
132 } else {
133 return reg;
134 }
135 }
136
137 // static
138 int RegisterTranslator::DistanceToTranslationWindow(Register reg) {
139 return kTranslationWindowStart - reg.index();
140 }
141
142 // static
143 bool RegisterTranslator::FitsInReg8Operand(Register reg) {
144 return reg.is_byte_operand() && reg.index() < kTranslationWindowStart;
145 }
146
147 // static
148 bool RegisterTranslator::FitsInReg16Operand(Register reg) {
149 int max_index = Register::MaxRegisterIndex() - kTranslationWindowLength + 1;
150 return reg.is_short_operand() && reg.index() < max_index;
151 }
152
153 // static
154 int RegisterTranslator::RegisterCountAdjustment(int register_count,
155 int parameter_count) {
156 if (register_count > kTranslationWindowStart) {
157 return kTranslationWindowLength;
158 } else if (parameter_count > 0) {
159 Register param0 = Register::FromParameterIndex(0, parameter_count);
160 if (!param0.is_byte_operand()) {
161 // TODO(oth): Number of parameters means translation is
162 // required, but the translation window location is such that
163 // some space is wasted. Hopefully a rare corner case, but could
164 // relocate window to limit waste.
165 return kTranslationWindowLimit + 1 - register_count;
166 }
167 }
168 return 0;
169 }
170
171 } // namespace interpreter
172 } // namespace internal
173 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/register-translator.h ('k') | src/log.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698