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

Side by Side Diff: src/compiler/x64/instruction-selector-x64.cc

Issue 763963002: [turbofan] Add checked load/store operators. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Reapply fix. Created 6 years 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/compiler/x64/code-generator-x64.cc ('k') | src/ia32/assembler-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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 #include "src/compiler/instruction-selector-impl.h" 5 #include "src/compiler/instruction-selector-impl.h"
6 #include "src/compiler/node-matchers.h" 6 #include "src/compiler/node-matchers.h"
7 7
8 namespace v8 { 8 namespace v8 {
9 namespace internal { 9 namespace internal {
10 namespace compiler { 10 namespace compiler {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 opcode = kX64Movl; 65 opcode = kX64Movl;
66 break; 66 break;
67 case kRepTagged: // Fall through. 67 case kRepTagged: // Fall through.
68 case kRepWord64: 68 case kRepWord64:
69 opcode = kX64Movq; 69 opcode = kX64Movq;
70 break; 70 break;
71 default: 71 default:
72 UNREACHABLE(); 72 UNREACHABLE();
73 return; 73 return;
74 } 74 }
75 if (g.CanBeImmediate(base)) { 75 if (g.CanBeImmediate(index)) {
76 // load [%base + #index]
77 Emit(opcode | AddressingModeField::encode(kMode_MRI),
78 g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index));
79 } else if (g.CanBeImmediate(base)) {
76 // load [#base + %index] 80 // load [#base + %index]
77 Emit(opcode | AddressingModeField::encode(kMode_MRI), 81 Emit(opcode | AddressingModeField::encode(kMode_MRI),
78 g.DefineAsRegister(node), g.UseRegister(index), g.UseImmediate(base)); 82 g.DefineAsRegister(node), g.UseRegister(index), g.UseImmediate(base));
79 } else if (g.CanBeImmediate(index)) {
80 // load [%base + #index]
81 Emit(opcode | AddressingModeField::encode(kMode_MRI),
82 g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index));
83 } else { 83 } else {
84 // load [%base + %index*1] 84 // load [%base + %index*1]
85 Emit(opcode | AddressingModeField::encode(kMode_MR1), 85 Emit(opcode | AddressingModeField::encode(kMode_MR1),
86 g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(index)); 86 g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(index));
87 } 87 }
88 } 88 }
89 89
90 90
91 void InstructionSelector::VisitStore(Node* node) { 91 void InstructionSelector::VisitStore(Node* node) {
92 X64OperandGenerator g(this); 92 X64OperandGenerator g(this);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 case kRepTagged: // Fall through. 129 case kRepTagged: // Fall through.
130 case kRepWord64: 130 case kRepWord64:
131 opcode = kX64Movq; 131 opcode = kX64Movq;
132 break; 132 break;
133 default: 133 default:
134 UNREACHABLE(); 134 UNREACHABLE();
135 return; 135 return;
136 } 136 }
137 InstructionOperand* value_operand = 137 InstructionOperand* value_operand =
138 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); 138 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value);
139 if (g.CanBeImmediate(base)) { 139 if (g.CanBeImmediate(index)) {
140 // store [%base + #index], %|#value
141 Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr,
142 g.UseRegister(base), g.UseImmediate(index), value_operand);
143 } else if (g.CanBeImmediate(base)) {
140 // store [#base + %index], %|#value 144 // store [#base + %index], %|#value
141 Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr, 145 Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr,
142 g.UseRegister(index), g.UseImmediate(base), value_operand); 146 g.UseRegister(index), g.UseImmediate(base), value_operand);
143 } else if (g.CanBeImmediate(index)) {
144 // store [%base + #index], %|#value
145 Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr,
146 g.UseRegister(base), g.UseImmediate(index), value_operand);
147 } else { 147 } else {
148 // store [%base + %index*1], %|#value 148 // store [%base + %index*1], %|#value
149 Emit(opcode | AddressingModeField::encode(kMode_MR1), nullptr, 149 Emit(opcode | AddressingModeField::encode(kMode_MR1), nullptr,
150 g.UseRegister(base), g.UseRegister(index), value_operand); 150 g.UseRegister(base), g.UseRegister(index), value_operand);
151 } 151 }
152 } 152 }
153 153
154 154
155 void InstructionSelector::VisitCheckedLoad(Node* node) {
156 MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
157 MachineType typ = TypeOf(OpParameter<MachineType>(node));
158 X64OperandGenerator g(this);
159 Node* const buffer = node->InputAt(0);
160 Node* const offset = node->InputAt(1);
161 Node* const length = node->InputAt(2);
162 ArchOpcode opcode;
163 switch (rep) {
164 case kRepWord8:
165 opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8;
166 break;
167 case kRepWord16:
168 opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16;
169 break;
170 case kRepWord32:
171 opcode = kCheckedLoadWord32;
172 break;
173 case kRepFloat32:
174 opcode = kCheckedLoadFloat32;
175 break;
176 case kRepFloat64:
177 opcode = kCheckedLoadFloat64;
178 break;
179 default:
180 UNREACHABLE();
181 return;
182 }
183 if (offset->opcode() == IrOpcode::kInt32Add && CanCover(node, offset)) {
184 Int32Matcher mlength(length);
185 Int32BinopMatcher moffset(offset);
186 if (mlength.HasValue() && moffset.right().HasValue() &&
187 mlength.Value() > moffset.right().Value()) {
188 InstructionOperand* offset_operand = g.UseRegister(moffset.left().node());
189 InstructionOperand* length_operand =
190 g.TempImmediate(mlength.Value() - moffset.right().Value());
191 Emit(opcode | AddressingModeField::encode(kMode_MR1I),
192 g.DefineAsRegister(node), offset_operand, length_operand,
193 g.UseRegister(buffer), offset_operand,
194 g.UseImmediate(moffset.right().node()));
195 return;
196 }
197 }
198 InstructionOperand* offset_operand = g.UseRegister(offset);
199 InstructionOperand* length_operand =
200 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length);
201 Emit(opcode | AddressingModeField::encode(kMode_MR1),
202 g.DefineAsRegister(node), offset_operand, length_operand,
203 g.UseRegister(buffer), offset_operand);
204 }
205
206
207 void InstructionSelector::VisitCheckedStore(Node* node) {
208 MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
209 X64OperandGenerator g(this);
210 Node* const buffer = node->InputAt(0);
211 Node* const offset = node->InputAt(1);
212 Node* const length = node->InputAt(2);
213 Node* const value = node->InputAt(3);
214 ArchOpcode opcode;
215 switch (rep) {
216 case kRepWord8:
217 opcode = kCheckedStoreWord8;
218 break;
219 case kRepWord16:
220 opcode = kCheckedStoreWord16;
221 break;
222 case kRepWord32:
223 opcode = kCheckedStoreWord32;
224 break;
225 case kRepFloat32:
226 opcode = kCheckedStoreFloat32;
227 break;
228 case kRepFloat64:
229 opcode = kCheckedStoreFloat64;
230 break;
231 default:
232 UNREACHABLE();
233 return;
234 }
235 InstructionOperand* value_operand =
236 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value);
237 if (offset->opcode() == IrOpcode::kInt32Add && CanCover(node, offset)) {
238 Int32Matcher mlength(length);
239 Int32BinopMatcher moffset(offset);
240 if (mlength.HasValue() && moffset.right().HasValue() &&
241 mlength.Value() > moffset.right().Value()) {
242 InstructionOperand* offset_operand = g.UseRegister(moffset.left().node());
243 InstructionOperand* length_operand =
244 g.TempImmediate(mlength.Value() - moffset.right().Value());
245 Emit(opcode | AddressingModeField::encode(kMode_MR1I), nullptr,
246 offset_operand, length_operand, value_operand, g.UseRegister(buffer),
247 offset_operand, g.UseImmediate(moffset.right().node()));
248 return;
249 }
250 }
251 InstructionOperand* offset_operand = g.UseRegister(offset);
252 InstructionOperand* length_operand =
253 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length);
254 Emit(opcode | AddressingModeField::encode(kMode_MR1), nullptr, offset_operand,
255 length_operand, value_operand, g.UseRegister(buffer), offset_operand);
256 }
257
258
155 // Shared routine for multiple binary operations. 259 // Shared routine for multiple binary operations.
156 static void VisitBinop(InstructionSelector* selector, Node* node, 260 static void VisitBinop(InstructionSelector* selector, Node* node,
157 InstructionCode opcode, FlagsContinuation* cont) { 261 InstructionCode opcode, FlagsContinuation* cont) {
158 X64OperandGenerator g(selector); 262 X64OperandGenerator g(selector);
159 Int32BinopMatcher m(node); 263 Int32BinopMatcher m(node);
160 Node* left = m.left().node(); 264 Node* left = m.left().node();
161 Node* right = m.right().node(); 265 Node* right = m.right().node();
162 InstructionOperand* inputs[4]; 266 InstructionOperand* inputs[4];
163 size_t input_count = 0; 267 size_t input_count = 0;
164 InstructionOperand* outputs[2]; 268 InstructionOperand* outputs[2];
(...skipping 1024 matching lines...) Expand 10 before | Expand all | Expand 10 after
1189 MachineOperatorBuilder::kFloat64Ceil | 1293 MachineOperatorBuilder::kFloat64Ceil |
1190 MachineOperatorBuilder::kFloat64RoundTruncate | 1294 MachineOperatorBuilder::kFloat64RoundTruncate |
1191 MachineOperatorBuilder::kWord32ShiftIsSafe; 1295 MachineOperatorBuilder::kWord32ShiftIsSafe;
1192 } 1296 }
1193 return MachineOperatorBuilder::kNoFlags; 1297 return MachineOperatorBuilder::kNoFlags;
1194 } 1298 }
1195 1299
1196 } // namespace compiler 1300 } // namespace compiler
1197 } // namespace internal 1301 } // namespace internal
1198 } // namespace v8 1302 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/x64/code-generator-x64.cc ('k') | src/ia32/assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698