Custom Opcodes versus built-in opcodes

I am using lowering instructions and using custom opcodes that I can
more easily directly map to my backend. These opcodes are then used to
emit a custom set of instructions into the MachineBasicBlock. I've been
able to get one to work correctly, however, I've ran into an issue where
my second one is being confused as a FRAMEADDR opcode instead of my
opcode.

DValue InstTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG& DAG){

MVT VT = Op.getValueType();

            SDValue Chain = Op.getOperand(0);

            SDValue LHS = Op.getOperand(2);

            SDValue RHS = Op.getOperand(3);

            SDValue Jump = Op.getOperand(4);

            bool logical_nz = getLogicalNZ(cmpOpcode);

            SDValue CmpValue;

            unsigned int brOpcode = CUSTOM::BRANCH_NZERO;

           CmpValue = DAG.getNode(CUSTOM::CMP, LHS.getValueType(),
Chain, DAG.getConstant(cmpOpcode, MVT::i32), LHS, RHS);

            return DAG.getNode(brOpcode, VT, Chain, Jump, CmpValue);
}

What I want to happen is to take the branch w/ condition codes and
convert it into a comparison and then a branch based on the result to
the BasicBlock in the Jump SDValue. What I expect to occur after this
function returns is for the SDValue that I created to be matched with my
BRANCH_NZERO instruction in my InstrInfo.td file. Instead what is
occurring is that it is mapping it for some reason to the FRAMEADDR
built-in instruction and running LowerFRAMEADDR. Both instructions are
enumerated to the same value, but they are part of different namespaces.

Any idea on how I can resolve this issue?

Thanks,

Micah Villmow

Systems Engineer

Advanced Technology & Performance

Advanced Micro Devices Inc.

4555 Great America Pkwy,

Santa Clara, CA. 95054

P: 408-572-6219

F: 408-572-6596

I am using lowering instructions and using custom opcodes that I can more
easily directly map to my backend. These opcodes are then used to emit a
custom set of instructions into the MachineBasicBlock. I've been able to get
one to work correctly, however, I've ran into an issue where my second one
is being confused as a FRAMEADDR opcode instead of my opcode.

[snip]

What I want to happen is to take the branch w/ condition codes and convert
it into a comparison and then a branch based on the result to the BasicBlock
in the Jump SDValue. What I expect to occur after this function returns is
for the SDValue that I created to be matched with my BRANCH_NZERO
instruction in my InstrInfo.td file. Instead what is occurring is that it is
mapping it for some reason to the FRAMEADDR built-in instruction and running
LowerFRAMEADDR. Both instructions are enumerated to the same value, but they
are part of different namespaces.

That's the problem. The "LowerFRAMEADDR" is called depending on the
enumeration's value, not on the namespace it's in. I can think of two
ways to solve this:

a) Change the enumeration of your BRANCH_NZERO instructions, or
2) Add your BRANCH_NZERO to the same namespace as FRAMEADDR.

-bw

I am using lowering instructions and using custom opcodes that I can

more

easily directly map to my backend. These opcodes are then used to emit

a

custom set of instructions into the MachineBasicBlock. I've been able

to get

one to work correctly, however, I've ran into an issue where my second

one

is being confused as a FRAMEADDR opcode instead of my opcode.

[snip]

What I want to happen is to take the branch w/ condition codes and

convert

it into a comparison and then a branch based on the result to the

BasicBlock

in the Jump SDValue. What I expect to occur after this function

returns is

for the SDValue that I created to be matched with my BRANCH_NZERO
instruction in my InstrInfo.td file. Instead what is occurring is that

it is

mapping it for some reason to the FRAMEADDR built-in instruction and

running

LowerFRAMEADDR. Both instructions are enumerated to the same value,

but they

are part of different namespaces.

That's the problem. The "LowerFRAMEADDR" is called depending on the
enumeration's value, not on the namespace it's in. I can think of two
ways to solve this:

a) Change the enumeration of your BRANCH_NZERO instructions, or
2) Add your BRANCH_NZERO to the same namespace as FRAMEADDR.

The problem with both of these solutions is that the opcodes are
dynamically generated with tablegen and thus I cannot change the
enumeration as I don't set the enumeration. Also changing the namespace
doesn't change the enumeration.

I think this can probably be classified as a bug in tablegen. It
shouldn't be generating enumerated opcode values with the same values as
built in opcodes.
-bw

Make sure to use DAG.getTargetNode() with custom opcodes. “target” nodes are encoded with an implicit delta added to their enum value.

-Chris

Actually, I’m wrong, sorry about that. It looks like the encoding is in the definition of the enum:

enum {
FIRST_NUMBER = ISD::BUILTIN_OP_END+SP::INSTRUCTION_LIST_END,
CMPICC, // Compare two GPR operands, set icc.
CMPFCC, // Compare two FP operands, set fcc.
BRICC, // Branch to dest on icc condition
BRFCC, // Branch to dest on fcc condition

Are your “targetISD” enums properly defined with the offset?

getTargetNode is required when passing in MachineInstr opcode numbers at isel time.

-Chris