Reviewers: Rodolph Perfetta, ulan,

Message:
PTAL

Description:
A64: Implement HRandom.

Please review this at https://codereview.chromium.org/145693002/

SVN Base: https://v8.googlecode.com/svn/branches/experimental/a64

Affected files (+93, -5 lines):
  M src/a64/lithium-a64.h
  M src/a64/lithium-a64.cc
  M src/a64/lithium-codegen-a64.h
  M src/a64/lithium-codegen-a64.cc


Index: src/a64/lithium-a64.cc
diff --git a/src/a64/lithium-a64.cc b/src/a64/lithium-a64.cc
index 0d9b44c47c613d3c00a358319c0b1104e1c05d00..179269eb06ab67f896602014713842a4e4a840b1 100644
--- a/src/a64/lithium-a64.cc
+++ b/src/a64/lithium-a64.cc
@@ -1248,6 +1248,15 @@ LInstruction* LChunkBuilder::DoCompareIDAndBranch(HCompareIDAndBranch* instr) {
 }


+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) {
   ASSERT(instr->left()->representation().IsTagged());
   ASSERT(instr->right()->representation().IsTagged());
@@ -1873,11 +1882,6 @@ LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) {
 }


-LInstruction* LChunkBuilder::DoRandom(HRandom* instr) {
-  UNIMPLEMENTED_INSTRUCTION();
-}
-
-
 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) {
   return MarkAsCall(DefineFixed(new(zone()) LRegExpLiteral, x0), instr);
 }
Index: src/a64/lithium-a64.h
diff --git a/src/a64/lithium-a64.h b/src/a64/lithium-a64.h
index f011364d1e42555bc081981e3773b094868e7127..14ced8f4408bded7725c1d9dfcc29b805e1af1ef 100644
--- a/src/a64/lithium-a64.h
+++ b/src/a64/lithium-a64.h
@@ -157,6 +157,7 @@ class LCodeGen;
   V(Parameter)                                  \
   V(Power)                                      \
   V(PushArgument)                               \
+  V(Random)                                     \
   V(RegExpLiteral)                              \
   V(Return)                                     \
   V(SeqStringSetChar)                           \
@@ -611,6 +612,19 @@ class LAllocate: public LTemplateInstruction<1, 1, 2> {
 };


+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")
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.
+  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, Operand(0xFFFF));
+  __ 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());
+ // 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);
+  // Return value is in x0.
+}
+
+
 void LCodeGen::DoMathExp(LMathExp* instr) {
   DoubleRegister input = ToDoubleRegister(instr->value());
   DoubleRegister result = ToDoubleRegister(instr->result());
Index: src/a64/lithium-codegen-a64.h
diff --git a/src/a64/lithium-codegen-a64.h b/src/a64/lithium-codegen-a64.h
index 15eaf2c4e816fd8fa9542f89ffe6bef47f9f09fa..8f0611212328851f9acb08d8332f15ed5b1515ee 100644
--- a/src/a64/lithium-codegen-a64.h
+++ b/src/a64/lithium-codegen-a64.h
@@ -158,6 +158,7 @@ class LCodeGen BASE_EMBEDDED {
   // 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