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:
parent
1b71e729bc
commit
e1bf0d47b1
@ -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.
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user