Commit 15df13ea authored by Ivica Bogosavljevic's avatar Ivica Bogosavljevic Committed by Commit Bot

MIPS: Cleanup ByteSwap macro

Shrink number of instruction in ByteSwap macro for some cases.
Allow that input and output registers can be the same.
Extend test to cover all test cases.

Change-Id: I7e0b86988fb73eed604751ffd89657cdff4abc3c
Reviewed-on: https://chromium-review.googlesource.com/951726Reviewed-by: 's avatarSreten Kovacevic <sreten.kovacevic@mips.com>
Commit-Queue: Ivica Bogosavljevic <ivica.bogosavljevic@mips.com>
Cr-Commit-Position: refs/heads/master@{#51787}
parent daa224d4
......@@ -674,7 +674,7 @@ void InstructionSelector::VisitWord64ReverseBytes(Node* node) { UNREACHABLE(); }
void InstructionSelector::VisitWord32ReverseBytes(Node* node) {
MipsOperandGenerator g(this);
Emit(kMipsByteSwap32, g.DefineAsRegister(node),
g.UseUniqueRegister(node->InputAt(0)));
g.UseRegister(node->InputAt(0)));
}
void InstructionSelector::VisitWord32Ctz(Node* node) {
......
......@@ -901,40 +901,38 @@ void TurboAssembler::ByteSwapSigned(Register dest, Register src,
int operand_size) {
DCHECK(operand_size == 1 || operand_size == 2 || operand_size == 4);
Register input = src;
if (operand_size == 2) {
Seh(src, src);
input = dest;
Seh(dest, src);
} else if (operand_size == 1) {
Seb(src, src);
input = dest;
Seb(dest, src);
}
// No need to do any preparation if operand_size is 4
if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
wsbh(dest, src);
wsbh(dest, input);
rotr(dest, dest, 16);
} else if (IsMipsArchVariant(kMips32r1) || IsMipsArchVariant(kLoongson)) {
Register tmp = at;
Register tmp2 = t8;
DCHECK(dest != src);
DCHECK(dest != tmp && dest != tmp2);
DCHECK(src != tmp && src != tmp2);
andi(tmp2, src, 0xFF);
sll(tmp2, tmp2, 24);
or_(tmp, zero_reg, tmp2);
andi(tmp2, input, 0xFF);
sll(tmp, tmp2, 24);
andi(tmp2, src, 0xFF00);
andi(tmp2, input, 0xFF00);
sll(tmp2, tmp2, 8);
or_(tmp, tmp, tmp2);
srl(src, src, 8);
andi(tmp2, src, 0xFF00);
srl(tmp2, input, 8);
andi(tmp2, tmp2, 0xFF00);
or_(tmp, tmp, tmp2);
srl(src, src, 16);
andi(tmp2, src, 0xFF);
or_(tmp, tmp, tmp2);
or_(dest, tmp, zero_reg);
srl(tmp2, input, 24);
or_(dest, tmp, tmp2);
}
}
......@@ -943,25 +941,28 @@ void TurboAssembler::ByteSwapUnsigned(Register dest, Register src,
DCHECK(operand_size == 1 || operand_size == 2);
if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
Register input = src;
if (operand_size == 1) {
andi(src, src, 0xFF);
input = dest;
andi(dest, src, 0xFF);
} else {
andi(src, src, 0xFFFF);
input = dest;
andi(dest, src, 0xFFFF);
}
// No need to do any preparation if operand_size is 4
wsbh(dest, src);
wsbh(dest, input);
rotr(dest, dest, 16);
} else if (IsMipsArchVariant(kMips32r1) || IsMipsArchVariant(kLoongson)) {
if (operand_size == 1) {
sll(src, src, 24);
sll(dest, src, 24);
} else {
Register tmp = at;
andi(tmp, src, 0xFF00);
sll(src, src, 24);
sll(dest, src, 24);
sll(tmp, tmp, 8);
or_(dest, tmp, src);
or_(dest, tmp, dest);
}
}
}
......
......@@ -58,6 +58,16 @@ TEST(BYTESWAP) {
int32_t r3;
int32_t r4;
int32_t r5;
int32_t t1;
int32_t t2;
int32_t t3;
int32_t t4;
int32_t t5;
int32_t p1;
int32_t p2;
int32_t p3;
int32_t p4;
int32_t p5;
};
T t;
......@@ -66,27 +76,37 @@ TEST(BYTESWAP) {
MacroAssembler* masm = &assembler;
__ lw(a2, MemOperand(a0, offsetof(T, r1)));
__ nop();
__ ByteSwapSigned(a1, a2, 4);
__ sw(a2, MemOperand(a0, offsetof(T, p1)));
__ sw(a1, MemOperand(a0, offsetof(T, t1)));
__ ByteSwapSigned(a2, a2, 4);
__ sw(a2, MemOperand(a0, offsetof(T, r1)));
__ lw(a2, MemOperand(a0, offsetof(T, r2)));
__ nop();
__ ByteSwapSigned(a1, a2, 2);
__ sw(a2, MemOperand(a0, offsetof(T, p2)));
__ sw(a1, MemOperand(a0, offsetof(T, t2)));
__ ByteSwapSigned(a2, a2, 2);
__ sw(a2, MemOperand(a0, offsetof(T, r2)));
__ lw(a2, MemOperand(a0, offsetof(T, r3)));
__ nop();
__ ByteSwapSigned(a1, a2, 1);
__ sw(a2, MemOperand(a0, offsetof(T, p3)));
__ sw(a1, MemOperand(a0, offsetof(T, t3)));
__ ByteSwapSigned(a2, a2, 1);
__ sw(a2, MemOperand(a0, offsetof(T, r3)));
__ lw(a2, MemOperand(a0, offsetof(T, r4)));
__ nop();
__ ByteSwapUnsigned(a1, a2, 1);
__ sw(a2, MemOperand(a0, offsetof(T, p4)));
__ sw(a1, MemOperand(a0, offsetof(T, t4)));
__ ByteSwapUnsigned(a2, a2, 1);
__ sw(a2, MemOperand(a0, offsetof(T, r4)));
__ lw(a2, MemOperand(a0, offsetof(T, r5)));
__ nop();
__ ByteSwapUnsigned(a1, a2, 2);
__ sw(a2, MemOperand(a0, offsetof(T, p5)));
__ sw(a1, MemOperand(a0, offsetof(T, t5)));
__ ByteSwapUnsigned(a2, a2, 2);
__ sw(a2, MemOperand(a0, offsetof(T, r5)));
......@@ -110,6 +130,18 @@ TEST(BYTESWAP) {
CHECK_EQ(static_cast<int32_t>(0x9FFFFFFF), t.r3);
CHECK_EQ(static_cast<int32_t>(0x9F000000), t.r4);
CHECK_EQ(static_cast<int32_t>(0xDE2C0000), t.r5);
CHECK_EQ(t.t1, t.r1);
CHECK_EQ(t.t2, t.r2);
CHECK_EQ(t.t3, t.r3);
CHECK_EQ(t.t4, t.r4);
CHECK_EQ(t.t5, t.r5);
CHECK_EQ(static_cast<int32_t>(0x781A15C3), t.p1);
CHECK_EQ(static_cast<int32_t>(0x2CDE), t.p2);
CHECK_EQ(static_cast<int32_t>(0x9F), t.p3);
CHECK_EQ(static_cast<int32_t>(0x9F), t.p4);
CHECK_EQ(static_cast<int32_t>(0x2CDE), t.p5);
}
static void TestNaN(const char *code) {
......
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