Commit 1f068187 authored by dusan.simicic's avatar dusan.simicic Committed by Commit bot

MIPS[64]: Implement fill.df, copy_u.df, copy_s.df instructions in simulator

- Increase FPUregisters_[] element size to 128b in order to support MSA regs
- Add skeleton for MSA instr. decoding in mips32 and mips64 simulator
- Add support for fill.df, copy_u.df and copy_s.df MSA instructions
- Assembler test for fill.df, copy_u.df and copy_s.df

BUG=

Review-Url: https://codereview.chromium.org/2799923002
Cr-Commit-Position: refs/heads/master@{#45529}
parent b67139bf
......@@ -370,6 +370,16 @@ const int kImm5Mask = ((1 << 5) - 1);
const int kImm8Mask = ((1 << 8) - 1);
const int kImm10Mask = ((1 << 10) - 1);
const int kMsaI5I10Mask = ((7U << 23) | ((1 << 6) - 1));
const int kMsaI8Mask = ((3U << 24) | ((1 << 6) - 1));
const int kMsaI5Mask = ((7U << 23) | ((1 << 6) - 1));
const int kMsaMI10Mask = (15U << 2);
const int kMsaBITMask = ((7U << 23) | ((1 << 6) - 1));
const int kMsaELMMask = (15U << 22);
const int kMsa3RMask = ((7U << 23) | ((1 << 6) - 1));
const int kMsa3RFMask = ((15U << 22) | ((1 << 6) - 1));
const int kMsaVECMask = (23U << 21);
const int kMsa2RMask = (7U << 18);
const int kMsa2RFMask = (15U << 17);
const int kRsFieldMask = ((1 << kRsBits) - 1) << kRsShift;
const int kRtFieldMask = ((1 << kRtBits) - 1) << kRtShift;
const int kRdFieldMask = ((1 << kRdBits) - 1) << kRdShift;
......
......@@ -59,17 +59,6 @@ class Decoder {
int InstructionDecode(byte* instruction);
private:
const uint32_t kMsaI8Mask = ((3U << 24) | ((1 << 6) - 1));
const uint32_t kMsaI5Mask = ((7U << 23) | ((1 << 6) - 1));
const uint32_t kMsaMI10Mask = (15U << 2);
const uint32_t kMsaBITMask = ((7U << 23) | ((1 << 6) - 1));
const uint32_t kMsaELMMask = (15U << 22);
const uint32_t kMsa3RMask = ((7U << 23) | ((1 << 6) - 1));
const uint32_t kMsa3RFMask = ((15U << 22) | ((1 << 6) - 1));
const uint32_t kMsaVECMask = (23U << 21);
const uint32_t kMsa2RMask = (7U << 18);
const uint32_t kMsa2RFMask = (15U << 17);
// Bottleneck functions to print into the out_buffer.
void PrintChar(const char ch);
void Print(const char* str);
......
This diff is collapsed.
......@@ -181,6 +181,43 @@ class Simulator {
kNumFPURegisters
};
// MSA registers
enum MSARegister {
w0,
w1,
w2,
w3,
w4,
w5,
w6,
w7,
w8,
w9,
w10,
w11,
w12,
w13,
w14,
w15,
w16,
w17,
w18,
w19,
w20,
w21,
w22,
w23,
w24,
w25,
w26,
w27,
w28,
w29,
w30,
w31,
kNumMSARegisters
};
explicit Simulator(Isolate* isolate);
~Simulator();
......@@ -213,6 +250,10 @@ class Simulator {
int32_t get_fpu_register_hi_word(int fpureg) const;
float get_fpu_register_float(int fpureg) const;
double get_fpu_register_double(int fpureg) const;
template <typename T>
void get_msa_register(int wreg, T* value);
template <typename T>
void set_msa_register(int wreg, const T* value);
void set_fcsr_bit(uint32_t cc, bool value);
bool test_fcsr_bit(uint32_t cc);
void set_fcsr_rounding_mode(FPURoundingMode mode);
......@@ -293,6 +334,9 @@ class Simulator {
// Helpers for data value tracing.
enum TraceType { BYTE, HALF, WORD, DWORD, FLOAT, DOUBLE, FLOAT_DOUBLE };
// MSA Data Format
enum MSADataFormat { MSA_VECT = 0, MSA_BYTE, MSA_HALF, MSA_WORD, MSA_DWORD };
// Read and write memory.
inline uint32_t ReadBU(int32_t addr);
inline int32_t ReadB(int32_t addr);
......@@ -313,6 +357,8 @@ class Simulator {
void TraceRegWr(int32_t value, TraceType t = WORD);
void TraceRegWr(int64_t value, TraceType t = DWORD);
template <typename T>
void TraceMSARegWr(T* value, TraceType t);
void TraceMemWr(int32_t addr, int32_t value, TraceType t = WORD);
void TraceMemRd(int32_t addr, int32_t value, TraceType t = WORD);
void TraceMemWr(int32_t addr, int64_t value, TraceType t = DWORD);
......@@ -352,6 +398,19 @@ class Simulator {
void DecodeTypeRegisterLRsType();
int DecodeMsaDataFormat();
void DecodeTypeMsaI8();
void DecodeTypeMsaI5();
void DecodeTypeMsaI10();
void DecodeTypeMsaELM();
void DecodeTypeMsaBIT();
void DecodeTypeMsaMI10();
void DecodeTypeMsa3R();
void DecodeTypeMsa3RF();
void DecodeTypeMsaVec();
void DecodeTypeMsa2R();
void DecodeTypeMsa2RF();
inline int32_t rs_reg() const { return instr_.RsValue(); }
inline int32_t rs() const { return get_register(rs_reg()); }
inline uint32_t rs_u() const {
......@@ -369,6 +428,9 @@ class Simulator {
inline int32_t fd_reg() const { return instr_.FdValue(); }
inline int32_t sa() const { return instr_.SaValue(); }
inline int32_t lsa_sa() const { return instr_.LsaSaValue(); }
inline int32_t ws_reg() const { return instr_.WsValue(); }
inline int32_t wt_reg() const { return instr_.WtValue(); }
inline int32_t wd_reg() const { return instr_.WdValue(); }
inline void SetResult(int32_t rd_reg, int32_t alu_out) {
set_register(rd_reg, alu_out);
......@@ -480,7 +542,9 @@ class Simulator {
// Coprocessor Registers.
// Note: FP32 mode uses only the lower 32-bit part of each element,
// the upper 32-bit is unpredictable.
int64_t FPUregisters_[kNumFPURegisters];
// Note: FPUregisters_[] array is increased to 64 * 8B = 32 * 16B in
// order to support MSA registers
int64_t FPUregisters_[kNumFPURegisters * 2];
// FPU control register.
uint32_t FCSR_;
......
......@@ -333,6 +333,16 @@ const int kImm5Mask = ((1 << 5) - 1);
const int kImm8Mask = ((1 << 8) - 1);
const int kImm10Mask = ((1 << 10) - 1);
const int kMsaI5I10Mask = ((7U << 23) | ((1 << 6) - 1));
const int kMsaI8Mask = ((3U << 24) | ((1 << 6) - 1));
const int kMsaI5Mask = ((7U << 23) | ((1 << 6) - 1));
const int kMsaMI10Mask = (15U << 2);
const int kMsaBITMask = ((7U << 23) | ((1 << 6) - 1));
const int kMsaELMMask = (15U << 22);
const int kMsa3RMask = ((7U << 23) | ((1 << 6) - 1));
const int kMsa3RFMask = ((15U << 22) | ((1 << 6) - 1));
const int kMsaVECMask = (23U << 21);
const int kMsa2RMask = (7U << 18);
const int kMsa2RFMask = (15U << 17);
const int kRsFieldMask = ((1 << kRsBits) - 1) << kRsShift;
const int kRtFieldMask = ((1 << kRtBits) - 1) << kRtShift;
const int kRdFieldMask = ((1 << kRdBits) - 1) << kRdShift;
......
......@@ -60,17 +60,6 @@ class Decoder {
int InstructionDecode(byte* instruction);
private:
const uint32_t kMsaI8Mask = ((3U << 24) | ((1 << 6) - 1));
const uint32_t kMsaI5Mask = ((7U << 23) | ((1 << 6) - 1));
const uint32_t kMsaMI10Mask = (15U << 2);
const uint32_t kMsaBITMask = ((7U << 23) | ((1 << 6) - 1));
const uint32_t kMsaELMMask = (15U << 22);
const uint32_t kMsa3RMask = ((7U << 23) | ((1 << 6) - 1));
const uint32_t kMsa3RFMask = ((15U << 22) | ((1 << 6) - 1));
const uint32_t kMsaVECMask = (23U << 21);
const uint32_t kMsa2RMask = (7U << 18);
const uint32_t kMsa2RFMask = (15U << 17);
// Bottleneck functions to print into the out_buffer.
void PrintChar(const char ch);
void Print(const char* str);
......
This diff is collapsed.
......@@ -189,6 +189,43 @@ class Simulator {
kNumFPURegisters
};
// MSA registers
enum MSARegister {
w0,
w1,
w2,
w3,
w4,
w5,
w6,
w7,
w8,
w9,
w10,
w11,
w12,
w13,
w14,
w15,
w16,
w17,
w18,
w19,
w20,
w21,
w22,
w23,
w24,
w25,
w26,
w27,
w28,
w29,
w30,
w31,
kNumMSARegisters
};
explicit Simulator(Isolate* isolate);
~Simulator();
......@@ -222,6 +259,10 @@ class Simulator {
int32_t get_fpu_register_hi_word(int fpureg) const;
float get_fpu_register_float(int fpureg) const;
double get_fpu_register_double(int fpureg) const;
template <typename T>
void get_msa_register(int wreg, T* value);
template <typename T>
void set_msa_register(int wreg, const T* value);
void set_fcsr_bit(uint32_t cc, bool value);
bool test_fcsr_bit(uint32_t cc);
bool set_fcsr_round_error(double original, double rounded);
......@@ -311,6 +352,9 @@ class Simulator {
WORD_DWORD
};
// MSA Data Format
enum MSADataFormat { MSA_VECT = 0, MSA_BYTE, MSA_HALF, MSA_WORD, MSA_DWORD };
// Read and write memory.
inline uint32_t ReadBU(int64_t addr);
inline int32_t ReadB(int64_t addr);
......@@ -336,6 +380,8 @@ class Simulator {
inline void DieOrDebug();
void TraceRegWr(int64_t value, TraceType t = DWORD);
template <typename T>
void TraceMSARegWr(T* value, TraceType t);
void TraceMemWr(int64_t addr, int64_t value, TraceType t);
void TraceMemRd(int64_t addr, int64_t value, TraceType t = DWORD);
......@@ -369,6 +415,19 @@ class Simulator {
void DecodeTypeRegisterLRsType();
int DecodeMsaDataFormat();
void DecodeTypeMsaI8();
void DecodeTypeMsaI5();
void DecodeTypeMsaI10();
void DecodeTypeMsaELM();
void DecodeTypeMsaBIT();
void DecodeTypeMsaMI10();
void DecodeTypeMsa3R();
void DecodeTypeMsa3RF();
void DecodeTypeMsaVec();
void DecodeTypeMsa2R();
void DecodeTypeMsa2RF();
// Executing is handled based on the instruction type.
void DecodeTypeRegister();
......@@ -389,6 +448,9 @@ class Simulator {
inline int32_t fd_reg() const { return instr_.FdValue(); }
inline int32_t sa() const { return instr_.SaValue(); }
inline int32_t lsa_sa() const { return instr_.LsaSaValue(); }
inline int32_t ws_reg() const { return instr_.WsValue(); }
inline int32_t wt_reg() const { return instr_.WtValue(); }
inline int32_t wd_reg() const { return instr_.WdValue(); }
inline void SetResult(const int32_t rd_reg, const int64_t alu_out) {
set_register(rd_reg, alu_out);
......@@ -508,7 +570,9 @@ class Simulator {
// Registers.
int64_t registers_[kNumSimuRegisters];
// Coprocessor Registers.
int64_t FPUregisters_[kNumFPURegisters];
// Note: FPUregisters_[] array is increased to 64 * 8B = 32 * 16B in
// order to support MSA registers
int64_t FPUregisters_[kNumFPURegisters * 2];
// FPU control register.
uint32_t FCSR_;
......
......@@ -46,7 +46,7 @@ using namespace v8::internal;
typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4);
typedef Object* (*F2)(int x, int y, int p2, int p3, int p4);
typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4);
typedef Object* (*F4)(void* p0, void* p1, int p2, int p3, int p4);
#define __ assm.
......@@ -5587,4 +5587,192 @@ TEST(Subu) {
}
}
TEST(MSA_fill_copy) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
typedef struct {
uint32_t u8;
uint32_t u16;
uint32_t u32;
uint32_t s8;
uint32_t s16;
uint32_t s32;
} T;
T t;
MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
if (!IsMipsArchVariant(kMips32r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
return;
{
CpuFeatureScope fscope(&assm, MIPS_SIMD);
__ li(t0, 0xa512b683);
__ fill_b(w0, t0);
__ fill_h(w2, t0);
__ fill_w(w4, t0);
__ copy_u_b(t1, w0, 11);
__ sw(t1, MemOperand(a0, offsetof(T, u8)));
__ copy_u_h(t1, w2, 6);
__ sw(t1, MemOperand(a0, offsetof(T, u16)));
__ copy_u_w(t1, w4, 3);
__ sw(t1, MemOperand(a0, offsetof(T, u32)));
__ copy_s_b(t1, w0, 8);
__ sw(t1, MemOperand(a0, offsetof(T, s8)));
__ copy_s_h(t1, w2, 5);
__ sw(t1, MemOperand(a0, offsetof(T, s16)));
__ copy_s_w(t1, w4, 1);
__ sw(t1, MemOperand(a0, offsetof(T, s32)));
__ jr(ra);
__ nop();
}
CodeDesc desc;
assm.GetCode(&desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
F3 f = FUNCTION_CAST<F3>(code->entry());
Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
USE(dummy);
CHECK_EQ(0x83u, t.u8);
CHECK_EQ(0xb683u, t.u16);
CHECK_EQ(0xa512b683u, t.u32);
CHECK_EQ(0xffffff83u, t.s8);
CHECK_EQ(0xffffb683u, t.s16);
CHECK_EQ(0xa512b683u, t.s32);
}
TEST(MSA_fill_copy_2) {
// Similar to MSA_fill_copy test, but also check overlaping between MSA and
// FPU registers with same numbers
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
typedef struct {
uint32_t w0;
uint32_t w1;
uint32_t w2;
uint32_t w3;
} T;
T t[2];
MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
if (!IsMipsArchVariant(kMips32r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
return;
{
CpuFeatureScope fscope(&assm, MIPS_SIMD);
__ li(t0, 0xaaaaaaaa);
__ li(t1, 0x55555555);
__ fill_w(w0, t0);
__ fill_w(w2, t0);
__ FmoveLow(f0, t1);
__ FmoveHigh(f2, t1);
#define STORE_MSA_REG(w_reg, base, scratch) \
__ copy_u_w(scratch, w_reg, 0); \
__ sw(scratch, MemOperand(base, offsetof(T, w0))); \
__ copy_u_w(scratch, w_reg, 1); \
__ sw(scratch, MemOperand(base, offsetof(T, w1))); \
__ copy_u_w(scratch, w_reg, 2); \
__ sw(scratch, MemOperand(base, offsetof(T, w2))); \
__ copy_u_w(scratch, w_reg, 3); \
__ sw(scratch, MemOperand(base, offsetof(T, w3)));
STORE_MSA_REG(w0, a0, t2)
STORE_MSA_REG(w2, a1, t2)
#undef STORE_MSA_REG
__ jr(ra);
__ nop();
}
CodeDesc desc;
assm.GetCode(&desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
F4 f = FUNCTION_CAST<F4>(code->entry());
Object* dummy = CALL_GENERATED_CODE(isolate, f, &t[0], &t[1], 0, 0, 0);
USE(dummy);
CHECK_EQ(0x55555555, t[0].w0);
CHECK_EQ(0xaaaaaaaa, t[0].w1);
CHECK_EQ(0xaaaaaaaa, t[0].w2);
CHECK_EQ(0xaaaaaaaa, t[0].w3);
CHECK_EQ(0xaaaaaaaa, t[1].w0);
CHECK_EQ(0x55555555, t[1].w1);
CHECK_EQ(0xaaaaaaaa, t[1].w2);
CHECK_EQ(0xaaaaaaaa, t[1].w3);
}
TEST(MSA_fill_copy_3) {
// Similar to MSA_fill_copy test, but also check overlaping between MSA and
// FPU registers with same numbers
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
typedef struct {
uint64_t d0;
uint64_t d1;
} T;
T t[2];
MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
if (!IsMipsArchVariant(kMips32r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
return;
{
CpuFeatureScope fscope(&assm, MIPS_SIMD);
__ li(t0, 0xaaaaaaaa);
__ li(t1, 0x55555555);
__ Move(f0, t0, t0);
__ Move(f2, t0, t0);
__ fill_w(w0, t1);
__ fill_w(w2, t1);
__ Sdc1(f0, MemOperand(a0, offsetof(T, d0)));
__ Sdc1(f2, MemOperand(a1, offsetof(T, d0)));
__ jr(ra);
__ nop();
}
CodeDesc desc;
assm.GetCode(&desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
F4 f = FUNCTION_CAST<F4>(code->entry());
Object* dummy = CALL_GENERATED_CODE(isolate, f, &t[0], &t[1], 0, 0, 0);
USE(dummy);
CHECK_EQ(0x5555555555555555, t[0].d0);
CHECK_EQ(0x5555555555555555, t[1].d0);
}
#undef __
......@@ -46,7 +46,7 @@ typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4);
typedef Object* (*F2)(int x, int y, int p2, int p3, int p4);
typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4);
typedef Object* (*F4)(int64_t x, int64_t y, int64_t p2, int64_t p3, int64_t p4);
typedef Object* (*F5)(void* p0, void* p1, int p2, int p3, int p4);
#define __ assm.
......@@ -6408,4 +6408,187 @@ TEST(Dins) {
}
}
TEST(MSA_fill_copy) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
typedef struct {
uint64_t u8;
uint64_t u16;
uint64_t u32;
uint64_t s8;
uint64_t s16;
uint64_t s32;
uint64_t s64;
} T;
T t;
MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
if ((kArchVariant != kMips64r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
return;
{
CpuFeatureScope fscope(&assm, MIPS_SIMD);
__ li(t0, 0x9e7689aca512b683);
__ fill_b(w0, t0);
__ fill_h(w2, t0);
__ fill_w(w4, t0);
__ fill_d(w6, t0);
__ copy_u_b(t1, w0, 11);
__ sd(t1, MemOperand(a0, offsetof(T, u8)));
__ copy_u_h(t1, w2, 6);
__ sd(t1, MemOperand(a0, offsetof(T, u16)));
__ copy_u_w(t1, w4, 3);
__ sd(t1, MemOperand(a0, offsetof(T, u32)));
__ copy_s_b(t1, w0, 8);
__ sd(t1, MemOperand(a0, offsetof(T, s8)));
__ copy_s_h(t1, w2, 5);
__ sd(t1, MemOperand(a0, offsetof(T, s16)));
__ copy_s_w(t1, w4, 1);
__ sd(t1, MemOperand(a0, offsetof(T, s32)));
__ copy_s_d(t1, w6, 0);
__ sd(t1, MemOperand(a0, offsetof(T, s64)));
__ jr(ra);
__ nop();
}
CodeDesc desc;
assm.GetCode(&desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
F3 f = FUNCTION_CAST<F3>(code->entry());
Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
USE(dummy);
CHECK_EQ(0x83u, t.u8);
CHECK_EQ(0xb683u, t.u16);
CHECK_EQ(0xa512b683u, t.u32);
CHECK_EQ(0xffffffffffffff83u, t.s8);
CHECK_EQ(0xffffffffffffb683u, t.s16);
CHECK_EQ(0xffffffffa512b683u, t.s32);
CHECK_EQ(0x9e7689aca512b683u, t.s64);
}
TEST(MSA_fill_copy_2) {
// Similar to MSA_fill_copy test, but also check overlaping between MSA and
// FPU registers with same numbers
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
typedef struct {
uint64_t d0;
uint64_t d1;
} T;
T t[2];
MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
if ((kArchVariant != kMips64r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
return;
{
CpuFeatureScope fscope(&assm, MIPS_SIMD);
__ li(t0, 0xaaaaaaaaaaaaaaaa);
__ li(t1, 0x5555555555555555);
__ fill_d(w0, t0);
__ fill_d(w2, t0);
__ Move(f0, t1);
__ Move(f2, t1);
#define STORE_MSA_REG(w_reg, base, scratch) \
__ copy_s_d(scratch, w_reg, 0); \
__ sd(scratch, MemOperand(base, offsetof(T, d0))); \
__ copy_s_d(scratch, w_reg, 1); \
__ sd(scratch, MemOperand(base, offsetof(T, d1)));
STORE_MSA_REG(w0, a0, t2)
STORE_MSA_REG(w2, a1, t2)
#undef STORE_MSA_REG
__ jr(ra);
__ nop();
}
CodeDesc desc;
assm.GetCode(&desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
F5 f = FUNCTION_CAST<F5>(code->entry());
Object* dummy = CALL_GENERATED_CODE(isolate, f, &t[0], &t[1], 0, 0, 0);
USE(dummy);
CHECK_EQ(0x5555555555555555, t[0].d0);
CHECK_EQ(0xaaaaaaaaaaaaaaaa, t[0].d1);
CHECK_EQ(0x5555555555555555, t[1].d0);
CHECK_EQ(0xaaaaaaaaaaaaaaaa, t[1].d1);
}
TEST(MSA_fill_copy_3) {
// Similar to MSA_fill_copy test, but also check overlaping between MSA and
// FPU registers with same numbers
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
typedef struct {
uint64_t d0;
uint64_t d1;
} T;
T t[2];
MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
if ((kArchVariant != kMips64r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
return;
{
CpuFeatureScope fscope(&assm, MIPS_SIMD);
__ li(t0, 0xaaaaaaaaaaaaaaaa);
__ li(t1, 0x5555555555555555);
__ Move(f0, t0);
__ Move(f2, t0);
__ fill_d(w0, t1);
__ fill_d(w2, t1);
__ Sdc1(f0, MemOperand(a0, offsetof(T, d0)));
__ Sdc1(f2, MemOperand(a1, offsetof(T, d0)));
__ jr(ra);
__ nop();
}
CodeDesc desc;
assm.GetCode(&desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
F5 f = FUNCTION_CAST<F5>(code->entry());
Object* dummy = CALL_GENERATED_CODE(isolate, f, &t[0], &t[1], 0, 0, 0);
USE(dummy);
CHECK_EQ(0x5555555555555555, t[0].d0);
CHECK_EQ(0x5555555555555555, t[1].d0);
}
#undef __
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment