Chromium Code Reviews| OLD | NEW |
|---|---|
| 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" |
| 11 #include "src/scopes.h" | 11 #include "src/scopes.h" |
| 12 | 12 |
| 13 namespace v8 { | 13 namespace v8 { |
| 14 namespace internal { | 14 namespace internal { |
| 15 namespace compiler { | 15 namespace compiler { |
| 16 | 16 |
| 17 #define __ masm()-> | 17 #define __ masm()-> |
| 18 | 18 |
| 19 | 19 |
| 20 // TODO(plind): Possibly avoid using these lithium names. | 20 // TODO(plind): Possibly avoid using these lithium names. |
| 21 #define kScratchReg kLithiumScratchReg | 21 #define kScratchReg kLithiumScratchReg |
| 22 #define kCompareReg kLithiumScratchReg2 | 22 #define kCompareReg kLithiumScratchReg2 |
| 23 #define kScratchReg2 kLithiumScratchReg2 | |
| 23 #define kScratchDoubleReg kLithiumScratchDouble | 24 #define kScratchDoubleReg kLithiumScratchDouble |
| 24 | 25 |
| 25 | 26 |
| 26 // TODO(plind): consider renaming these macros. | 27 // TODO(plind): consider renaming these macros. |
| 27 #define TRACE_MSG(msg) \ | 28 #define TRACE_MSG(msg) \ |
| 28 PrintF("code_gen: \'%s\' in function %s at line %d\n", msg, __FUNCTION__, \ | 29 PrintF("code_gen: \'%s\' in function %s at line %d\n", msg, __FUNCTION__, \ |
| 29 __LINE__) | 30 __LINE__) |
| 30 | 31 |
| 31 #define TRACE_UNIMPL() \ | 32 #define TRACE_UNIMPL() \ |
| 32 PrintF("UNIMPLEMENTED code_generator_mips: %s at line %d\n", __FUNCTION__, \ | 33 PrintF("UNIMPLEMENTED code_generator_mips: %s at line %d\n", __FUNCTION__, \ |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 155 public: | 156 public: |
| 156 OutOfLineLoadInteger(CodeGenerator* gen, Register result) | 157 OutOfLineLoadInteger(CodeGenerator* gen, Register result) |
| 157 : OutOfLineCode(gen), result_(result) {} | 158 : OutOfLineCode(gen), result_(result) {} |
| 158 | 159 |
| 159 void Generate() FINAL { __ mov(result_, zero_reg); } | 160 void Generate() FINAL { __ mov(result_, zero_reg); } |
| 160 | 161 |
| 161 private: | 162 private: |
| 162 Register const result_; | 163 Register const result_; |
| 163 }; | 164 }; |
| 164 | 165 |
| 166 | |
| 167 class OutOfLineRound : public OutOfLineCode { | |
| 168 public: | |
| 169 OutOfLineRound(CodeGenerator* gen, DoubleRegister result) | |
| 170 : OutOfLineCode(gen), result_(result) {} | |
| 171 | |
| 172 void Generate() FINAL { | |
| 173 // Handle rounding to zero case where sign has to be preserved. | |
| 174 // High bits of double input already in kScratchReg. | |
| 175 __ srl(at, kScratchReg, 31); | |
| 176 __ sll(at, at, 31); | |
| 177 __ Mthc1(at, result_); | |
| 178 } | |
| 179 | |
| 180 private: | |
| 181 DoubleRegister const result_; | |
| 182 }; | |
| 183 | |
| 184 | |
| 185 class OutOfLineTruncate FINAL : public OutOfLineRound { | |
| 186 public: | |
| 187 OutOfLineTruncate(CodeGenerator* gen, DoubleRegister result) | |
| 188 : OutOfLineRound(gen, result) {} | |
| 189 }; | |
| 190 | |
| 191 | |
| 192 class OutOfLineFloor FINAL : public OutOfLineRound { | |
| 193 public: | |
| 194 OutOfLineFloor(CodeGenerator* gen, DoubleRegister result) | |
| 195 : OutOfLineRound(gen, result) {} | |
| 196 }; | |
| 197 | |
| 198 | |
| 199 class OutOfLineCeil FINAL : public OutOfLineRound { | |
| 200 public: | |
| 201 OutOfLineCeil(CodeGenerator* gen, DoubleRegister result) | |
| 202 : OutOfLineRound(gen, result) {} | |
| 203 }; | |
| 204 | |
| 165 } // namespace | 205 } // namespace |
| 166 | 206 |
| 167 | 207 |
| 168 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width, asm_instr) \ | 208 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width, asm_instr) \ |
| 169 do { \ | 209 do { \ |
| 170 auto result = i.Output##width##Register(); \ | 210 auto result = i.Output##width##Register(); \ |
| 171 auto ool = new (zone()) OutOfLineLoad##width(this, result); \ | 211 auto ool = new (zone()) OutOfLineLoad##width(this, result); \ |
| 172 if (instr->InputAt(0)->IsRegister()) { \ | 212 if (instr->InputAt(0)->IsRegister()) { \ |
| 173 auto offset = i.InputRegister(0); \ | 213 auto offset = i.InputRegister(0); \ |
| 174 __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \ | 214 __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \ |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 232 } else { \ | 272 } else { \ |
| 233 auto offset = i.InputOperand(0).immediate(); \ | 273 auto offset = i.InputOperand(0).immediate(); \ |
| 234 auto value = i.InputRegister(2); \ | 274 auto value = i.InputRegister(2); \ |
| 235 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \ | 275 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \ |
| 236 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ | 276 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ |
| 237 } \ | 277 } \ |
| 238 __ bind(&done); \ | 278 __ bind(&done); \ |
| 239 } while (0) | 279 } while (0) |
| 240 | 280 |
| 241 | 281 |
| 282 #define ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(asm_instr, operation) \ | |
| 283 do { \ | |
| 284 auto ool = \ | |
| 285 new (zone()) OutOfLine##operation(this, i.OutputDoubleRegister()); \ | |
| 286 Label done; \ | |
| 287 __ Mfhc1(kScratchReg, i.InputDoubleRegister(0)); \ | |
| 288 __ Ext(at, kScratchReg, 20, 11); \ | |
| 289 __ Branch(USE_DELAY_SLOT, &done, hs, at, Operand(1075)); \ | |
|
paul.l...
2014/12/18 18:07:41
Hmmm, would prefer we don't use so many magic numb
dusmil.imgtec
2014/12/22 14:34:49
Done.
| |
| 290 __ mov_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ | |
| 291 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ | |
| 292 __ Move(at, kScratchReg2, i.OutputDoubleRegister()); \ | |
| 293 __ or_(at, at, kScratchReg2); \ | |
| 294 __ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg)); \ | |
| 295 __ cvt_d_l(i.OutputDoubleRegister(), i.OutputDoubleRegister()); \ | |
| 296 __ bind(ool->exit()); \ | |
| 297 __ bind(&done); \ | |
| 298 } while (0) | |
| 299 | |
| 300 | |
| 242 // Assembles an instruction after register allocation, producing machine code. | 301 // Assembles an instruction after register allocation, producing machine code. |
| 243 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 302 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
| 244 MipsOperandConverter i(this, instr); | 303 MipsOperandConverter i(this, instr); |
| 245 InstructionCode opcode = instr->opcode(); | 304 InstructionCode opcode = instr->opcode(); |
| 246 | 305 |
| 247 switch (ArchOpcodeField::decode(opcode)) { | 306 switch (ArchOpcodeField::decode(opcode)) { |
| 248 case kArchCallCodeObject: { | 307 case kArchCallCodeObject: { |
| 249 EnsureSpaceForLazyDeopt(); | 308 EnsureSpaceForLazyDeopt(); |
| 250 if (instr->InputAt(0)->IsImmediate()) { | 309 if (instr->InputAt(0)->IsImmediate()) { |
| 251 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), | 310 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 400 FrameScope scope(masm(), StackFrame::MANUAL); | 459 FrameScope scope(masm(), StackFrame::MANUAL); |
| 401 __ PrepareCallCFunction(0, 2, kScratchReg); | 460 __ PrepareCallCFunction(0, 2, kScratchReg); |
| 402 __ MovToFloatParameters(i.InputDoubleRegister(0), | 461 __ MovToFloatParameters(i.InputDoubleRegister(0), |
| 403 i.InputDoubleRegister(1)); | 462 i.InputDoubleRegister(1)); |
| 404 __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()), | 463 __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()), |
| 405 0, 2); | 464 0, 2); |
| 406 // Move the result in the double result register. | 465 // Move the result in the double result register. |
| 407 __ MovFromFloatResult(i.OutputDoubleRegister()); | 466 __ MovFromFloatResult(i.OutputDoubleRegister()); |
| 408 break; | 467 break; |
| 409 } | 468 } |
| 469 case kMipsFloat64Floor: { | |
| 470 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(floor_l_d, Floor); | |
| 471 break; | |
| 472 } | |
| 473 case kMipsFloat64Ceil: { | |
| 474 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(ceil_l_d, Ceil); | |
| 475 break; | |
| 476 } | |
| 477 case kMipsFloat64RoundTruncate: { | |
| 478 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(trunc_l_d, Truncate); | |
| 479 break; | |
| 480 } | |
| 410 case kMipsSqrtD: { | 481 case kMipsSqrtD: { |
| 411 __ sqrt_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 482 __ sqrt_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
| 412 break; | 483 break; |
| 413 } | 484 } |
| 414 case kMipsCvtSD: { | 485 case kMipsCvtSD: { |
| 415 __ cvt_s_d(i.OutputSingleRegister(), i.InputDoubleRegister(0)); | 486 __ cvt_s_d(i.OutputSingleRegister(), i.InputDoubleRegister(0)); |
| 416 break; | 487 break; |
| 417 } | 488 } |
| 418 case kMipsCvtDS: { | 489 case kMipsCvtDS: { |
| 419 __ cvt_d_s(i.OutputDoubleRegister(), i.InputSingleRegister(0)); | 490 __ cvt_d_s(i.OutputDoubleRegister(), i.InputSingleRegister(0)); |
| (...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1103 } | 1174 } |
| 1104 } | 1175 } |
| 1105 MarkLazyDeoptSite(); | 1176 MarkLazyDeoptSite(); |
| 1106 } | 1177 } |
| 1107 | 1178 |
| 1108 #undef __ | 1179 #undef __ |
| 1109 | 1180 |
| 1110 } // namespace compiler | 1181 } // namespace compiler |
| 1111 } // namespace internal | 1182 } // namespace internal |
| 1112 } // namespace v8 | 1183 } // namespace v8 |
| OLD | NEW |