diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index 06e886c6bb..7c94730f12 100644 --- a/src/mips/lithium-codegen-mips.cc +++ b/src/mips/lithium-codegen-mips.cc @@ -1,4 +1,4 @@ -// Copyright 2011 the V8 project authors. All rights reserved. +// Copyright 2012 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -3095,6 +3095,27 @@ 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(f0)); + ASSERT(ToRegister(instr->InputAt(0)).is(a0)); + + __ PrepareCallCFunction(1, a1); + __ lw(a0, FieldMemOperand(a0, GlobalObject::kGlobalContextOffset)); + __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); + + // 0x41300000 is the top half of 1.0 x 2^20 as a double. + __ li(a2, Operand(0x41300000)); + // Move 0x41300000xxxxxxxx (x = random bits in v0) to FPU. + __ Move(f12, v0, a2); + // Move 0x4130000000000000 to FPU. + __ Move(f14, zero_reg, a2); + // Subtract to get the result. + __ sub_d(f0, f12, f14); +} + + void LCodeGen::DoMathLog(LUnaryMathOperation* instr) { ASSERT(ToDoubleRegister(instr->result()).is(f4)); TranscendentalCacheStub stub(TranscendentalCache::LOG, diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc index 90e1024ba9..b66b98f208 100644 --- a/src/mips/lithium-mips.cc +++ b/src/mips/lithium-mips.cc @@ -1,4 +1,4 @@ -// Copyright 2011 the V8 project authors. All rights reserved. +// Copyright 2012 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -1428,6 +1428,15 @@ LInstruction* LChunkBuilder::DoPower(HPower* instr) { } +LInstruction* LChunkBuilder::DoRandom(HRandom* instr) { + ASSERT(instr->representation().IsDouble()); + ASSERT(instr->global_object()->representation().IsTagged()); + LOperand* global_object = UseFixed(instr->global_object(), a0); + LRandom* result = new LRandom(global_object); + return MarkAsCall(DefineFixedDouble(result, f0), instr); +} + + LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) { Representation r = instr->GetInputRepresentation(); ASSERT(instr->left()->representation().IsTagged()); diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h index da59dd8b0c..069a0251fd 100644 --- a/src/mips/lithium-mips.h +++ b/src/mips/lithium-mips.h @@ -1,4 +1,4 @@ -// Copyright 2011 the V8 project authors. All rights reserved. +// Copyright 2012 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -141,6 +141,7 @@ class LCodeGen; V(Parameter) \ V(Power) \ V(PushArgument) \ + V(Random) \ V(RegExpLiteral) \ V(Return) \ V(ShiftI) \ @@ -1026,6 +1027,17 @@ class LPower: public LTemplateInstruction<1, 2, 0> { }; +class LRandom: public LTemplateInstruction<1, 1, 0> { + public: + explicit LRandom(LOperand* global_object) { + inputs_[0] = global_object; + } + + DECLARE_CONCRETE_INSTRUCTION(Random, "random") + DECLARE_HYDROGEN_ACCESSOR(Random) +}; + + class LArithmeticD: public LTemplateInstruction<1, 2, 0> { public: LArithmeticD(Token::Value op, LOperand* left, LOperand* right)