[LLVMdev] Instructions working on 64bit registers without true support for 64bit operations
Fabian Scheler
fabian.scheler at gmail.com
Mon Jul 23 06:24:03 PDT 2012
Hi LLVM-folks,
I just wanted to let you know, that I finally succeeded to load an
64-bit immediate value
using a pattern incorporating two INSERT_SUBREG-nodes.
> 2. Use a pattern consisting of INSERT_SUBREG-nodes
>
> A colleague of mine (who originally implemented the TriCore-backend)
> suggested to use a pattern that replaces 64bit-constants by tow
> INSERT_SUBREG-nodes. I ended up having the following pattern:
>
> def : Pat<(i64 imm:$imm),
> (INSERT_SUBREG
> (INSERT_SUBREG
> (i64 (IMPLICIT_DEF)),
> (i32 (LO32 imm:$imm)),
> sub_even),
> (i32 (HI32 imm:$imm)),
> sub_odd)>;
The pattern I use for this purpose looks like this:
def : Pat<(i64 imm:$imm),
(INSERT_SUBREG (i64 (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
(ADDIrlc (MOVHrlc (HA16 (i32
(LO32 imm:$imm)))), (LO16 (i32 (LO32 imm:$imm)))),
sub_even)),
(ADDIrlc (MOVHrlc (HA16 (i32 (HI32
imm:$imm)))), (LO16 (i32 (HI32 imm:$imm)))),
sub_odd)>;
here {HA,LO}16 {HI,LO} looks like this:
// Lower 16 bits of a 32-bit word
def LO16 : SDNodeXForm<imm, [{
return getLo16(N);
}]>;
// Higher 16 bits (arithmetic) of a 32-bit word
def HA16 : SDNodeXForm<imm, [{
return getHa16(N);
}]>;
// Lower 32 bits of a 64-bit word
def LO32 : SDNodeXForm<imm, [{
return getConst((uint32_t) N->getZExtValue(), MVT::i32);;
}]>;
// Higher 32 bits (logical) of a 64-bit word
def HI32 : SDNodeXForm<imm, [{
return getConst((uint32_t)(N->getZExtValue() >> 32), MVT::i32);
}]>;
The pattern posted first did not work for the following two reasons (I
guess, but I don't know):
1. My calling conventions were not set up properly, ie. 64-bit
parameter passing was not specified.
2. The expansion mentioned below was not carried out by tablegen :-( I
have another pattern
to load an 32-bit immediate constant:
def : Pat<(i32 imm:$imm), (ADDIrlc (MOVHrlc (HA16 imm:$imm)), (LO16 imm:$imm))>;
However, I was not able to specify that {HI,LO}32 yield 32-bit
immediates so the pattern above matches ....
> OK, this leaves a DAG where all i64-Constant-nodes are replaced by to
> nested INSERT_SUBREG-nodes, but how do I get rid of that
> INSERT_SUBREG-stuff. Do I have to lower it separately? Should there be
> some magic that eliminates those nodes for me?
>
> Maybe, I just have to make clear that (LO32 imm:$imm) yields a
> 32bit-Constant (How can I do this?), as there is another pattern to
> load a 32bit-Constant into a register.
Ciao, Fabian
More information about the llvm-dev
mailing list