Restricting instruction pattern matching by register class

With a “toy” target with non-homogeneous register banks and specific instructions for copying or summing values between them (remotely similar to a 6502 but with multiple acculmulators and indexes), I’m trying to restrict instruction selection by the register class. However given these (simplified extracts) from the .td definitions:

def aRegs : RegisterClass<“ToyCPU”, [i8], 8,
(add a0, a1, a2, a3 )>;

def xRegs : RegisterClass<“ToyCPU”, [i8], 8,
(add x0, x1, x2, x3, x4, x5, x6, x7 )>;

// Add an index to an accumulator
// (aN = aN + xO => “ADX aN, xO”)
let Constraints = “$src = $dst” in {
def ADX : ToyInst<0x0600, //opcode
(outs aRegs:$dst), (ins aRegs:$src, xRegs:$src2),
“adx {$dst, $src2}”,
[(set aRegs:$dst, (add aRegs:$src xRegs:$src2))]>;
}

it seemingly ignores the register class, emitting assembler such as “adx a1, a0”.

The only direct commentary that I’ve found is this thread:

http://lists.cs.uiuc.edu/pipermail/llvmdev/2007-September/010815.html

which (as I understand) says that register class constraints can only be handled through custom pattern code. Before heading in that direction I’d welcome confirmation that - eight years after that thread - this remains the best approach for restricting register selections?

/Tyro

Hi Tyro,

With a “toy” target with non-homogeneous register banks and specific instructions for copying or summing values between them (remotely similar to a 6502 but with multiple acculmulators and indexes), I’m trying to restrict instruction selection by the register class. However given these (simplified extracts) from the .td definitions:

def aRegs : RegisterClass<“ToyCPU”, [i8], 8,
(add a0, a1, a2, a3 )>;

def xRegs : RegisterClass<“ToyCPU”, [i8], 8,
(add x0, x1, x2, x3, x4, x5, x6, x7 )>;

// Add an index to an accumulator
// (aN = aN + xO => “ADX aN, xO”)
let Constraints = “$src = $dst” in {
def ADX : ToyInst<0x0600, //opcode
(outs aRegs:$dst), (ins aRegs:$src, xRegs:$src2),
“adx {$dst, $src2}”,
[(set aRegs:$dst, (add aRegs:$src xRegs:$src2))]>;
}

it seemingly ignores the register class, emitting assembler such as "adx a1, a0”.

If you’re emitting this, it looks like to me you have a pattern that allow to produce those or your asm printer is not printing the xRegs correctly.

Could you check the output of (-mllvm) -print-machineinstrs?

After register selection, if you grabbed the right ADX, you should see ADX … ; vregDst:aRegs, vregSrc:aRegs, vregSrc2:xRegs. If that is not the case, your not selection the right thing.

The only direct commentary that I’ve found is this thread:

http://lists.cs.uiuc.edu/pipermail/llvmdev/2007-September/010815.html

which (as I understand) says that register class constraints can only be handled through custom pattern code. Before heading in that direction I’d welcome confirmation that - eight years after that thread - this remains the best approach for restricting register selections?

What are you trying to achieve with this restricted instruction selection by register class?

Cheers,
-Quentin