Revision: 18852
Author:   [email protected]
Date:     Mon Jan 27 12:55:12 2014 UTC
Log:      A64: Implement HRandom.

[email protected]

Review URL: https://codereview.chromium.org/145693002
http://code.google.com/p/v8/source/detail?r=18852

Modified:
 /branches/experimental/a64/src/a64/lithium-a64.cc
 /branches/experimental/a64/src/a64/lithium-a64.h
 /branches/experimental/a64/src/a64/lithium-codegen-a64.cc
 /branches/experimental/a64/src/a64/lithium-codegen-a64.h

=======================================
--- /branches/experimental/a64/src/a64/lithium-a64.cc Fri Jan 24 15:58:36 2014 UTC +++ /branches/experimental/a64/src/a64/lithium-a64.cc Mon Jan 27 12:55:12 2014 UTC
@@ -1291,6 +1291,15 @@
     return new(zone()) LCmpIDAndBranch(left, right);
   }
 }
+
+
+LInstruction* LChunkBuilder::DoRandom(HRandom* instr) {
+  ASSERT(instr->representation().IsDouble());
+  ASSERT(instr->global_object()->representation().IsTagged());
+  LOperand* global_object = UseFixed(instr->global_object(), x0);
+  LRandom* result = new(zone()) LRandom(global_object);
+  return MarkAsCall(DefineFixedDouble(result, d7), instr);
+}


 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
@@ -1930,11 +1939,6 @@
   LOperand* argument = UseRegister(instr->argument());
   return new(zone()) LPushArgument(argument);
 }
-
-
-LInstruction* LChunkBuilder::DoRandom(HRandom* instr) {
-  UNIMPLEMENTED_INSTRUCTION();
-}


 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) {
=======================================
--- /branches/experimental/a64/src/a64/lithium-a64.h Fri Jan 24 15:58:36 2014 UTC +++ /branches/experimental/a64/src/a64/lithium-a64.h Mon Jan 27 12:55:12 2014 UTC
@@ -162,6 +162,7 @@
   V(Parameter)                                  \
   V(Power)                                      \
   V(PushArgument)                               \
+  V(Random)                                     \
   V(RegExpLiteral)                              \
   V(Return)                                     \
   V(SeqStringSetChar)                           \
@@ -2083,6 +2084,19 @@
 };


+class LRandom: public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LRandom(LOperand* global_object) {
+    inputs_[0] = global_object;
+  }
+
+  LOperand* global_object() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(Random, "random")
+  DECLARE_HYDROGEN_ACCESSOR(Random)
+};
+
+
 class LRegExpLiteral: public LTemplateInstruction<1, 0, 0> {
  public:
   DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp-literal")
=======================================
--- /branches/experimental/a64/src/a64/lithium-codegen-a64.cc Fri Jan 24 15:58:36 2014 UTC +++ /branches/experimental/a64/src/a64/lithium-codegen-a64.cc Mon Jan 27 12:55:12 2014 UTC
@@ -3667,6 +3667,76 @@
   CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
   ASSERT(ToDoubleRegister(instr->result()).Is(d0));
 }
+
+
+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) {
=======================================
--- /branches/experimental/a64/src/a64/lithium-codegen-a64.h Fri Jan 24 14:09:40 2014 UTC +++ /branches/experimental/a64/src/a64/lithium-codegen-a64.h Mon Jan 27 12:55:12 2014 UTC
@@ -157,6 +157,7 @@
   // Deferred code support.
   void DoDeferredNumberTagD(LNumberTagD* instr);
   void DoDeferredStackCheck(LStackCheck* instr);
+  void DoDeferredRandom(LRandom* instr);
   void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
   void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
   void DoDeferredMathAbsTagged(LMathAbsTagged* instr,

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to