| 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 1940 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1951 __ pinsrd(res, Operand(temp), 1); | 1951 __ pinsrd(res, Operand(temp), 1); |
| 1952 } | 1952 } |
| 1953 } else { | 1953 } else { |
| 1954 __ Set(temp, Immediate(upper)); | 1954 __ Set(temp, Immediate(upper)); |
| 1955 __ movd(res, Operand(temp)); | 1955 __ movd(res, Operand(temp)); |
| 1956 __ psllq(res, 32); | 1956 __ psllq(res, 32); |
| 1957 if (lower != 0) { | 1957 if (lower != 0) { |
| 1958 XMMRegister xmm_scratch = double_scratch0(); | 1958 XMMRegister xmm_scratch = double_scratch0(); |
| 1959 __ Set(temp, Immediate(lower)); | 1959 __ Set(temp, Immediate(lower)); |
| 1960 __ movd(xmm_scratch, Operand(temp)); | 1960 __ movd(xmm_scratch, Operand(temp)); |
| 1961 __ por(res, xmm_scratch); | 1961 __ orps(res, xmm_scratch); |
| 1962 } | 1962 } |
| 1963 } | 1963 } |
| 1964 } | 1964 } |
| 1965 } | 1965 } |
| 1966 } | 1966 } |
| 1967 | 1967 |
| 1968 | 1968 |
| 1969 void LCodeGen::DoConstantE(LConstantE* instr) { | 1969 void LCodeGen::DoConstantE(LConstantE* instr) { |
| 1970 __ lea(ToRegister(instr->result()), Operand::StaticVariable(instr->value())); | 1970 __ lea(ToRegister(instr->result()), Operand::StaticVariable(instr->value())); |
| 1971 } | 1971 } |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2052 __ bind(&runtime); | 2052 __ bind(&runtime); |
| 2053 __ PrepareCallCFunction(2, scratch); | 2053 __ PrepareCallCFunction(2, scratch); |
| 2054 __ mov(Operand(esp, 0), object); | 2054 __ mov(Operand(esp, 0), object); |
| 2055 __ mov(Operand(esp, 1 * kPointerSize), Immediate(index)); | 2055 __ mov(Operand(esp, 1 * kPointerSize), Immediate(index)); |
| 2056 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); | 2056 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); |
| 2057 __ bind(&done); | 2057 __ bind(&done); |
| 2058 } | 2058 } |
| 2059 } | 2059 } |
| 2060 | 2060 |
| 2061 | 2061 |
| 2062 Operand LCodeGen::BuildSeqStringOperand(Register string, |
| 2063 LOperand* index, |
| 2064 String::Encoding encoding) { |
| 2065 if (index->IsConstantOperand()) { |
| 2066 int offset = ToRepresentation(LConstantOperand::cast(index), |
| 2067 Representation::Integer32()); |
| 2068 if (encoding == String::TWO_BYTE_ENCODING) { |
| 2069 offset *= kUC16Size; |
| 2070 } |
| 2071 STATIC_ASSERT(kCharSize == 1); |
| 2072 return FieldOperand(string, SeqString::kHeaderSize + offset); |
| 2073 } |
| 2074 return FieldOperand( |
| 2075 string, ToRegister(index), |
| 2076 encoding == String::ONE_BYTE_ENCODING ? times_1 : times_2, |
| 2077 SeqString::kHeaderSize); |
| 2078 } |
| 2079 |
| 2080 |
| 2062 void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) { | 2081 void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) { |
| 2082 String::Encoding encoding = instr->hydrogen()->encoding(); |
| 2063 Register string = ToRegister(instr->string()); | 2083 Register string = ToRegister(instr->string()); |
| 2064 Register index = ToRegister(instr->index()); | |
| 2065 Register value = ToRegister(instr->value()); | |
| 2066 String::Encoding encoding = instr->encoding(); | |
| 2067 | 2084 |
| 2068 if (FLAG_debug_code) { | 2085 if (FLAG_debug_code) { |
| 2069 __ push(value); | 2086 __ push(string); |
| 2070 __ mov(value, FieldOperand(string, HeapObject::kMapOffset)); | 2087 __ mov(string, FieldOperand(string, HeapObject::kMapOffset)); |
| 2071 __ movzx_b(value, FieldOperand(value, Map::kInstanceTypeOffset)); | 2088 __ movzx_b(string, FieldOperand(string, Map::kInstanceTypeOffset)); |
| 2072 | 2089 |
| 2073 __ and_(value, Immediate(kStringRepresentationMask | kStringEncodingMask)); | 2090 __ and_(string, Immediate(kStringRepresentationMask | kStringEncodingMask)); |
| 2074 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; | 2091 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; |
| 2075 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; | 2092 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; |
| 2076 __ cmp(value, Immediate(encoding == String::ONE_BYTE_ENCODING | 2093 __ cmp(string, Immediate(encoding == String::ONE_BYTE_ENCODING |
| 2077 ? one_byte_seq_type : two_byte_seq_type)); | 2094 ? one_byte_seq_type : two_byte_seq_type)); |
| 2078 __ Check(equal, kUnexpectedStringType); | 2095 __ Check(equal, kUnexpectedStringType); |
| 2079 __ pop(value); | 2096 __ pop(string); |
| 2080 } | 2097 } |
| 2081 | 2098 |
| 2082 if (encoding == String::ONE_BYTE_ENCODING) { | 2099 Operand operand = BuildSeqStringOperand(string, instr->index(), encoding); |
| 2083 __ mov_b(FieldOperand(string, index, times_1, SeqString::kHeaderSize), | 2100 if (instr->value()->IsConstantOperand()) { |
| 2084 value); | 2101 int value = ToRepresentation(LConstantOperand::cast(instr->value()), |
| 2102 Representation::Integer32()); |
| 2103 ASSERT_LE(0, value); |
| 2104 if (encoding == String::ONE_BYTE_ENCODING) { |
| 2105 ASSERT_LE(value, String::kMaxOneByteCharCode); |
| 2106 __ mov_b(operand, static_cast<int8_t>(value)); |
| 2107 } else { |
| 2108 ASSERT_LE(value, String::kMaxUtf16CodeUnit); |
| 2109 __ mov_w(operand, static_cast<int16_t>(value)); |
| 2110 } |
| 2085 } else { | 2111 } else { |
| 2086 __ mov_w(FieldOperand(string, index, times_2, SeqString::kHeaderSize), | 2112 Register value = ToRegister(instr->value()); |
| 2087 value); | 2113 if (encoding == String::ONE_BYTE_ENCODING) { |
| 2114 __ mov_b(operand, value); |
| 2115 } else { |
| 2116 __ mov_w(operand, value); |
| 2117 } |
| 2088 } | 2118 } |
| 2089 } | 2119 } |
| 2090 | 2120 |
| 2091 | 2121 |
| 2092 void LCodeGen::DoThrow(LThrow* instr) { | 2122 void LCodeGen::DoThrow(LThrow* instr) { |
| 2093 __ push(ToOperand(instr->value())); | 2123 __ push(ToOperand(instr->value())); |
| 2094 ASSERT(ToRegister(instr->context()).is(esi)); | 2124 ASSERT(ToRegister(instr->context()).is(esi)); |
| 2095 CallRuntime(Runtime::kThrow, 1, instr); | 2125 CallRuntime(Runtime::kThrow, 1, instr); |
| 2096 | 2126 |
| 2097 if (FLAG_debug_code) { | 2127 if (FLAG_debug_code) { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2177 } else { | 2207 } else { |
| 2178 // Since we operate on +0 and/or -0, addsd and andsd have the same effect. | 2208 // Since we operate on +0 and/or -0, addsd and andsd have the same effect. |
| 2179 __ addsd(left_reg, right_reg); | 2209 __ addsd(left_reg, right_reg); |
| 2180 } | 2210 } |
| 2181 __ jmp(&return_left, Label::kNear); | 2211 __ jmp(&return_left, Label::kNear); |
| 2182 | 2212 |
| 2183 __ bind(&check_nan_left); | 2213 __ bind(&check_nan_left); |
| 2184 __ ucomisd(left_reg, left_reg); // NaN check. | 2214 __ ucomisd(left_reg, left_reg); // NaN check. |
| 2185 __ j(parity_even, &return_left, Label::kNear); // left == NaN. | 2215 __ j(parity_even, &return_left, Label::kNear); // left == NaN. |
| 2186 __ bind(&return_right); | 2216 __ bind(&return_right); |
| 2187 __ movsd(left_reg, right_reg); | 2217 __ movaps(left_reg, right_reg); |
| 2188 | 2218 |
| 2189 __ bind(&return_left); | 2219 __ bind(&return_left); |
| 2190 } | 2220 } |
| 2191 } | 2221 } |
| 2192 | 2222 |
| 2193 | 2223 |
| 2194 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { | 2224 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { |
| 2195 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { | 2225 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { |
| 2196 CpuFeatureScope scope(masm(), SSE2); | 2226 CpuFeatureScope scope(masm(), SSE2); |
| 2197 XMMRegister left = ToDoubleRegister(instr->left()); | 2227 XMMRegister left = ToDoubleRegister(instr->left()); |
| (...skipping 1790 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3988 DeoptimizeIf(equal, instr->environment()); | 4018 DeoptimizeIf(equal, instr->environment()); |
| 3989 __ jmp(&done); | 4019 __ jmp(&done); |
| 3990 | 4020 |
| 3991 __ bind(&below_one_half); | 4021 __ bind(&below_one_half); |
| 3992 __ movsd(xmm_scratch, Operand::StaticVariable(minus_one_half)); | 4022 __ movsd(xmm_scratch, Operand::StaticVariable(minus_one_half)); |
| 3993 __ ucomisd(xmm_scratch, input_reg); | 4023 __ ucomisd(xmm_scratch, input_reg); |
| 3994 __ j(below_equal, &round_to_zero); | 4024 __ j(below_equal, &round_to_zero); |
| 3995 | 4025 |
| 3996 // CVTTSD2SI rounds towards zero, we use ceil(x - (-0.5)) and then | 4026 // CVTTSD2SI rounds towards zero, we use ceil(x - (-0.5)) and then |
| 3997 // compare and compensate. | 4027 // compare and compensate. |
| 3998 __ movsd(input_temp, input_reg); // Do not alter input_reg. | 4028 __ movaps(input_temp, input_reg); // Do not alter input_reg. |
| 3999 __ subsd(input_temp, xmm_scratch); | 4029 __ subsd(input_temp, xmm_scratch); |
| 4000 __ cvttsd2si(output_reg, Operand(input_temp)); | 4030 __ cvttsd2si(output_reg, Operand(input_temp)); |
| 4001 // Catch minint due to overflow, and to prevent overflow when compensating. | 4031 // Catch minint due to overflow, and to prevent overflow when compensating. |
| 4002 __ cmp(output_reg, 0x80000000u); | 4032 __ cmp(output_reg, 0x80000000u); |
| 4003 __ RecordComment("D2I conversion overflow"); | 4033 __ RecordComment("D2I conversion overflow"); |
| 4004 DeoptimizeIf(equal, instr->environment()); | 4034 DeoptimizeIf(equal, instr->environment()); |
| 4005 | 4035 |
| 4006 __ Cvtsi2sd(xmm_scratch, output_reg); | 4036 __ Cvtsi2sd(xmm_scratch, output_reg); |
| 4007 __ ucomisd(xmm_scratch, input_temp); | 4037 __ ucomisd(xmm_scratch, input_temp); |
| 4008 __ j(equal, &done); | 4038 __ j(equal, &done); |
| (...skipping 2380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6389 FixedArray::kHeaderSize - kPointerSize)); | 6419 FixedArray::kHeaderSize - kPointerSize)); |
| 6390 __ bind(&done); | 6420 __ bind(&done); |
| 6391 } | 6421 } |
| 6392 | 6422 |
| 6393 | 6423 |
| 6394 #undef __ | 6424 #undef __ |
| 6395 | 6425 |
| 6396 } } // namespace v8::internal | 6426 } } // namespace v8::internal |
| 6397 | 6427 |
| 6398 #endif // V8_TARGET_ARCH_IA32 | 6428 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |