mirror of
https://github.com/dart-lang/sdk
synced 2024-09-20 06:51:34 +00:00
Precompilation/x64: Load float vector constants via Thread.
Cannot put these in the object pool because some of these instructions are used in intrinsics. BUG=http://dartbug.com/24450 R=fschneider@google.com Review URL: https://codereview.chromium.org/1488403002 .
This commit is contained in:
parent
d9b1301821
commit
9cf30c9697
|
@ -1625,14 +1625,17 @@ ASSEMBLER_TEST_RUN(LoadImmediateMedNeg4, test) {
|
|||
static void EnterTestFrame(Assembler* assembler) {
|
||||
__ EnterFrame(0);
|
||||
__ Push(CODE_REG);
|
||||
__ Push(THR);
|
||||
__ TagAndPushPP();
|
||||
__ ldr(CODE_REG, Address(R0, VMHandles::kOffsetOfRawPtrInHandle));
|
||||
__ mov(THR, R1);
|
||||
__ LoadPoolPointer(PP);
|
||||
}
|
||||
|
||||
|
||||
static void LeaveTestFrame(Assembler* assembler) {
|
||||
__ PopAndUntagPP();
|
||||
__ Pop(THR);
|
||||
__ Pop(CODE_REG);
|
||||
__ LeaveFrame();
|
||||
}
|
||||
|
@ -1652,7 +1655,7 @@ ASSEMBLER_TEST_GENERATE(LoadImmediatePPSmall, assembler) {
|
|||
|
||||
|
||||
ASSEMBLER_TEST_RUN(LoadImmediatePPSmall, test) {
|
||||
EXPECT_EQ(42, test->InvokeWithCode<int64_t>());
|
||||
EXPECT_EQ(42, test->InvokeWithCodeAndThread<int64_t>());
|
||||
}
|
||||
|
||||
|
||||
|
@ -1667,7 +1670,7 @@ ASSEMBLER_TEST_GENERATE(LoadImmediatePPMed, assembler) {
|
|||
|
||||
|
||||
ASSEMBLER_TEST_RUN(LoadImmediatePPMed, test) {
|
||||
EXPECT_EQ(0xf1234123, test->InvokeWithCode<int64_t>());
|
||||
EXPECT_EQ(0xf1234123, test->InvokeWithCodeAndThread<int64_t>());
|
||||
}
|
||||
|
||||
|
||||
|
@ -1682,7 +1685,7 @@ ASSEMBLER_TEST_GENERATE(LoadImmediatePPMed2, assembler) {
|
|||
|
||||
|
||||
ASSEMBLER_TEST_RUN(LoadImmediatePPMed2, test) {
|
||||
EXPECT_EQ(0x4321f1234124, test->InvokeWithCode<int64_t>());
|
||||
EXPECT_EQ(0x4321f1234124, test->InvokeWithCodeAndThread<int64_t>());
|
||||
}
|
||||
|
||||
|
||||
|
@ -1698,23 +1701,15 @@ ASSEMBLER_TEST_GENERATE(LoadImmediatePPLarge, assembler) {
|
|||
|
||||
ASSEMBLER_TEST_RUN(LoadImmediatePPLarge, test) {
|
||||
EXPECT_EQ(static_cast<int64_t>(0x9287436598237465),
|
||||
test->InvokeWithCode<int64_t>());
|
||||
test->InvokeWithCodeAndThread<int64_t>());
|
||||
}
|
||||
|
||||
|
||||
#define ASSEMBLER_TEST_RUN_WITH_THREAD(result_type, var_name) \
|
||||
Thread* thread = Thread::Current(); \
|
||||
result_type var_name = test->InvokeWithCode<result_type>(thread);
|
||||
|
||||
|
||||
// LoadObject null.
|
||||
ASSEMBLER_TEST_GENERATE(LoadObjectNull, assembler) {
|
||||
__ SetupDartSP(kTestStackSpace);
|
||||
EnterTestFrame(assembler);
|
||||
__ Push(THR);
|
||||
__ mov(THR, R1);
|
||||
__ LoadObject(R0, Object::null_object());
|
||||
__ Pop(THR);
|
||||
LeaveTestFrame(assembler);
|
||||
__ mov(CSP, SP);
|
||||
__ ret();
|
||||
|
@ -1722,18 +1717,14 @@ ASSEMBLER_TEST_GENERATE(LoadObjectNull, assembler) {
|
|||
|
||||
|
||||
ASSEMBLER_TEST_RUN(LoadObjectNull, test) {
|
||||
ASSEMBLER_TEST_RUN_WITH_THREAD(RawObject*, result);
|
||||
EXPECT_EQ(Object::null(), result);
|
||||
EXPECT_EQ(Object::null(), test->InvokeWithCodeAndThread<RawObject*>());
|
||||
}
|
||||
|
||||
|
||||
ASSEMBLER_TEST_GENERATE(LoadObjectTrue, assembler) {
|
||||
__ SetupDartSP(kTestStackSpace);
|
||||
EnterTestFrame(assembler);
|
||||
__ Push(THR);
|
||||
__ mov(THR, R1);
|
||||
__ LoadObject(R0, Bool::True());
|
||||
__ Pop(THR);
|
||||
LeaveTestFrame(assembler);
|
||||
__ mov(CSP, SP);
|
||||
__ ret();
|
||||
|
@ -1741,18 +1732,14 @@ ASSEMBLER_TEST_GENERATE(LoadObjectTrue, assembler) {
|
|||
|
||||
|
||||
ASSEMBLER_TEST_RUN(LoadObjectTrue, test) {
|
||||
ASSEMBLER_TEST_RUN_WITH_THREAD(RawObject*, result);
|
||||
EXPECT_EQ(Bool::True().raw(), result);
|
||||
EXPECT_EQ(Bool::True().raw(), test->InvokeWithCodeAndThread<RawObject*>());
|
||||
}
|
||||
|
||||
|
||||
ASSEMBLER_TEST_GENERATE(LoadObjectFalse, assembler) {
|
||||
__ SetupDartSP(kTestStackSpace);
|
||||
EnterTestFrame(assembler);
|
||||
__ Push(THR);
|
||||
__ mov(THR, R1);
|
||||
__ LoadObject(R0, Bool::False());
|
||||
__ Pop(THR);
|
||||
LeaveTestFrame(assembler);
|
||||
__ mov(CSP, SP);
|
||||
__ ret();
|
||||
|
@ -1760,8 +1747,7 @@ ASSEMBLER_TEST_GENERATE(LoadObjectFalse, assembler) {
|
|||
|
||||
|
||||
ASSEMBLER_TEST_RUN(LoadObjectFalse, test) {
|
||||
ASSEMBLER_TEST_RUN_WITH_THREAD(RawObject*, result);
|
||||
EXPECT_EQ(Bool::False().raw(), result);
|
||||
EXPECT_EQ(Bool::False().raw(), test->InvokeWithCodeAndThread<RawObject*>());
|
||||
}
|
||||
|
||||
|
||||
|
@ -3591,7 +3577,7 @@ ASSEMBLER_TEST_GENERATE(ComputeRange, assembler) {
|
|||
__ SetupDartSP(kTestStackSpace);
|
||||
EnterTestFrame(assembler);
|
||||
Label miss, done;
|
||||
__ ComputeRange(R0, R1, R2, &miss);
|
||||
__ ComputeRange(R0, R2, R3, &miss);
|
||||
__ b(&done);
|
||||
|
||||
__ Bind(&miss);
|
||||
|
@ -3605,7 +3591,8 @@ ASSEMBLER_TEST_GENERATE(ComputeRange, assembler) {
|
|||
|
||||
|
||||
ASSEMBLER_TEST_RUN(ComputeRange, test) {
|
||||
#define RANGE_OF(arg_type, v) test->InvokeWithCode<intptr_t, arg_type>(v)
|
||||
#define RANGE_OF(arg_type, v) \
|
||||
test->InvokeWithCodeAndThread<intptr_t, arg_type>(v)
|
||||
|
||||
EXPECT_EQ(ICData::kInt32RangeBit, RANGE_OF(RawSmi*, Smi::New(0)));
|
||||
EXPECT_EQ(ICData::kInt32RangeBit, RANGE_OF(RawSmi*, Smi::New(1)));
|
||||
|
|
|
@ -785,57 +785,29 @@ void Assembler::orps(XmmRegister dst, XmmRegister src) {
|
|||
}
|
||||
|
||||
void Assembler::notps(XmmRegister dst) {
|
||||
static const struct ALIGN16 {
|
||||
uint32_t a;
|
||||
uint32_t b;
|
||||
uint32_t c;
|
||||
uint32_t d;
|
||||
} float_not_constant =
|
||||
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
|
||||
LoadImmediate(
|
||||
TMP, Immediate(reinterpret_cast<intptr_t>(&float_not_constant)));
|
||||
// { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
|
||||
movq(TMP, Address(THR, Thread::float_not_address_offset()));
|
||||
xorps(dst, Address(TMP, 0));
|
||||
}
|
||||
|
||||
|
||||
void Assembler::negateps(XmmRegister dst) {
|
||||
static const struct ALIGN16 {
|
||||
uint32_t a;
|
||||
uint32_t b;
|
||||
uint32_t c;
|
||||
uint32_t d;
|
||||
} float_negate_constant =
|
||||
{ 0x80000000, 0x80000000, 0x80000000, 0x80000000 };
|
||||
LoadImmediate(
|
||||
TMP, Immediate(reinterpret_cast<intptr_t>(&float_negate_constant)));
|
||||
// { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }
|
||||
movq(TMP, Address(THR, Thread::float_negate_address_offset()));
|
||||
xorps(dst, Address(TMP, 0));
|
||||
}
|
||||
|
||||
|
||||
void Assembler::absps(XmmRegister dst) {
|
||||
static const struct ALIGN16 {
|
||||
uint32_t a;
|
||||
uint32_t b;
|
||||
uint32_t c;
|
||||
uint32_t d;
|
||||
} float_absolute_constant =
|
||||
{ 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF };
|
||||
LoadImmediate(
|
||||
TMP, Immediate(reinterpret_cast<intptr_t>(&float_absolute_constant)));
|
||||
// { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF }
|
||||
movq(TMP, Address(THR, Thread::float_absolute_address_offset()));
|
||||
andps(dst, Address(TMP, 0));
|
||||
}
|
||||
|
||||
|
||||
void Assembler::zerowps(XmmRegister dst) {
|
||||
static const struct ALIGN16 {
|
||||
uint32_t a;
|
||||
uint32_t b;
|
||||
uint32_t c;
|
||||
uint32_t d;
|
||||
} float_zerow_constant =
|
||||
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 };
|
||||
LoadImmediate(
|
||||
TMP, Immediate(reinterpret_cast<intptr_t>(&float_zerow_constant)));
|
||||
// { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 }
|
||||
movq(TMP, Address(THR, Thread::float_zerow_address_offset()));
|
||||
andps(dst, Address(TMP, 0));
|
||||
}
|
||||
|
||||
|
@ -1017,13 +989,8 @@ void Assembler::addpd(XmmRegister dst, XmmRegister src) {
|
|||
|
||||
|
||||
void Assembler::negatepd(XmmRegister dst) {
|
||||
static const struct ALIGN16 {
|
||||
uint64_t a;
|
||||
uint64_t b;
|
||||
} double_negate_constant =
|
||||
{ 0x8000000000000000LL, 0x8000000000000000LL };
|
||||
LoadImmediate(
|
||||
TMP, Immediate(reinterpret_cast<intptr_t>(&double_negate_constant)));
|
||||
// { 0x8000000000000000LL, 0x8000000000000000LL }
|
||||
movq(TMP, Address(THR, Thread::double_negate_address_offset()));
|
||||
xorpd(dst, Address(TMP, 0));
|
||||
}
|
||||
|
||||
|
@ -1065,13 +1032,8 @@ void Assembler::divpd(XmmRegister dst, XmmRegister src) {
|
|||
|
||||
|
||||
void Assembler::abspd(XmmRegister dst) {
|
||||
static const struct ALIGN16 {
|
||||
uint64_t a;
|
||||
uint64_t b;
|
||||
} double_absolute_const =
|
||||
{ 0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL };
|
||||
LoadImmediate(
|
||||
TMP, Immediate(reinterpret_cast<intptr_t>(&double_absolute_const)));
|
||||
// { 0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL }
|
||||
movq(TMP, Address(THR, Thread::double_abs_address_offset()));
|
||||
andpd(dst, Address(TMP, 0));
|
||||
}
|
||||
|
||||
|
@ -3160,25 +3122,15 @@ void Assembler::IncrementSmiField(const Address& dest, int64_t increment) {
|
|||
|
||||
|
||||
void Assembler::DoubleNegate(XmmRegister d) {
|
||||
static const struct ALIGN16 {
|
||||
uint64_t a;
|
||||
uint64_t b;
|
||||
} double_negate_constant =
|
||||
{0x8000000000000000LL, 0x8000000000000000LL};
|
||||
LoadImmediate(
|
||||
TMP, Immediate(reinterpret_cast<intptr_t>(&double_negate_constant)));
|
||||
// {0x8000000000000000LL, 0x8000000000000000LL}
|
||||
movq(TMP, Address(THR, Thread::double_negate_address_offset()));
|
||||
xorpd(d, Address(TMP, 0));
|
||||
}
|
||||
|
||||
|
||||
void Assembler::DoubleAbs(XmmRegister reg) {
|
||||
static const struct ALIGN16 {
|
||||
uint64_t a;
|
||||
uint64_t b;
|
||||
} double_abs_constant =
|
||||
{0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL};
|
||||
LoadImmediate(TMP,
|
||||
Immediate(reinterpret_cast<intptr_t>(&double_abs_constant)));
|
||||
// {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL}
|
||||
movq(TMP, Address(THR, Thread::double_abs_address_offset()));
|
||||
andpd(reg, Address(TMP, 0));
|
||||
}
|
||||
|
||||
|
|
|
@ -2021,16 +2021,21 @@ ASSEMBLER_TEST_RUN(PackedDoubleSub, test) {
|
|||
|
||||
|
||||
static void EnterTestFrame(Assembler* assembler) {
|
||||
COMPILE_ASSERT(THR != CallingConventions::kArg1Reg);
|
||||
COMPILE_ASSERT(CODE_REG != CallingConventions::kArg2Reg);
|
||||
__ EnterFrame(0);
|
||||
__ pushq(CODE_REG);
|
||||
__ pushq(PP);
|
||||
__ pushq(THR);
|
||||
__ movq(CODE_REG, Address(CallingConventions::kArg1Reg,
|
||||
VMHandles::kOffsetOfRawPtrInHandle));
|
||||
__ movq(THR, CallingConventions::kArg2Reg);
|
||||
__ LoadPoolPointer(PP);
|
||||
}
|
||||
|
||||
|
||||
static void LeaveTestFrame(Assembler* assembler) {
|
||||
__ popq(THR);
|
||||
__ popq(PP);
|
||||
__ popq(CODE_REG);
|
||||
__ LeaveFrame();
|
||||
|
@ -2053,7 +2058,7 @@ ASSEMBLER_TEST_GENERATE(PackedDoubleNegate, assembler) {
|
|||
|
||||
|
||||
ASSEMBLER_TEST_RUN(PackedDoubleNegate, test) {
|
||||
double res = test->InvokeWithCode<double>();
|
||||
double res = test->InvokeWithCodeAndThread<double>();
|
||||
EXPECT_FLOAT_EQ(-1.0, res, 0.000001f);
|
||||
}
|
||||
|
||||
|
@ -2074,7 +2079,7 @@ ASSEMBLER_TEST_GENERATE(PackedDoubleAbsolute, assembler) {
|
|||
|
||||
|
||||
ASSEMBLER_TEST_RUN(PackedDoubleAbsolute, test) {
|
||||
double res = test->InvokeWithCode<double>();
|
||||
double res = test->InvokeWithCodeAndThread<double>();
|
||||
EXPECT_FLOAT_EQ(1.0, res, 0.000001f);
|
||||
}
|
||||
|
||||
|
@ -2520,7 +2525,7 @@ ASSEMBLER_TEST_GENERATE(PackedNegate, assembler) {
|
|||
|
||||
|
||||
ASSEMBLER_TEST_RUN(PackedNegate, test) {
|
||||
float res = test->InvokeWithCode<float>();
|
||||
float res = test->InvokeWithCodeAndThread<float>();
|
||||
EXPECT_FLOAT_EQ(-12.3f, res, 0.001f);
|
||||
}
|
||||
|
||||
|
@ -2538,7 +2543,7 @@ ASSEMBLER_TEST_GENERATE(PackedAbsolute, assembler) {
|
|||
|
||||
|
||||
ASSEMBLER_TEST_RUN(PackedAbsolute, test) {
|
||||
float res = test->InvokeWithCode<float>();
|
||||
float res = test->InvokeWithCodeAndThread<float>();
|
||||
EXPECT_FLOAT_EQ(15.3f, res, 0.001f);
|
||||
}
|
||||
|
||||
|
@ -2554,7 +2559,7 @@ ASSEMBLER_TEST_GENERATE(PackedSetWZero, assembler) {
|
|||
|
||||
|
||||
ASSEMBLER_TEST_RUN(PackedSetWZero, test) {
|
||||
float res = test->InvokeWithCode<float>();
|
||||
float res = test->InvokeWithCodeAndThread<float>();
|
||||
EXPECT_FLOAT_EQ(0.0f, res, 0.001f);
|
||||
}
|
||||
|
||||
|
@ -2678,7 +2683,7 @@ ASSEMBLER_TEST_GENERATE(PackedLogicalNot, assembler) {
|
|||
|
||||
|
||||
ASSEMBLER_TEST_RUN(PackedLogicalNot, test) {
|
||||
uint32_t res = test->InvokeWithCode<uint32_t>();
|
||||
uint32_t res = test->InvokeWithCodeAndThread<uint32_t>();
|
||||
EXPECT_EQ(static_cast<uword>(0x0), res);
|
||||
}
|
||||
|
||||
|
@ -3103,7 +3108,7 @@ ASSEMBLER_TEST_GENERATE(TestObjectCompare, assembler) {
|
|||
|
||||
|
||||
ASSEMBLER_TEST_RUN(TestObjectCompare, test) {
|
||||
bool res = test->InvokeWithCode<bool>();
|
||||
bool res = test->InvokeWithCodeAndThread<bool>();
|
||||
EXPECT_EQ(true, res);
|
||||
}
|
||||
|
||||
|
@ -3415,10 +3420,13 @@ ASSEMBLER_TEST_RUN(DoubleToDoubleTrunc, test) {
|
|||
ASSEMBLER_TEST_GENERATE(DoubleAbs, assembler) {
|
||||
EnterTestFrame(assembler);
|
||||
#if defined(TARGET_OS_WINDOWS)
|
||||
// First argument is code object, MSVC passes second argument in XMM1.
|
||||
__ DoubleAbs(XMM1);
|
||||
__ movaps(XMM0, XMM1);
|
||||
// First argument is code object, second argument is thread. MSVC passes
|
||||
// third argument in XMM2.
|
||||
__ DoubleAbs(XMM2);
|
||||
__ movaps(XMM0, XMM2);
|
||||
#else
|
||||
// SysV ABI allocates integral and double registers for arguments
|
||||
// independently.
|
||||
__ DoubleAbs(XMM0);
|
||||
#endif
|
||||
LeaveTestFrame(assembler);
|
||||
|
@ -3428,10 +3436,10 @@ ASSEMBLER_TEST_GENERATE(DoubleAbs, assembler) {
|
|||
|
||||
ASSEMBLER_TEST_RUN(DoubleAbs, test) {
|
||||
double val = -12.45;
|
||||
double res = test->InvokeWithCode<double, double>(val);
|
||||
double res = test->InvokeWithCodeAndThread<double, double>(val);
|
||||
EXPECT_FLOAT_EQ(-val, res, 0.001);
|
||||
val = 12.45;
|
||||
res = test->InvokeWithCode<double, double>(val);
|
||||
res = test->InvokeWithCodeAndThread<double, double>(val);
|
||||
EXPECT_FLOAT_EQ(val, res, 0.001);
|
||||
}
|
||||
|
||||
|
|
|
@ -87,6 +87,51 @@ LEAF_RUNTIME_ENTRY_LIST(DEFAULT_INIT)
|
|||
}
|
||||
|
||||
|
||||
static const struct ALIGN16 {
|
||||
uint64_t a;
|
||||
uint64_t b;
|
||||
} double_negate_constant =
|
||||
{0x8000000000000000LL, 0x8000000000000000LL};
|
||||
|
||||
static const struct ALIGN16 {
|
||||
uint64_t a;
|
||||
uint64_t b;
|
||||
} double_abs_constant =
|
||||
{0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL};
|
||||
|
||||
static const struct ALIGN16 {
|
||||
uint32_t a;
|
||||
uint32_t b;
|
||||
uint32_t c;
|
||||
uint32_t d;
|
||||
} float_not_constant =
|
||||
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
|
||||
|
||||
static const struct ALIGN16 {
|
||||
uint32_t a;
|
||||
uint32_t b;
|
||||
uint32_t c;
|
||||
uint32_t d;
|
||||
} float_negate_constant =
|
||||
{ 0x80000000, 0x80000000, 0x80000000, 0x80000000 };
|
||||
|
||||
static const struct ALIGN16 {
|
||||
uint32_t a;
|
||||
uint32_t b;
|
||||
uint32_t c;
|
||||
uint32_t d;
|
||||
} float_absolute_constant =
|
||||
{ 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF };
|
||||
|
||||
static const struct ALIGN16 {
|
||||
uint32_t a;
|
||||
uint32_t b;
|
||||
uint32_t c;
|
||||
uint32_t d;
|
||||
} float_zerow_constant =
|
||||
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 };
|
||||
|
||||
|
||||
void Thread::InitVMConstants() {
|
||||
#define ASSERT_VM_HEAP(type_name, member_name, init_expr, default_init_value) \
|
||||
ASSERT((init_expr)->IsOldObject());
|
||||
|
|
|
@ -79,7 +79,6 @@ class Zone;
|
|||
V(RawCode*, invoke_dart_code_stub_, \
|
||||
StubCode::InvokeDartCode_entry()->code(), NULL) \
|
||||
|
||||
|
||||
#define CACHED_ADDRESSES_LIST(V) \
|
||||
V(uword, update_store_buffer_entry_point_, \
|
||||
StubCode::UpdateStoreBuffer_entry()->EntryPoint(), 0) \
|
||||
|
@ -87,12 +86,23 @@ class Zone;
|
|||
NativeEntry::NativeCallWrapperEntry(), 0) \
|
||||
V(RawString**, predefined_symbols_address_, \
|
||||
Symbols::PredefinedAddress(), NULL) \
|
||||
V(uword, double_negate_address_, \
|
||||
reinterpret_cast<uword>(&double_negate_constant), 0) \
|
||||
V(uword, double_abs_address_, \
|
||||
reinterpret_cast<uword>(&double_abs_constant), 0) \
|
||||
V(uword, float_not_address_, \
|
||||
reinterpret_cast<uword>(&float_not_constant), 0) \
|
||||
V(uword, float_negate_address_, \
|
||||
reinterpret_cast<uword>(&float_negate_constant), 0) \
|
||||
V(uword, float_absolute_address_, \
|
||||
reinterpret_cast<uword>(&float_absolute_constant), 0) \
|
||||
V(uword, float_zerow_address_, \
|
||||
reinterpret_cast<uword>(&float_zerow_constant), 0) \
|
||||
|
||||
#define CACHED_CONSTANTS_LIST(V) \
|
||||
CACHED_VM_OBJECTS_LIST(V) \
|
||||
CACHED_ADDRESSES_LIST(V) \
|
||||
|
||||
|
||||
// A VM thread; may be executing Dart code or performing helper tasks like
|
||||
// garbage collection or compilation. The Thread structure associated with
|
||||
// a thread is allocated by EnsureInit before entering an isolate, and destroyed
|
||||
|
|
|
@ -360,36 +360,44 @@ class AssemblerTest {
|
|||
|
||||
uword entry() const { return code_.EntryPoint(); }
|
||||
|
||||
// Invoke/InvokeWithCode is used to call assembler test functions using the
|
||||
// ABI calling convention.
|
||||
// Invoke/InvokeWithCodeAndThread is used to call assembler test functions
|
||||
// using the ABI calling convention.
|
||||
// ResultType is the return type of the assembler test function.
|
||||
// ArgNType is the type of the Nth argument.
|
||||
#if defined(USING_SIMULATOR)
|
||||
|
||||
#if defined(ARCH_IS_64_BIT)
|
||||
// TODO(fschneider): Make InvokeWithCode<> more general and work on 32-bit.
|
||||
// TODO(fschneider): Make InvokeWithCodeAndThread<> more general and work on
|
||||
// 32-bit.
|
||||
// Since Simulator::Call always return a int64_t, bit_cast does not work
|
||||
// on 32-bit platforms when returning an int32_t. Since template functions
|
||||
// don't support partial specialization, we'd need to introduce a helper
|
||||
// class to support 32-bit return types.
|
||||
template<typename ResultType> ResultType InvokeWithCode() {
|
||||
template<typename ResultType> ResultType InvokeWithCodeAndThread() {
|
||||
const bool fp_return = is_double<ResultType>::value;
|
||||
const bool fp_args = false;
|
||||
Thread* thread = Thread::Current();
|
||||
ASSERT(thread != NULL);
|
||||
return bit_cast<ResultType, int64_t>(Simulator::Current()->Call(
|
||||
bit_cast<intptr_t, uword>(entry()),
|
||||
reinterpret_cast<intptr_t>(&code_), 0, 0, 0, fp_return, fp_args));
|
||||
reinterpret_cast<intptr_t>(&code_),
|
||||
reinterpret_cast<intptr_t>(thread),
|
||||
0, 0, fp_return, fp_args));
|
||||
}
|
||||
template<typename ResultType, typename Arg1Type>
|
||||
ResultType InvokeWithCode(Arg1Type arg1) {
|
||||
ResultType InvokeWithCodeAndThread(Arg1Type arg1) {
|
||||
const bool fp_return = is_double<ResultType>::value;
|
||||
const bool fp_args = is_double<Arg1Type>::value;
|
||||
// TODO(fschneider): Support double arguments for simulator calls.
|
||||
COMPILE_ASSERT(!fp_args);
|
||||
Thread* thread = Thread::Current();
|
||||
ASSERT(thread != NULL);
|
||||
return bit_cast<ResultType, int64_t>(Simulator::Current()->Call(
|
||||
bit_cast<intptr_t, uword>(entry()),
|
||||
reinterpret_cast<intptr_t>(&code_),
|
||||
reinterpret_cast<intptr_t>(thread),
|
||||
reinterpret_cast<intptr_t>(arg1),
|
||||
0, 0, fp_return, fp_args));
|
||||
0, fp_return, fp_args));
|
||||
}
|
||||
#endif // ARCH_IS_64_BIT
|
||||
|
||||
|
@ -413,15 +421,19 @@ class AssemblerTest {
|
|||
0, fp_return, fp_args);
|
||||
}
|
||||
#else
|
||||
template<typename ResultType> ResultType InvokeWithCode() {
|
||||
typedef ResultType (*FunctionType) (const Code&);
|
||||
return reinterpret_cast<FunctionType>(entry())(code_);
|
||||
template<typename ResultType> ResultType InvokeWithCodeAndThread() {
|
||||
Thread* thread = Thread::Current();
|
||||
ASSERT(thread != NULL);
|
||||
typedef ResultType (*FunctionType) (const Code&, Thread*);
|
||||
return reinterpret_cast<FunctionType>(entry())(code_, thread);
|
||||
}
|
||||
|
||||
template<typename ResultType, typename Arg1Type>
|
||||
ResultType InvokeWithCode(Arg1Type arg1) {
|
||||
typedef ResultType (*FunctionType) (const Code&, Arg1Type);
|
||||
return reinterpret_cast<FunctionType>(entry())(code_, arg1);
|
||||
ResultType InvokeWithCodeAndThread(Arg1Type arg1) {
|
||||
Thread* thread = Thread::Current();
|
||||
ASSERT(thread != NULL);
|
||||
typedef ResultType (*FunctionType) (const Code&, Thread*, Arg1Type);
|
||||
return reinterpret_cast<FunctionType>(entry())(code_, thread, arg1);
|
||||
}
|
||||
|
||||
template<typename ResultType,
|
||||
|
|
Loading…
Reference in a new issue