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

Side by Side Diff: src/compiler/arm/code-generator-arm.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/access-builder.cc ('k') | src/compiler/arm/instruction-selector-arm.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 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/arm/macro-assembler-arm.h" 7 #include "src/arm/macro-assembler-arm.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"
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 *first_index += 2; 135 *first_index += 2;
136 return MemOperand(InputRegister(index + 0), InputInt32(index + 1)); 136 return MemOperand(InputRegister(index + 0), InputInt32(index + 1));
137 case kMode_Offset_RR: 137 case kMode_Offset_RR:
138 *first_index += 2; 138 *first_index += 2;
139 return MemOperand(InputRegister(index + 0), InputRegister(index + 1)); 139 return MemOperand(InputRegister(index + 0), InputRegister(index + 1));
140 } 140 }
141 UNREACHABLE(); 141 UNREACHABLE();
142 return MemOperand(r0); 142 return MemOperand(r0);
143 } 143 }
144 144
145 MemOperand InputOffset() { 145 MemOperand InputOffset(int first_index = 0) {
146 int index = 0; 146 return InputOffset(&first_index);
147 return InputOffset(&index);
148 } 147 }
149 148
150 MemOperand ToMemOperand(InstructionOperand* op) const { 149 MemOperand ToMemOperand(InstructionOperand* op) const {
151 DCHECK(op != NULL); 150 DCHECK(op != NULL);
152 DCHECK(!op->IsRegister()); 151 DCHECK(!op->IsRegister());
153 DCHECK(!op->IsDoubleRegister()); 152 DCHECK(!op->IsDoubleRegister());
154 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); 153 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
155 // The linkage computes where all spill slots are located. 154 // The linkage computes where all spill slots are located.
156 FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), 0); 155 FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), 0);
157 return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset()); 156 return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset());
158 } 157 }
159 }; 158 };
160 159
161 160
161 namespace {
162
163 class OutOfLineLoadFloat32 FINAL : public OutOfLineCode {
164 public:
165 OutOfLineLoadFloat32(CodeGenerator* gen, SwVfpRegister result)
166 : OutOfLineCode(gen), result_(result) {}
167
168 void Generate() FINAL {
169 __ vmov(result_, std::numeric_limits<float>::quiet_NaN());
170 }
171
172 private:
173 SwVfpRegister const result_;
174 };
175
176
177 class OutOfLineLoadFloat64 FINAL : public OutOfLineCode {
178 public:
179 OutOfLineLoadFloat64(CodeGenerator* gen, DwVfpRegister result)
180 : OutOfLineCode(gen), result_(result) {}
181
182 void Generate() FINAL {
183 __ vmov(result_, std::numeric_limits<double>::quiet_NaN(), kScratchReg);
184 }
185
186 private:
187 DwVfpRegister const result_;
188 };
189
190
191 class OutOfLineLoadInteger FINAL : public OutOfLineCode {
192 public:
193 OutOfLineLoadInteger(CodeGenerator* gen, Register result)
194 : OutOfLineCode(gen), result_(result) {}
195
196 void Generate() FINAL { __ mov(result_, Operand::Zero()); }
197
198 private:
199 Register const result_;
200 };
201
202 } // namespace
203
204
205 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width) \
206 do { \
207 auto result = i.OutputFloat##width##Register(); \
208 auto offset = i.InputRegister(0); \
209 if (instr->InputAt(1)->IsRegister()) { \
210 __ cmp(offset, i.InputRegister(1)); \
211 } else { \
212 __ cmp(offset, i.InputImmediate(1)); \
213 } \
214 auto ool = new (zone()) OutOfLineLoadFloat##width(this, result); \
215 __ b(hs, ool->entry()); \
216 __ vldr(result, i.InputOffset(2)); \
217 __ bind(ool->exit()); \
218 DCHECK_EQ(LeaveCC, i.OutputSBit()); \
219 } while (0)
220
221
222 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \
223 do { \
224 auto result = i.OutputRegister(); \
225 auto offset = i.InputRegister(0); \
226 if (instr->InputAt(1)->IsRegister()) { \
227 __ cmp(offset, i.InputRegister(1)); \
228 } else { \
229 __ cmp(offset, i.InputImmediate(1)); \
230 } \
231 auto ool = new (zone()) OutOfLineLoadInteger(this, result); \
232 __ b(hs, ool->entry()); \
233 __ asm_instr(result, i.InputOffset(2)); \
234 __ bind(ool->exit()); \
235 DCHECK_EQ(LeaveCC, i.OutputSBit()); \
236 } while (0)
237
238
239 #define ASSEMBLE_CHECKED_STORE_FLOAT(width) \
240 do { \
241 auto offset = i.InputRegister(0); \
242 if (instr->InputAt(1)->IsRegister()) { \
243 __ cmp(offset, i.InputRegister(1)); \
244 } else { \
245 __ cmp(offset, i.InputImmediate(1)); \
246 } \
247 auto value = i.InputFloat##width##Register(2); \
248 __ vstr(value, i.InputOffset(3), lo); \
249 DCHECK_EQ(LeaveCC, i.OutputSBit()); \
250 } while (0)
251
252
253 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \
254 do { \
255 auto offset = i.InputRegister(0); \
256 if (instr->InputAt(1)->IsRegister()) { \
257 __ cmp(offset, i.InputRegister(1)); \
258 } else { \
259 __ cmp(offset, i.InputImmediate(1)); \
260 } \
261 auto value = i.InputRegister(2); \
262 __ asm_instr(value, i.InputOffset(3), lo); \
263 DCHECK_EQ(LeaveCC, i.OutputSBit()); \
264 } while (0)
265
266
162 // Assembles an instruction after register allocation, producing machine code. 267 // Assembles an instruction after register allocation, producing machine code.
163 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { 268 void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
164 ArmOperandConverter i(this, instr); 269 ArmOperandConverter i(this, instr);
165 270
166 switch (ArchOpcodeField::decode(instr->opcode())) { 271 switch (ArchOpcodeField::decode(instr->opcode())) {
167 case kArchCallCodeObject: { 272 case kArchCallCodeObject: {
168 EnsureSpaceForLazyDeopt(); 273 EnsureSpaceForLazyDeopt();
169 if (instr->InputAt(0)->IsImmediate()) { 274 if (instr->InputAt(0)->IsImmediate()) {
170 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), 275 __ Call(Handle<Code>::cast(i.InputHeapObject(0)),
171 RelocInfo::CODE_TARGET); 276 RelocInfo::CODE_TARGET);
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 Register value = i.InputRegister(2); 633 Register value = i.InputRegister(2);
529 __ add(index, object, index); 634 __ add(index, object, index);
530 __ str(value, MemOperand(index)); 635 __ str(value, MemOperand(index));
531 SaveFPRegsMode mode = 636 SaveFPRegsMode mode =
532 frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; 637 frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
533 LinkRegisterStatus lr_status = kLRHasNotBeenSaved; 638 LinkRegisterStatus lr_status = kLRHasNotBeenSaved;
534 __ RecordWrite(object, index, value, lr_status, mode); 639 __ RecordWrite(object, index, value, lr_status, mode);
535 DCHECK_EQ(LeaveCC, i.OutputSBit()); 640 DCHECK_EQ(LeaveCC, i.OutputSBit());
536 break; 641 break;
537 } 642 }
643 case kCheckedLoadInt8:
644 ASSEMBLE_CHECKED_LOAD_INTEGER(ldrsb);
645 break;
646 case kCheckedLoadUint8:
647 ASSEMBLE_CHECKED_LOAD_INTEGER(ldrb);
648 break;
649 case kCheckedLoadInt16:
650 ASSEMBLE_CHECKED_LOAD_INTEGER(ldrsh);
651 break;
652 case kCheckedLoadUint16:
653 ASSEMBLE_CHECKED_LOAD_INTEGER(ldrh);
654 break;
655 case kCheckedLoadWord32:
656 ASSEMBLE_CHECKED_LOAD_INTEGER(ldr);
657 break;
658 case kCheckedLoadFloat32:
659 ASSEMBLE_CHECKED_LOAD_FLOAT(32);
660 break;
661 case kCheckedLoadFloat64:
662 ASSEMBLE_CHECKED_LOAD_FLOAT(64);
663 break;
664 case kCheckedStoreWord8:
665 ASSEMBLE_CHECKED_STORE_INTEGER(strb);
666 break;
667 case kCheckedStoreWord16:
668 ASSEMBLE_CHECKED_STORE_INTEGER(strh);
669 break;
670 case kCheckedStoreWord32:
671 ASSEMBLE_CHECKED_STORE_INTEGER(str);
672 break;
673 case kCheckedStoreFloat32:
674 ASSEMBLE_CHECKED_STORE_FLOAT(32);
675 break;
676 case kCheckedStoreFloat64:
677 ASSEMBLE_CHECKED_STORE_FLOAT(64);
678 break;
538 } 679 }
539 } 680 }
540 681
541 682
542 // Assembles branches after an instruction. 683 // Assembles branches after an instruction.
543 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { 684 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
544 ArmOperandConverter i(this, instr); 685 ArmOperandConverter i(this, instr);
545 Label* tlabel = branch->true_label; 686 Label* tlabel = branch->true_label;
546 Label* flabel = branch->false_label; 687 Label* flabel = branch->false_label;
547 switch (branch->condition) { 688 switch (branch->condition) {
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
821 break; 962 break;
822 case Constant::kHeapObject: 963 case Constant::kHeapObject:
823 __ Move(dst, src.ToHeapObject()); 964 __ Move(dst, src.ToHeapObject());
824 break; 965 break;
825 case Constant::kRpoNumber: 966 case Constant::kRpoNumber:
826 UNREACHABLE(); // TODO(dcarney): loading RPO constants on arm. 967 UNREACHABLE(); // TODO(dcarney): loading RPO constants on arm.
827 break; 968 break;
828 } 969 }
829 if (destination->IsStackSlot()) __ str(dst, g.ToMemOperand(destination)); 970 if (destination->IsStackSlot()) __ str(dst, g.ToMemOperand(destination));
830 } else if (src.type() == Constant::kFloat32) { 971 } else if (src.type() == Constant::kFloat32) {
831 SwVfpRegister dst = destination->IsDoubleRegister()
832 ? g.ToFloat32Register(destination)
833 : kScratchDoubleReg.low();
834 // TODO(turbofan): Can we do better here?
835 __ mov(ip, Operand(bit_cast<int32_t>(src.ToFloat32())));
836 __ vmov(dst, ip);
837 if (destination->IsDoubleStackSlot()) { 972 if (destination->IsDoubleStackSlot()) {
838 __ vstr(dst, g.ToMemOperand(destination)); 973 MemOperand dst = g.ToMemOperand(destination);
974 __ mov(ip, Operand(bit_cast<int32_t>(src.ToFloat32())));
975 __ str(ip, dst);
976 } else {
977 SwVfpRegister dst = g.ToFloat32Register(destination);
978 __ vmov(dst, src.ToFloat32());
839 } 979 }
840 } else { 980 } else {
841 DCHECK_EQ(Constant::kFloat64, src.type()); 981 DCHECK_EQ(Constant::kFloat64, src.type());
842 DwVfpRegister dst = destination->IsDoubleRegister() 982 DwVfpRegister dst = destination->IsDoubleRegister()
843 ? g.ToFloat64Register(destination) 983 ? g.ToFloat64Register(destination)
844 : kScratchDoubleReg; 984 : kScratchDoubleReg;
845 __ vmov(dst, src.ToFloat64()); 985 __ vmov(dst, src.ToFloat64(), kScratchReg);
846 if (destination->IsDoubleStackSlot()) { 986 if (destination->IsDoubleStackSlot()) {
847 __ vstr(dst, g.ToMemOperand(destination)); 987 __ vstr(dst, g.ToMemOperand(destination));
848 } 988 }
849 } 989 }
850 } else if (source->IsDoubleRegister()) { 990 } else if (source->IsDoubleRegister()) {
851 DwVfpRegister src = g.ToDoubleRegister(source); 991 DwVfpRegister src = g.ToDoubleRegister(source);
852 if (destination->IsDoubleRegister()) { 992 if (destination->IsDoubleRegister()) {
853 DwVfpRegister dst = g.ToDoubleRegister(destination); 993 DwVfpRegister dst = g.ToDoubleRegister(destination);
854 __ Move(dst, src); 994 __ Move(dst, src);
855 } else { 995 } else {
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 } 1102 }
963 } 1103 }
964 MarkLazyDeoptSite(); 1104 MarkLazyDeoptSite();
965 } 1105 }
966 1106
967 #undef __ 1107 #undef __
968 1108
969 } // namespace compiler 1109 } // namespace compiler
970 } // namespace internal 1110 } // namespace internal
971 } // namespace v8 1111 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/access-builder.cc ('k') | src/compiler/arm/instruction-selector-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698