Commit fdf19ffa authored by marija.antic's avatar marija.antic Committed by Commit bot

MIPS64: Fix rotate instructions in simulator

Fix for drotr and drotr32 instructions in MIPS64 simulator.

BUG=

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

Cr-Commit-Position: refs/heads/master@{#35420}
parent a58045a9
...@@ -1162,26 +1162,22 @@ void Decoder::DecodeTypeRegisterSPECIAL(Instruction* instr) { ...@@ -1162,26 +1162,22 @@ void Decoder::DecodeTypeRegisterSPECIAL(Instruction* instr) {
if (instr->RsValue() == 0) { if (instr->RsValue() == 0) {
Format(instr, "srl 'rd, 'rt, 'sa"); Format(instr, "srl 'rd, 'rt, 'sa");
} else { } else {
if (kArchVariant == kMips64r2) { Format(instr, "rotr 'rd, 'rt, 'sa");
Format(instr, "rotr 'rd, 'rt, 'sa");
} else {
Unknown(instr);
}
} }
break; break;
case DSRL: case DSRL:
if (instr->RsValue() == 0) { if (instr->RsValue() == 0) {
Format(instr, "dsrl 'rd, 'rt, 'sa"); Format(instr, "dsrl 'rd, 'rt, 'sa");
} else { } else {
if (kArchVariant == kMips64r2) { Format(instr, "drotr 'rd, 'rt, 'sa");
Format(instr, "drotr 'rd, 'rt, 'sa");
} else {
Unknown(instr);
}
} }
break; break;
case DSRL32: case DSRL32:
Format(instr, "dsrl32 'rd, 'rt, 'sa"); if (instr->RsValue() == 0) {
Format(instr, "dsrl32 'rd, 'rt, 'sa");
} else {
Format(instr, "drotr32 'rd, 'rt, 'sa");
}
break; break;
case SRA: case SRA:
Format(instr, "sra 'rd, 'rt, 'sa"); Format(instr, "sra 'rd, 'rt, 'sa");
...@@ -1202,22 +1198,14 @@ void Decoder::DecodeTypeRegisterSPECIAL(Instruction* instr) { ...@@ -1202,22 +1198,14 @@ void Decoder::DecodeTypeRegisterSPECIAL(Instruction* instr) {
if (instr->SaValue() == 0) { if (instr->SaValue() == 0) {
Format(instr, "srlv 'rd, 'rt, 'rs"); Format(instr, "srlv 'rd, 'rt, 'rs");
} else { } else {
if (kArchVariant == kMips64r2) { Format(instr, "rotrv 'rd, 'rt, 'rs");
Format(instr, "rotrv 'rd, 'rt, 'rs");
} else {
Unknown(instr);
}
} }
break; break;
case DSRLV: case DSRLV:
if (instr->SaValue() == 0) { if (instr->SaValue() == 0) {
Format(instr, "dsrlv 'rd, 'rt, 'rs"); Format(instr, "dsrlv 'rd, 'rt, 'rs");
} else { } else {
if (kArchVariant == kMips64r2) { Format(instr, "drotrv 'rd, 'rt, 'rs");
Format(instr, "drotrv 'rd, 'rt, 'rs");
} else {
Unknown(instr);
}
} }
break; break;
case SRAV: case SRAV:
......
...@@ -3420,21 +3420,50 @@ void Simulator::DecodeTypeRegisterSPECIAL() { ...@@ -3420,21 +3420,50 @@ void Simulator::DecodeTypeRegisterSPECIAL() {
// bits instruction. RS field is always equal to 0. // bits instruction. RS field is always equal to 0.
// Sign-extend the 32-bit result. // Sign-extend the 32-bit result.
alu_out = static_cast<int32_t>(static_cast<uint32_t>(rt_u()) >> sa()); alu_out = static_cast<int32_t>(static_cast<uint32_t>(rt_u()) >> sa());
} else { } else if (rs_reg() == 1) {
// Logical right-rotate of a word by a fixed number of bits. This // Logical right-rotate of a word by a fixed number of bits. This
// is special case of SRL instruction, added in MIPS32 Release 2. // is special case of SRL instruction, added in MIPS32 Release 2.
// RS field is equal to 00001. // RS field is equal to 00001.
alu_out = static_cast<int32_t>( alu_out = static_cast<int32_t>(
base::bits::RotateRight32(static_cast<const uint32_t>(rt_u()), base::bits::RotateRight32(static_cast<const uint32_t>(rt_u()),
static_cast<const uint32_t>(sa()))); static_cast<const uint32_t>(sa())));
} else {
UNREACHABLE();
} }
SetResult(rd_reg(), alu_out); SetResult(rd_reg(), alu_out);
break; break;
case DSRL: case DSRL:
SetResult(rd_reg(), rt_u() >> sa()); if (rs_reg() == 0) {
// Regular logical right shift of a word by a fixed number of
// bits instruction. RS field is always equal to 0.
// Sign-extend the 64-bit result.
alu_out = static_cast<int64_t>(rt_u() >> sa());
} else if (rs_reg() == 1) {
// Logical right-rotate of a word by a fixed number of bits. This
// is special case of SRL instruction, added in MIPS32 Release 2.
// RS field is equal to 00001.
alu_out = static_cast<int64_t>(base::bits::RotateRight64(rt_u(), sa()));
} else {
UNREACHABLE();
}
SetResult(rd_reg(), alu_out);
break; break;
case DSRL32: case DSRL32:
SetResult(rd_reg(), rt_u() >> sa() >> 32); if (rs_reg() == 0) {
// Regular logical right shift of a word by a fixed number of
// bits instruction. RS field is always equal to 0.
// Sign-extend the 64-bit result.
alu_out = static_cast<int64_t>(rt_u() >> sa() >> 32);
} else if (rs_reg() == 1) {
// Logical right-rotate of a word by a fixed number of bits. This
// is special case of SRL instruction, added in MIPS32 Release 2.
// RS field is equal to 00001.
alu_out =
static_cast<int64_t>(base::bits::RotateRight64(rt_u(), sa() + 32));
} else {
UNREACHABLE();
}
SetResult(rd_reg(), alu_out);
break; break;
case SRA: case SRA:
SetResult(rd_reg(), (int32_t)rt() >> sa()); SetResult(rd_reg(), (int32_t)rt() >> sa());
...@@ -3470,12 +3499,13 @@ void Simulator::DecodeTypeRegisterSPECIAL() { ...@@ -3470,12 +3499,13 @@ void Simulator::DecodeTypeRegisterSPECIAL() {
if (sa() == 0) { if (sa() == 0) {
// Regular logical right-shift of a word by a variable number of // Regular logical right-shift of a word by a variable number of
// bits instruction. SA field is always equal to 0. // bits instruction. SA field is always equal to 0.
alu_out = rt_u() >> rs(); alu_out = static_cast<int64_t>(rt_u() >> rs());
} else { } else {
// Logical right-rotate of a word by a variable number of bits. // Logical right-rotate of a word by a variable number of bits.
// This is special case od SRLV instruction, added in MIPS32 // This is special case od SRLV instruction, added in MIPS32
// Release 2. SA field is equal to 00001. // Release 2. SA field is equal to 00001.
alu_out = base::bits::RotateRight64(rt_u(), rs_u()); alu_out =
static_cast<int64_t>(base::bits::RotateRight64(rt_u(), rs_u()));
} }
SetResult(rd_reg(), alu_out); SetResult(rd_reg(), alu_out);
break; break;
......
...@@ -530,41 +530,28 @@ TEST(Type0) { ...@@ -530,41 +530,28 @@ TEST(Type0) {
COMPARE(dsrav(v0, v1, fp), COMPARE(dsrav(v0, v1, fp),
"03c31017 dsrav v0, v1, fp"); "03c31017 dsrav v0, v1, fp");
if (kArchVariant == kMips64r2) { COMPARE(rotr(a0, a1, 0), "00252002 rotr a0, a1, 0");
COMPARE(rotr(a0, a1, 0), COMPARE(rotr(s0, s1, 8), "00318202 rotr s0, s1, 8");
"00252002 rotr a0, a1, 0"); COMPARE(rotr(a6, a7, 24), "002b5602 rotr a6, a7, 24");
COMPARE(rotr(s0, s1, 8), COMPARE(rotr(v0, v1, 31), "002317c2 rotr v0, v1, 31");
"00318202 rotr s0, s1, 8"); COMPARE(drotr(a0, a1, 0), "0025203a drotr a0, a1, 0");
COMPARE(rotr(a6, a7, 24), COMPARE(drotr(s0, s1, 8), "0031823a drotr s0, s1, 8");
"002b5602 rotr a6, a7, 24"); COMPARE(drotr(a6, a7, 24), "002b563a drotr a6, a7, 24");
COMPARE(rotr(v0, v1, 31), COMPARE(drotr(v0, v1, 31), "002317fa drotr v0, v1, 31");
"002317c2 rotr v0, v1, 31");
COMPARE(drotr(a0, a1, 0), COMPARE(drotr32(a0, a1, 0), "0025203e drotr32 a0, a1, 0");
"0025203a drotr a0, a1, 0"); COMPARE(drotr32(s0, s1, 8), "0031823e drotr32 s0, s1, 8");
COMPARE(drotr(s0, s1, 8), COMPARE(drotr32(a6, a7, 24), "002b563e drotr32 a6, a7, 24");
"0031823a drotr s0, s1, 8"); COMPARE(drotr32(v0, v1, 31), "002317fe drotr32 v0, v1, 31");
COMPARE(drotr(a6, a7, 24),
"002b563a drotr a6, a7, 24"); COMPARE(rotrv(a0, a1, a2), "00c52046 rotrv a0, a1, a2");
COMPARE(drotr(v0, v1, 31), COMPARE(rotrv(s0, s1, s2), "02518046 rotrv s0, s1, s2");
"002317fa drotr v0, v1, 31"); COMPARE(rotrv(a6, a7, t0), "018b5046 rotrv a6, a7, t0");
COMPARE(rotrv(v0, v1, fp), "03c31046 rotrv v0, v1, fp");
COMPARE(rotrv(a0, a1, a2), COMPARE(drotrv(a0, a1, a2), "00c52056 drotrv a0, a1, a2");
"00c52046 rotrv a0, a1, a2"); COMPARE(drotrv(s0, s1, s2), "02518056 drotrv s0, s1, s2");
COMPARE(rotrv(s0, s1, s2), COMPARE(drotrv(a6, a7, t0), "018b5056 drotrv a6, a7, t0");
"02518046 rotrv s0, s1, s2"); COMPARE(drotrv(v0, v1, fp), "03c31056 drotrv v0, v1, fp");
COMPARE(rotrv(a6, a7, t0),
"018b5046 rotrv a6, a7, t0");
COMPARE(rotrv(v0, v1, fp),
"03c31046 rotrv v0, v1, fp");
COMPARE(drotrv(a0, a1, a2),
"00c52056 drotrv a0, a1, a2");
COMPARE(drotrv(s0, s1, s2),
"02518056 drotrv s0, s1, s2");
COMPARE(drotrv(a6, a7, t0),
"018b5056 drotrv a6, a7, t0");
COMPARE(drotrv(v0, v1, fp),
"03c31056 drotrv v0, v1, fp");
}
COMPARE(break_(0), COMPARE(break_(0),
"0000000d break, code: 0x00000 (0)"); "0000000d break, code: 0x00000 (0)");
......
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