Alternate instruction encoding for subtargets - SOLVED

Can I tell tablegen to have two encodings and switch between them
using a predicate?

After some deliberations, I modified tablegen to generate several
versions of the GenCodeEmitter file. My tablegen now accepts a new
command line parameter called "emitter-instfld". This specifies the
name of the field in Instruction that holds the encoded bytes. In my
target's td files I simply specify both encodings at the same time.

This is my target's Instruction base class. It defines the traditional
field Inst and also an additional field Inst6 that holds the alternate
encodings for the KCPSM6 sub-target.

/// base class - a picoblaze instruction
class InstPB<Format form, dag outs, dag ins, string asmstr, list<dag>

: Instruction

{
  field bits<18> Inst; // for KCPSM3
  field bits<18> Inst6; // for KCPSM6

  Format Form = form;
  bits<4> FormBits = Form.Value;
  // TSFlags layout should be kept in sync with PBlazeInstrInfo.h.
  let TSFlags{3-0} = FormBits;

  let Namespace = "PB";

  dag OutOperandList = outs;
  dag InOperandList = ins;
  let AsmString = asmstr;
  let Pattern = pattern;
}

My instruction formats classes encode the same instruction twice: into
the Inst and Inst6 fields. The operation subcode which is different
between the sub-targets is also specified twice in the class
parameters as the op13 (KCPSM3) and op16 (KCPSM6) argument.

class AJumpCC<bits<6> op13, bits<6> op16,
                dag outs, dag ins, string asmstr, list<dag> pattern>
        : InstPB<FCCAA, outs, ins, asmstr, pattern>
{
    bits<2> cc; // condition codes
    bits<12> dst; // address field

    // encode KCPSM3
    let Inst{17-12} = op13;
    let Inst{11-10} = cc;
    let Inst{9-0} = dst{9-0};

    // encode KCPSM6
    let Inst6{17-16} = op16{5-4};
    let Inst6{15-14} = cc;
    let Inst6{13-12} = op16{1-0};
    let Inst6{11-0} = dst;
}

Each instruction def in the td file was augmented to specify the new
op16 opcode for the new sub-target. Hence, no instructions are
duplicated and this change has no effect on the custom lowering passes
that can continue to hand-insert specific target instructions.

def JUMP_cond : AJumpCC<0b110101, 0b110010, (outs), (ins i8imm:$cc,
brtarget:$dst),
                        "jump \t$cc, $dst",
                        [(PBjumpcc simm8:$cc, bb:$dst)]>;

Finally, I modified the build system to call "tablegen -gen-emitter"
twice, first with "-emitter-instfld=Inst" to generate the encoder for
KCPSM3 and then with "-emitter-instfld=Inst6" to generate the encoder
for KCPSM6. This creates two *GenCodeEmitter.inc files that are
included in the MCCodeEmitter (conflicting function names taken care
of by the preprocessor...), and henceforth the encoder implementation
can be dynamically switched in runtime according to the current -mcpu.

Curious readers may find the hacked tablegen attached.

Cheers,
Jara

tablegen-hack.patch (2.98 KB)