Commit 6993cd0d authored by balazs.kilvady's avatar balazs.kilvady Committed by Commit bot

MIPS: Fix 'MIPS:r6 compact branch optimization.'

Jic and jialc compact branch ops are fixed as they does not have 'forbidden slot' restriction. Also COP1 branches (CTI instructions) added to IsForbiddenAfterBranchInstr().

TEST=cctest/test-disasm-mips/Type0
BUG=

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

Cr-Commit-Position: refs/heads/master@{#31922}
parent e28e4d5f
...@@ -1423,7 +1423,6 @@ void Assembler::beqc(Register rs, Register rt, int16_t offset) { ...@@ -1423,7 +1423,6 @@ void Assembler::beqc(Register rs, Register rt, int16_t offset) {
void Assembler::beqzc(Register rs, int32_t offset) { void Assembler::beqzc(Register rs, int32_t offset) {
DCHECK(IsMipsArchVariant(kMips32r6)); DCHECK(IsMipsArchVariant(kMips32r6));
DCHECK(!(rs.is(zero_reg))); DCHECK(!(rs.is(zero_reg)));
DCHECK(is_int21(offset));
GenInstrImmediate(POP66, rs, offset, CompactBranchType::COMPACT_BRANCH); GenInstrImmediate(POP66, rs, offset, CompactBranchType::COMPACT_BRANCH);
} }
...@@ -1442,7 +1441,6 @@ void Assembler::bnec(Register rs, Register rt, int16_t offset) { ...@@ -1442,7 +1441,6 @@ void Assembler::bnec(Register rs, Register rt, int16_t offset) {
void Assembler::bnezc(Register rs, int32_t offset) { void Assembler::bnezc(Register rs, int32_t offset) {
DCHECK(IsMipsArchVariant(kMips32r6)); DCHECK(IsMipsArchVariant(kMips32r6));
DCHECK(!(rs.is(zero_reg))); DCHECK(!(rs.is(zero_reg)));
DCHECK(is_int21(offset));
GenInstrImmediate(POP76, rs, offset, CompactBranchType::COMPACT_BRANCH); GenInstrImmediate(POP76, rs, offset, CompactBranchType::COMPACT_BRANCH);
} }
...@@ -1497,16 +1495,14 @@ void Assembler::jalr(Register rs, Register rd) { ...@@ -1497,16 +1495,14 @@ void Assembler::jalr(Register rs, Register rd) {
void Assembler::jic(Register rt, int16_t offset) { void Assembler::jic(Register rt, int16_t offset) {
DCHECK(IsMipsArchVariant(kMips32r6)); DCHECK(IsMipsArchVariant(kMips32r6));
GenInstrImmediate(POP66, zero_reg, rt, offset, GenInstrImmediate(POP66, zero_reg, rt, offset);
CompactBranchType::COMPACT_BRANCH);
} }
void Assembler::jialc(Register rt, int16_t offset) { void Assembler::jialc(Register rt, int16_t offset) {
DCHECK(IsMipsArchVariant(kMips32r6)); DCHECK(IsMipsArchVariant(kMips32r6));
positions_recorder()->WriteRecordedPositions(); positions_recorder()->WriteRecordedPositions();
GenInstrImmediate(POP76, zero_reg, rt, offset, GenInstrImmediate(POP76, zero_reg, rt, offset);
CompactBranchType::COMPACT_BRANCH);
} }
......
...@@ -1143,6 +1143,8 @@ class Assembler : public AssemblerBase { ...@@ -1143,6 +1143,8 @@ class Assembler : public AssemblerBase {
UNREACHABLE(); UNREACHABLE();
} }
bool IsPrevInstrCompactBranch() { return prev_instr_compact_branch_; }
protected: protected:
// Relocation for a type-recording IC has the AST id added to it. This // Relocation for a type-recording IC has the AST id added to it. This
// member variable is a way to pass the information from the call site to // member variable is a way to pass the information from the call site to
...@@ -1206,8 +1208,6 @@ class Assembler : public AssemblerBase { ...@@ -1206,8 +1208,6 @@ class Assembler : public AssemblerBase {
return block_buffer_growth_; return block_buffer_growth_;
} }
bool IsPrevInstrCompactBranch() { return prev_instr_compact_branch_; }
private: private:
inline static void set_target_internal_reference_encoded_at(Address pc, inline static void set_target_internal_reference_encoded_at(Address pc,
Address target); Address target);
......
...@@ -166,6 +166,17 @@ bool Instruction::IsForbiddenAfterBranchInstr(Instr instr) { ...@@ -166,6 +166,17 @@ bool Instruction::IsForbiddenAfterBranchInstr(Instr instr) {
return false; return false;
} }
break; break;
case COP1:
switch (instr & kRsFieldMask) {
case BC1:
case BC1EQZ:
case BC1NEZ:
return true;
break;
default:
return false;
}
break;
default: default:
return false; return false;
} }
......
...@@ -1435,9 +1435,9 @@ void Decoder::DecodeTypeImmediate(Instruction* instr) { ...@@ -1435,9 +1435,9 @@ void Decoder::DecodeTypeImmediate(Instruction* instr) {
break; break;
case POP76: case POP76:
if (instr->RsValue() == JIALC) { if (instr->RsValue() == JIALC) {
Format(instr, "jialc 'rt, 'imm16x"); Format(instr, "jialc 'rt, 'imm16s");
} else { } else {
Format(instr, "bnezc 'rs, 'imm21x -> 'imm21p4s2"); Format(instr, "bnezc 'rs, 'imm21s -> 'imm21p4s2");
} }
break; break;
// ------------- Arithmetic instructions. // ------------- Arithmetic instructions.
......
...@@ -38,12 +38,18 @@ ...@@ -38,12 +38,18 @@
using namespace v8::internal; using namespace v8::internal;
bool prev_instr_compact_branch = false;
bool DisassembleAndCompare(byte* pc, const char* compare_string) { bool DisassembleAndCompare(byte* pc, const char* compare_string) {
disasm::NameConverter converter; disasm::NameConverter converter;
disasm::Disassembler disasm(converter); disasm::Disassembler disasm(converter);
EmbeddedVector<char, 128> disasm_buffer; EmbeddedVector<char, 128> disasm_buffer;
if (prev_instr_compact_branch) {
disasm.InstructionDecode(disasm_buffer, pc);
pc += 4;
}
disasm.InstructionDecode(disasm_buffer, pc); disasm.InstructionDecode(disasm_buffer, pc);
if (strcmp(compare_string, disasm_buffer.start()) != 0) { if (strcmp(compare_string, disasm_buffer.start()) != 0) {
...@@ -97,8 +103,14 @@ if (failure) { \ ...@@ -97,8 +103,14 @@ if (failure) { \
int pc_offset = assm.pc_offset(); \ int pc_offset = assm.pc_offset(); \
byte *progcounter = &buffer[pc_offset]; \ byte *progcounter = &buffer[pc_offset]; \
char str_with_address[100]; \ char str_with_address[100]; \
snprintf(str_with_address, sizeof(str_with_address), "%s -> %p", \ prev_instr_compact_branch = assm.IsPrevInstrCompactBranch(); \
compare_string, progcounter + 4 + (offset * 4)); \ if (prev_instr_compact_branch) { \
snprintf(str_with_address, sizeof(str_with_address), "%s -> %p", \
compare_string, progcounter + 8 + (offset * 4)); \
} else { \
snprintf(str_with_address, sizeof(str_with_address), "%s -> %p", \
compare_string, progcounter + 4 + (offset * 4)); \
} \
assm.asm_; \ assm.asm_; \
if (!DisassembleAndCompare(progcounter, str_with_address)) failure = true; \ if (!DisassembleAndCompare(progcounter, str_with_address)) failure = true; \
} }
...@@ -273,11 +285,11 @@ TEST(Type0) { ...@@ -273,11 +285,11 @@ TEST(Type0) {
COMPARE_PC_REL_COMPACT(beqzc(a0, 1048575), COMPARE_PC_REL_COMPACT(beqzc(a0, 1048575),
"d88fffff beqzc a0, 1048575", 1048575); "d88fffff beqzc a0, 1048575", 1048575);
COMPARE_PC_REL_COMPACT(bnezc(a0, 0), "f8800000 bnezc a0, 0x0", 0); COMPARE_PC_REL_COMPACT(bnezc(a0, 0), "f8800000 bnezc a0, 0", 0);
COMPARE_PC_REL_COMPACT(bnezc(a0, 0xfffff), // 0x0fffff == 1048575. COMPARE_PC_REL_COMPACT(bnezc(a0, 1048575), // int21 maximal value.
"f88fffff bnezc a0, 0xfffff", 1048575); "f88fffff bnezc a0, 1048575", 1048575);
COMPARE_PC_REL_COMPACT(bnezc(a0, 0x100000), // 0x100000 == -1048576. COMPARE_PC_REL_COMPACT(bnezc(a0, -1048576), // int21 minimal value.
"f8900000 bnezc a0, 0x100000", -1048576); "f8900000 bnezc a0, -1048576", -1048576);
COMPARE_PC_REL_COMPACT(bc(-33554432), "ca000000 bc -33554432", COMPARE_PC_REL_COMPACT(bc(-33554432), "ca000000 bc -33554432",
-33554432); -33554432);
...@@ -296,29 +308,29 @@ TEST(Type0) { ...@@ -296,29 +308,29 @@ TEST(Type0) {
33554431); 33554431);
COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, -32768), COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, -32768),
"18858000 bgeuc a0, a1, -32768", -32768); "18858000 bgeuc a0, a1, -32768", -32768);
COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, -1), COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, -1),
"1885ffff bgeuc a0, a1, -1", -1); "1885ffff bgeuc a0, a1, -1", -1);
COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, 1), COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, 1), "18850001 bgeuc a0, a1, 1",
"18850001 bgeuc a0, a1, 1", 1); 1);
COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, 32767), COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, 32767),
"18857fff bgeuc a0, a1, 32767", 32767); "18857fff bgeuc a0, a1, 32767", 32767);
COMPARE_PC_REL_COMPACT(bgezalc(a0, -32768), COMPARE_PC_REL_COMPACT(bgezalc(a0, -32768),
"18848000 bgezalc a0, -32768", -32768); "18848000 bgezalc a0, -32768", -32768);
COMPARE_PC_REL_COMPACT(bgezalc(a0, -1), "1884ffff bgezalc a0, -1", COMPARE_PC_REL_COMPACT(bgezalc(a0, -1), "1884ffff bgezalc a0, -1",
-1); -1);
COMPARE_PC_REL_COMPACT(bgezalc(a0, 1), "18840001 bgezalc a0, 1", 1); COMPARE_PC_REL_COMPACT(bgezalc(a0, 1), "18840001 bgezalc a0, 1", 1);
COMPARE_PC_REL_COMPACT(bgezalc(a0, 32767), COMPARE_PC_REL_COMPACT(bgezalc(a0, 32767),
"18847fff bgezalc a0, 32767", 32767); "18847fff bgezalc a0, 32767", 32767);
COMPARE_PC_REL_COMPACT(blezalc(a0, -32768), COMPARE_PC_REL_COMPACT(blezalc(a0, -32768),
"18048000 blezalc a0, -32768", -32768); "18048000 blezalc a0, -32768", -32768);
COMPARE_PC_REL_COMPACT(blezalc(a0, -1), "1804ffff blezalc a0, -1", COMPARE_PC_REL_COMPACT(blezalc(a0, -1), "1804ffff blezalc a0, -1",
-1); -1);
COMPARE_PC_REL_COMPACT(blezalc(a0, 1), "18040001 blezalc a0, 1", 1); COMPARE_PC_REL_COMPACT(blezalc(a0, 1), "18040001 blezalc a0, 1", 1);
COMPARE_PC_REL_COMPACT(blezalc(a0, 32767), COMPARE_PC_REL_COMPACT(blezalc(a0, 32767),
"18047fff blezalc a0, 32767", 32767); "18047fff blezalc a0, 32767", 32767);
COMPARE_PC_REL_COMPACT(bltuc(a0, a1, -32768), COMPARE_PC_REL_COMPACT(bltuc(a0, a1, -32768),
"1c858000 bltuc a0, a1, -32768", -32768); "1c858000 bltuc a0, a1, -32768", -32768);
...@@ -376,13 +388,13 @@ TEST(Type0) { ...@@ -376,13 +388,13 @@ TEST(Type0) {
"5c847fff bltzc a0, 32767", 32767); "5c847fff bltzc a0, 32767", 32767);
COMPARE_PC_REL_COMPACT(bltc(a0, a1, -32768), COMPARE_PC_REL_COMPACT(bltc(a0, a1, -32768),
"5c858000 bltc a0, a1, -32768", -32768); "5c858000 bltc a0, a1, -32768", -32768);
COMPARE_PC_REL_COMPACT(bltc(a0, a1, -1), COMPARE_PC_REL_COMPACT(bltc(a0, a1, -1),
"5c85ffff bltc a0, a1, -1", -1); "5c85ffff bltc a0, a1, -1", -1);
COMPARE_PC_REL_COMPACT(bltc(a0, a1, 1), "5c850001 bltc a0, a1, 1", COMPARE_PC_REL_COMPACT(bltc(a0, a1, 1), "5c850001 bltc a0, a1, 1",
1); 1);
COMPARE_PC_REL_COMPACT(bltc(a0, a1, 32767), COMPARE_PC_REL_COMPACT(bltc(a0, a1, 32767),
"5c857fff bltc a0, a1, 32767", 32767); "5c857fff bltc a0, a1, 32767", 32767);
COMPARE_PC_REL_COMPACT(bgtzc(a0, -32768), COMPARE_PC_REL_COMPACT(bgtzc(a0, -32768),
"5c048000 bgtzc a0, -32768", -32768); "5c048000 bgtzc a0, -32768", -32768);
...@@ -413,13 +425,13 @@ TEST(Type0) { ...@@ -413,13 +425,13 @@ TEST(Type0) {
1); 1);
COMPARE_PC_REL_COMPACT(beqc(a0, a1, -32768), COMPARE_PC_REL_COMPACT(beqc(a0, a1, -32768),
"20858000 beqc a0, a1, -32768", -32768); "20858000 beqc a0, a1, -32768", -32768);
COMPARE_PC_REL_COMPACT(beqc(a0, a1, -1), "2085ffff beqc a0, a1, -1", COMPARE_PC_REL_COMPACT(beqc(a0, a1, -1),
-1); "2085ffff beqc a0, a1, -1", -1);
COMPARE_PC_REL_COMPACT(beqc(a0, a1, 1), "20850001 beqc a0, a1, 1", COMPARE_PC_REL_COMPACT(beqc(a0, a1, 1), "20850001 beqc a0, a1, 1",
1); 1);
COMPARE_PC_REL_COMPACT(beqc(a0, a1, 32767), COMPARE_PC_REL_COMPACT(beqc(a0, a1, 32767),
"20857fff beqc a0, a1, 32767", 32767); "20857fff beqc a0, a1, 32767", 32767);
COMPARE_PC_REL_COMPACT(bnec(a0, a1, -32768), COMPARE_PC_REL_COMPACT(bnec(a0, a1, -32768),
"60858000 bnec a0, a1, -32768", -32768); "60858000 bnec a0, a1, -32768", -32768);
...@@ -836,11 +848,11 @@ TEST(Type0) { ...@@ -836,11 +848,11 @@ TEST(Type0) {
} }
if (IsMipsArchVariant(kMips32r6)) { if (IsMipsArchVariant(kMips32r6)) {
COMPARE(jialc(a0, -32768), "f8048000 jialc a0, 0x8000"); COMPARE(jialc(a0, -32768), "f8048000 jialc a0, -32768");
COMPARE(jialc(a0, -1), "f804ffff jialc a0, 0xffff"); COMPARE(jialc(a0, -1), "f804ffff jialc a0, -1");
COMPARE(jialc(v0, 0), "f8020000 jialc v0, 0x0"); COMPARE(jialc(v0, 0), "f8020000 jialc v0, 0");
COMPARE(jialc(s1, 1), "f8110001 jialc s1, 0x1"); COMPARE(jialc(s1, 1), "f8110001 jialc s1, 1");
COMPARE(jialc(a0, 32767), "f8047fff jialc a0, 0x7fff"); COMPARE(jialc(a0, 32767), "f8047fff jialc a0, 32767");
} }
VERIFY_RUN(); VERIFY_RUN();
......
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