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.