Commit f00b4e94 authored by dusan.milosavljevic's avatar dusan.milosavljevic Committed by Commit bot

MIPS: Refactor simulator and add selection instructions for r6.

TEST=
BUG=

Review URL: https://codereview.chromium.org/1046873004

Cr-Commit-Position: refs/heads/master@{#27530}
parent 00477a5d
......@@ -1920,6 +1920,34 @@ void Assembler::movf(Register rd, Register rs, uint16_t cc) {
}
void Assembler::seleqz(Register rs, Register rt, Register rd) {
DCHECK(IsMipsArchVariant(kMips32r6));
GenInstrRegister(SPECIAL, rs, rt, rd, 0, SELEQZ_S);
}
void Assembler::seleqz(SecondaryField fmt, FPURegister fd, FPURegister ft,
FPURegister fs) {
DCHECK(IsMipsArchVariant(kMips32r6));
DCHECK((fmt == D) || (fmt == S));
GenInstrRegister(COP1, fmt, ft, fs, fd, SELEQZ_C);
}
void Assembler::selnez(Register rs, Register rt, Register rd) {
DCHECK(IsMipsArchVariant(kMips32r6));
GenInstrRegister(SPECIAL, rs, rt, rd, 0, SELNEZ_S);
}
void Assembler::selnez(SecondaryField fmt, FPURegister fd, FPURegister ft,
FPURegister fs) {
DCHECK(IsMipsArchVariant(kMips32r6));
DCHECK((fmt == D) || (fmt == S));
GenInstrRegister(COP1, fmt, ft, fs, fd, SELNEZ_C);
}
// Bit twiddling.
void Assembler::clz(Register rd, Register rs) {
if (!IsMipsArchVariant(kMips32r6)) {
......
......@@ -252,6 +252,8 @@ Instruction::Type Instruction::InstructionType() const {
case MOVZ:
case MOVN:
case MOVCI:
case SELEQZ_S:
case SELNEZ_S:
return kRegisterType;
default:
return kUnsupported;
......@@ -280,6 +282,8 @@ Instruction::Type Instruction::InstructionType() const {
case BC1: // Branch on coprocessor condition.
case BC1EQZ:
case BC1NEZ:
case SELEQZ_C:
case SELNEZ_C:
return kImmediateType;
default:
return kRegisterType;
......
This diff is collapsed.
This diff is collapsed.
......@@ -265,6 +265,47 @@ class Simulator {
// Executing is handled based on the instruction type.
void DecodeTypeRegister(Instruction* instr);
// Called from DecodeTypeRegisterCOP1
void DecodeTypeRegisterDRsType(Instruction* instr, const int32_t& fr_reg,
const int32_t& fs_reg, const int32_t& ft_reg,
const int32_t& fd_reg);
void DecodeTypeRegisterWRsType(Instruction* instr, int32_t& alu_out,
const int32_t& fd_reg, const int32_t& fs_reg);
void DecodeTypeRegisterSRsType(Instruction* instr, const int32_t& ft_reg,
const int32_t& fs_reg, const int32_t& fd_reg);
void DecodeTypeRegisterLRsType(Instruction* instr, const int32_t& ft_reg,
const int32_t& fs_reg, const int32_t& fd_reg);
// Functions called from DeocodeTypeRegister
void DecodeTypeRegisterCOP1(
Instruction* instr, const int32_t& rs_reg, const int32_t& rs,
const uint32_t& rs_u, const int32_t& rt_reg, const int32_t& rt,
const uint32_t& rt_u, const int32_t& rd_reg, const int32_t& fr_reg,
const int32_t& fs_reg, const int32_t& ft_reg, const int32_t& fd_reg,
int64_t& i64hilo, uint64_t& u64hilo, int32_t& alu_out, bool& do_interrupt,
int32_t& current_pc, int32_t& next_pc, int32_t& return_addr_reg);
void DecodeTypeRegisterCOP1X(Instruction* instr, const int32_t& fr_reg,
const int32_t& fs_reg, const int32_t& ft_reg,
const int32_t& fd_reg);
void DecodeTypeRegisterSPECIAL(
Instruction* instr, const int32_t& rs_reg, const int32_t& rs,
const uint32_t& rs_u, const int32_t& rt_reg, const int32_t& rt,
const uint32_t& rt_u, const int32_t& rd_reg, const int32_t& fr_reg,
const int32_t& fs_reg, const int32_t& ft_reg, const int32_t& fd_reg,
int64_t& i64hilo, uint64_t& u64hilo, int32_t& alu_out, bool& do_interrupt,
int32_t& current_pc, int32_t& next_pc, int32_t& return_addr_reg);
void DecodeTypeRegisterSPECIAL2(Instruction* instr, const int32_t& rd_reg,
int32_t& alu_out);
void DecodeTypeRegisterSPECIAL3(Instruction* instr, const int32_t& rt_reg,
int32_t& alu_out);
// Helper function for DecodeTypeRegister.
void ConfigureTypeRegister(Instruction* instr,
int32_t* alu_out,
......
......@@ -2139,13 +2139,8 @@ void Assembler::seleqz(Register rs, Register rt, Register rd) {
// FPR.
void Assembler::seleqz(SecondaryField fmt, FPURegister fd,
FPURegister ft, FPURegister fs) {
DCHECK(kArchVariant == kMips64r6);
DCHECK(fmt == D);
DCHECK(fmt == S);
Instr instr = COP1 | fmt << kRsShift | ft.code() << kFtShift |
fs.code() << kFsShift | fd.code() << kFdShift | SELEQZ_C;
emit(instr);
DCHECK((fmt == D) || (fmt == S));
GenInstrRegister(COP1, fmt, ft, fs, fd, SELEQZ_C);
}
......@@ -2160,12 +2155,8 @@ void Assembler::selnez(Register rs, Register rt, Register rd) {
void Assembler::selnez(SecondaryField fmt, FPURegister fd,
FPURegister ft, FPURegister fs) {
DCHECK(kArchVariant == kMips64r6);
DCHECK(fmt == D);
DCHECK(fmt == S);
Instr instr = COP1 | fmt << kRsShift | ft.code() << kFtShift |
fs.code() << kFsShift | fd.code() << kFdShift | SELNEZ_C;
emit(instr);
DCHECK((fmt == D) || (fmt == S));
GenInstrRegister(COP1, fmt, ft, fs, fd, SELNEZ_C);
}
......
......@@ -269,6 +269,8 @@ Instruction::Type Instruction::InstructionType() const {
case MOVZ:
case MOVN:
case MOVCI:
case SELEQZ_S:
case SELNEZ_S:
return kRegisterType;
default:
return kUnsupported;
......
This diff is collapsed.
This diff is collapsed.
......@@ -312,6 +312,45 @@ class Simulator {
inline int32_t SetDoubleHIW(double* addr);
inline int32_t SetDoubleLOW(double* addr);
// functions called from DecodeTypeRegister
void DecodeTypeRegisterCOP1(Instruction* instr, const int64_t& rs_reg,
const int64_t& rs, const uint64_t& rs_u,
const int64_t& rt_reg, const int64_t& rt,
const uint64_t& rt_u, const int64_t& rd_reg,
const int32_t& fr_reg, const int32_t& fs_reg,
const int32_t& ft_reg, const int64_t& fd_reg,
int64_t& alu_out);
void DecodeTypeRegisterCOP1X(Instruction* instr, const int32_t& fr_reg,
const int32_t& fs_reg, const int32_t& ft_reg,
const int64_t& fd_reg);
void DecodeTypeRegisterSPECIAL(
Instruction* instr, const int64_t& rs_reg, const int64_t& rs,
const uint64_t& rs_u, const int64_t& rt_reg, const int64_t& rt,
const uint64_t& rt_u, const int64_t& rd_reg, const int32_t& fr_reg,
const int32_t& fs_reg, const int32_t& ft_reg, const int64_t& fd_reg,
int64_t& i64hilo, uint64_t& u64hilo, int64_t& alu_out, bool& do_interrupt,
int64_t& current_pc, int64_t& next_pc, int64_t& return_addr_reg,
int64_t& i128resultH, int64_t& i128resultL);
void DecodeTypeRegisterSPECIAL2(Instruction* instr, const int64_t& rd_reg,
int64_t& alu_out);
void DecodeTypeRegisterSPECIAL3(Instruction* instr, const int64_t& rt_reg,
int64_t& alu_out);
void DecodeTypeRegisterSRsType(Instruction* instr, const int32_t& fs_reg,
const int64_t& fd_reg);
void DecodeTypeRegisterDRsType(Instruction* instr, const int32_t& fs_reg,
const int64_t& ft_reg, const int32_t& fd_reg);
void DecodeTypeRegisterWRsType(Instruction* instr, const int32_t& fs_reg,
const int32_t& fd_reg, int64_t& alu_out);
void DecodeTypeRegisterLRsType(Instruction* instr, const int32_t& fs_reg,
const int32_t& fd_reg, const int32_t& ft_reg);
// Executing is handled based on the instruction type.
void DecodeTypeRegister(Instruction* instr);
......
......@@ -48,6 +48,93 @@ typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4);
#define __ assm.
TEST(MIPS16) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
MacroAssembler assm(isolate, NULL, 0);
typedef struct test {
int a;
int b;
int c;
int d;
double e;
double f;
double g;
double h;
double i;
double j;
double k;
double l;
} Test;
Test test;
// integer part of test
__ addiu(t1, zero_reg, 1); // t1=1
__ seleqz(t1, zero_reg, t3); // t3=1
__ sw(t3, MemOperand(a0, OFFSET_OF(Test, a))); // a=1
__ seleqz(t1, t1, t2); // t2=0
__ sw(t2, MemOperand(a0, OFFSET_OF(Test, b))); // b=0
__ selnez(t1, zero_reg, t3); // t3=1;
__ sw(t3, MemOperand(a0, OFFSET_OF(Test, c))); // c=0
__ selnez(t1, t1, t3); // t3=1
__ sw(t3, MemOperand(a0, OFFSET_OF(Test, d))); // d=1
// floating point part of test S format
__ li(t0, 0x80);
__ mtc1(t0, f4);
__ cvt_d_w(f4, f4); // f4=0x80
__ li(t0, 0xf3);
__ mtc1(t0, f6);
__ cvt_d_w(f6, f6); // f6=0xf3
__ seleqz(S, f8, f4, f6); // f8=0xf3
__ seleqz(S, f10, f6, f6); // f10=0
__ sdc1(f8, MemOperand(a0, OFFSET_OF(Test, e))); // e=0xf3
__ sdc1(f10, MemOperand(a0, OFFSET_OF(Test, f))); // f=0
__ selnez(S, f8, f4, f6); // f8=0
__ selnez(S, f10, f6, f6); // f10=0xf3*/
__ sdc1(f8, MemOperand(a0, OFFSET_OF(Test, g))); // g=0
__ sdc1(f10, MemOperand(a0, OFFSET_OF(Test, h))); // h=0xf3
__ li(t0, 0x80);
__ mtc1(t0, f4);
__ cvt_d_w(f4, f4); // f4=0x80
__ li(t0, 0xf3);
__ mtc1(t0, f6);
__ cvt_d_w(f6, f6); // f6=0xf3
__ seleqz(D, f8, f4, f6); // f8=0xf3
__ seleqz(D, f10, f6, f6); // f10=0
__ sdc1(f8, MemOperand(a0, OFFSET_OF(Test, i))); // i=0xf3
__ sdc1(f10, MemOperand(a0, OFFSET_OF(Test, j))); // j=0
__ selnez(S, f8, f4, f6); // f8=0
__ selnez(S, f10, f6, f6); // f10=0xf3*/
__ sdc1(f8, MemOperand(a0, OFFSET_OF(Test, k))); // k=0
__ sdc1(f10, MemOperand(a0, OFFSET_OF(Test, l))); // l=0xf3
__ jr(ra);
__ nop();
CodeDesc desc;
assm.GetCode(&desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
(CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
CHECK_EQ(test.a, 1);
CHECK_EQ(test.b, 0);
CHECK_EQ(test.c, 0);
CHECK_EQ(test.d, 1);
CHECK_EQ(test.e, 0xf3);
CHECK_EQ(test.f, 0x0);
CHECK_EQ(test.g, 0);
CHECK_EQ(test.h, 0xf3);
CHECK_EQ(test.i, 0xf3);
CHECK_EQ(test.j, 0x0);
CHECK_EQ(test.k, 0);
CHECK_EQ(test.l, 0xf3);
}
TEST(MIPS0) {
......
......@@ -48,6 +48,72 @@ typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4);
#define __ assm.
TEST(MIPS17) {
if (kArchVariant == kMips64r6) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
MacroAssembler assm(isolate, NULL, 0);
typedef struct test {
int a;
int b;
int c;
int d;
double i;
double j;
double k;
double l;
} Test;
Test test;
// integer part of test
__ addiu(t1, zero_reg, 1); // t1=1
__ seleqz(t1, zero_reg, t3); // t3=1
__ sw(t3, MemOperand(a0, OFFSET_OF(Test, a))); // a=1
__ seleqz(t1, t1, t2); // t2=0
__ sw(t2, MemOperand(a0, OFFSET_OF(Test, b))); // b=0
__ selnez(t1, zero_reg, t3); // t3=1;
__ sw(t3, MemOperand(a0, OFFSET_OF(Test, c))); // c=0
__ selnez(t1, t1, t3); // t3=1
__ sw(t3, MemOperand(a0, OFFSET_OF(Test, d))); // d=1
// floating point part of test
__ li(t0, 0x80);
__ mtc1(t0, f4);
__ cvt_d_w(f4, f4); // f4=0x80
__ li(t0, 0xf3);
__ mtc1(t0, f6);
__ cvt_d_w(f6, f6); // f6=0xf3
__ seleqz(D, f8, f4, f6); // f8=0xf3
__ seleqz(D, f10, f6, f6); // f10=0
__ sdc1(f8, MemOperand(a0, OFFSET_OF(Test, i))); // i=0xf3
__ sdc1(f10, MemOperand(a0, OFFSET_OF(Test, j))); // j=0
__ selnez(D, f8, f4, f6); // f8=0
__ selnez(D, f10, f6, f6); // f10=0xf3*/
__ sdc1(f8, MemOperand(a0, OFFSET_OF(Test, k))); // k=0
__ sdc1(f10, MemOperand(a0, OFFSET_OF(Test, l))); // l=0xf3
__ jr(ra);
__ nop();
CodeDesc desc;
assm.GetCode(&desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
(CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
CHECK_EQ(test.a, 1);
CHECK_EQ(test.b, 0);
CHECK_EQ(test.c, 0);
CHECK_EQ(test.d, 1);
CHECK_EQ(test.i, 0xf3);
CHECK_EQ(test.j, 0x0);
CHECK_EQ(test.k, 0);
CHECK_EQ(test.l, 0xf3);
}
}
TEST(MIPS0) {
CcTest::InitializeVM();
......
......@@ -90,6 +90,20 @@ bool DisassembleAndCompare(byte* pc, const char* compare_string) {
if (failure) { \
V8_Fatal(__FILE__, __LINE__, "MIPS Disassembler tests failed.\n"); \
}
// tests only seleqz, selnez, seleqz.fmt and selnez.fmt
TEST(Type1) {
SET_UP();
if (IsMipsArchVariant(kMips32r6)) {
COMPARE(seleqz(a0, a1, a2), "00853035 seleqz a0, a1, a2");
COMPARE(selnez(a0, a1, a2), "00853037 selnez a0, a1, a2");
COMPARE(seleqz(S, f0, f1, f2), "45000894 seleqz.S f0, f1, f2");
COMPARE(selnez(S, f0, f1, f2), "45000897 selnez.S f0, f1, f2");
COMPARE(seleqz(D, f3, f4, f5), "00853035 seleqz.D f3, f4, f5");
COMPARE(selnez(D, f3, f4, f5), "00853037 selnez.D f3, f4, f5");
}
VERIFY_RUN();
}
TEST(Type0) {
......
......@@ -92,6 +92,25 @@ if (failure) { \
}
TEST(Type1) {
if (kArchVariant == kMips64r6) {
SET_UP();
COMPARE(seleqz(a0, a1, a2), "00853035 seleqz a0, a1, a2");
COMPARE(selnez(a0, a1, a2), "00853037 selnez a0, a1, a2");
COMPARE(seleqz(D, f3, f4, f5), "462428d4 seleqz.D f4, f5, f3");
COMPARE(selnez(D, f3, f4, f5), "462428d7 selnez.D f4, f5, f3");
/*COMPARE(min(D, f3, f4, f5),
"462428dc min.D f4, f5, f3");
COMPARE(max(D, f3, f4, f5),
"462428de max.D f4, f5, f3");*/
VERIFY_RUN();
}
}
TEST(Type0) {
SET_UP();
......
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