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

Side by Side Diff: src/compiler/arm64/code-generator-arm64.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
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/code-generator.h" 5 #include "src/compiler/code-generator.h"
6 6
7 #include "src/arm64/macro-assembler-arm64.h" 7 #include "src/arm64/macro-assembler-arm64.h"
8 #include "src/compiler/code-generator-impl.h" 8 #include "src/compiler/code-generator-impl.h"
9 #include "src/compiler/gap-resolver.h" 9 #include "src/compiler/gap-resolver.h"
10 #include "src/compiler/node-matchers.h" 10 #include "src/compiler/node-matchers.h"
11 #include "src/compiler/node-properties-inl.h" 11 #include "src/compiler/node-properties-inl.h"
12 #include "src/scopes.h" 12 #include "src/scopes.h"
13 13
14 namespace v8 { 14 namespace v8 {
15 namespace internal { 15 namespace internal {
16 namespace compiler { 16 namespace compiler {
17 17
18 #define __ masm()-> 18 #define __ masm()->
19 19
20 20
21 // Adds Arm64-specific methods to convert InstructionOperands. 21 // Adds Arm64-specific methods to convert InstructionOperands.
22 class Arm64OperandConverter FINAL : public InstructionOperandConverter { 22 class Arm64OperandConverter FINAL : public InstructionOperandConverter {
23 public: 23 public:
24 Arm64OperandConverter(CodeGenerator* gen, Instruction* instr) 24 Arm64OperandConverter(CodeGenerator* gen, Instruction* instr)
25 : InstructionOperandConverter(gen, instr) {} 25 : InstructionOperandConverter(gen, instr) {}
26 26
27 DoubleRegister InputFloat32Register(int index) {
28 return InputDoubleRegister(index).S();
29 }
30
31 DoubleRegister InputFloat64Register(int index) {
32 return InputDoubleRegister(index);
33 }
34
35 DoubleRegister OutputFloat32Register() { return OutputDoubleRegister().S(); }
36
37 DoubleRegister OutputFloat64Register() { return OutputDoubleRegister(); }
38
27 Register InputRegister32(int index) { 39 Register InputRegister32(int index) {
28 return ToRegister(instr_->InputAt(index)).W(); 40 return ToRegister(instr_->InputAt(index)).W();
29 } 41 }
30 42
31 Register InputRegister64(int index) { return InputRegister(index); } 43 Register InputRegister64(int index) { return InputRegister(index); }
32 44
33 Operand InputImmediate(int index) { 45 Operand InputImmediate(int index) {
34 return ToImmediate(instr_->InputAt(index)); 46 return ToImmediate(instr_->InputAt(index));
35 } 47 }
36 48
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 *first_index += 2; 111 *first_index += 2;
100 return MemOperand(InputRegister(index + 0), InputInt32(index + 1)); 112 return MemOperand(InputRegister(index + 0), InputInt32(index + 1));
101 case kMode_MRR: 113 case kMode_MRR:
102 *first_index += 2; 114 *first_index += 2;
103 return MemOperand(InputRegister(index + 0), InputRegister(index + 1)); 115 return MemOperand(InputRegister(index + 0), InputRegister(index + 1));
104 } 116 }
105 UNREACHABLE(); 117 UNREACHABLE();
106 return MemOperand(no_reg); 118 return MemOperand(no_reg);
107 } 119 }
108 120
109 MemOperand MemoryOperand() { 121 MemOperand MemoryOperand(int first_index = 0) {
110 int index = 0; 122 return MemoryOperand(&first_index);
111 return MemoryOperand(&index);
112 } 123 }
113 124
114 Operand ToOperand(InstructionOperand* op) { 125 Operand ToOperand(InstructionOperand* op) {
115 if (op->IsRegister()) { 126 if (op->IsRegister()) {
116 return Operand(ToRegister(op)); 127 return Operand(ToRegister(op));
117 } 128 }
118 return ToImmediate(op); 129 return ToImmediate(op);
119 } 130 }
120 131
121 Operand ToOperand32(InstructionOperand* op) { 132 Operand ToOperand32(InstructionOperand* op) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 DCHECK(!op->IsDoubleRegister()); 167 DCHECK(!op->IsDoubleRegister());
157 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); 168 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
158 // The linkage computes where all spill slots are located. 169 // The linkage computes where all spill slots are located.
159 FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), 0); 170 FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), 0);
160 return MemOperand(offset.from_stack_pointer() ? masm->StackPointer() : fp, 171 return MemOperand(offset.from_stack_pointer() ? masm->StackPointer() : fp,
161 offset.offset()); 172 offset.offset());
162 } 173 }
163 }; 174 };
164 175
165 176
177 namespace {
178
179 class OutOfLineLoadFloat32 FINAL : public OutOfLineCode {
180 public:
181 OutOfLineLoadFloat32(CodeGenerator* gen, DoubleRegister result)
182 : OutOfLineCode(gen), result_(result) {}
183
184 void Generate() FINAL {
185 __ Fmov(result_, std::numeric_limits<float>::quiet_NaN());
186 }
187
188 private:
189 DoubleRegister const result_;
190 };
191
192
193 class OutOfLineLoadFloat64 FINAL : public OutOfLineCode {
194 public:
195 OutOfLineLoadFloat64(CodeGenerator* gen, DoubleRegister result)
196 : OutOfLineCode(gen), result_(result) {}
197
198 void Generate() FINAL {
199 __ Fmov(result_, std::numeric_limits<double>::quiet_NaN());
200 }
201
202 private:
203 DoubleRegister const result_;
204 };
205
206
207 class OutOfLineLoadInteger FINAL : public OutOfLineCode {
208 public:
209 OutOfLineLoadInteger(CodeGenerator* gen, Register result)
210 : OutOfLineCode(gen), result_(result) {}
211
212 void Generate() FINAL { __ Mov(result_, 0); }
213
214 private:
215 Register const result_;
216 };
217
218 } // namespace
219
220
221 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width) \
222 do { \
223 auto result = i.OutputFloat##width##Register(); \
224 auto offset = i.InputRegister32(0); \
225 auto length = i.InputOperand32(1); \
226 __ Cmp(offset, length); \
227 auto ool = new (zone()) OutOfLineLoadFloat##width(this, result); \
228 __ B(hs, ool->entry()); \
229 __ Ldr(result, i.MemoryOperand(2)); \
230 __ Bind(ool->exit()); \
231 } while (0)
232
233
234 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \
235 do { \
236 auto result = i.OutputRegister32(); \
237 auto offset = i.InputRegister32(0); \
238 auto length = i.InputOperand32(1); \
239 __ Cmp(offset, length); \
240 auto ool = new (zone()) OutOfLineLoadInteger(this, result); \
241 __ B(hs, ool->entry()); \
242 __ asm_instr(result, i.MemoryOperand(2)); \
243 __ Bind(ool->exit()); \
244 } while (0)
245
246
247 #define ASSEMBLE_CHECKED_STORE_FLOAT(width) \
248 do { \
249 auto offset = i.InputRegister32(0); \
250 auto length = i.InputOperand32(1); \
251 __ Cmp(offset, length); \
252 Label done; \
253 __ B(hs, &done); \
254 __ Str(i.InputFloat##width##Register(2), i.MemoryOperand(3)); \
255 __ Bind(&done); \
256 } while (0)
257
258
259 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \
260 do { \
261 auto offset = i.InputRegister32(0); \
262 auto length = i.InputOperand32(1); \
263 __ Cmp(offset, length); \
264 Label done; \
265 __ B(hs, &done); \
266 __ asm_instr(i.InputRegister32(2), i.MemoryOperand(3)); \
267 __ Bind(&done); \
268 } while (0)
269
270
166 #define ASSEMBLE_SHIFT(asm_instr, width) \ 271 #define ASSEMBLE_SHIFT(asm_instr, width) \
167 do { \ 272 do { \
168 if (instr->InputAt(1)->IsRegister()) { \ 273 if (instr->InputAt(1)->IsRegister()) { \
169 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), \ 274 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), \
170 i.InputRegister##width(1)); \ 275 i.InputRegister##width(1)); \
171 } else { \ 276 } else { \
172 int64_t imm = i.InputOperand##width(1).immediate().value(); \ 277 int64_t imm = i.InputOperand##width(1).immediate().value(); \
173 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), imm); \ 278 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), imm); \
174 } \ 279 } \
175 } while (0) 280 } while (0)
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 temp = scope.AcquireX(); 714 temp = scope.AcquireX();
610 lr_status = kLRHasBeenSaved; 715 lr_status = kLRHasBeenSaved;
611 __ Push(lr, temp); // Need to push a pair 716 __ Push(lr, temp); // Need to push a pair
612 } 717 }
613 __ RecordWrite(object, index, value, lr_status, mode); 718 __ RecordWrite(object, index, value, lr_status, mode);
614 if (csp.is(masm()->StackPointer())) { 719 if (csp.is(masm()->StackPointer())) {
615 __ Pop(temp, lr); 720 __ Pop(temp, lr);
616 } 721 }
617 break; 722 break;
618 } 723 }
724 case kCheckedLoadInt8:
725 ASSEMBLE_CHECKED_LOAD_INTEGER(Ldrsb);
726 break;
727 case kCheckedLoadUint8:
728 ASSEMBLE_CHECKED_LOAD_INTEGER(Ldrb);
729 break;
730 case kCheckedLoadInt16:
731 ASSEMBLE_CHECKED_LOAD_INTEGER(Ldrsh);
732 break;
733 case kCheckedLoadUint16:
734 ASSEMBLE_CHECKED_LOAD_INTEGER(Ldrh);
735 break;
736 case kCheckedLoadWord32:
737 ASSEMBLE_CHECKED_LOAD_INTEGER(Ldr);
738 break;
739 case kCheckedLoadFloat32:
740 ASSEMBLE_CHECKED_LOAD_FLOAT(32);
741 break;
742 case kCheckedLoadFloat64:
743 ASSEMBLE_CHECKED_LOAD_FLOAT(64);
744 break;
745 case kCheckedStoreWord8:
746 ASSEMBLE_CHECKED_STORE_INTEGER(Strb);
747 break;
748 case kCheckedStoreWord16:
749 ASSEMBLE_CHECKED_STORE_INTEGER(Strh);
750 break;
751 case kCheckedStoreWord32:
752 ASSEMBLE_CHECKED_STORE_INTEGER(Str);
753 break;
754 case kCheckedStoreFloat32:
755 ASSEMBLE_CHECKED_STORE_FLOAT(32);
756 break;
757 case kCheckedStoreFloat64:
758 ASSEMBLE_CHECKED_STORE_FLOAT(64);
759 break;
619 } 760 }
620 } 761 }
621 762
622 763
623 // Assemble branches after this instruction. 764 // Assemble branches after this instruction.
624 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { 765 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
625 Arm64OperandConverter i(this, instr); 766 Arm64OperandConverter i(this, instr);
626 Label* tlabel = branch->true_label; 767 Label* tlabel = branch->true_label;
627 Label* flabel = branch->false_label; 768 Label* flabel = branch->false_label;
628 switch (branch->condition) { 769 switch (branch->condition) {
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 case kUnsignedGreaterThan: 904 case kUnsignedGreaterThan:
764 cc = hi; 905 cc = hi;
765 break; 906 break;
766 case kOverflow: 907 case kOverflow:
767 cc = vs; 908 cc = vs;
768 break; 909 break;
769 case kNotOverflow: 910 case kNotOverflow:
770 cc = vc; 911 cc = vc;
771 break; 912 break;
772 } 913 }
773 __ bind(&check); 914 __ Bind(&check);
774 __ Cset(reg, cc); 915 __ Cset(reg, cc);
775 __ Bind(&done); 916 __ Bind(&done);
776 } 917 }
777 918
778 919
779 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) { 920 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) {
780 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( 921 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
781 isolate(), deoptimization_id, Deoptimizer::LAZY); 922 isolate(), deoptimization_id, Deoptimizer::LAZY);
782 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); 923 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
783 } 924 }
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 } 1157 }
1017 } 1158 }
1018 MarkLazyDeoptSite(); 1159 MarkLazyDeoptSite();
1019 } 1160 }
1020 1161
1021 #undef __ 1162 #undef __
1022 1163
1023 } // namespace compiler 1164 } // namespace compiler
1024 } // namespace internal 1165 } // namespace internal
1025 } // namespace v8 1166 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/arm/instruction-selector-arm.cc ('k') | src/compiler/arm64/instruction-selector-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698