Joshua,
You can achieve this through the use of SDNodeXForm and Pat's. Here's a
snippet to get your started.
def imm_neg_XFORM : SDNodeXForm<imm, [{
return CurDAG->getTargetConstant(-N->getSExtValue(), MVT::i8);
}]>;
def imm0_255_neg : PatLeaf<(i8 imm), [{
unsigned Val = N->getZExtValue();
return Val > 0 && Val < 256;
}], imm_neg_XFORM>;
def : Pat<(add GPR8:$src1, imm0_255_neg:$src2),
(SUB8ri GPR8:$src1, imm0_255_neg:$src3)>;
--Owen
On Jan 10, 2012, at 1:23 PM, Joshua Nedrud wrote:
> Hello,
> I am working on a AVR backend and have a version up and running that will
convert LLVM IR code to assembly code for my target. I have written a bunch of
instructions from the AVR Instruction Set in AVRInstrInfo.td and not much else.
In a simple test case I am attempting to compile (if that is the word you are
supposed to use for this operation) test.ll:
>
> define i8 @foo(i8 %a, i8 %b) {
> entry:
> %c = sub i8 %a, 5
> ret i8 %c
> }
>
> with `build/Debug/bin/llc -march=avr llvm.ll -o -` and I receive:
>
> .file "test.ll"
> .text
> .global foo
> .type foo, at function
> foo: # @foo
> # BB#0: # %entry
> MOV r22, r24
> LDI r24, -5
> ADD r24, r18
> RET
> .tmp0:
> .size foo, .tmp0-foo
>
> While I would like the output as such:
>
> .file "test.ll"
> .text
> .global foo
> .type foo, at function
> foo: # @foo
> # BB#0: # %entry
> SUB r24, 5
> RET
> .tmp0:
> .size foo, .tmp0-foo
>
> With that my question is how to get LLVM to select SUB instead of the
pattern above. I have tried to place SUB8ri (see below) before the ADD8rr
instruction in the .td file, but that does not seem to make a difference.
*things to note, the AVR instruction set does not contain a ADD8ri, so I would
eventually like to convert all add register and immediate to subtract register
and -immediate, but for now if I could just get LLVM to use SUB8ri in the most
straightforward case that would work for me. Thanks,
> Joshua
>
> // SUB8ri definition
> let Constraints = "$src = $dst" in
> def SUB8ri : Instruction {
> let Namespace = "AVR";
> dag OutOperandList = (outs GPR8:$dst);
> dag InOperandList = (ins GPR8:$src, i8imm:$src2);
> let AsmString = "SUB\t{$dst, $src2}";
> let Pattern = [(set GPR8:$dst, (opnode GPR8:$src, imm:$src2))];
> }
>
> Joshua Nedrud
> Master of Science, Biomedical Engineering
>
>
>
>
>
>
>
>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev