Bug 516903 - nanojit: fix printing of cmov, cmovq. r=edwsmith.

This commit is contained in:
Nicholas Nethercote 2009-09-17 10:39:03 +10:00
parent afba815d74
commit d43a49fd27
2 changed files with 44 additions and 4 deletions

View File

@ -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

View File

@ -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();