OLD | NEW |
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 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 __ vldr(dbl_scratch, mem_op.rn(), mem_op.offset()); | 511 __ vldr(dbl_scratch, mem_op.rn(), mem_op.offset()); |
512 return dbl_scratch; | 512 return dbl_scratch; |
513 } | 513 } |
514 UNREACHABLE(); | 514 UNREACHABLE(); |
515 return dbl_scratch; | 515 return dbl_scratch; |
516 } | 516 } |
517 | 517 |
518 | 518 |
519 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { | 519 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { |
520 HConstant* constant = chunk_->LookupConstant(op); | 520 HConstant* constant = chunk_->LookupConstant(op); |
521 ASSERT(chunk_->LookupLiteralRepresentation(op).IsTagged()); | 521 ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged()); |
522 return constant->handle(); | 522 return constant->handle(); |
523 } | 523 } |
524 | 524 |
525 | 525 |
526 bool LCodeGen::IsInteger32(LConstantOperand* op) const { | 526 bool LCodeGen::IsInteger32(LConstantOperand* op) const { |
527 return chunk_->LookupLiteralRepresentation(op).IsInteger32(); | 527 return chunk_->LookupLiteralRepresentation(op).IsInteger32(); |
528 } | 528 } |
529 | 529 |
530 | 530 |
| 531 bool LCodeGen::IsSmi(LConstantOperand* op) const { |
| 532 return chunk_->LookupLiteralRepresentation(op).IsSmi(); |
| 533 } |
| 534 |
| 535 |
531 int LCodeGen::ToInteger32(LConstantOperand* op) const { | 536 int LCodeGen::ToInteger32(LConstantOperand* op) const { |
532 HConstant* constant = chunk_->LookupConstant(op); | 537 HConstant* constant = chunk_->LookupConstant(op); |
533 return constant->Integer32Value(); | 538 return constant->Integer32Value(); |
534 } | 539 } |
535 | 540 |
536 | 541 |
537 double LCodeGen::ToDouble(LConstantOperand* op) const { | 542 double LCodeGen::ToDouble(LConstantOperand* op) const { |
538 HConstant* constant = chunk_->LookupConstant(op); | 543 HConstant* constant = chunk_->LookupConstant(op); |
539 ASSERT(constant->HasDoubleValue()); | 544 ASSERT(constant->HasDoubleValue()); |
540 return constant->DoubleValue(); | 545 return constant->DoubleValue(); |
(...skipping 1660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2201 void LCodeGen::DoDebugBreak(LDebugBreak* instr) { | 2206 void LCodeGen::DoDebugBreak(LDebugBreak* instr) { |
2202 __ stop("LBreak"); | 2207 __ stop("LBreak"); |
2203 } | 2208 } |
2204 | 2209 |
2205 | 2210 |
2206 void LCodeGen::DoBranch(LBranch* instr) { | 2211 void LCodeGen::DoBranch(LBranch* instr) { |
2207 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 2212 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
2208 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 2213 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
2209 | 2214 |
2210 Representation r = instr->hydrogen()->value()->representation(); | 2215 Representation r = instr->hydrogen()->value()->representation(); |
2211 if (r.IsInteger32()) { | 2216 if (r.IsInteger32() || r.IsSmi()) { |
2212 Register reg = ToRegister(instr->value()); | 2217 Register reg = ToRegister(instr->value()); |
2213 __ cmp(reg, Operand::Zero()); | 2218 __ cmp(reg, Operand::Zero()); |
2214 EmitBranch(true_block, false_block, ne); | 2219 EmitBranch(true_block, false_block, ne); |
2215 } else if (r.IsDouble()) { | 2220 } else if (r.IsDouble()) { |
2216 DwVfpRegister reg = ToDoubleRegister(instr->value()); | 2221 DwVfpRegister reg = ToDoubleRegister(instr->value()); |
2217 // Test the double value. Zero and NaN are false. | 2222 // Test the double value. Zero and NaN are false. |
2218 __ VFPCompareAndSetFlags(reg, 0.0); | 2223 __ VFPCompareAndSetFlags(reg, 0.0); |
2219 __ cmp(r0, r0, vs); // If NaN, set the Z flag. | 2224 __ cmp(r0, r0, vs); // If NaN, set the Z flag. |
2220 EmitBranch(true_block, false_block, ne); | 2225 EmitBranch(true_block, false_block, ne); |
2221 } else { | 2226 } else { |
(...skipping 1983 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4205 | 4210 |
4206 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { | 4211 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { |
4207 Representation representation = instr->representation(); | 4212 Representation representation = instr->representation(); |
4208 | 4213 |
4209 Register object = ToRegister(instr->object()); | 4214 Register object = ToRegister(instr->object()); |
4210 Register scratch = scratch0(); | 4215 Register scratch = scratch0(); |
4211 int offset = instr->offset(); | 4216 int offset = instr->offset(); |
4212 | 4217 |
4213 Handle<Map> transition = instr->transition(); | 4218 Handle<Map> transition = instr->transition(); |
4214 | 4219 |
4215 if (FLAG_track_fields && representation.IsSmi()) { | 4220 if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { |
4216 Register value = ToRegister(instr->value()); | |
4217 __ SmiTag(value, value, SetCC); | |
4218 if (!instr->hydrogen()->value()->range()->IsInSmiRange()) { | |
4219 DeoptimizeIf(vs, instr->environment()); | |
4220 } | |
4221 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { | |
4222 Register value = ToRegister(instr->value()); | 4221 Register value = ToRegister(instr->value()); |
4223 if (!instr->hydrogen()->value()->type().IsHeapObject()) { | 4222 if (!instr->hydrogen()->value()->type().IsHeapObject()) { |
4224 __ tst(value, Operand(kSmiTagMask)); | 4223 __ tst(value, Operand(kSmiTagMask)); |
4225 DeoptimizeIf(eq, instr->environment()); | 4224 DeoptimizeIf(eq, instr->environment()); |
4226 } | 4225 } |
4227 } else if (FLAG_track_double_fields && representation.IsDouble()) { | 4226 } else if (FLAG_track_double_fields && representation.IsDouble()) { |
4228 ASSERT(transition.is_null()); | 4227 ASSERT(transition.is_null()); |
4229 ASSERT(instr->is_in_object()); | 4228 ASSERT(instr->is_in_object()); |
4230 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); | 4229 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); |
4231 DwVfpRegister value = ToDoubleRegister(instr->value()); | 4230 DwVfpRegister value = ToDoubleRegister(instr->value()); |
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4698 Register scratch = scratch0(); | 4697 Register scratch = scratch0(); |
4699 __ ldr(scratch, ToMemOperand(input)); | 4698 __ ldr(scratch, ToMemOperand(input)); |
4700 __ vmov(single_scratch, scratch); | 4699 __ vmov(single_scratch, scratch); |
4701 } else { | 4700 } else { |
4702 __ vmov(single_scratch, ToRegister(input)); | 4701 __ vmov(single_scratch, ToRegister(input)); |
4703 } | 4702 } |
4704 __ vcvt_f64_s32(ToDoubleRegister(output), single_scratch); | 4703 __ vcvt_f64_s32(ToDoubleRegister(output), single_scratch); |
4705 } | 4704 } |
4706 | 4705 |
4707 | 4706 |
| 4707 void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) { |
| 4708 LOperand* input = instr->value(); |
| 4709 ASSERT(input->IsRegister()); |
| 4710 LOperand* output = instr->result(); |
| 4711 ASSERT(output->IsRegister()); |
| 4712 __ SmiTag(ToRegister(output), ToRegister(input), SetCC); |
| 4713 if (!instr->hydrogen()->value()->HasRange() || |
| 4714 !instr->hydrogen()->value()->range()->IsInSmiRange()) { |
| 4715 DeoptimizeIf(vs, instr->environment()); |
| 4716 } |
| 4717 } |
| 4718 |
| 4719 |
4708 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { | 4720 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { |
4709 LOperand* input = instr->value(); | 4721 LOperand* input = instr->value(); |
4710 LOperand* output = instr->result(); | 4722 LOperand* output = instr->result(); |
4711 | 4723 |
4712 SwVfpRegister flt_scratch = double_scratch0().low(); | 4724 SwVfpRegister flt_scratch = double_scratch0().low(); |
4713 __ vmov(flt_scratch, ToRegister(input)); | 4725 __ vmov(flt_scratch, ToRegister(input)); |
4714 __ vcvt_f64_u32(ToDoubleRegister(output), flt_scratch); | 4726 __ vcvt_f64_u32(ToDoubleRegister(output), flt_scratch); |
4715 } | 4727 } |
4716 | 4728 |
4717 | 4729 |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5120 } | 5132 } |
5121 | 5133 |
5122 | 5134 |
5123 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { | 5135 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { |
5124 Register result_reg = ToRegister(instr->result()); | 5136 Register result_reg = ToRegister(instr->result()); |
5125 Register scratch1 = scratch0(); | 5137 Register scratch1 = scratch0(); |
5126 Register scratch2 = ToRegister(instr->temp()); | 5138 Register scratch2 = ToRegister(instr->temp()); |
5127 DwVfpRegister double_input = ToDoubleRegister(instr->value()); | 5139 DwVfpRegister double_input = ToDoubleRegister(instr->value()); |
5128 DwVfpRegister double_scratch = double_scratch0(); | 5140 DwVfpRegister double_scratch = double_scratch0(); |
5129 | 5141 |
5130 Label done; | 5142 if (instr->truncating()) { |
| 5143 Register scratch3 = ToRegister(instr->temp2()); |
| 5144 __ ECMAToInt32(result_reg, double_input, |
| 5145 scratch1, scratch2, scratch3, double_scratch); |
| 5146 } else { |
| 5147 __ TryDoubleToInt32Exact(result_reg, double_input, double_scratch); |
| 5148 // Deoptimize if the input wasn't a int32 (inside a double). |
| 5149 DeoptimizeIf(ne, instr->environment()); |
| 5150 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 5151 Label done; |
| 5152 __ cmp(result_reg, Operand::Zero()); |
| 5153 __ b(ne, &done); |
| 5154 __ vmov(scratch1, double_input.high()); |
| 5155 __ tst(scratch1, Operand(HeapNumber::kSignMask)); |
| 5156 DeoptimizeIf(ne, instr->environment()); |
| 5157 __ bind(&done); |
| 5158 } |
| 5159 } |
| 5160 } |
| 5161 |
| 5162 |
| 5163 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { |
| 5164 Register result_reg = ToRegister(instr->result()); |
| 5165 Register scratch1 = scratch0(); |
| 5166 Register scratch2 = ToRegister(instr->temp()); |
| 5167 DwVfpRegister double_input = ToDoubleRegister(instr->value()); |
| 5168 DwVfpRegister double_scratch = double_scratch0(); |
5131 | 5169 |
5132 if (instr->truncating()) { | 5170 if (instr->truncating()) { |
5133 Register scratch3 = ToRegister(instr->temp2()); | 5171 Register scratch3 = ToRegister(instr->temp2()); |
5134 __ ECMAToInt32(result_reg, double_input, | 5172 __ ECMAToInt32(result_reg, double_input, |
5135 scratch1, scratch2, scratch3, double_scratch); | 5173 scratch1, scratch2, scratch3, double_scratch); |
5136 } else { | 5174 } else { |
5137 __ TryDoubleToInt32Exact(result_reg, double_input, double_scratch); | 5175 __ TryDoubleToInt32Exact(result_reg, double_input, double_scratch); |
5138 // Deoptimize if the input wasn't a int32 (inside a double). | 5176 // Deoptimize if the input wasn't a int32 (inside a double). |
5139 DeoptimizeIf(ne, instr->environment()); | 5177 DeoptimizeIf(ne, instr->environment()); |
| 5178 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 5179 Label done; |
| 5180 __ cmp(result_reg, Operand::Zero()); |
| 5181 __ b(ne, &done); |
| 5182 __ vmov(scratch1, double_input.high()); |
| 5183 __ tst(scratch1, Operand(HeapNumber::kSignMask)); |
| 5184 DeoptimizeIf(ne, instr->environment()); |
| 5185 __ bind(&done); |
| 5186 } |
5140 } | 5187 } |
5141 __ bind(&done); | 5188 __ SmiTag(result_reg, SetCC); |
| 5189 DeoptimizeIf(vs, instr->environment()); |
5142 } | 5190 } |
5143 | 5191 |
5144 | 5192 |
5145 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { | 5193 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { |
5146 LOperand* input = instr->value(); | 5194 LOperand* input = instr->value(); |
5147 __ tst(ToRegister(input), Operand(kSmiTagMask)); | 5195 __ tst(ToRegister(input), Operand(kSmiTagMask)); |
5148 DeoptimizeIf(ne, instr->environment()); | 5196 DeoptimizeIf(ne, instr->environment()); |
5149 } | 5197 } |
5150 | 5198 |
5151 | 5199 |
(...skipping 758 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5910 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); | 5958 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); |
5911 __ ldr(result, FieldMemOperand(scratch, | 5959 __ ldr(result, FieldMemOperand(scratch, |
5912 FixedArray::kHeaderSize - kPointerSize)); | 5960 FixedArray::kHeaderSize - kPointerSize)); |
5913 __ bind(&done); | 5961 __ bind(&done); |
5914 } | 5962 } |
5915 | 5963 |
5916 | 5964 |
5917 #undef __ | 5965 #undef __ |
5918 | 5966 |
5919 } } // namespace v8::internal | 5967 } } // namespace v8::internal |
OLD | NEW |