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

Side by Side Diff: src/mips/lithium-codegen-mips.cc

Issue 14046026: Merged r13848, r13849, r13944, r14013, r14099, r14101, r14145, r14158, r14196 into 3.17 branch. (Closed) Base URL: https://v8.googlecode.com/svn/branches/3.17
Patch Set: Created 7 years, 8 months 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 | Annotate | Revision Log
« no previous file with comments | « src/mips/constants-mips.h ('k') | src/mips/macro-assembler-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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 Safepoint::DeoptMode deopt_mode_; 58 Safepoint::DeoptMode deopt_mode_;
59 }; 59 };
60 60
61 61
62 #define __ masm()-> 62 #define __ masm()->
63 63
64 bool LCodeGen::GenerateCode() { 64 bool LCodeGen::GenerateCode() {
65 HPhase phase("Z_Code generation", chunk()); 65 HPhase phase("Z_Code generation", chunk());
66 ASSERT(is_unused()); 66 ASSERT(is_unused());
67 status_ = GENERATING; 67 status_ = GENERATING;
68 CpuFeatures::Scope scope(FPU);
69 68
70 // Open a frame scope to indicate that there is a frame on the stack. The 69 // Open a frame scope to indicate that there is a frame on the stack. The
71 // NONE indicates that the scope shouldn't actually generate code to set up 70 // NONE indicates that the scope shouldn't actually generate code to set up
72 // the frame (that is done in GeneratePrologue). 71 // the frame (that is done in GeneratePrologue).
73 FrameScope frame_scope(masm_, StackFrame::NONE); 72 FrameScope frame_scope(masm_, StackFrame::NONE);
74 73
75 return GeneratePrologue() && 74 return GeneratePrologue() &&
76 GenerateBody() && 75 GenerateBody() &&
77 GenerateDeferredCode() && 76 GenerateDeferredCode() &&
78 GenerateDeoptJumpTable() && 77 GenerateDeoptJumpTable() &&
(...skipping 1126 matching lines...) Expand 10 before | Expand all | Expand 10 after
1205 1204
1206 1205
1207 void LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) { 1206 void LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) {
1208 DoubleRegister addend = ToDoubleRegister(instr->addend()); 1207 DoubleRegister addend = ToDoubleRegister(instr->addend());
1209 DoubleRegister multiplier = ToDoubleRegister(instr->multiplier()); 1208 DoubleRegister multiplier = ToDoubleRegister(instr->multiplier());
1210 DoubleRegister multiplicand = ToDoubleRegister(instr->multiplicand()); 1209 DoubleRegister multiplicand = ToDoubleRegister(instr->multiplicand());
1211 1210
1212 // This is computed in-place. 1211 // This is computed in-place.
1213 ASSERT(addend.is(ToDoubleRegister(instr->result()))); 1212 ASSERT(addend.is(ToDoubleRegister(instr->result())));
1214 1213
1214 CpuFeatures::Scope scope(FPU);
1215 __ madd_d(addend, addend, multiplier, multiplicand); 1215 __ madd_d(addend, addend, multiplier, multiplicand);
1216 } 1216 }
1217 1217
1218 1218
1219 void LCodeGen::DoMulI(LMulI* instr) { 1219 void LCodeGen::DoMulI(LMulI* instr) {
1220 Register scratch = scratch0(); 1220 Register scratch = scratch0();
1221 Register result = ToRegister(instr->result()); 1221 Register result = ToRegister(instr->result());
1222 // Note that result may alias left. 1222 // Note that result may alias left.
1223 Register left = ToRegister(instr->left()); 1223 Register left = ToRegister(instr->left());
1224 LOperand* right_op = instr->right(); 1224 LOperand* right_op = instr->right();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1261 uint32_t constant_abs = (constant + mask) ^ mask; 1261 uint32_t constant_abs = (constant + mask) ^ mask;
1262 1262
1263 if (IsPowerOf2(constant_abs) || 1263 if (IsPowerOf2(constant_abs) ||
1264 IsPowerOf2(constant_abs - 1) || 1264 IsPowerOf2(constant_abs - 1) ||
1265 IsPowerOf2(constant_abs + 1)) { 1265 IsPowerOf2(constant_abs + 1)) {
1266 if (IsPowerOf2(constant_abs)) { 1266 if (IsPowerOf2(constant_abs)) {
1267 int32_t shift = WhichPowerOf2(constant_abs); 1267 int32_t shift = WhichPowerOf2(constant_abs);
1268 __ sll(result, left, shift); 1268 __ sll(result, left, shift);
1269 } else if (IsPowerOf2(constant_abs - 1)) { 1269 } else if (IsPowerOf2(constant_abs - 1)) {
1270 int32_t shift = WhichPowerOf2(constant_abs - 1); 1270 int32_t shift = WhichPowerOf2(constant_abs - 1);
1271 __ sll(result, left, shift); 1271 __ sll(scratch, left, shift);
1272 __ Addu(result, result, left); 1272 __ Addu(result, scratch, left);
1273 } else if (IsPowerOf2(constant_abs + 1)) { 1273 } else if (IsPowerOf2(constant_abs + 1)) {
1274 int32_t shift = WhichPowerOf2(constant_abs + 1); 1274 int32_t shift = WhichPowerOf2(constant_abs + 1);
1275 __ sll(result, left, shift); 1275 __ sll(scratch, left, shift);
1276 __ Subu(result, result, left); 1276 __ Subu(result, scratch, left);
1277 } 1277 }
1278 1278
1279 // Correct the sign of the result is the constant is negative. 1279 // Correct the sign of the result is the constant is negative.
1280 if (constant < 0) { 1280 if (constant < 0) {
1281 __ Subu(result, zero_reg, result); 1281 __ Subu(result, zero_reg, result);
1282 } 1282 }
1283 1283
1284 } else { 1284 } else {
1285 // Generate standard code. 1285 // Generate standard code.
1286 __ li(at, constant); 1286 __ li(at, constant);
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after
1819 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1819 int false_block = chunk_->LookupDestination(instr->false_block_id());
1820 1820
1821 Representation r = instr->hydrogen()->value()->representation(); 1821 Representation r = instr->hydrogen()->value()->representation();
1822 if (r.IsInteger32()) { 1822 if (r.IsInteger32()) {
1823 Register reg = ToRegister(instr->value()); 1823 Register reg = ToRegister(instr->value());
1824 EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg)); 1824 EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg));
1825 } else if (r.IsDouble()) { 1825 } else if (r.IsDouble()) {
1826 CpuFeatures::Scope scope(FPU); 1826 CpuFeatures::Scope scope(FPU);
1827 DoubleRegister reg = ToDoubleRegister(instr->value()); 1827 DoubleRegister reg = ToDoubleRegister(instr->value());
1828 // Test the double value. Zero and NaN are false. 1828 // Test the double value. Zero and NaN are false.
1829 EmitBranchF(true_block, false_block, ne, reg, kDoubleRegZero); 1829 EmitBranchF(true_block, false_block, nue, reg, kDoubleRegZero);
1830 } else { 1830 } else {
1831 ASSERT(r.IsTagged()); 1831 ASSERT(r.IsTagged());
1832 Register reg = ToRegister(instr->value()); 1832 Register reg = ToRegister(instr->value());
1833 HType type = instr->hydrogen()->value()->type(); 1833 HType type = instr->hydrogen()->value()->type();
1834 if (type.IsBoolean()) { 1834 if (type.IsBoolean()) {
1835 __ LoadRoot(at, Heap::kTrueValueRootIndex); 1835 __ LoadRoot(at, Heap::kTrueValueRootIndex);
1836 EmitBranch(true_block, false_block, eq, reg, Operand(at)); 1836 EmitBranch(true_block, false_block, eq, reg, Operand(at));
1837 } else if (type.IsSmi()) { 1837 } else if (type.IsSmi()) {
1838 EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg)); 1838 EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg));
1839 } else { 1839 } else {
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after
2520 Token::Value op = instr->op(); 2520 Token::Value op = instr->op();
2521 2521
2522 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); 2522 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op);
2523 CallCode(ic, RelocInfo::CODE_TARGET, instr); 2523 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2524 // On MIPS there is no need for a "no inlined smi code" marker (nop). 2524 // On MIPS there is no need for a "no inlined smi code" marker (nop).
2525 2525
2526 Condition condition = ComputeCompareCondition(op); 2526 Condition condition = ComputeCompareCondition(op);
2527 // A minor optimization that relies on LoadRoot always emitting one 2527 // A minor optimization that relies on LoadRoot always emitting one
2528 // instruction. 2528 // instruction.
2529 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm()); 2529 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm());
2530 Label done; 2530 Label done, check;
2531 __ Branch(USE_DELAY_SLOT, &done, condition, v0, Operand(zero_reg)); 2531 __ Branch(USE_DELAY_SLOT, &done, condition, v0, Operand(zero_reg));
2532 __ bind(&check);
2532 __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex); 2533 __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex);
2534 ASSERT_EQ(1, masm()->InstructionsGeneratedSince(&check));
2533 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex); 2535 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex);
2534 ASSERT_EQ(3, masm()->InstructionsGeneratedSince(&done));
2535 __ bind(&done); 2536 __ bind(&done);
2536 } 2537 }
2537 2538
2538 2539
2539 void LCodeGen::DoReturn(LReturn* instr) { 2540 void LCodeGen::DoReturn(LReturn* instr) {
2540 if (FLAG_trace && info()->IsOptimizing()) { 2541 if (FLAG_trace && info()->IsOptimizing()) {
2541 // Push the return value on the stack as the parameter. 2542 // Push the return value on the stack as the parameter.
2542 // Runtime::TraceExit returns its parameter in v0. 2543 // Runtime::TraceExit returns its parameter in v0.
2543 __ push(v0); 2544 __ push(v0);
2544 __ CallRuntime(Runtime::kTraceExit, 1); 2545 __ CallRuntime(Runtime::kTraceExit, 1);
(...skipping 954 matching lines...) Expand 10 before | Expand all | Expand 10 after
3499 } 3500 }
3500 3501
3501 3502
3502 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { 3503 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) {
3503 Register input = ToRegister(instr->value()); 3504 Register input = ToRegister(instr->value());
3504 Register result = ToRegister(instr->result()); 3505 Register result = ToRegister(instr->result());
3505 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); 3506 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
3506 Label done; 3507 Label done;
3507 __ Branch(USE_DELAY_SLOT, &done, ge, input, Operand(zero_reg)); 3508 __ Branch(USE_DELAY_SLOT, &done, ge, input, Operand(zero_reg));
3508 __ mov(result, input); 3509 __ mov(result, input);
3509 ASSERT_EQ(2, masm()->InstructionsGeneratedSince(&done));
3510 __ subu(result, zero_reg, input);
3511 // Overflow if result is still negative, i.e. 0x80000000. 3510 // Overflow if result is still negative, i.e. 0x80000000.
3512 DeoptimizeIf(lt, instr->environment(), result, Operand(zero_reg)); 3511 DeoptimizeIf(lt, instr->environment(), result, Operand(zero_reg));
3513 __ bind(&done); 3512 __ bind(&done);
3514 } 3513 }
3515 3514
3516 3515
3517 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { 3516 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
3518 CpuFeatures::Scope scope(FPU); 3517 CpuFeatures::Scope scope(FPU);
3519 // Class for deferred case. 3518 // Class for deferred case.
3520 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { 3519 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
(...skipping 1007 matching lines...) Expand 10 before | Expand all | Expand 10 after
4528 4527
4529 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); 4528 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
4530 __ Branch(deferred->entry(), hi, reg, Operand(Smi::kMaxValue)); 4529 __ Branch(deferred->entry(), hi, reg, Operand(Smi::kMaxValue));
4531 __ SmiTag(reg, reg); 4530 __ SmiTag(reg, reg);
4532 __ bind(deferred->exit()); 4531 __ bind(deferred->exit());
4533 } 4532 }
4534 4533
4535 4534
4536 // Convert unsigned integer with specified number of leading zeroes in binary 4535 // Convert unsigned integer with specified number of leading zeroes in binary
4537 // representation to IEEE 754 double. 4536 // representation to IEEE 754 double.
4538 // Integer to convert is passed in register hiword. 4537 // Integer to convert is passed in register src.
4539 // Resulting double is returned in registers hiword:loword. 4538 // Resulting double is returned in registers hiword:loword.
4540 // This functions does not work correctly for 0. 4539 // This functions does not work correctly for 0.
4541 static void GenerateUInt2Double(MacroAssembler* masm, 4540 static void GenerateUInt2Double(MacroAssembler* masm,
4541 Register src,
4542 Register hiword, 4542 Register hiword,
4543 Register loword, 4543 Register loword,
4544 Register scratch, 4544 Register scratch,
4545 int leading_zeroes) { 4545 int leading_zeroes) {
4546 const int meaningful_bits = kBitsPerInt - leading_zeroes - 1; 4546 const int meaningful_bits = kBitsPerInt - leading_zeroes - 1;
4547 const int biased_exponent = HeapNumber::kExponentBias + meaningful_bits; 4547 const int biased_exponent = HeapNumber::kExponentBias + meaningful_bits;
4548 4548
4549 const int mantissa_shift_for_hi_word = 4549 const int mantissa_shift_for_hi_word =
4550 meaningful_bits - HeapNumber::kMantissaBitsInTopWord; 4550 meaningful_bits - HeapNumber::kMantissaBitsInTopWord;
4551 const int mantissa_shift_for_lo_word = 4551 const int mantissa_shift_for_lo_word =
4552 kBitsPerInt - mantissa_shift_for_hi_word; 4552 kBitsPerInt - mantissa_shift_for_hi_word;
4553 masm->li(scratch, Operand(biased_exponent << HeapNumber::kExponentShift)); 4553 masm->li(scratch, Operand(biased_exponent << HeapNumber::kExponentShift));
4554 if (mantissa_shift_for_hi_word > 0) { 4554 if (mantissa_shift_for_hi_word > 0) {
4555 masm->sll(loword, hiword, mantissa_shift_for_lo_word); 4555 masm->sll(loword, src, mantissa_shift_for_lo_word);
4556 masm->srl(hiword, hiword, mantissa_shift_for_hi_word); 4556 masm->srl(hiword, src, mantissa_shift_for_hi_word);
4557 masm->Or(hiword, scratch, hiword); 4557 masm->Or(hiword, scratch, hiword);
4558 } else { 4558 } else {
4559 masm->mov(loword, zero_reg); 4559 masm->mov(loword, zero_reg);
4560 masm->sll(hiword, hiword, mantissa_shift_for_hi_word); 4560 masm->sll(hiword, src, mantissa_shift_for_hi_word);
4561 masm->Or(hiword, scratch, hiword); 4561 masm->Or(hiword, scratch, hiword);
4562 } 4562 }
4563 4563
4564 // If least significant bit of biased exponent was not 1 it was corrupted 4564 // If least significant bit of biased exponent was not 1 it was corrupted
4565 // by most significant bit of mantissa so we should fix that. 4565 // by most significant bit of mantissa so we should fix that.
4566 if (!(biased_exponent & 1)) { 4566 if (!(biased_exponent & 1)) {
4567 masm->li(scratch, 1 << HeapNumber::kExponentShift); 4567 masm->li(scratch, 1 << HeapNumber::kExponentShift);
4568 masm->nor(scratch, scratch, scratch); 4568 masm->nor(scratch, scratch, scratch);
4569 masm->and_(hiword, hiword, scratch); 4569 masm->and_(hiword, hiword, scratch);
4570 } 4570 }
(...skipping 30 matching lines...) Expand all
4601 FloatingPointHelper::ConvertIntToDouble(masm(), src, dest, f0, 4601 FloatingPointHelper::ConvertIntToDouble(masm(), src, dest, f0,
4602 sfpd_lo, sfpd_hi, 4602 sfpd_lo, sfpd_hi,
4603 scratch0(), f2); 4603 scratch0(), f2);
4604 } 4604 }
4605 } else { 4605 } else {
4606 if (CpuFeatures::IsSupported(FPU)) { 4606 if (CpuFeatures::IsSupported(FPU)) {
4607 CpuFeatures::Scope scope(FPU); 4607 CpuFeatures::Scope scope(FPU);
4608 __ mtc1(src, dbl_scratch); 4608 __ mtc1(src, dbl_scratch);
4609 __ Cvt_d_uw(dbl_scratch, dbl_scratch, f22); 4609 __ Cvt_d_uw(dbl_scratch, dbl_scratch, f22);
4610 } else { 4610 } else {
4611 Label no_leading_zero, done; 4611 Label no_leading_zero, convert_done;
4612 __ And(at, src, Operand(0x80000000)); 4612 __ And(at, src, Operand(0x80000000));
4613 __ Branch(&no_leading_zero, ne, at, Operand(zero_reg)); 4613 __ Branch(&no_leading_zero, ne, at, Operand(zero_reg));
4614 4614
4615 // Integer has one leading zeros. 4615 // Integer has one leading zeros.
4616 GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, t0, 1); 4616 GenerateUInt2Double(masm(), src, sfpd_hi, sfpd_lo, t0, 1);
4617 __ Branch(&done); 4617 __ Branch(&convert_done);
4618 4618
4619 __ bind(&no_leading_zero); 4619 __ bind(&no_leading_zero);
4620 GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, t0, 0); 4620 GenerateUInt2Double(masm(), src, sfpd_hi, sfpd_lo, t0, 0);
4621 __ Branch(&done); 4621 __ bind(&convert_done);
4622 } 4622 }
4623 } 4623 }
4624 4624
4625 if (FLAG_inline_new) { 4625 if (FLAG_inline_new) {
4626 __ LoadRoot(scratch0(), Heap::kHeapNumberMapRootIndex); 4626 __ LoadRoot(scratch0(), Heap::kHeapNumberMapRootIndex);
4627 __ AllocateHeapNumber(t1, a3, t0, scratch0(), &slow, DONT_TAG_RESULT); 4627 __ AllocateHeapNumber(t1, a3, t0, scratch0(), &slow, DONT_TAG_RESULT);
4628 __ Move(dst, t1); 4628 __ Move(dst, t1);
4629 __ Branch(&done); 4629 __ Branch(&done);
4630 } 4630 }
4631 4631
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
4854 4854
4855 Label done; 4855 Label done;
4856 4856
4857 // The input is a tagged HeapObject. 4857 // The input is a tagged HeapObject.
4858 // Heap number map check. 4858 // Heap number map check.
4859 __ lw(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 4859 __ lw(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset));
4860 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 4860 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
4861 // This 'at' value and scratch1 map value are used for tests in both clauses 4861 // This 'at' value and scratch1 map value are used for tests in both clauses
4862 // of the if. 4862 // of the if.
4863 4863
4864 CpuFeatures::Scope scope(FPU);
4864 if (instr->truncating()) { 4865 if (instr->truncating()) {
4865 CpuFeatures::Scope scope(FPU);
4866 Register scratch3 = ToRegister(instr->temp2()); 4866 Register scratch3 = ToRegister(instr->temp2());
4867 FPURegister single_scratch = double_scratch.low(); 4867 FPURegister single_scratch = double_scratch.low();
4868 ASSERT(!scratch3.is(input_reg) && 4868 ASSERT(!scratch3.is(input_reg) &&
4869 !scratch3.is(scratch1) && 4869 !scratch3.is(scratch1) &&
4870 !scratch3.is(scratch2)); 4870 !scratch3.is(scratch2));
4871 // Performs a truncating conversion of a floating point number as used by 4871 // Performs a truncating conversion of a floating point number as used by
4872 // the JS bitwise operations. 4872 // the JS bitwise operations.
4873 Label heap_number; 4873 Label heap_number;
4874 __ Branch(&heap_number, eq, scratch1, Operand(at)); // HeapNumber map? 4874 __ Branch(&heap_number, eq, scratch1, Operand(at)); // HeapNumber map?
4875 // Check for undefined. Undefined is converted to zero for truncating 4875 // Check for undefined. Undefined is converted to zero for truncating
(...skipping 1188 matching lines...) Expand 10 before | Expand all | Expand 10 after
6064 __ Subu(scratch, result, scratch); 6064 __ Subu(scratch, result, scratch);
6065 __ lw(result, FieldMemOperand(scratch, 6065 __ lw(result, FieldMemOperand(scratch,
6066 FixedArray::kHeaderSize - kPointerSize)); 6066 FixedArray::kHeaderSize - kPointerSize));
6067 __ bind(&done); 6067 __ bind(&done);
6068 } 6068 }
6069 6069
6070 6070
6071 #undef __ 6071 #undef __
6072 6072
6073 } } // namespace v8::internal 6073 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/mips/constants-mips.h ('k') | src/mips/macro-assembler-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698