mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 594296 - Fix the implementation of Assembler::asm_cmov() in the SH4 backend (r=nnethercote r=rreitmai sr=edwsmith)
--HG-- extra : convert_revision : 616a6130e06155aead8751eba04981e3760999c8
This commit is contained in:
parent
d2c59c063a
commit
7eb372bec3
@ -2141,27 +2141,63 @@ namespace nanojit
|
|||||||
RegisterMask allow = inst->isD() ? FpRegs : GpRegs;
|
RegisterMask allow = inst->isD() ? FpRegs : GpRegs;
|
||||||
|
|
||||||
Register dest_reg = prepareResultReg(inst, allow);
|
Register dest_reg = prepareResultReg(inst, allow);
|
||||||
Register src_reg = findRegFor(if_false, allow & ~rmask(dest_reg));
|
|
||||||
|
|
||||||
// 3. If the test is "true", we branched over the copy.
|
// Try to re-use the result register for one of the arguments.
|
||||||
underrunProtect(2 * sizeof(NIns));
|
Register src_true_reg = if_true->isInReg() ? if_true->getReg() : dest_reg;
|
||||||
NIns *after_mov = _nIns;
|
Register src_false_reg = if_false->isInReg() ? if_false->getReg() : dest_reg;
|
||||||
|
|
||||||
// 2. If the test is "false", copy the register.
|
// Note that iftrue and iffalse may actually be the same, though
|
||||||
|
// it shouldn't happen with the LIR optimizers turned on.
|
||||||
|
if (src_true_reg == src_false_reg && if_true != if_false) {
|
||||||
|
// We can't re-use the result register for both arguments,
|
||||||
|
// so force one into its own register.
|
||||||
|
src_false_reg = findRegFor(if_false, allow & ~rmask(dest_reg));
|
||||||
|
NanoAssert(if_false->isInReg());
|
||||||
|
}
|
||||||
|
|
||||||
|
underrunProtect(6 * sizeof(NIns));
|
||||||
|
// 3. If the test is "true", copy the "true" source register.
|
||||||
|
NIns *after_mov_true = _nIns;
|
||||||
if (inst->isop(LIR_cmovd)) {
|
if (inst->isop(LIR_cmovd)) {
|
||||||
SH4_fmov(src_reg, dest_reg);
|
SH4_fmov(src_true_reg, dest_reg);
|
||||||
SH4_fmov(Register(src_reg + 1), Register(dest_reg + 1));
|
SH4_fmov(Register(src_true_reg + 1), Register(dest_reg + 1));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SH4_mov(src_reg, dest_reg);
|
SH4_mov(src_true_reg, dest_reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
findSpecificRegFor(if_true, dest_reg);
|
// 2. If the test is "false", copy the "false" source register
|
||||||
|
// then jump over the "mov if true".
|
||||||
|
NIns *after_mov_false = _nIns;
|
||||||
|
|
||||||
// 1. Branch [or not] according to the condition.
|
SH4_nop();
|
||||||
asm_branch(false, condition, after_mov);
|
SH4_bra(SH4_LABEL(after_mov_true));
|
||||||
|
|
||||||
|
if (inst->isop(LIR_cmovd)) {
|
||||||
|
SH4_fmov(src_false_reg, dest_reg);
|
||||||
|
SH4_fmov(Register(src_false_reg + 1), Register(dest_reg + 1));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SH4_mov(src_false_reg, dest_reg);
|
||||||
|
}
|
||||||
|
|
||||||
freeResourcesOf(inst);
|
freeResourcesOf(inst);
|
||||||
|
|
||||||
|
// If we re-used the result register, mark it as active for either if_true
|
||||||
|
// or if_false (or both in the corner-case where they're the same).
|
||||||
|
if (src_true_reg == dest_reg) {
|
||||||
|
NanoAssert(!if_true->isInReg());
|
||||||
|
findSpecificRegForUnallocated(if_true, dest_reg);
|
||||||
|
} else if (src_false_reg == dest_reg) {
|
||||||
|
NanoAssert(!if_false->isInReg());
|
||||||
|
findSpecificRegForUnallocated(if_false, dest_reg);
|
||||||
|
} else {
|
||||||
|
NanoAssert(if_false->isInReg());
|
||||||
|
NanoAssert(if_true->isInReg());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. Branch [or not] according to the condition.
|
||||||
|
asm_branch(false, condition, after_mov_false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Assembler::asm_cond(LIns *inst) {
|
void Assembler::asm_cond(LIns *inst) {
|
||||||
|
Loading…
Reference in New Issue
Block a user