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

Side by Side Diff: src/compiler/x64/code-generator-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/verifier.cc ('k') | src/compiler/x64/instruction-selector-x64.cc » ('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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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/code-generator.h" 5 #include "src/compiler/code-generator.h"
6 6
7 #include "src/compiler/code-generator-impl.h" 7 #include "src/compiler/code-generator-impl.h"
8 #include "src/compiler/gap-resolver.h" 8 #include "src/compiler/gap-resolver.h"
9 #include "src/compiler/node-matchers.h" 9 #include "src/compiler/node-matchers.h"
10 #include "src/compiler/node-properties-inl.h" 10 #include "src/compiler/node-properties-inl.h"
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 return Operand(index, scale, disp); 112 return Operand(index, scale, disp);
113 } 113 }
114 case kMode_None: 114 case kMode_None:
115 UNREACHABLE(); 115 UNREACHABLE();
116 return Operand(no_reg, 0); 116 return Operand(no_reg, 0);
117 } 117 }
118 UNREACHABLE(); 118 UNREACHABLE();
119 return Operand(no_reg, 0); 119 return Operand(no_reg, 0);
120 } 120 }
121 121
122 Operand MemoryOperand() { 122 Operand MemoryOperand(int first_input = 0) {
123 int first_input = 0;
124 return MemoryOperand(&first_input); 123 return MemoryOperand(&first_input);
125 } 124 }
126 }; 125 };
127 126
128 127
129 static bool HasImmediateInput(Instruction* instr, int index) { 128 namespace {
129
130 bool HasImmediateInput(Instruction* instr, int index) {
130 return instr->InputAt(index)->IsImmediate(); 131 return instr->InputAt(index)->IsImmediate();
131 } 132 }
132 133
133 134
135 class OutOfLineLoadInteger FINAL : public OutOfLineCode {
136 public:
137 OutOfLineLoadInteger(CodeGenerator* gen, Register result)
138 : OutOfLineCode(gen), result_(result) {}
139
140 void Generate() FINAL { __ xorl(result_, result_); }
141
142 private:
143 Register const result_;
144 };
145
146
147 class OutOfLineLoadFloat FINAL : public OutOfLineCode {
148 public:
149 OutOfLineLoadFloat(CodeGenerator* gen, XMMRegister result)
150 : OutOfLineCode(gen), result_(result) {}
151
152 void Generate() FINAL { __ pcmpeqd(result_, result_); }
153
154 private:
155 XMMRegister const result_;
156 };
157
158 } // namespace
159
160
134 #define ASSEMBLE_UNOP(asm_instr) \ 161 #define ASSEMBLE_UNOP(asm_instr) \
135 do { \ 162 do { \
136 if (instr->Output()->IsRegister()) { \ 163 if (instr->Output()->IsRegister()) { \
137 __ asm_instr(i.OutputRegister()); \ 164 __ asm_instr(i.OutputRegister()); \
138 } else { \ 165 } else { \
139 __ asm_instr(i.OutputOperand()); \ 166 __ asm_instr(i.OutputOperand()); \
140 } \ 167 } \
141 } while (0) 168 } while (0)
142 169
143 170
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 if (instr->InputAt(1)->IsDoubleRegister()) { \ 240 if (instr->InputAt(1)->IsDoubleRegister()) { \
214 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \ 241 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \
215 i.InputDoubleRegister(1)); \ 242 i.InputDoubleRegister(1)); \
216 } else { \ 243 } else { \
217 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \ 244 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \
218 i.InputOperand(1)); \ 245 i.InputOperand(1)); \
219 } \ 246 } \
220 } while (0) 247 } while (0)
221 248
222 249
250 #define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr) \
251 do { \
252 auto result = i.OutputDoubleRegister(); \
253 auto offset = i.InputRegister(0); \
254 if (instr->InputAt(1)->IsRegister()) { \
255 __ cmpl(offset, i.InputRegister(1)); \
256 } else { \
257 __ cmpl(offset, i.InputImmediate(1)); \
258 } \
259 OutOfLineCode* ool = new (zone()) OutOfLineLoadFloat(this, result); \
260 __ j(above_equal, ool->entry()); \
261 __ asm_instr(result, i.MemoryOperand(2)); \
262 __ bind(ool->exit()); \
263 } while (false)
264
265
266 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \
267 do { \
268 auto result = i.OutputRegister(); \
269 auto offset = i.InputRegister(0); \
270 if (instr->InputAt(1)->IsRegister()) { \
271 __ cmpl(offset, i.InputRegister(1)); \
272 } else { \
273 __ cmpl(offset, i.InputImmediate(1)); \
274 } \
275 OutOfLineCode* ool = new (zone()) OutOfLineLoadInteger(this, result); \
276 __ j(above_equal, ool->entry()); \
277 __ asm_instr(result, i.MemoryOperand(2)); \
278 __ bind(ool->exit()); \
279 } while (false)
280
281
282 #define ASSEMBLE_CHECKED_STORE_FLOAT(asm_instr) \
283 do { \
284 auto offset = i.InputRegister(0); \
285 if (instr->InputAt(1)->IsRegister()) { \
286 __ cmpl(offset, i.InputRegister(1)); \
287 } else { \
288 __ cmpl(offset, i.InputImmediate(1)); \
289 } \
290 Label done; \
291 __ j(above_equal, &done, Label::kNear); \
292 __ asm_instr(i.MemoryOperand(3), i.InputDoubleRegister(2)); \
293 __ bind(&done); \
294 } while (false)
295
296
297 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \
298 do { \
299 auto offset = i.InputRegister(0); \
300 if (instr->InputAt(1)->IsRegister()) { \
301 __ cmpl(offset, i.InputRegister(1)); \
302 } else { \
303 __ cmpl(offset, i.InputImmediate(1)); \
304 } \
305 Label done; \
306 __ j(above_equal, &done, Label::kNear); \
307 if (instr->InputAt(2)->IsRegister()) { \
308 __ asm_instr(i.MemoryOperand(3), i.InputRegister(2)); \
309 } else { \
310 __ asm_instr(i.MemoryOperand(3), i.InputImmediate(2)); \
311 } \
312 __ bind(&done); \
313 } while (false)
314
315
223 // Assembles an instruction after register allocation, producing machine code. 316 // Assembles an instruction after register allocation, producing machine code.
224 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { 317 void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
225 X64OperandConverter i(this, instr); 318 X64OperandConverter i(this, instr);
226 319
227 switch (ArchOpcodeField::decode(instr->opcode())) { 320 switch (ArchOpcodeField::decode(instr->opcode())) {
228 case kArchCallCodeObject: { 321 case kArchCallCodeObject: {
229 EnsureSpaceForLazyDeopt(); 322 EnsureSpaceForLazyDeopt();
230 if (HasImmediateInput(instr, 0)) { 323 if (HasImmediateInput(instr, 0)) {
231 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); 324 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0));
232 __ Call(code, RelocInfo::CODE_TARGET); 325 __ Call(code, RelocInfo::CODE_TARGET);
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 Register index = i.InputRegister(1); 753 Register index = i.InputRegister(1);
661 Register value = i.InputRegister(2); 754 Register value = i.InputRegister(2);
662 __ movsxlq(index, index); 755 __ movsxlq(index, index);
663 __ movq(Operand(object, index, times_1, 0), value); 756 __ movq(Operand(object, index, times_1, 0), value);
664 __ leaq(index, Operand(object, index, times_1, 0)); 757 __ leaq(index, Operand(object, index, times_1, 0));
665 SaveFPRegsMode mode = 758 SaveFPRegsMode mode =
666 frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; 759 frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
667 __ RecordWrite(object, index, value, mode); 760 __ RecordWrite(object, index, value, mode);
668 break; 761 break;
669 } 762 }
763 case kCheckedLoadInt8:
764 ASSEMBLE_CHECKED_LOAD_INTEGER(movsxbl);
765 break;
766 case kCheckedLoadUint8:
767 ASSEMBLE_CHECKED_LOAD_INTEGER(movzxbl);
768 break;
769 case kCheckedLoadInt16:
770 ASSEMBLE_CHECKED_LOAD_INTEGER(movsxwl);
771 break;
772 case kCheckedLoadUint16:
773 ASSEMBLE_CHECKED_LOAD_INTEGER(movzxwl);
774 break;
775 case kCheckedLoadWord32:
776 ASSEMBLE_CHECKED_LOAD_INTEGER(movl);
777 break;
778 case kCheckedLoadFloat32:
779 ASSEMBLE_CHECKED_LOAD_FLOAT(movss);
780 break;
781 case kCheckedLoadFloat64:
782 ASSEMBLE_CHECKED_LOAD_FLOAT(movsd);
783 break;
784 case kCheckedStoreWord8:
785 ASSEMBLE_CHECKED_STORE_INTEGER(movb);
786 break;
787 case kCheckedStoreWord16:
788 ASSEMBLE_CHECKED_STORE_INTEGER(movw);
789 break;
790 case kCheckedStoreWord32:
791 ASSEMBLE_CHECKED_STORE_INTEGER(movl);
792 break;
793 case kCheckedStoreFloat32:
794 ASSEMBLE_CHECKED_STORE_FLOAT(movss);
795 break;
796 case kCheckedStoreFloat64:
797 ASSEMBLE_CHECKED_STORE_FLOAT(movsd);
798 break;
670 } 799 }
671 } 800 }
672 801
673 802
674 // Assembles branches after this instruction. 803 // Assembles branches after this instruction.
675 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { 804 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
676 X64OperandConverter i(this, instr); 805 X64OperandConverter i(this, instr);
677 Label::Distance flabel_distance = 806 Label::Distance flabel_distance =
678 branch->fallthru ? Label::kNear : Label::kFar; 807 branch->fallthru ? Label::kNear : Label::kFar;
679 Label* tlabel = branch->true_label; 808 Label* tlabel = branch->true_label;
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
1076 } 1205 }
1077 } 1206 }
1078 MarkLazyDeoptSite(); 1207 MarkLazyDeoptSite();
1079 } 1208 }
1080 1209
1081 #undef __ 1210 #undef __
1082 1211
1083 } // namespace internal 1212 } // namespace internal
1084 } // namespace compiler 1213 } // namespace compiler
1085 } // namespace v8 1214 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/verifier.cc ('k') | src/compiler/x64/instruction-selector-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698