[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