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

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

Issue 773113005: MIPS64: [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/mips64/instruction-selector-mips64.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 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 *first_index += 2; 96 *first_index += 2;
97 return MemOperand(InputRegister(index + 0), InputInt32(index + 1)); 97 return MemOperand(InputRegister(index + 0), InputInt32(index + 1));
98 case kMode_MRR: 98 case kMode_MRR:
99 // TODO(plind): r6 address mode, to be implemented ... 99 // TODO(plind): r6 address mode, to be implemented ...
100 UNREACHABLE(); 100 UNREACHABLE();
101 } 101 }
102 UNREACHABLE(); 102 UNREACHABLE();
103 return MemOperand(no_reg); 103 return MemOperand(no_reg);
104 } 104 }
105 105
106 MemOperand MemoryOperand() { 106 MemOperand MemoryOperand(int index = 0) { return MemoryOperand(&index); }
107 int index = 0;
108 return MemoryOperand(&index);
109 }
110 107
111 MemOperand ToMemOperand(InstructionOperand* op) const { 108 MemOperand ToMemOperand(InstructionOperand* op) const {
112 DCHECK(op != NULL); 109 DCHECK(op != NULL);
113 DCHECK(!op->IsRegister()); 110 DCHECK(!op->IsRegister());
114 DCHECK(!op->IsDoubleRegister()); 111 DCHECK(!op->IsDoubleRegister());
115 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); 112 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
116 // The linkage computes where all spill slots are located. 113 // The linkage computes where all spill slots are located.
117 FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), 0); 114 FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), 0);
118 return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset()); 115 return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset());
119 } 116 }
120 }; 117 };
121 118
122 119
123 static inline bool HasRegisterInput(Instruction* instr, int index) { 120 static inline bool HasRegisterInput(Instruction* instr, int index) {
124 return instr->InputAt(index)->IsRegister(); 121 return instr->InputAt(index)->IsRegister();
125 } 122 }
126 123
127 124
125 namespace {
126
127 class OutOfLineLoadSingle FINAL : public OutOfLineCode {
128 public:
129 OutOfLineLoadSingle(CodeGenerator* gen, FloatRegister result)
130 : OutOfLineCode(gen), result_(result) {}
131
132 void Generate() FINAL {
133 __ Move(result_, std::numeric_limits<float>::quiet_NaN());
134 }
135
136 private:
137 FloatRegister const result_;
138 };
139
140
141 class OutOfLineLoadDouble FINAL : public OutOfLineCode {
142 public:
143 OutOfLineLoadDouble(CodeGenerator* gen, DoubleRegister result)
144 : OutOfLineCode(gen), result_(result) {}
145
146 void Generate() FINAL {
147 __ Move(result_, std::numeric_limits<double>::quiet_NaN());
148 }
149
150 private:
151 DoubleRegister const result_;
152 };
153
154
155 class OutOfLineLoadInteger FINAL : public OutOfLineCode {
156 public:
157 OutOfLineLoadInteger(CodeGenerator* gen, Register result)
158 : OutOfLineCode(gen), result_(result) {}
159
160 void Generate() FINAL { __ mov(result_, zero_reg); }
161
162 private:
163 Register const result_;
164 };
165
166 } // namespace
167
168
169 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width, asm_instr) \
170 do { \
171 auto result = i.Output##width##Register(); \
172 auto offset = i.InputRegister(0); \
173 auto ool = new (zone()) OutOfLineLoad##width(this, result); \
174 __ Branch(ool->entry(), hs, offset, Operand(i.InputRegister(1))); \
175 __ Daddu(at, i.InputRegister(2), offset); \
176 __ asm_instr(result, MemOperand(at, 0)); \
177 __ bind(ool->exit()); \
178 } while (0)
179
180
181 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \
182 do { \
183 auto result = i.OutputRegister(); \
184 auto offset = i.InputRegister(0); \
185 auto ool = new (zone()) OutOfLineLoadInteger(this, result); \
186 __ Branch(ool->entry(), hs, offset, Operand(i.InputRegister(1))); \
187 __ Daddu(at, i.InputRegister(2), offset); \
188 __ asm_instr(result, MemOperand(at, 0)); \
189 __ bind(ool->exit()); \
190 } while (0)
191
192
193 #define ASSEMBLE_CHECKED_STORE_FLOAT(width, asm_instr) \
194 do { \
195 auto offset = i.InputRegister(0); \
196 Label done; \
197 __ Branch(&done, hs, offset, Operand(i.InputRegister(1))); \
198 auto value = i.Input##width##Register(2); \
199 __ Daddu(at, i.InputRegister(3), offset); \
200 __ asm_instr(value, MemOperand(at, 0)); \
201 __ bind(&done); \
202 } while (0)
203
204
205 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \
206 do { \
207 auto offset = i.InputRegister(0); \
208 Label done; \
209 __ Branch(&done, hs, offset, Operand(i.InputRegister(1))); \
210 auto value = i.InputRegister(2); \
211 __ Daddu(at, i.InputRegister(3), offset); \
212 __ asm_instr(value, MemOperand(at, 0)); \
213 __ bind(&done); \
214 } while (0)
215
216
128 // Assembles an instruction after register allocation, producing machine code. 217 // Assembles an instruction after register allocation, producing machine code.
129 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { 218 void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
130 MipsOperandConverter i(this, instr); 219 MipsOperandConverter i(this, instr);
131 InstructionCode opcode = instr->opcode(); 220 InstructionCode opcode = instr->opcode();
132 221
133 switch (ArchOpcodeField::decode(opcode)) { 222 switch (ArchOpcodeField::decode(opcode)) {
134 case kArchCallCodeObject: { 223 case kArchCallCodeObject: {
135 EnsureSpaceForLazyDeopt(); 224 EnsureSpaceForLazyDeopt();
136 if (instr->InputAt(0)->IsImmediate()) { 225 if (instr->InputAt(0)->IsImmediate()) {
137 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), 226 __ Call(Handle<Code>::cast(i.InputHeapObject(0)),
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 case kMips64StackClaim: { 551 case kMips64StackClaim: {
463 int words = MiscField::decode(instr->opcode()); 552 int words = MiscField::decode(instr->opcode());
464 __ Dsubu(sp, sp, Operand(words << kPointerSizeLog2)); 553 __ Dsubu(sp, sp, Operand(words << kPointerSizeLog2));
465 break; 554 break;
466 } 555 }
467 case kMips64StoreToStackSlot: { 556 case kMips64StoreToStackSlot: {
468 int slot = MiscField::decode(instr->opcode()); 557 int slot = MiscField::decode(instr->opcode());
469 __ sd(i.InputRegister(0), MemOperand(sp, slot << kPointerSizeLog2)); 558 __ sd(i.InputRegister(0), MemOperand(sp, slot << kPointerSizeLog2));
470 break; 559 break;
471 } 560 }
472 case kMips64StoreWriteBarrier: 561 case kMips64StoreWriteBarrier: {
473 Register object = i.InputRegister(0); 562 Register object = i.InputRegister(0);
474 Register index = i.InputRegister(1); 563 Register index = i.InputRegister(1);
475 Register value = i.InputRegister(2); 564 Register value = i.InputRegister(2);
476 __ daddu(index, object, index); 565 __ daddu(index, object, index);
477 __ sd(value, MemOperand(index)); 566 __ sd(value, MemOperand(index));
478 SaveFPRegsMode mode = 567 SaveFPRegsMode mode =
479 frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; 568 frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
480 RAStatus ra_status = kRAHasNotBeenSaved; 569 RAStatus ra_status = kRAHasNotBeenSaved;
481 __ RecordWrite(object, index, value, ra_status, mode); 570 __ RecordWrite(object, index, value, ra_status, mode);
482 break; 571 break;
572 }
573 case kCheckedLoadInt8:
574 ASSEMBLE_CHECKED_LOAD_INTEGER(lb);
575 break;
576 case kCheckedLoadUint8:
577 ASSEMBLE_CHECKED_LOAD_INTEGER(lbu);
578 break;
579 case kCheckedLoadInt16:
580 ASSEMBLE_CHECKED_LOAD_INTEGER(lh);
581 break;
582 case kCheckedLoadUint16:
583 ASSEMBLE_CHECKED_LOAD_INTEGER(lhu);
584 break;
585 case kCheckedLoadWord32:
586 ASSEMBLE_CHECKED_LOAD_INTEGER(lw);
587 break;
588 case kCheckedLoadFloat32:
589 ASSEMBLE_CHECKED_LOAD_FLOAT(Single, lwc1);
590 break;
591 case kCheckedLoadFloat64:
592 ASSEMBLE_CHECKED_LOAD_FLOAT(Double, ldc1);
593 break;
594 case kCheckedStoreWord8:
595 ASSEMBLE_CHECKED_STORE_INTEGER(sb);
596 break;
597 case kCheckedStoreWord16:
598 ASSEMBLE_CHECKED_STORE_INTEGER(sh);
599 break;
600 case kCheckedStoreWord32:
601 ASSEMBLE_CHECKED_STORE_INTEGER(sw);
602 break;
603 case kCheckedStoreFloat32:
604 ASSEMBLE_CHECKED_STORE_FLOAT(Single, swc1);
605 break;
606 case kCheckedStoreFloat64:
607 ASSEMBLE_CHECKED_STORE_FLOAT(Double, sdc1);
608 break;
483 } 609 }
484 } 610 }
485 611
486 612
487 #define UNSUPPORTED_COND(opcode, condition) \ 613 #define UNSUPPORTED_COND(opcode, condition) \
488 OFStream out(stdout); \ 614 OFStream out(stdout); \
489 out << "Unsupported " << #opcode << " condition: \"" << condition << "\""; \ 615 out << "Unsupported " << #opcode << " condition: \"" << condition << "\""; \
490 UNIMPLEMENTED(); 616 UNIMPLEMENTED();
491 617
492 // Assembles branches after an instruction. 618 // Assembles branches after an instruction.
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after
1083 break; 1209 break;
1084 case Constant::kHeapObject: 1210 case Constant::kHeapObject:
1085 __ li(dst, src.ToHeapObject()); 1211 __ li(dst, src.ToHeapObject());
1086 break; 1212 break;
1087 case Constant::kRpoNumber: 1213 case Constant::kRpoNumber:
1088 UNREACHABLE(); // TODO(titzer): loading RPO numbers on mips64. 1214 UNREACHABLE(); // TODO(titzer): loading RPO numbers on mips64.
1089 break; 1215 break;
1090 } 1216 }
1091 if (destination->IsStackSlot()) __ sd(dst, g.ToMemOperand(destination)); 1217 if (destination->IsStackSlot()) __ sd(dst, g.ToMemOperand(destination));
1092 } else if (src.type() == Constant::kFloat32) { 1218 } else if (src.type() == Constant::kFloat32) {
1093 FPURegister dst = destination->IsDoubleRegister()
1094 ? g.ToDoubleRegister(destination)
1095 : kScratchDoubleReg.low();
1096 // TODO(turbofan): Can we do better here?
1097 __ li(at, Operand(bit_cast<int32_t>(src.ToFloat32())));
1098 __ mtc1(at, dst);
1099 if (destination->IsDoubleStackSlot()) { 1219 if (destination->IsDoubleStackSlot()) {
1100 __ swc1(dst, g.ToMemOperand(destination)); 1220 MemOperand dst = g.ToMemOperand(destination);
1221 __ li(at, Operand(bit_cast<int32_t>(src.ToFloat32())));
1222 __ sw(at, dst);
1223 } else {
1224 FloatRegister dst = g.ToSingleRegister(destination);
1225 __ Move(dst, src.ToFloat32());
1101 } 1226 }
1102 } else { 1227 } else {
1103 DCHECK_EQ(Constant::kFloat64, src.type()); 1228 DCHECK_EQ(Constant::kFloat64, src.type());
1104 DoubleRegister dst = destination->IsDoubleRegister() 1229 DoubleRegister dst = destination->IsDoubleRegister()
1105 ? g.ToDoubleRegister(destination) 1230 ? g.ToDoubleRegister(destination)
1106 : kScratchDoubleReg; 1231 : kScratchDoubleReg;
1107 __ Move(dst, src.ToFloat64()); 1232 __ Move(dst, src.ToFloat64());
1108 if (destination->IsDoubleStackSlot()) { 1233 if (destination->IsDoubleStackSlot()) {
1109 __ sdc1(dst, g.ToMemOperand(destination)); 1234 __ sdc1(dst, g.ToMemOperand(destination));
1110 } 1235 }
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 } 1352 }
1228 } 1353 }
1229 MarkLazyDeoptSite(); 1354 MarkLazyDeoptSite();
1230 } 1355 }
1231 1356
1232 #undef __ 1357 #undef __
1233 1358
1234 } // namespace compiler 1359 } // namespace compiler
1235 } // namespace internal 1360 } // namespace internal
1236 } // namespace v8 1361 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/compiler/mips64/instruction-selector-mips64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698