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

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

Issue 1613163002: [interpreter] Wide register support. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Unbreak tests. Created 4 years, 11 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
(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), emitting_moves_(false), window_registers_count_(0) {}
15
16
17 void RegisterTranslator::TranslateInputRegisters(Bytecode bytecode,
18 uint32_t* raw_operands,
19 int raw_operand_count) {
20 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), raw_operand_count);
21 if (!emitting_moves_) {
22 emitting_moves_ = true;
23 DCHECK_EQ(window_registers_count_, 0);
24 int register_bitmap = Bytecodes::GetRegisterOperandBitmap(bytecode);
25 for (int i = 0; i < raw_operand_count; i++) {
26 if ((register_bitmap & (1 << i)) == 0) {
27 continue;
28 }
29 Register in_reg = Register::FromRawOperand(raw_operands[i]);
30 Register out_reg = TranslateAndMove(bytecode, i, in_reg);
31 raw_operands[i] = out_reg.ToRawOperand();
32 }
33 emitting_moves_ = false;
34 } else {
35 // When the register translator is translating registers, it will
36 // cause the bytecode generator to emit moves on it's behalf. This
37 // path is reached by these moves.
38 DCHECK(bytecode == Bytecode::kMovWide && raw_operand_count == 2 &&
39 Register::FromRawOperand(raw_operands[0]).is_valid() &&
40 Register::FromRawOperand(raw_operands[1]).is_valid());
41 }
42 }
43
44
45 Register RegisterTranslator::TranslateAndMove(Bytecode bytecode,
46 int operand_index, Register reg) {
47 OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index);
48 Register translated_reg = Translate(reg);
49 Register addressable_reg = MakeAddressable(translated_reg, operand_type);
50 if (addressable_reg != translated_reg) {
51 CHECK(operand_type == OperandType::kReg8 &&
52 mover()->RegisterOperandIsMovable(bytecode, operand_index));
53 mover()->MoveRegisterUntranslated(translated_reg, addressable_reg);
54 }
55 return addressable_reg;
56 }
57
58
59 void RegisterTranslator::TranslateOutputRegisters() {
60 if (!emitting_moves_) {
61 emitting_moves_ = true;
62 while (window_registers_count_ > 0) {
63 window_registers_count_ -= 1;
64 Register source(kTranslationWindowStart + window_registers_count_);
65 Register destination = window_registers_[window_registers_count_];
66 mover()->MoveRegisterUntranslated(source, destination);
67 }
68 emitting_moves_ = false;
69 }
70 }
71
72
73 Register RegisterTranslator::MakeAddressable(Register reg,
74 OperandType reg_type) {
75 DCHECK(!InTranslationWindow(reg));
76 OperandSize reg_size = Bytecodes::SizeOfOperand(reg_type);
77 if (reg_size == OperandSize::kByte && !FitsInReg8Operand(reg)) {
78 // TODO(oth): Moves into and out from translation window could be
79 // decoupled if there were metadata to say whether the register
80 // operand was an input, output, or input-and-output for a given
81 // bytecode.
82 Register destination(kTranslationWindowStart + window_registers_count_);
83 window_registers_[window_registers_count_] = reg;
84 window_registers_count_ += 1;
85 DCHECK_LE(window_registers_count_, kTranslationWindowLength);
86 return destination;
87 } else {
88 return reg;
89 }
90 }
91
92
93 // static
94 Register RegisterTranslator::Translate(Register reg) {
95 if (reg.index() >= kTranslationWindowStart) {
96 return Register(reg.index() + kTranslationWindowLength);
97 } else {
98 return reg;
99 }
100 }
101
102
103 // static
104 bool RegisterTranslator::InTranslationWindow(Register reg) {
105 return (reg.index() >= kTranslationWindowStart &&
106 reg.index() <= kTranslationWindowLimit);
107 }
108
109
110 // static
111 Register RegisterTranslator::UntranslateRegister(Register reg) {
112 if (reg.index() >= kTranslationWindowStart) {
113 return Register(reg.index() - kTranslationWindowLength);
114 } else {
115 return reg;
116 }
117 }
118
119
120 // static
121 int RegisterTranslator::DistanceToTranslationWindow(Register reg) {
122 return kTranslationWindowStart - reg.index();
123 }
124
125
126 // static
127 bool RegisterTranslator::FitsInReg8Operand(Register reg) {
128 return reg.is_byte_operand() && reg.index() < kTranslationWindowStart;
129 }
130
131
132 // static
133 bool RegisterTranslator::FitsInReg16Operand(Register reg) {
134 int max_index = Register::MaxRegisterIndex() - kTranslationWindowLength + 1;
135 return reg.is_short_operand() && reg.index() < max_index;
136 }
137
138
139 // static
140 int RegisterTranslator::RegisterCountAdjustment(int register_count,
141 int parameter_count) {
142 if (register_count > kTranslationWindowStart) {
143 return kTranslationWindowLength;
144 } else if (parameter_count > 0) {
145 Register param0 = Register::FromParameterIndex(0, parameter_count);
146 if (!param0.is_byte_operand()) {
147 // TODO(oth): Number of parameters means translation is
148 // required, but the translation window location is such that
149 // some space is wasted. Hopefully a rare corner case, but could
150 // relocate window to limit waste.
151 return kTranslationWindowLimit + 1 - register_count;
152 }
153 }
154 return 0;
155 }
156
157 } // namespace interpreter
158 } // namespace internal
159 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698