Chromium Code Reviews| Index: src/a64/lithium-codegen-a64.cc |
| diff --git a/src/a64/lithium-codegen-a64.cc b/src/a64/lithium-codegen-a64.cc |
| index 7ab8cb71cdc7223b82dfbb74b4eb97b122b1450f..456f333aa1d14343d3640e832c1311383e7bfdbb 100644 |
| --- a/src/a64/lithium-codegen-a64.cc |
| +++ b/src/a64/lithium-codegen-a64.cc |
| @@ -3543,6 +3543,75 @@ void LCodeGen::DoMathCos(LMathCos* instr) { |
| } |
| +void LCodeGen::DoRandom(LRandom* instr) { |
| + class DeferredDoRandom: public LDeferredCode { |
| + public: |
| + DeferredDoRandom(LCodeGen* codegen, LRandom* instr) |
| + : LDeferredCode(codegen), instr_(instr) { } |
| + virtual void Generate() { codegen()->DoDeferredRandom(instr_); } |
| + virtual LInstruction* instr() { return instr_; } |
| + |
| + private: |
| + LRandom* instr_; |
| + }; |
| + |
| + DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr); |
| + |
| + // Having marked this instruction as a call we can use any registers. |
|
Rodolph Perfetta
2014/01/23 15:02:14
ASSERT(instr->IsMarkedAsCall());
|
| + ASSERT(ToDoubleRegister(instr->result()).is(d7)); |
| + ASSERT(ToRegister(instr->global_object()).is(x0)); |
| + |
| + static const int kSeedSize = sizeof(uint32_t); |
| + STATIC_ASSERT(kPointerSize == 2 * kSeedSize); |
| + |
| + Register global_object = x0; |
| + __ Ldr(global_object, |
| + FieldMemOperand(global_object, GlobalObject::kNativeContextOffset)); |
| + static const int kRandomSeedOffset = |
| + FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize; |
| + __ Ldr(x1, FieldMemOperand(global_object, kRandomSeedOffset)); |
| + // x1: FixedArray of the native context's random seeds |
| + |
| + // Load state[0]. |
| + __ Ldr(w2, FieldMemOperand(x1, ByteArray::kHeaderSize)); |
| + // If state[0] == 0, call runtime to initialize seeds. |
| + __ cbz(w2, deferred->entry()); |
|
ulan
2014/01/23 14:48:08
Use Cbz of masm.
Rodolph Perfetta
2014/01/23 15:02:14
cbz -> Cbz
Benedikt Meurer
2014/01/24 06:37:53
Done.
|
| + // Load state[1]. |
| + __ Ldr(w3, FieldMemOperand(x1, ByteArray::kHeaderSize + kSeedSize)); |
| + |
| + // state[0] = 18273 * (state[0] & 0xFFFF) + (state[0] >> 16) |
| + __ And(w4, w2, Operand(0xFFFF)); |
|
Rodolph Perfetta
2014/01/23 15:02:14
No need for Operand, And(w4, 0xFFFF) works.
This
Benedikt Meurer
2014/01/24 06:37:53
Done.
|
| + __ Mov(w5, Operand(18273)); |
| + __ Mul(w5, w5, w4); |
| + __ Add(w2, w5, Operand(w2, LSR, 16)); |
| + // Save state[0]. |
| + __ Str(w2, FieldMemOperand(x1, ByteArray::kHeaderSize)); |
| + |
| + // state[1] = 36969 * (state[1] & 0xFFFF) + (state[1] >> 16) |
| + __ And(w4, w3, Operand(0xFFFF)); |
| + __ Mov(w5, Operand(36969)); |
| + __ Mul(w5, w5, w4); |
| + __ Add(w3, w5, Operand(w3, LSR, 16)); |
| + // Save state[1]. |
| + __ Str(w3, FieldMemOperand(x1, ByteArray::kHeaderSize + kSeedSize)); |
| + |
| + // Random bit pattern = (state[0] << 14) + (state[1] & 0x3FFFF) |
| + __ And(w3, w3, Operand(0x3FFFF)); |
| + __ Add(w0, w3, Operand(w2, LSL, 14)); |
| + |
| + __ bind(deferred->exit()); |
|
ulan
2014/01/23 14:48:08
Use Bind of masm.
Rodolph Perfetta
2014/01/23 15:02:14
bind -> Bind
Benedikt Meurer
2014/01/24 06:37:53
Done.
|
| + // Interpret the 32 random bits as a 0.32 fixed point number, and convert to |
| + // a double in the range 0.0 <= number < 1.0. |
| + __ Ucvtf(d7, w0, 32); |
| +} |
| + |
| + |
| +void LCodeGen::DoDeferredRandom(LRandom* instr) { |
| + __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 0); |
|
Rodolph Perfetta
2014/01/23 15:02:14
the function takes a parameter.
Benedikt Meurer
2014/01/24 06:37:53
Done.
|
| + // Return value is in x0. |
| +} |
| + |
| + |
| void LCodeGen::DoMathExp(LMathExp* instr) { |
| DoubleRegister input = ToDoubleRegister(instr->value()); |
| DoubleRegister result = ToDoubleRegister(instr->result()); |