I'm trying to emit a conditional move in the ARM backend for a custom
intrinsic. Basically, I want to emit the following the following
instruction sequence:
cmp r0, r1
moveq r2, #1
To implement this, I first emit a compare instruction and then I'm
trying to emit the conditional move, which is failing.
BuildMI(&MBB, DL, TII->get(ARM::CMPrr))
.addReg(MI.getOperand(1).getReg())
.addReg(MI.getOperand(2).getReg())
.addImm(ARMCC::EQ);
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVr),
MI.getOperand(0).getReg())
.addImm(ARMCC::EQ)
.addImm(1)
.addReg(0); // 's' bit
But with the last conditional move, I am a bit lost. The result of the
condional move should be saved in operand 0. Can someone help on how to
emit this instruction?
Cheers,
Robert
_______________________________________________
LLVM Developers mailing list
llvm...@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
On 13 February 2017 at 09:36, Robert Schilling via llvm-dev
<llvm...@lists.llvm.org> wrote:
> BuildMI(&MBB, DL, TII->get(ARM::CMPrr))
> .addReg(MI.getOperand(1).getReg())
> .addReg(MI.getOperand(2).getReg())
> .addImm(ARMCC::EQ);
ARM comparisons don't need to know what kind of comparison they're
actually going to be used for. So that ARMCC::EQ is actually turning
this instruction from a "cmp ..." into a "cmpeq ..." (i.e. only
perform the comparison if a previous compare was "eq").
What you probably want (on trunk LLVM) for that last operand is
"add(predOps(ARMCC::AL))" where "AL" means always.
> BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVr),
> MI.getOperand(0).getReg())
> .addImm(ARMCC::EQ)
> .addImm(1)
> .addReg(0); // 's' bit
MOVr is a move between two registers, you want the "MOVi" (move
immediate) instruction instead. MOVi takes 3 operands relating to the
condition code (all after the immediate):
First, the options for whether this particular move should be
predicated (like the CMPrr) above. There are two of these operands,
first an ARMCC value, and then a register which should be 0 if you're
using ARMCC::AL and ARM::CPSR otherwise (this is used to track which
instructions actually use CPSR, and obviously an instruction that's
always executed doesn't). This is what the predOps does above.
Second, there's another register argument which is set based on
whether this instruction should *set* the CPSR flags register. Since
you don't want this, you should use 0 (== NoReg). In trunk you'd write
"add(condCodeOp())" for that.
Putting it all together I think this last one should be
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVi),
MI.getOperand(0).getReg())
.addImm(1)
.add(predOps(ARMCC::EQ)
.add(condCodeOp());
It's worth noting that this'll only work in ARM mode. Thumb mode has a
completely different set of instructions in LLVM, usually starting
with "t" or "t2".
Hope this helps.
Tim.
> .add(predOps(ARMCC::EQ)
Sorry, this should be "predOps(ARMCC::EQ, ARM::CPSR)".