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.