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 1771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1782 __ PrepareCallCFunction(2, scratch); | 1782 __ PrepareCallCFunction(2, scratch); |
1783 __ li(a1, Operand(index)); | 1783 __ li(a1, Operand(index)); |
1784 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); | 1784 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); |
1785 __ bind(&done); | 1785 __ bind(&done); |
1786 } | 1786 } |
1787 } | 1787 } |
1788 | 1788 |
1789 | 1789 |
1790 void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) { | 1790 void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) { |
1791 Register string = ToRegister(instr->string()); | 1791 Register string = ToRegister(instr->string()); |
1792 LOperand* index_op = instr->index(); | 1792 Register index = ToRegister(instr->index()); |
1793 Register value = ToRegister(instr->value()); | 1793 Register value = ToRegister(instr->value()); |
1794 Register scratch = scratch0(); | 1794 Register scratch = scratch0(); |
1795 String::Encoding encoding = instr->encoding(); | 1795 String::Encoding encoding = instr->encoding(); |
1796 | 1796 |
1797 if (FLAG_debug_code) { | 1797 if (FLAG_debug_code) { |
1798 __ lw(scratch, FieldMemOperand(string, HeapObject::kMapOffset)); | 1798 __ lw(at, FieldMemOperand(string, HeapObject::kMapOffset)); |
1799 __ lbu(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset)); | 1799 __ lbu(at, FieldMemOperand(at, Map::kInstanceTypeOffset)); |
1800 | 1800 |
1801 __ And(scratch, scratch, | 1801 __ And(at, at, Operand(kStringRepresentationMask | kStringEncodingMask)); |
1802 Operand(kStringRepresentationMask | kStringEncodingMask)); | |
1803 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; | 1802 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; |
1804 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; | 1803 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; |
1805 __ Subu(at, scratch, Operand(encoding == String::ONE_BYTE_ENCODING | 1804 __ Subu(at, at, Operand(encoding == String::ONE_BYTE_ENCODING |
1806 ? one_byte_seq_type : two_byte_seq_type)); | 1805 ? one_byte_seq_type : two_byte_seq_type)); |
1807 __ Check(eq, kUnexpectedStringType, at, Operand(zero_reg)); | 1806 __ Check(eq, kUnexpectedStringType, at, Operand(zero_reg)); |
1808 } | 1807 } |
1809 | 1808 |
1810 if (index_op->IsConstantOperand()) { | 1809 __ Addu(scratch, |
1811 int constant_index = ToInteger32(LConstantOperand::cast(index_op)); | 1810 string, |
1812 if (encoding == String::ONE_BYTE_ENCODING) { | 1811 Operand(SeqString::kHeaderSize - kHeapObjectTag)); |
1813 __ sb(value, | 1812 if (encoding == String::ONE_BYTE_ENCODING) { |
1814 FieldMemOperand(string, SeqString::kHeaderSize + constant_index)); | 1813 __ Addu(at, scratch, index); |
1815 } else { | 1814 __ sb(value, MemOperand(at)); |
1816 __ sh(value, | |
1817 FieldMemOperand(string, SeqString::kHeaderSize + constant_index * 2)); | |
1818 } | |
1819 } else { | 1815 } else { |
1820 Register index = ToRegister(index_op); | 1816 __ sll(at, index, 1); |
1821 if (encoding == String::ONE_BYTE_ENCODING) { | 1817 __ Addu(at, scratch, at); |
1822 __ Addu(scratch, string, Operand(index)); | 1818 __ sh(value, MemOperand(at)); |
1823 __ sb(value, FieldMemOperand(scratch, SeqString::kHeaderSize)); | |
1824 } else { | |
1825 __ sll(scratch, index, 1); | |
1826 __ Addu(scratch, string, scratch); | |
1827 __ sh(value, FieldMemOperand(scratch, SeqString::kHeaderSize)); | |
1828 } | |
1829 } | 1819 } |
1830 } | 1820 } |
1831 | 1821 |
1832 | 1822 |
1833 void LCodeGen::DoThrow(LThrow* instr) { | 1823 void LCodeGen::DoThrow(LThrow* instr) { |
1834 Register input_reg = EmitLoadRegister(instr->value(), at); | 1824 Register input_reg = EmitLoadRegister(instr->value(), at); |
1835 __ push(input_reg); | 1825 __ push(input_reg); |
1836 CallRuntime(Runtime::kThrow, 1, instr); | 1826 CallRuntime(Runtime::kThrow, 1, instr); |
1837 | 1827 |
1838 if (FLAG_debug_code) { | 1828 if (FLAG_debug_code) { |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2060 __ BranchF(chunk_->GetAssemblyLabel(false_block), NULL, | 2050 __ BranchF(chunk_->GetAssemblyLabel(false_block), NULL, |
2061 condition, src1, src2); | 2051 condition, src1, src2); |
2062 } | 2052 } |
2063 | 2053 |
2064 | 2054 |
2065 void LCodeGen::DoDebugBreak(LDebugBreak* instr) { | 2055 void LCodeGen::DoDebugBreak(LDebugBreak* instr) { |
2066 __ stop("LDebugBreak"); | 2056 __ stop("LDebugBreak"); |
2067 } | 2057 } |
2068 | 2058 |
2069 | 2059 |
| 2060 void LCodeGen::DoIsNumberAndBranch(LIsNumberAndBranch* instr) { |
| 2061 Representation r = instr->hydrogen()->value()->representation(); |
| 2062 if (r.IsSmiOrInteger32() || r.IsDouble()) { |
| 2063 EmitBranch(instr, al, zero_reg, Operand(zero_reg)); |
| 2064 } else { |
| 2065 ASSERT(r.IsTagged()); |
| 2066 Register reg = ToRegister(instr->value()); |
| 2067 HType type = instr->hydrogen()->value()->type(); |
| 2068 if (type.IsTaggedNumber()) { |
| 2069 EmitBranch(instr, al, zero_reg, Operand(zero_reg)); |
| 2070 } |
| 2071 __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); |
| 2072 __ lw(scratch0(), FieldMemOperand(reg, HeapObject::kMapOffset)); |
| 2073 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); |
| 2074 EmitBranch(instr, eq, scratch0(), Operand(at)); |
| 2075 } |
| 2076 } |
| 2077 |
| 2078 |
2070 void LCodeGen::DoBranch(LBranch* instr) { | 2079 void LCodeGen::DoBranch(LBranch* instr) { |
2071 Representation r = instr->hydrogen()->value()->representation(); | 2080 Representation r = instr->hydrogen()->value()->representation(); |
2072 if (r.IsInteger32() || r.IsSmi()) { | 2081 if (r.IsInteger32() || r.IsSmi()) { |
2073 ASSERT(!info()->IsStub()); | 2082 ASSERT(!info()->IsStub()); |
2074 Register reg = ToRegister(instr->value()); | 2083 Register reg = ToRegister(instr->value()); |
2075 EmitBranch(instr, ne, reg, Operand(zero_reg)); | 2084 EmitBranch(instr, ne, reg, Operand(zero_reg)); |
2076 } else if (r.IsDouble()) { | 2085 } else if (r.IsDouble()) { |
2077 ASSERT(!info()->IsStub()); | 2086 ASSERT(!info()->IsStub()); |
2078 DoubleRegister reg = ToDoubleRegister(instr->value()); | 2087 DoubleRegister reg = ToDoubleRegister(instr->value()); |
2079 // Test the double value. Zero and NaN are false. | 2088 // Test the double value. Zero and NaN are false. |
(...skipping 2145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4225 } else { | 4234 } else { |
4226 key = ToRegister(instr->key()); | 4235 key = ToRegister(instr->key()); |
4227 } | 4236 } |
4228 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 4237 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
4229 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 4238 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
4230 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 4239 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
4231 int additional_offset = instr->additional_index() << element_size_shift; | 4240 int additional_offset = instr->additional_index() << element_size_shift; |
4232 | 4241 |
4233 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 4242 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
4234 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 4243 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
4235 Register address = scratch0(); | |
4236 FPURegister value(ToDoubleRegister(instr->value())); | 4244 FPURegister value(ToDoubleRegister(instr->value())); |
4237 if (key_is_constant) { | 4245 if (key_is_constant) { |
4238 if (constant_key != 0) { | 4246 __ Addu(scratch0(), external_pointer, constant_key << |
4239 __ Addu(address, external_pointer, | 4247 element_size_shift); |
4240 Operand(constant_key << element_size_shift)); | |
4241 } else { | |
4242 address = external_pointer; | |
4243 } | |
4244 } else { | 4248 } else { |
4245 __ sll(address, key, shift_size); | 4249 __ sll(scratch0(), key, shift_size); |
4246 __ Addu(address, external_pointer, address); | 4250 __ Addu(scratch0(), scratch0(), external_pointer); |
4247 } | 4251 } |
4248 | 4252 |
4249 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 4253 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
4250 __ cvt_s_d(double_scratch0(), value); | 4254 __ cvt_s_d(double_scratch0(), value); |
4251 __ swc1(double_scratch0(), MemOperand(address, additional_offset)); | 4255 __ swc1(double_scratch0(), MemOperand(scratch0(), additional_offset)); |
4252 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS | 4256 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS |
4253 __ sdc1(value, MemOperand(address, additional_offset)); | 4257 __ sdc1(value, MemOperand(scratch0(), additional_offset)); |
4254 } | 4258 } |
4255 } else { | 4259 } else { |
4256 Register value(ToRegister(instr->value())); | 4260 Register value(ToRegister(instr->value())); |
4257 MemOperand mem_operand = PrepareKeyedOperand( | 4261 MemOperand mem_operand = PrepareKeyedOperand( |
4258 key, external_pointer, key_is_constant, constant_key, | 4262 key, external_pointer, key_is_constant, constant_key, |
4259 element_size_shift, shift_size, | 4263 element_size_shift, shift_size, |
4260 instr->additional_index(), additional_offset); | 4264 instr->additional_index(), additional_offset); |
4261 switch (elements_kind) { | 4265 switch (elements_kind) { |
4262 case EXTERNAL_PIXEL_ELEMENTS: | 4266 case EXTERNAL_PIXEL_ELEMENTS: |
4263 case EXTERNAL_BYTE_ELEMENTS: | 4267 case EXTERNAL_BYTE_ELEMENTS: |
(...skipping 21 matching lines...) Expand all Loading... |
4285 UNREACHABLE(); | 4289 UNREACHABLE(); |
4286 break; | 4290 break; |
4287 } | 4291 } |
4288 } | 4292 } |
4289 } | 4293 } |
4290 | 4294 |
4291 | 4295 |
4292 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { | 4296 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { |
4293 DoubleRegister value = ToDoubleRegister(instr->value()); | 4297 DoubleRegister value = ToDoubleRegister(instr->value()); |
4294 Register elements = ToRegister(instr->elements()); | 4298 Register elements = ToRegister(instr->elements()); |
| 4299 Register key = no_reg; |
4295 Register scratch = scratch0(); | 4300 Register scratch = scratch0(); |
4296 DoubleRegister double_scratch = double_scratch0(); | |
4297 bool key_is_constant = instr->key()->IsConstantOperand(); | 4301 bool key_is_constant = instr->key()->IsConstantOperand(); |
4298 Label not_nan, done; | 4302 int constant_key = 0; |
| 4303 Label not_nan; |
4299 | 4304 |
4300 // Calculate the effective address of the slot in the array to store the | 4305 // Calculate the effective address of the slot in the array to store the |
4301 // double value. | 4306 // double value. |
4302 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); | |
4303 if (key_is_constant) { | 4307 if (key_is_constant) { |
4304 int constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 4308 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
4305 if (constant_key & 0xF0000000) { | 4309 if (constant_key & 0xF0000000) { |
4306 Abort(kArrayIndexConstantValueTooBig); | 4310 Abort(kArrayIndexConstantValueTooBig); |
4307 } | 4311 } |
4308 __ Addu(scratch, elements, | |
4309 Operand((constant_key << element_size_shift) + | |
4310 FixedDoubleArray::kHeaderSize - kHeapObjectTag)); | |
4311 } else { | 4312 } else { |
4312 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 4313 key = ToRegister(instr->key()); |
4313 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 4314 } |
4314 __ Addu(scratch, elements, | 4315 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); |
| 4316 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
| 4317 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
| 4318 if (key_is_constant) { |
| 4319 __ Addu(scratch, elements, Operand((constant_key << element_size_shift) + |
| 4320 FixedDoubleArray::kHeaderSize - kHeapObjectTag)); |
| 4321 } else { |
| 4322 __ sll(scratch, key, shift_size); |
| 4323 __ Addu(scratch, elements, Operand(scratch)); |
| 4324 __ Addu(scratch, scratch, |
4315 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); | 4325 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); |
4316 __ sll(at, ToRegister(instr->key()), shift_size); | |
4317 __ Addu(scratch, scratch, at); | |
4318 } | 4326 } |
4319 | 4327 |
4320 if (instr->NeedsCanonicalization()) { | 4328 if (instr->NeedsCanonicalization()) { |
4321 Label is_nan; | 4329 Label is_nan; |
4322 // Check for NaN. All NaNs must be canonicalized. | 4330 // Check for NaN. All NaNs must be canonicalized. |
4323 __ BranchF(NULL, &is_nan, eq, value, value); | 4331 __ BranchF(NULL, &is_nan, eq, value, value); |
4324 __ Branch(¬_nan); | 4332 __ Branch(¬_nan); |
4325 | 4333 |
4326 // Only load canonical NaN if the comparison above set the overflow. | 4334 // Only load canonical NaN if the comparison above set the overflow. |
4327 __ bind(&is_nan); | 4335 __ bind(&is_nan); |
4328 __ Move(double_scratch, | 4336 __ Move(value, FixedDoubleArray::canonical_not_the_hole_nan_as_double()); |
4329 FixedDoubleArray::canonical_not_the_hole_nan_as_double()); | |
4330 __ sdc1(double_scratch, MemOperand(scratch, instr->additional_index() << | |
4331 element_size_shift)); | |
4332 __ Branch(&done); | |
4333 } | 4337 } |
4334 | 4338 |
4335 __ bind(¬_nan); | 4339 __ bind(¬_nan); |
4336 __ sdc1(value, MemOperand(scratch, instr->additional_index() << | 4340 __ sdc1(value, MemOperand(scratch, instr->additional_index() << |
4337 element_size_shift)); | 4341 element_size_shift)); |
4338 __ bind(&done); | |
4339 } | 4342 } |
4340 | 4343 |
4341 | 4344 |
4342 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { | 4345 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { |
4343 Register value = ToRegister(instr->value()); | 4346 Register value = ToRegister(instr->value()); |
4344 Register elements = ToRegister(instr->elements()); | 4347 Register elements = ToRegister(instr->elements()); |
4345 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) | 4348 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) |
4346 : no_reg; | 4349 : no_reg; |
4347 Register scratch = scratch0(); | 4350 Register scratch = scratch0(); |
4348 Register store_base = scratch; | 4351 Register store_base = scratch; |
(...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4924 private: | 4927 private: |
4925 LTaggedToI* instr_; | 4928 LTaggedToI* instr_; |
4926 }; | 4929 }; |
4927 | 4930 |
4928 LOperand* input = instr->value(); | 4931 LOperand* input = instr->value(); |
4929 ASSERT(input->IsRegister()); | 4932 ASSERT(input->IsRegister()); |
4930 ASSERT(input->Equals(instr->result())); | 4933 ASSERT(input->Equals(instr->result())); |
4931 | 4934 |
4932 Register input_reg = ToRegister(input); | 4935 Register input_reg = ToRegister(input); |
4933 | 4936 |
4934 if (instr->hydrogen()->value()->representation().IsSmi()) { | 4937 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr); |
4935 __ SmiUntag(input_reg); | |
4936 } else { | |
4937 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr); | |
4938 | 4938 |
4939 // Let the deferred code handle the HeapObject case. | 4939 // Let the deferred code handle the HeapObject case. |
4940 __ JumpIfNotSmi(input_reg, deferred->entry()); | 4940 __ JumpIfNotSmi(input_reg, deferred->entry()); |
4941 | 4941 |
4942 // Smi to int32 conversion. | 4942 // Smi to int32 conversion. |
4943 __ SmiUntag(input_reg); | 4943 __ SmiUntag(input_reg); |
4944 __ bind(deferred->exit()); | 4944 __ bind(deferred->exit()); |
4945 } | |
4946 } | 4945 } |
4947 | 4946 |
4948 | 4947 |
4949 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { | 4948 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { |
4950 LOperand* input = instr->value(); | 4949 LOperand* input = instr->value(); |
4951 ASSERT(input->IsRegister()); | 4950 ASSERT(input->IsRegister()); |
4952 LOperand* result = instr->result(); | 4951 LOperand* result = instr->result(); |
4953 ASSERT(result->IsDoubleRegister()); | 4952 ASSERT(result->IsDoubleRegister()); |
4954 | 4953 |
4955 Register input_reg = ToRegister(input); | 4954 Register input_reg = ToRegister(input); |
(...skipping 818 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5774 __ Subu(scratch, result, scratch); | 5773 __ Subu(scratch, result, scratch); |
5775 __ lw(result, FieldMemOperand(scratch, | 5774 __ lw(result, FieldMemOperand(scratch, |
5776 FixedArray::kHeaderSize - kPointerSize)); | 5775 FixedArray::kHeaderSize - kPointerSize)); |
5777 __ bind(&done); | 5776 __ bind(&done); |
5778 } | 5777 } |
5779 | 5778 |
5780 | 5779 |
5781 #undef __ | 5780 #undef __ |
5782 | 5781 |
5783 } } // namespace v8::internal | 5782 } } // namespace v8::internal |
OLD | NEW |