MIPSR6: Reenable branch delay slot in fp branch instructions

Release 6 FP branch instruction contain branch delay slots
so we can reenable them.

Change-Id: I793b6acbcfd73f92c7e94ba99608616cc8d68199
Reviewed-on: https://chromium-review.googlesource.com/1016282
Reviewed-by: Sreten Kovacevic <sreten.kovacevic@mips.com>
Commit-Queue: Sreten Kovacevic <sreten.kovacevic@mips.com>
Cr-Commit-Position: refs/heads/master@{#52669}
This commit is contained in:
Ivica Bogosavljevic 2018-04-18 11:24:55 +02:00 committed by Commit Bot
parent 1b71e729bc
commit e1bf0d47b1
8 changed files with 52 additions and 36 deletions

View File

@ -3035,15 +3035,19 @@ void Assembler::cmp_d(FPUCondition cond, FPURegister fd, FPURegister fs,
void Assembler::bc1eqz(int16_t offset, FPURegister ft) {
DCHECK(IsMipsArchVariant(kMips32r6));
BlockTrampolinePoolScope block_trampoline_pool(this);
Instr instr = COP1 | BC1EQZ | ft.code() << kFtShift | (offset & kImm16Mask);
emit(instr, CompactBranchType::COMPACT_BRANCH);
emit(instr);
BlockTrampolinePoolFor(1); // For associated delay slot.
}
void Assembler::bc1nez(int16_t offset, FPURegister ft) {
DCHECK(IsMipsArchVariant(kMips32r6));
BlockTrampolinePoolScope block_trampoline_pool(this);
Instr instr = COP1 | BC1NEZ | ft.code() << kFtShift | (offset & kImm16Mask);
emit(instr, CompactBranchType::COMPACT_BRANCH);
emit(instr);
BlockTrampolinePoolFor(1); // For associated delay slot.
}

View File

@ -1710,6 +1710,7 @@ void TurboAssembler::Neg_s(FPURegister fd, FPURegister fs) {
} else {
DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r1) ||
IsMipsArchVariant(kLoongson));
BlockTrampolinePoolScope block_trampoline_pool(this);
Label is_nan, done;
Register scratch1 = t8;
Register scratch2 = t9;
@ -1735,6 +1736,7 @@ void TurboAssembler::Neg_d(FPURegister fd, FPURegister fs) {
} else {
DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r1) ||
IsMipsArchVariant(kLoongson));
BlockTrampolinePoolScope block_trampoline_pool(this);
Label is_nan, done;
Register scratch1 = t8;
Register scratch2 = t9;
@ -2115,49 +2117,51 @@ void TurboAssembler::CompareIsNanF(SecondaryField sizeField, FPURegister cmp1,
CompareF(sizeField, UN, cmp1, cmp2);
}
void TurboAssembler::BranchTrueShortF(Label* target) {
void TurboAssembler::BranchTrueShortF(Label* target, BranchDelaySlot bd) {
if (IsMipsArchVariant(kMips32r6)) {
bc1nez(target, kDoubleCompareReg);
nop();
} else {
bc1t(target);
}
if (bd == PROTECT) {
nop();
}
}
void TurboAssembler::BranchFalseShortF(Label* target) {
void TurboAssembler::BranchFalseShortF(Label* target, BranchDelaySlot bd) {
if (IsMipsArchVariant(kMips32r6)) {
bc1eqz(target, kDoubleCompareReg);
nop();
} else {
bc1f(target);
}
if (bd == PROTECT) {
nop();
}
}
void TurboAssembler::BranchTrueF(Label* target) {
void TurboAssembler::BranchTrueF(Label* target, BranchDelaySlot bd) {
bool long_branch =
target->is_bound() ? !is_near(target) : is_trampoline_emitted();
if (long_branch) {
Label skip;
BranchFalseShortF(&skip);
BranchLong(target, PROTECT);
BranchLong(target, bd);
bind(&skip);
} else {
BranchTrueShortF(target);
BranchTrueShortF(target, bd);
}
}
void TurboAssembler::BranchFalseF(Label* target) {
void TurboAssembler::BranchFalseF(Label* target, BranchDelaySlot bd) {
bool long_branch =
target->is_bound() ? !is_near(target) : is_trampoline_emitted();
if (long_branch) {
Label skip;
BranchTrueShortF(&skip);
BranchLong(target, PROTECT);
BranchLong(target, bd);
bind(&skip);
} else {
BranchFalseShortF(target);
BranchFalseShortF(target, bd);
}
}

View File

@ -228,11 +228,11 @@ class TurboAssembler : public Assembler {
CompareIsNanF(D, cmp1, cmp2);
}
void BranchTrueShortF(Label* target);
void BranchFalseShortF(Label* target);
void BranchTrueShortF(Label* target, BranchDelaySlot bd = PROTECT);
void BranchFalseShortF(Label* target, BranchDelaySlot bd = PROTECT);
void BranchTrueF(Label* target);
void BranchFalseF(Label* target);
void BranchTrueF(Label* target, BranchDelaySlot bd = PROTECT);
void BranchFalseF(Label* target, BranchDelaySlot bd = PROTECT);
// MSA Branches
void BranchMSA(Label* target, MSABranchDF df, MSABranchCondition cond,

View File

@ -6386,10 +6386,10 @@ void Simulator::DecodeTypeImmediate() {
break;
}
case BC1EQZ:
BranchCompactHelper(!(get_fpu_register(ft_reg) & 0x1), 16);
BranchHelper(!(get_fpu_register(ft_reg) & 0x1));
break;
case BC1NEZ:
BranchCompactHelper(get_fpu_register(ft_reg) & 0x1, 16);
BranchHelper(get_fpu_register(ft_reg) & 0x1);
break;
case BZ_V: {
msa_reg_t wt;

View File

@ -3355,15 +3355,19 @@ void Assembler::cmp_d(FPUCondition cond, FPURegister fd, FPURegister fs,
void Assembler::bc1eqz(int16_t offset, FPURegister ft) {
DCHECK_EQ(kArchVariant, kMips64r6);
BlockTrampolinePoolScope block_trampoline_pool(this);
Instr instr = COP1 | BC1EQZ | ft.code() << kFtShift | (offset & kImm16Mask);
emit(instr, CompactBranchType::COMPACT_BRANCH);
emit(instr);
BlockTrampolinePoolFor(1); // For associated delay slot.
}
void Assembler::bc1nez(int16_t offset, FPURegister ft) {
DCHECK_EQ(kArchVariant, kMips64r6);
BlockTrampolinePoolScope block_trampoline_pool(this);
Instr instr = COP1 | BC1NEZ | ft.code() << kFtShift | (offset & kImm16Mask);
emit(instr, CompactBranchType::COMPACT_BRANCH);
emit(instr);
BlockTrampolinePoolFor(1); // For associated delay slot.
}

View File

@ -2066,6 +2066,7 @@ void TurboAssembler::Neg_s(FPURegister fd, FPURegister fs) {
neg_s(fd, fs);
} else {
DCHECK_EQ(kArchVariant, kMips64r2);
BlockTrampolinePoolScope block_trampoline_pool(this);
Label is_nan, done;
Register scratch1 = t8;
Register scratch2 = t9;
@ -2090,6 +2091,7 @@ void TurboAssembler::Neg_d(FPURegister fd, FPURegister fs) {
neg_d(fd, fs);
} else {
DCHECK_EQ(kArchVariant, kMips64r2);
BlockTrampolinePoolScope block_trampoline_pool(this);
Label is_nan, done;
Register scratch1 = t8;
Register scratch2 = t9;
@ -2635,49 +2637,51 @@ void TurboAssembler::CompareIsNanF(SecondaryField sizeField, FPURegister cmp1,
CompareF(sizeField, UN, cmp1, cmp2);
}
void TurboAssembler::BranchTrueShortF(Label* target) {
void TurboAssembler::BranchTrueShortF(Label* target, BranchDelaySlot bd) {
if (kArchVariant == kMips64r6) {
bc1nez(target, kDoubleCompareReg);
nop();
} else {
bc1t(target);
}
if (bd == PROTECT) {
nop();
}
}
void TurboAssembler::BranchFalseShortF(Label* target) {
void TurboAssembler::BranchFalseShortF(Label* target, BranchDelaySlot bd) {
if (kArchVariant == kMips64r6) {
bc1eqz(target, kDoubleCompareReg);
nop();
} else {
bc1f(target);
}
if (bd == PROTECT) {
nop();
}
}
void TurboAssembler::BranchTrueF(Label* target) {
void TurboAssembler::BranchTrueF(Label* target, BranchDelaySlot bd) {
bool long_branch =
target->is_bound() ? !is_near(target) : is_trampoline_emitted();
if (long_branch) {
Label skip;
BranchFalseShortF(&skip);
BranchLong(target, PROTECT);
BranchLong(target, bd);
bind(&skip);
} else {
BranchTrueShortF(target);
BranchTrueShortF(target, bd);
}
}
void TurboAssembler::BranchFalseF(Label* target) {
void TurboAssembler::BranchFalseF(Label* target, BranchDelaySlot bd) {
bool long_branch =
target->is_bound() ? !is_near(target) : is_trampoline_emitted();
if (long_branch) {
Label skip;
BranchTrueShortF(&skip);
BranchLong(target, PROTECT);
BranchLong(target, bd);
bind(&skip);
} else {
BranchFalseShortF(target);
BranchFalseShortF(target, bd);
}
}

View File

@ -257,11 +257,11 @@ class TurboAssembler : public Assembler {
CompareIsNanF(D, cmp1, cmp2);
}
void BranchTrueShortF(Label* target);
void BranchFalseShortF(Label* target);
void BranchTrueShortF(Label* target, BranchDelaySlot bd = PROTECT);
void BranchFalseShortF(Label* target, BranchDelaySlot bd = PROTECT);
void BranchTrueF(Label* target);
void BranchFalseF(Label* target);
void BranchTrueF(Label* target, BranchDelaySlot bd = PROTECT);
void BranchFalseF(Label* target, BranchDelaySlot bd = PROTECT);
// MSA branches
void BranchMSA(Label* target, MSABranchDF df, MSABranchCondition cond,

View File

@ -6625,10 +6625,10 @@ void Simulator::DecodeTypeImmediate() {
break;
}
case BC1EQZ:
BranchCompactHelper(!(get_fpu_register(ft_reg) & 0x1), 16);
BranchHelper(!(get_fpu_register(ft_reg) & 0x1));
break;
case BC1NEZ:
BranchCompactHelper((get_fpu_register(ft_reg) & 0x1), 16);
BranchHelper(get_fpu_register(ft_reg) & 0x1);
break;
case BZ_V: {
msa_reg_t wt;