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

Side by Side Diff: src/x64/code-stubs-x64.cc

Issue 5437002: Add generated code to calculate Math.log and to search Transcendental cache f... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years 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/x64/assembler-x64.cc ('k') | src/x64/codegen-x64.h » ('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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 1089 matching lines...) Expand 10 before | Expand all | Expand 10 after
1100 __ movq(Operand(rcx, 2 * kIntSize), rax); 1100 __ movq(Operand(rcx, 2 * kIntSize), rax);
1101 __ ret(kPointerSize); 1101 __ ret(kPointerSize);
1102 } 1102 }
1103 1103
1104 1104
1105 Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() { 1105 Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() {
1106 switch (type_) { 1106 switch (type_) {
1107 // Add more cases when necessary. 1107 // Add more cases when necessary.
1108 case TranscendentalCache::SIN: return Runtime::kMath_sin; 1108 case TranscendentalCache::SIN: return Runtime::kMath_sin;
1109 case TranscendentalCache::COS: return Runtime::kMath_cos; 1109 case TranscendentalCache::COS: return Runtime::kMath_cos;
1110 case TranscendentalCache::LOG: return Runtime::kMath_log;
1110 default: 1111 default:
1111 UNIMPLEMENTED(); 1112 UNIMPLEMENTED();
1112 return Runtime::kAbort; 1113 return Runtime::kAbort;
1113 } 1114 }
1114 } 1115 }
1115 1116
1116 1117
1117 void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm, 1118 void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm,
1118 Label* on_nan_result) { 1119 Label* on_nan_result) {
1119 // Registers: 1120 // Registers:
1120 // rbx: Bits of input double. Must be preserved. 1121 // rbx: Bits of input double. Must be preserved.
1121 // rcx: Pointer to cache entry. Must be preserved. 1122 // rcx: Pointer to cache entry. Must be preserved.
1122 // st(0): Input double 1123 // st(0): Input double
1123 Label done; 1124 Label done;
1124 ASSERT(type_ == TranscendentalCache::SIN || 1125 if (type_ == TranscendentalCache::SIN || type_ == TranscendentalCache::COS) {
1125 type_ == TranscendentalCache::COS); 1126 // Both fsin and fcos require arguments in the range +/-2^63 and
1126 // More transcendental types can be added later. 1127 // return NaN for infinities and NaN. They can share all code except
1128 // the actual fsin/fcos operation.
1129 Label in_range;
1130 // If argument is outside the range -2^63..2^63, fsin/cos doesn't
1131 // work. We must reduce it to the appropriate range.
1132 __ movq(rdi, rbx);
1133 // Move exponent and sign bits to low bits.
1134 __ shr(rdi, Immediate(HeapNumber::kMantissaBits));
1135 // Remove sign bit.
1136 __ andl(rdi, Immediate((1 << HeapNumber::kExponentBits) - 1));
1137 int supported_exponent_limit = (63 + HeapNumber::kExponentBias);
1138 __ cmpl(rdi, Immediate(supported_exponent_limit));
1139 __ j(below, &in_range);
1140 // Check for infinity and NaN. Both return NaN for sin.
1141 __ cmpl(rdi, Immediate(0x7ff));
1142 __ j(equal, on_nan_result);
1127 1143
1128 // Both fsin and fcos require arguments in the range +/-2^63 and 1144 // Use fpmod to restrict argument to the range +/-2*PI.
1129 // return NaN for infinities and NaN. They can share all code except 1145 __ fldpi();
1130 // the actual fsin/fcos operation. 1146 __ fadd(0);
1131 Label in_range; 1147 __ fld(1);
1132 // If argument is outside the range -2^63..2^63, fsin/cos doesn't 1148 // FPU Stack: input, 2*pi, input.
1133 // work. We must reduce it to the appropriate range. 1149 {
1134 __ movq(rdi, rbx); 1150 Label no_exceptions;
1135 // Move exponent and sign bits to low bits. 1151 __ fwait();
1136 __ shr(rdi, Immediate(HeapNumber::kMantissaBits)); 1152 __ fnstsw_ax();
1137 // Remove sign bit. 1153 // Clear if Illegal Operand or Zero Division exceptions are set.
1138 __ andl(rdi, Immediate((1 << HeapNumber::kExponentBits) - 1)); 1154 __ testl(rax, Immediate(5)); // #IO and #ZD flags of FPU status word.
1139 int supported_exponent_limit = (63 + HeapNumber::kExponentBias); 1155 __ j(zero, &no_exceptions);
1140 __ cmpl(rdi, Immediate(supported_exponent_limit)); 1156 __ fnclex();
1141 __ j(below, &in_range); 1157 __ bind(&no_exceptions);
1142 // Check for infinity and NaN. Both return NaN for sin. 1158 }
1143 __ cmpl(rdi, Immediate(0x7ff));
1144 __ j(equal, on_nan_result);
1145 1159
1146 // Use fpmod to restrict argument to the range +/-2*PI. 1160 // Compute st(0) % st(1)
1147 __ fldpi(); 1161 {
1148 __ fadd(0); 1162 NearLabel partial_remainder_loop;
1149 __ fld(1); 1163 __ bind(&partial_remainder_loop);
1150 // FPU Stack: input, 2*pi, input. 1164 __ fprem1();
1151 { 1165 __ fwait();
1152 Label no_exceptions; 1166 __ fnstsw_ax();
1153 __ fwait(); 1167 __ testl(rax, Immediate(0x400)); // Check C2 bit of FPU status word.
1154 __ fnstsw_ax(); 1168 // If C2 is set, computation only has partial result. Loop to
1155 // Clear if Illegal Operand or Zero Division exceptions are set. 1169 // continue computation.
1156 __ testl(rax, Immediate(5)); // #IO and #ZD flags of FPU status word. 1170 __ j(not_zero, &partial_remainder_loop);
1157 __ j(zero, &no_exceptions);
1158 __ fnclex();
1159 __ bind(&no_exceptions);
1160 } 1171 }
1161 1172 // FPU Stack: input, 2*pi, input % 2*pi
1162 // Compute st(0) % st(1) 1173 __ fstp(2);
1163 { 1174 // FPU Stack: input % 2*pi, 2*pi,
1164 NearLabel partial_remainder_loop; 1175 __ fstp(0);
1165 __ bind(&partial_remainder_loop); 1176 // FPU Stack: input % 2*pi
1166 __ fprem1(); 1177 __ bind(&in_range);
1167 __ fwait(); 1178 switch (type_) {
1168 __ fnstsw_ax(); 1179 case TranscendentalCache::SIN:
1169 __ testl(rax, Immediate(0x400)); // Check C2 bit of FPU status word. 1180 __ fsin();
1170 // If C2 is set, computation only has partial result. Loop to 1181 break;
1171 // continue computation. 1182 case TranscendentalCache::COS:
1172 __ j(not_zero, &partial_remainder_loop); 1183 __ fcos();
1184 break;
1185 default:
1186 UNREACHABLE();
1187 }
1188 __ bind(&done);
1189 } else {
1190 ASSERT(type_ == TranscendentalCache::LOG);
1191 __ fldln2();
1192 __ fxch();
1193 __ fyl2x();
1173 } 1194 }
1174 // FPU Stack: input, 2*pi, input % 2*pi
1175 __ fstp(2);
1176 // FPU Stack: input % 2*pi, 2*pi,
1177 __ fstp(0);
1178 // FPU Stack: input % 2*pi
1179 __ bind(&in_range);
1180 switch (type_) {
1181 case TranscendentalCache::SIN:
1182 __ fsin();
1183 break;
1184 case TranscendentalCache::COS:
1185 __ fcos();
1186 break;
1187 default:
1188 UNREACHABLE();
1189 }
1190 __ bind(&done);
1191 } 1195 }
1192 1196
1193 1197
1194 // Get the integer part of a heap number. 1198 // Get the integer part of a heap number.
1195 // Overwrites the contents of rdi, rbx and rcx. Result cannot be rdi or rbx. 1199 // Overwrites the contents of rdi, rbx and rcx. Result cannot be rdi or rbx.
1196 void IntegerConvert(MacroAssembler* masm, 1200 void IntegerConvert(MacroAssembler* masm,
1197 Register result, 1201 Register result,
1198 Register source) { 1202 Register source) {
1199 // Result may be rcx. If result and source are the same register, source will 1203 // Result may be rcx. If result and source are the same register, source will
1200 // be overwritten. 1204 // be overwritten.
(...skipping 2783 matching lines...) Expand 10 before | Expand all | Expand 10 after
3984 // tagged as a small integer. 3988 // tagged as a small integer.
3985 __ bind(&runtime); 3989 __ bind(&runtime);
3986 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 3990 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
3987 } 3991 }
3988 3992
3989 #undef __ 3993 #undef __
3990 3994
3991 } } // namespace v8::internal 3995 } } // namespace v8::internal
3992 3996
3993 #endif // V8_TARGET_ARCH_X64 3997 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/assembler-x64.cc ('k') | src/x64/codegen-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698