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) {
|
||||
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()) {
|
||||
outputf(" %s # handled by the guard",
|
||||
_thisfrag->lirbuf->names->formatIns(ins->oprnd1()));
|
||||
// Special case: code is generated for guard conditions at
|
||||
// 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
|
||||
|
@ -686,6 +686,36 @@ namespace nanojit
|
||||
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)
|
||||
{
|
||||
LOpcode condop = cond->opcode();
|
||||
|
Loading…
Reference in New Issue
Block a user