[LLVMdev] selecting select_cc

Andrew Lenharth alenhar2 at cs.uiuc.edu
Mon Aug 21 13:53:37 PDT 2006


On Mon, 2006-08-21 at 17:09 -0300, Rafael EspĂ­ndola wrote:
> I am trying to add support for select_cc. In ARM it can be implemented with:
> 
> mov $dst, $falseVal
> cmp $a, $b
> moveq $dst, $trueVal
> 
> My current strategy is to expand select_cc in two ARM nodes:
> ARM::SELECT and ARM::CMP.  The two nodes would be connected by a flag
> edge.
> 
> ARM::CMP would then expand to "cmp $a, $b". This instruction has no
> results. It only alters the CPSR (current program status register).
> 
> ARM::SELECT would expand to a conditional move (moveq for example).
> Something similar is done by the Alpha backend:
> 
> ---------------------------------------------------------------------------------------------
> def CMOVEQ   : OForm4<  0x11, 0x24, "cmoveq $RCOND,$RTRUE,$RDEST",
>                 [(set GPRC:$RDEST, (select (seteq GPRC:$RCOND, 0),
> GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>;
> ----------------------------------------------------------------------------------------------
> 
> One thing that I don't understand is how the $RFALSE value is used.
> $RDEST must equal $RFALSE before the cmov is executed. How does the
> Alpha backend enforces this?

That instruction is marked as a two address instruction (see
AlphaInstrFormats.td).  This forces the register allocator to allocate
the first two virtual registers to the same physical register.  The
Operand list for that class is defined as:
let OperandList = (ops GPRC:$RDEST, GPRC:$RFALSE, GPRC:$RTRUE, GPRC:
$RCOND);
so along with:
let isTwoAddress = 1;
RDEST and RFALSE are the same physical register (post allocation).

I seem to recall that this is necessary so that a virtual register is
not used and defined by the same instruction.

Andrew





More information about the llvm-dev mailing list