Commit e1bf0d47 authored by Ivica Bogosavljevic's avatar Ivica Bogosavljevic Committed by Commit Bot

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/1016282Reviewed-by: 's avatarSreten Kovacevic <sreten.kovacevic@mips.com>
Commit-Queue: Sreten Kovacevic <sreten.kovacevic@mips.com>
Cr-Commit-Position: refs/heads/master@{#52669}
parent 1b71e729
...@@ -3035,15 +3035,19 @@ void Assembler::cmp_d(FPUCondition cond, FPURegister fd, FPURegister fs, ...@@ -3035,15 +3035,19 @@ void Assembler::cmp_d(FPUCondition cond, FPURegister fd, FPURegister fs,
void Assembler::bc1eqz(int16_t offset, FPURegister ft) { void Assembler::bc1eqz(int16_t offset, FPURegister ft) {
DCHECK(IsMipsArchVariant(kMips32r6)); DCHECK(IsMipsArchVariant(kMips32r6));
BlockTrampolinePoolScope block_trampoline_pool(this);
Instr instr = COP1 | BC1EQZ | ft.code() << kFtShift | (offset & kImm16Mask); 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) { void Assembler::bc1nez(int16_t offset, FPURegister ft) {
DCHECK(IsMipsArchVariant(kMips32r6)); DCHECK(IsMipsArchVariant(kMips32r6));
BlockTrampolinePoolScope block_trampoline_pool(this);
Instr instr = COP1 | BC1NEZ | ft.code() << kFtShift | (offset & kImm16Mask); Instr instr = COP1 | BC1NEZ | ft.code() << kFtShift | (offset & kImm16Mask);
emit(instr, CompactBranchType::COMPACT_BRANCH); emit(instr);
BlockTrampolinePoolFor(1); // For associated delay slot.
} }
......
...@@ -1710,6 +1710,7 @@ void TurboAssembler::Neg_s(FPURegister fd, FPURegister fs) { ...@@ -1710,6 +1710,7 @@ void TurboAssembler::Neg_s(FPURegister fd, FPURegister fs) {
} else { } else {
DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r1) || DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r1) ||
IsMipsArchVariant(kLoongson)); IsMipsArchVariant(kLoongson));
BlockTrampolinePoolScope block_trampoline_pool(this);
Label is_nan, done; Label is_nan, done;
Register scratch1 = t8; Register scratch1 = t8;
Register scratch2 = t9; Register scratch2 = t9;
...@@ -1735,6 +1736,7 @@ void TurboAssembler::Neg_d(FPURegister fd, FPURegister fs) { ...@@ -1735,6 +1736,7 @@ void TurboAssembler::Neg_d(FPURegister fd, FPURegister fs) {
} else { } else {
DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r1) || DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r1) ||
IsMipsArchVariant(kLoongson)); IsMipsArchVariant(kLoongson));
BlockTrampolinePoolScope block_trampoline_pool(this);
Label is_nan, done; Label is_nan, done;
Register scratch1 = t8; Register scratch1 = t8;
Register scratch2 = t9; Register scratch2 = t9;
...@@ -2115,49 +2117,51 @@ void TurboAssembler::CompareIsNanF(SecondaryField sizeField, FPURegister cmp1, ...@@ -2115,49 +2117,51 @@ void TurboAssembler::CompareIsNanF(SecondaryField sizeField, FPURegister cmp1,
CompareF(sizeField, UN, cmp1, cmp2); CompareF(sizeField, UN, cmp1, cmp2);
} }
void TurboAssembler::BranchTrueShortF(Label* target) { void TurboAssembler::BranchTrueShortF(Label* target, BranchDelaySlot bd) {
if (IsMipsArchVariant(kMips32r6)) { if (IsMipsArchVariant(kMips32r6)) {
bc1nez(target, kDoubleCompareReg); bc1nez(target, kDoubleCompareReg);
nop();
} else { } else {
bc1t(target); bc1t(target);
}
if (bd == PROTECT) {
nop(); nop();
} }
} }
void TurboAssembler::BranchFalseShortF(Label* target) { void TurboAssembler::BranchFalseShortF(Label* target, BranchDelaySlot bd) {
if (IsMipsArchVariant(kMips32r6)) { if (IsMipsArchVariant(kMips32r6)) {
bc1eqz(target, kDoubleCompareReg); bc1eqz(target, kDoubleCompareReg);
nop();
} else { } else {
bc1f(target); bc1f(target);
}
if (bd == PROTECT) {
nop(); nop();
} }
} }
void TurboAssembler::BranchTrueF(Label* target) { void TurboAssembler::BranchTrueF(Label* target, BranchDelaySlot bd) {
bool long_branch = bool long_branch =
target->is_bound() ? !is_near(target) : is_trampoline_emitted(); target->is_bound() ? !is_near(target) : is_trampoline_emitted();
if (long_branch) { if (long_branch) {
Label skip; Label skip;
BranchFalseShortF(&skip); BranchFalseShortF(&skip);
BranchLong(target, PROTECT); BranchLong(target, bd);
bind(&skip); bind(&skip);
} else { } else {
BranchTrueShortF(target); BranchTrueShortF(target, bd);
} }
} }
void TurboAssembler::BranchFalseF(Label* target) { void TurboAssembler::BranchFalseF(Label* target, BranchDelaySlot bd) {
bool long_branch = bool long_branch =
target->is_bound() ? !is_near(target) : is_trampoline_emitted(); target->is_bound() ? !is_near(target) : is_trampoline_emitted();
if (long_branch) { if (long_branch) {
Label skip; Label skip;
BranchTrueShortF(&skip); BranchTrueShortF(&skip);
BranchLong(target, PROTECT); BranchLong(target, bd);
bind(&skip); bind(&skip);
} else { } else {
BranchFalseShortF(target); BranchFalseShortF(target, bd);
} }
} }
......
...@@ -228,11 +228,11 @@ class TurboAssembler : public Assembler { ...@@ -228,11 +228,11 @@ class TurboAssembler : public Assembler {
CompareIsNanF(D, cmp1, cmp2); CompareIsNanF(D, cmp1, cmp2);
} }
void BranchTrueShortF(Label* target); void BranchTrueShortF(Label* target, BranchDelaySlot bd = PROTECT);
void BranchFalseShortF(Label* target); void BranchFalseShortF(Label* target, BranchDelaySlot bd = PROTECT);
void BranchTrueF(Label* target); void BranchTrueF(Label* target, BranchDelaySlot bd = PROTECT);
void BranchFalseF(Label* target); void BranchFalseF(Label* target, BranchDelaySlot bd = PROTECT);
// MSA Branches // MSA Branches
void BranchMSA(Label* target, MSABranchDF df, MSABranchCondition cond, void BranchMSA(Label* target, MSABranchDF df, MSABranchCondition cond,
......
...@@ -6386,10 +6386,10 @@ void Simulator::DecodeTypeImmediate() { ...@@ -6386,10 +6386,10 @@ void Simulator::DecodeTypeImmediate() {
break; break;
} }
case BC1EQZ: case BC1EQZ:
BranchCompactHelper(!(get_fpu_register(ft_reg) & 0x1), 16); BranchHelper(!(get_fpu_register(ft_reg) & 0x1));
break; break;
case BC1NEZ: case BC1NEZ:
BranchCompactHelper(get_fpu_register(ft_reg) & 0x1, 16); BranchHelper(get_fpu_register(ft_reg) & 0x1);
break; break;
case BZ_V: { case BZ_V: {
msa_reg_t wt; msa_reg_t wt;
......
...@@ -3355,15 +3355,19 @@ void Assembler::cmp_d(FPUCondition cond, FPURegister fd, FPURegister fs, ...@@ -3355,15 +3355,19 @@ void Assembler::cmp_d(FPUCondition cond, FPURegister fd, FPURegister fs,
void Assembler::bc1eqz(int16_t offset, FPURegister ft) { void Assembler::bc1eqz(int16_t offset, FPURegister ft) {
DCHECK_EQ(kArchVariant, kMips64r6); DCHECK_EQ(kArchVariant, kMips64r6);
BlockTrampolinePoolScope block_trampoline_pool(this);
Instr instr = COP1 | BC1EQZ | ft.code() << kFtShift | (offset & kImm16Mask); 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) { void Assembler::bc1nez(int16_t offset, FPURegister ft) {
DCHECK_EQ(kArchVariant, kMips64r6); DCHECK_EQ(kArchVariant, kMips64r6);
BlockTrampolinePoolScope block_trampoline_pool(this);
Instr instr = COP1 | BC1NEZ | ft.code() << kFtShift | (offset & kImm16Mask); Instr instr = COP1 | BC1NEZ | ft.code() << kFtShift | (offset & kImm16Mask);
emit(instr, CompactBranchType::COMPACT_BRANCH); emit(instr);
BlockTrampolinePoolFor(1); // For associated delay slot.
} }
......
...@@ -2066,6 +2066,7 @@ void TurboAssembler::Neg_s(FPURegister fd, FPURegister fs) { ...@@ -2066,6 +2066,7 @@ void TurboAssembler::Neg_s(FPURegister fd, FPURegister fs) {
neg_s(fd, fs); neg_s(fd, fs);
} else { } else {
DCHECK_EQ(kArchVariant, kMips64r2); DCHECK_EQ(kArchVariant, kMips64r2);
BlockTrampolinePoolScope block_trampoline_pool(this);
Label is_nan, done; Label is_nan, done;
Register scratch1 = t8; Register scratch1 = t8;
Register scratch2 = t9; Register scratch2 = t9;
...@@ -2090,6 +2091,7 @@ void TurboAssembler::Neg_d(FPURegister fd, FPURegister fs) { ...@@ -2090,6 +2091,7 @@ void TurboAssembler::Neg_d(FPURegister fd, FPURegister fs) {
neg_d(fd, fs); neg_d(fd, fs);
} else { } else {
DCHECK_EQ(kArchVariant, kMips64r2); DCHECK_EQ(kArchVariant, kMips64r2);
BlockTrampolinePoolScope block_trampoline_pool(this);
Label is_nan, done; Label is_nan, done;
Register scratch1 = t8; Register scratch1 = t8;
Register scratch2 = t9; Register scratch2 = t9;
...@@ -2635,49 +2637,51 @@ void TurboAssembler::CompareIsNanF(SecondaryField sizeField, FPURegister cmp1, ...@@ -2635,49 +2637,51 @@ void TurboAssembler::CompareIsNanF(SecondaryField sizeField, FPURegister cmp1,
CompareF(sizeField, UN, cmp1, cmp2); CompareF(sizeField, UN, cmp1, cmp2);
} }
void TurboAssembler::BranchTrueShortF(Label* target) { void TurboAssembler::BranchTrueShortF(Label* target, BranchDelaySlot bd) {
if (kArchVariant == kMips64r6) { if (kArchVariant == kMips64r6) {
bc1nez(target, kDoubleCompareReg); bc1nez(target, kDoubleCompareReg);
nop();
} else { } else {
bc1t(target); bc1t(target);
}
if (bd == PROTECT) {
nop(); nop();
} }
} }
void TurboAssembler::BranchFalseShortF(Label* target) { void TurboAssembler::BranchFalseShortF(Label* target, BranchDelaySlot bd) {
if (kArchVariant == kMips64r6) { if (kArchVariant == kMips64r6) {
bc1eqz(target, kDoubleCompareReg); bc1eqz(target, kDoubleCompareReg);
nop();
} else { } else {
bc1f(target); bc1f(target);
}
if (bd == PROTECT) {
nop(); nop();
} }
} }
void TurboAssembler::BranchTrueF(Label* target) { void TurboAssembler::BranchTrueF(Label* target, BranchDelaySlot bd) {
bool long_branch = bool long_branch =
target->is_bound() ? !is_near(target) : is_trampoline_emitted(); target->is_bound() ? !is_near(target) : is_trampoline_emitted();
if (long_branch) { if (long_branch) {
Label skip; Label skip;
BranchFalseShortF(&skip); BranchFalseShortF(&skip);
BranchLong(target, PROTECT); BranchLong(target, bd);
bind(&skip); bind(&skip);
} else { } else {
BranchTrueShortF(target); BranchTrueShortF(target, bd);
} }
} }
void TurboAssembler::BranchFalseF(Label* target) { void TurboAssembler::BranchFalseF(Label* target, BranchDelaySlot bd) {
bool long_branch = bool long_branch =
target->is_bound() ? !is_near(target) : is_trampoline_emitted(); target->is_bound() ? !is_near(target) : is_trampoline_emitted();
if (long_branch) { if (long_branch) {
Label skip; Label skip;
BranchTrueShortF(&skip); BranchTrueShortF(&skip);
BranchLong(target, PROTECT); BranchLong(target, bd);
bind(&skip); bind(&skip);
} else { } else {
BranchFalseShortF(target); BranchFalseShortF(target, bd);
} }
} }
......
...@@ -257,11 +257,11 @@ class TurboAssembler : public Assembler { ...@@ -257,11 +257,11 @@ class TurboAssembler : public Assembler {
CompareIsNanF(D, cmp1, cmp2); CompareIsNanF(D, cmp1, cmp2);
} }
void BranchTrueShortF(Label* target); void BranchTrueShortF(Label* target, BranchDelaySlot bd = PROTECT);
void BranchFalseShortF(Label* target); void BranchFalseShortF(Label* target, BranchDelaySlot bd = PROTECT);
void BranchTrueF(Label* target); void BranchTrueF(Label* target, BranchDelaySlot bd = PROTECT);
void BranchFalseF(Label* target); void BranchFalseF(Label* target, BranchDelaySlot bd = PROTECT);
// MSA branches // MSA branches
void BranchMSA(Label* target, MSABranchDF df, MSABranchCondition cond, void BranchMSA(Label* target, MSABranchDF df, MSABranchCondition cond,
......
...@@ -6625,10 +6625,10 @@ void Simulator::DecodeTypeImmediate() { ...@@ -6625,10 +6625,10 @@ void Simulator::DecodeTypeImmediate() {
break; break;
} }
case BC1EQZ: case BC1EQZ:
BranchCompactHelper(!(get_fpu_register(ft_reg) & 0x1), 16); BranchHelper(!(get_fpu_register(ft_reg) & 0x1));
break; break;
case BC1NEZ: case BC1NEZ:
BranchCompactHelper((get_fpu_register(ft_reg) & 0x1), 16); BranchHelper(get_fpu_register(ft_reg) & 0x1);
break; break;
case BZ_V: { case BZ_V: {
msa_reg_t wt; msa_reg_t wt;
......
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