Index: src/x64/lithium-codegen-x64.cc |
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc |
index bafe74eec5e52c2c9bc3566963e354da497dd531..58dca6989a5a2da973efed7a1401230a6dbeebec 100644 |
--- a/src/x64/lithium-codegen-x64.cc |
+++ b/src/x64/lithium-codegen-x64.cc |
@@ -2926,6 +2926,41 @@ void LCodeGen::DoPower(LPower* instr) { |
} |
+void LCodeGen::DoRandom(LRandom* instr) { |
+ // Having marked this instruction as a call we can use any |
+ // registers. |
+ ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); |
+ |
+ // Choose the right register for the first argument depending on |
+ // calling convention. |
+#ifdef _WIN64 |
+ ASSERT(ToRegister(instr->InputAt(0)).is(rcx)); |
+ Register global_object = rdx; |
Jakob Kummerow
2012/01/11 08:10:40
Unused variable. Also, s/rdx/rcx/.
Mads Ager (chromium)
2012/01/11 10:24:46
Done.
|
+#else |
+ ASSERT(ToRegister(instr->InputAt(0)).is(rdi)); |
+ Register global_object = rdi; |
+#endif |
+ |
+ __ PrepareCallCFunction(1); |
+#ifdef _WIN64 |
Jakob Kummerow
2012/01/11 08:10:40
If you made use of the |global_object| variable de
Mads Ager (chromium)
2012/01/11 10:24:46
Whoops. Thanks Jakob, that was indeed the intentio
|
+ __ movq(rcx, FieldOperand(rcx, GlobalObject::kGlobalContextOffset)); |
+#else |
+ __ movq(rdi, FieldOperand(rdi, GlobalObject::kGlobalContextOffset)); |
+#endif |
+ __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); |
+ |
+ // Convert 32 random bits in rax to 0.(32 random bits) in a double |
+ // by computing: |
+ // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). |
+ __ movl(rcx, Immediate(0x49800000)); // 1.0 x 2^20 as single. |
+ __ movd(xmm2, rcx); |
+ __ movd(xmm1, rax); |
+ __ cvtss2sd(xmm2, xmm2); |
+ __ xorps(xmm1, xmm2); |
+ __ subsd(xmm1, xmm2); |
+} |
+ |
+ |
void LCodeGen::DoMathLog(LUnaryMathOperation* instr) { |
ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); |
TranscendentalCacheStub stub(TranscendentalCache::LOG, |