mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 516903 - nanojit: fix printing of cmov, cmovq. r=edwsmith.
This commit is contained in:
parent
afba815d74
commit
d43a49fd27
@ -1357,11 +1357,21 @@ namespace nanojit
|
|||||||
//
|
//
|
||||||
if (_logc->lcbits & LC_Assembly) {
|
if (_logc->lcbits & LC_Assembly) {
|
||||||
outputf(" %s", _thisfrag->lirbuf->names->formatIns(ins));
|
outputf(" %s", _thisfrag->lirbuf->names->formatIns(ins));
|
||||||
// Special case: a guard condition won't get printed next time
|
|
||||||
// around the loop, so do it now.
|
|
||||||
if (ins->isGuard() && ins->oprnd1()) {
|
if (ins->isGuard() && ins->oprnd1()) {
|
||||||
outputf(" %s # handled by the guard",
|
// Special case: code is generated for guard conditions at
|
||||||
_thisfrag->lirbuf->names->formatIns(ins->oprnd1()));
|
// the same time that code is generated for the guard
|
||||||
|
// itself. If the condition is only used by the guard, we
|
||||||
|
// must print it now otherwise it won't get printed. So
|
||||||
|
// we do print it now, with an explanatory comment. If
|
||||||
|
// the condition *is* used again we'll end up printing it
|
||||||
|
// twice, but that's ok.
|
||||||
|
outputf(" %s # codegen'd with the %s",
|
||||||
|
_thisfrag->lirbuf->names->formatIns(ins->oprnd1()), lirNames[op]);
|
||||||
|
|
||||||
|
} else if (ins->isop(LIR_cmov) || ins->isop(LIR_qcmov)) {
|
||||||
|
// Likewise for cmov conditions.
|
||||||
|
outputf(" %s # codegen'd with the %s",
|
||||||
|
_thisfrag->lirbuf->names->formatIns(ins->oprnd1()), lirNames[op]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -686,6 +686,36 @@ namespace nanojit
|
|||||||
JMP(exit);
|
JMP(exit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This generates a 'test' or 'cmp' instruction for a condition, which
|
||||||
|
// causes the condition codes to be set appropriately. It's used with
|
||||||
|
// conditional branches, conditional moves, and when generating
|
||||||
|
// conditional values. For example:
|
||||||
|
//
|
||||||
|
// LIR: eq1 = eq a, 0
|
||||||
|
// LIR: xf1: xf eq1 -> ...
|
||||||
|
// asm: test edx, edx # generated by this function
|
||||||
|
// asm: je ...
|
||||||
|
//
|
||||||
|
// If this is the only use of eq1, then on entry 'cond' is *not* marked as
|
||||||
|
// used, and we do not allocate a register for it. That's because its
|
||||||
|
// result ends up in the condition codes rather than a normal register.
|
||||||
|
// This doesn't get recorded in the regstate and so the asm code that
|
||||||
|
// consumes the result (eg. a conditional branch like 'je') must follow
|
||||||
|
// shortly after.
|
||||||
|
//
|
||||||
|
// If eq1 is instead used again later, we will also generate code
|
||||||
|
// (eg. in asm_cond()) to compute it into a normal register, something
|
||||||
|
// like this:
|
||||||
|
//
|
||||||
|
// LIR: eq1 = eq a, 0
|
||||||
|
// LIR: test edx, edx
|
||||||
|
// asm: sete ebx
|
||||||
|
// asm: movzx ebx, ebx
|
||||||
|
//
|
||||||
|
// In this case we end up computing the condition twice, but that's ok, as
|
||||||
|
// it's just as short as testing eq1's value in the code generated for the
|
||||||
|
// guard.
|
||||||
|
//
|
||||||
void Assembler::asm_cmp(LIns *cond)
|
void Assembler::asm_cmp(LIns *cond)
|
||||||
{
|
{
|
||||||
LOpcode condop = cond->opcode();
|
LOpcode condop = cond->opcode();
|
||||||
|
Loading…
Reference in New Issue
Block a user