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

Side by Side Diff: src/compiler/mips/code-generator-mips.cc

Issue 762853004: MIPS: [turbofan] Add checked load/store operators. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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 | « no previous file | src/compiler/mips/instruction-selector-mips.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 #include "src/compiler/code-generator-impl.h" 6 #include "src/compiler/code-generator-impl.h"
7 #include "src/compiler/gap-resolver.h" 7 #include "src/compiler/gap-resolver.h"
8 #include "src/compiler/node-matchers.h" 8 #include "src/compiler/node-matchers.h"
9 #include "src/compiler/node-properties-inl.h" 9 #include "src/compiler/node-properties-inl.h"
10 #include "src/mips/macro-assembler-mips.h" 10 #include "src/mips/macro-assembler-mips.h"
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 *first_index += 2; 95 *first_index += 2;
96 return MemOperand(InputRegister(index + 0), InputInt32(index + 1)); 96 return MemOperand(InputRegister(index + 0), InputInt32(index + 1));
97 case kMode_MRR: 97 case kMode_MRR:
98 // TODO(plind): r6 address mode, to be implemented ... 98 // TODO(plind): r6 address mode, to be implemented ...
99 UNREACHABLE(); 99 UNREACHABLE();
100 } 100 }
101 UNREACHABLE(); 101 UNREACHABLE();
102 return MemOperand(no_reg); 102 return MemOperand(no_reg);
103 } 103 }
104 104
105 MemOperand MemoryOperand() { 105 MemOperand MemoryOperand(int index = 0) { return MemoryOperand(&index); }
106 int index = 0;
107 return MemoryOperand(&index);
108 }
109 106
110 MemOperand ToMemOperand(InstructionOperand* op) const { 107 MemOperand ToMemOperand(InstructionOperand* op) const {
111 DCHECK(op != NULL); 108 DCHECK(op != NULL);
112 DCHECK(!op->IsRegister()); 109 DCHECK(!op->IsRegister());
113 DCHECK(!op->IsDoubleRegister()); 110 DCHECK(!op->IsDoubleRegister());
114 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); 111 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
115 // The linkage computes where all spill slots are located. 112 // The linkage computes where all spill slots are located.
116 FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), 0); 113 FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), 0);
117 return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset()); 114 return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset());
118 } 115 }
119 }; 116 };
120 117
121 118
122 static inline bool HasRegisterInput(Instruction* instr, int index) { 119 static inline bool HasRegisterInput(Instruction* instr, int index) {
123 return instr->InputAt(index)->IsRegister(); 120 return instr->InputAt(index)->IsRegister();
124 } 121 }
125 122
126 123
124 namespace {
125
126 class OutOfLineLoadSingle FINAL : public OutOfLineCode {
127 public:
128 OutOfLineLoadSingle(CodeGenerator* gen, FloatRegister result)
129 : OutOfLineCode(gen), result_(result) {}
130
131 void Generate() FINAL {
132 __ Move(result_, std::numeric_limits<float>::quiet_NaN());
133 }
134
135 private:
136 FloatRegister const result_;
137 };
138
139
140 class OutOfLineLoadDouble FINAL : public OutOfLineCode {
141 public:
142 OutOfLineLoadDouble(CodeGenerator* gen, DoubleRegister result)
143 : OutOfLineCode(gen), result_(result) {}
144
145 void Generate() FINAL {
146 __ Move(result_, std::numeric_limits<double>::quiet_NaN());
147 }
148
149 private:
150 DoubleRegister const result_;
151 };
152
153
154 class OutOfLineLoadInteger FINAL : public OutOfLineCode {
155 public:
156 OutOfLineLoadInteger(CodeGenerator* gen, Register result)
157 : OutOfLineCode(gen), result_(result) {}
158
159 void Generate() FINAL { __ mov(result_, zero_reg); }
160
161 private:
162 Register const result_;
163 };
164
165 } // namespace
166
167
168 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width, asm_instr) \
169 do { \
170 auto result = i.Output##width##Register(); \
171 auto offset = i.InputRegister(0); \
172 auto ool = new (zone()) OutOfLineLoad##width(this, result); \
173 __ Branch(ool->entry(), hs, offset, Operand(i.InputRegister(1))); \
174 __ addu(at, i.InputRegister(2), offset); \
175 __ asm_instr(result, MemOperand(at, 0)); \
176 __ bind(ool->exit()); \
177 } while (0)
178
179
180 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \
181 do { \
182 auto result = i.OutputRegister(); \
183 auto offset = i.InputRegister(0); \
184 auto ool = new (zone()) OutOfLineLoadInteger(this, result); \
185 __ Branch(ool->entry(), hs, offset, Operand(i.InputRegister(1))); \
186 __ addu(at, i.InputRegister(2), offset); \
187 __ asm_instr(result, MemOperand(at, 0)); \
188 __ bind(ool->exit()); \
189 } while (0)
190
191
192 #define ASSEMBLE_CHECKED_STORE_FLOAT(width, asm_instr) \
193 do { \
194 auto offset = i.InputRegister(0); \
195 Label done; \
196 __ Branch(&done, hs, offset, Operand(i.InputRegister(1))); \
197 auto value = i.Input##width##Register(2); \
198 __ addu(at, i.InputRegister(3), offset); \
199 __ asm_instr(value, MemOperand(at, 0)); \
200 __ bind(&done); \
201 } while (0)
202
203
204 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \
205 do { \
206 auto offset = i.InputRegister(0); \
207 Label done; \
208 __ Branch(&done, hs, offset, Operand(i.InputRegister(1))); \
209 auto value = i.InputRegister(2); \
210 __ addu(at, i.InputRegister(3), offset); \
211 __ asm_instr(value, MemOperand(at, 0)); \
212 __ bind(&done); \
213 } while (0)
214
215
127 // Assembles an instruction after register allocation, producing machine code. 216 // Assembles an instruction after register allocation, producing machine code.
128 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { 217 void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
129 MipsOperandConverter i(this, instr); 218 MipsOperandConverter i(this, instr);
130 InstructionCode opcode = instr->opcode(); 219 InstructionCode opcode = instr->opcode();
131 220
132 switch (ArchOpcodeField::decode(opcode)) { 221 switch (ArchOpcodeField::decode(opcode)) {
133 case kArchCallCodeObject: { 222 case kArchCallCodeObject: {
134 EnsureSpaceForLazyDeopt(); 223 EnsureSpaceForLazyDeopt();
135 if (instr->InputAt(0)->IsImmediate()) { 224 if (instr->InputAt(0)->IsImmediate()) {
136 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), 225 __ Call(Handle<Code>::cast(i.InputHeapObject(0)),
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 } 455 }
367 case kMipsLdc1: 456 case kMipsLdc1:
368 __ ldc1(i.OutputDoubleRegister(), i.MemoryOperand()); 457 __ ldc1(i.OutputDoubleRegister(), i.MemoryOperand());
369 break; 458 break;
370 case kMipsSdc1: 459 case kMipsSdc1:
371 __ sdc1(i.InputDoubleRegister(2), i.MemoryOperand()); 460 __ sdc1(i.InputDoubleRegister(2), i.MemoryOperand());
372 break; 461 break;
373 case kMipsPush: 462 case kMipsPush:
374 __ Push(i.InputRegister(0)); 463 __ Push(i.InputRegister(0));
375 break; 464 break;
376 case kMipsStoreWriteBarrier: 465 case kMipsStoreWriteBarrier: {
377 Register object = i.InputRegister(0); 466 Register object = i.InputRegister(0);
378 Register index = i.InputRegister(1); 467 Register index = i.InputRegister(1);
379 Register value = i.InputRegister(2); 468 Register value = i.InputRegister(2);
380 __ addu(index, object, index); 469 __ addu(index, object, index);
381 __ sw(value, MemOperand(index)); 470 __ sw(value, MemOperand(index));
382 SaveFPRegsMode mode = 471 SaveFPRegsMode mode =
383 frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; 472 frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
384 RAStatus ra_status = kRAHasNotBeenSaved; 473 RAStatus ra_status = kRAHasNotBeenSaved;
385 __ RecordWrite(object, index, value, ra_status, mode); 474 __ RecordWrite(object, index, value, ra_status, mode);
386 break; 475 break;
476 }
477 case kCheckedLoadInt8:
478 ASSEMBLE_CHECKED_LOAD_INTEGER(lb);
479 break;
480 case kCheckedLoadUint8:
481 ASSEMBLE_CHECKED_LOAD_INTEGER(lbu);
482 break;
483 case kCheckedLoadInt16:
484 ASSEMBLE_CHECKED_LOAD_INTEGER(lh);
485 break;
486 case kCheckedLoadUint16:
487 ASSEMBLE_CHECKED_LOAD_INTEGER(lhu);
488 break;
489 case kCheckedLoadWord32:
490 ASSEMBLE_CHECKED_LOAD_INTEGER(lw);
491 break;
492 case kCheckedLoadFloat32:
493 ASSEMBLE_CHECKED_LOAD_FLOAT(Single, lwc1);
494 break;
495 case kCheckedLoadFloat64:
496 ASSEMBLE_CHECKED_LOAD_FLOAT(Double, ldc1);
497 break;
498 case kCheckedStoreWord8:
499 ASSEMBLE_CHECKED_STORE_INTEGER(sb);
500 break;
501 case kCheckedStoreWord16:
502 ASSEMBLE_CHECKED_STORE_INTEGER(sh);
503 break;
504 case kCheckedStoreWord32:
505 ASSEMBLE_CHECKED_STORE_INTEGER(sw);
506 break;
507 case kCheckedStoreFloat32:
508 ASSEMBLE_CHECKED_STORE_FLOAT(Single, swc1);
509 break;
510 case kCheckedStoreFloat64:
511 ASSEMBLE_CHECKED_STORE_FLOAT(Double, sdc1);
512 break;
387 } 513 }
388 } 514 }
389 515
390 516
391 #define UNSUPPORTED_COND(opcode, condition) \ 517 #define UNSUPPORTED_COND(opcode, condition) \
392 OFStream out(stdout); \ 518 OFStream out(stdout); \
393 out << "Unsupported " << #opcode << " condition: \"" << condition << "\""; \ 519 out << "Unsupported " << #opcode << " condition: \"" << condition << "\""; \
394 UNIMPLEMENTED(); 520 UNIMPLEMENTED();
395 521
396 // Assembles branches after an instruction. 522 // Assembles branches after an instruction.
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 break; 924 break;
799 case Constant::kHeapObject: 925 case Constant::kHeapObject:
800 __ li(dst, src.ToHeapObject()); 926 __ li(dst, src.ToHeapObject());
801 break; 927 break;
802 case Constant::kRpoNumber: 928 case Constant::kRpoNumber:
803 UNREACHABLE(); // TODO(titzer): loading RPO numbers on mips. 929 UNREACHABLE(); // TODO(titzer): loading RPO numbers on mips.
804 break; 930 break;
805 } 931 }
806 if (destination->IsStackSlot()) __ sw(dst, g.ToMemOperand(destination)); 932 if (destination->IsStackSlot()) __ sw(dst, g.ToMemOperand(destination));
807 } else if (src.type() == Constant::kFloat32) { 933 } else if (src.type() == Constant::kFloat32) {
808 FPURegister dst = destination->IsDoubleRegister()
809 ? g.ToDoubleRegister(destination)
810 : kScratchDoubleReg.low();
811 // TODO(turbofan): Can we do better here?
812 __ li(at, Operand(bit_cast<int32_t>(src.ToFloat32())));
813 __ mtc1(at, dst);
814 if (destination->IsDoubleStackSlot()) { 934 if (destination->IsDoubleStackSlot()) {
815 __ swc1(dst, g.ToMemOperand(destination)); 935 MemOperand dst = g.ToMemOperand(destination);
936 __ li(at, Operand(bit_cast<int32_t>(src.ToFloat32())));
937 __ sw(at, dst);
938 } else {
939 FloatRegister dst = g.ToSingleRegister(destination);
940 __ Move(dst, src.ToFloat32());
816 } 941 }
817 } else { 942 } else {
818 DCHECK_EQ(Constant::kFloat64, src.type()); 943 DCHECK_EQ(Constant::kFloat64, src.type());
819 DoubleRegister dst = destination->IsDoubleRegister() 944 DoubleRegister dst = destination->IsDoubleRegister()
820 ? g.ToDoubleRegister(destination) 945 ? g.ToDoubleRegister(destination)
821 : kScratchDoubleReg; 946 : kScratchDoubleReg;
822 __ Move(dst, src.ToFloat64()); 947 __ Move(dst, src.ToFloat64());
823 if (destination->IsDoubleStackSlot()) { 948 if (destination->IsDoubleStackSlot()) {
824 __ sdc1(dst, g.ToMemOperand(destination)); 949 __ sdc1(dst, g.ToMemOperand(destination));
825 } 950 }
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
942 } 1067 }
943 } 1068 }
944 MarkLazyDeoptSite(); 1069 MarkLazyDeoptSite();
945 } 1070 }
946 1071
947 #undef __ 1072 #undef __
948 1073
949 } // namespace compiler 1074 } // namespace compiler
950 } // namespace internal 1075 } // namespace internal
951 } // namespace v8 1076 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/compiler/mips/instruction-selector-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698