Node definitions, Pseudo ops and lowering SELECT/COND_BRANCH to branch instructions

Hello,
Im back trying to finish my backend to a simple RISC cpu SABRE now that most of the tedious process of examining undergraduate students is out of the way. I have managed to describe the registers and the instructions in the architecture and have added support for 32 bit immediates (thanks to Christopher Lamb) as the instruction set only supports 17 bit immediates directly.

Could anyone please describe the main features of how an llvm instruction such as SELECT and COND_BRANCH are lowered/expanded into branch instructions?
I have seen this thread
http://lists.cs.uiuc.edu/pipermail/llvmdev/2006-October/006892.html
but was wondering if anyone could comment on this process in a little more detail.

I presume I need to define various target independent nodes, like below ...
def SDT_SABREcondbr : SDTypeProfile<0,3, // no result, 3 operands, rega, regb, immediate
[ SDTCisVT<1,i32>, SDTCisVT<2,OtherVT> ]>;

def SABREcondbranch: SDNode <"SABREISD::COND_BRANCH" , SDT_SABREcondbr,
                         [SDNPHasChain]>;

def COND_BRANCH: Pseudo<(ops IntRegs:$a, IntRegs:$b, target:$dst),
         "${:comment}COND_BRANCH $a, $b, $dst",
         [(SABREcondbranch IntRegs:$a, IntRegs:$bm bb:$dst)]>;

and I need a setOperationAction(ISD::BRCOND, MVT::Other, Expand);

Im a little confused as to how BRCOND (or select for that matter) are then actually lowered to a particular branch instruction that is for the sake of argument ....
BLE %a, %b, newpc ie iff %a <= %b then branch to newpc.

I have been looking at the PPC and the sparc backend sources for information. I'd just like a little more (abstract) clarification before diving into this in some detail and gdb-ing through the specifics of the PPC/Sparc codegeneration for my helloworld bytecode.

Thanks,
         Andy

      Dr. Andy Nisbet: URL http://www.docm.mmu.ac.uk/STAFF/A.Nisbet
Department of Computing and Mathematics, John Dalton Building, Manchester
        Metropolitan University, Chester Street, Manchester M1 5GD, UK.
Email: A.Nisbet@mmu.ac.uk, Phone:(+44)-161-247-1556; Fax:(+44)-161-247-1483.

"Before acting on this email or opening any attachments you
should read the Manchester Metropolitan University's email
disclaimer available on its website
Email Disclaimer · Manchester Metropolitan University "

Hello,
Im back trying to finish my backend to a simple RISC cpu SABRE now
that most of the tedious process of examining undergraduate students
is out of the way. I have managed to describe the registers and the
instructions in the architecture and have added support for 32 bit
immediates (thanks to Christopher Lamb) as the instruction set only
supports 17 bit immediates directly.

Could anyone please describe the main features of how an llvm
instruction such as SELECT and COND_BRANCH are lowered/expanded into
branch instructions?
I have seen this thread
http://lists.cs.uiuc.edu/pipermail/llvmdev/2006-October/006892.html
but was wondering if anyone could comment on this process in a little
more detail.

I presume I need to define various target independent nodes, like below ...
def SDT_SABREcondbr : SDTypeProfile<0,3, // no result, 3 operands,
rega, regb, immediate
[ SDTCisVT<1,i32>, SDTCisVT<2,OtherVT> ]>;

def SABREcondbranch: SDNode <"SABREISD::COND_BRANCH" , SDT_SABREcondbr,
                         [SDNPHasChain]>;

This is not target independent but a target specific node.

def COND_BRANCH: Pseudo<(ops IntRegs:$a, IntRegs:$b, target:$dst),
         "${:comment}COND_BRANCH $a, $b, $dst",
         [(SABREcondbranch IntRegs:$a, IntRegs:$bm bb:$dst)]>;

Where is the conditional code in the operand list?

and I need a setOperationAction(ISD::BRCOND, MVT::Other, Expand);

I assume SABRE does not have an instruction BRCOND can directly map to? If there is a direct mapping from the target independent node to a target specific node, then you do not want to set operation action to expand.

When you ask legalizer to expand BRCOND, it expands it to BR_CC node which have the following operands: condition code, lhs of comparison, rhs, destination. If that maps to SABRE conditional branch instruction, then you can write a pattern to match to that.

In most of the cases, target specific conditional branches do not map exactly to BR_CC. That's why you see something like this in SparcISelLowering.cpp:

setOperationAction(ISD::BR_CC, MVT::i32, Custom);
setOperationAction(ISD::BR_CC, MVT::f32, Custom);
setOperationAction(ISD::BR_CC, MVT::f64, Custom);

This allows you to write C++ code to custom lower it to target specific node such as SABREISD::COND_BRANCH. There are plenty of examples of this in the other targets.

Hope this helps.

Evan