Hi Kevin,

To get some portion of a constant immediate you can use SDNodeXForms to

transform constant SDNodes into other values. For a worked example, in the

MIPS backend we use this for constant synthesis by materializing the value into a

register:

(From lib/Target/MipsInstrInfo.td):

// Transformation Function - get the lower 16 bits.

def LO16 : SDNodeXForm<imm, [{

return getImm(N, N->getZExtValue() & 0xFFFF);

}]>;

The above fragment will take an immediate node and get the lower 16 bits.

// Transformation Function - get the higher 16 bits.

def HI16 : SDNodeXForm<imm, [{

return getImm(N, (N->getZExtValue() >> 16) & 0xFFFF);

}]>;

Similarly, get the high 16 bits.

def LUiORiPred : PatLeaf<(imm), [{

int64_t SVal = N->getSExtValue();

return isInt<32>(SVal) && (SVal & 0xffff);

}]>;

For completeness sake I've included this, but it's return true there are bits in both

16 bit fragments.

Then we use (here VT = i32, ORiOp is our logical or which takes an immediate,

LUiOp loads the upper bits of a register with an immediate, zeroing the lower 16 bits):

// Arbitrary immediates

def : MipsPat<(VT LUiORiPred:$imm), (ORiOp (LUiOp (HI16 imm:$imm)), (LO16 imm:$imm))>;

This anonymous pattern matches any sign-extended 32 bit immediate due to

LUiORiPred, and the expression (HI16 imm:$imm) takes an immediate and

extracts the upper bits of the immediate into a constant which LUiOp accepts.

The outer (LO16 imm:$imm) expression gets the lower 16 bits which ORiOp accepts.

As the SDNodeXForm takes arbitrary C++ code, you can go a bit farther with

transforming values.

Depending on your target, the usage of SDNodeXForm example alone may be

enough for your needs, otherwise hopefully the synthesize into a register example

is sufficient.

Thanks,

Simon