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

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

Powered by Google App Engine
This is Rietveld 408576698