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

Unified Diff: src/a64/lithium-codegen-a64.cc

Issue 145693002: A64: Implement HRandom. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Next try Created 6 years, 11 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/a64/lithium-codegen-a64.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/a64/lithium-codegen-a64.cc
diff --git a/src/a64/lithium-codegen-a64.cc b/src/a64/lithium-codegen-a64.cc
index c730da724586943c5ba8adab516e946649a1bba0..e71a137461927a4531a866d9654fc4fbedd28039 100644
--- a/src/a64/lithium-codegen-a64.cc
+++ b/src/a64/lithium-codegen-a64.cc
@@ -3532,6 +3532,76 @@ 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.
+ 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());
+ // Load state[1].
+ __ Ldr(w3, FieldMemOperand(x1, ByteArray::kHeaderSize + kSeedSize));
+
+ // state[0] = 18273 * (state[0] & 0xFFFF) + (state[0] >> 16)
+ __ And(w4, w2, 0xFFFF);
+ __ Mov(w5, 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, 0xFFFF);
+ __ Mov(w5, 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, 0x3FFFF);
+ __ Add(w0, w3, Operand(w2, LSL, 14));
+
+ __ Bind(deferred->exit());
+ // 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()), 1);
+ // Return value is in x0.
+}
+
+
void LCodeGen::DoMathExp(LMathExp* instr) {
DoubleRegister input = ToDoubleRegister(instr->value());
DoubleRegister result = ToDoubleRegister(instr->result());
« no previous file with comments | « src/a64/lithium-codegen-a64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698