Emitting assembler code

Hello,
I'm trying to write assembler code writer, and of course, have new questions.
I'd like the structure my implementation like this:

   if (/*binary instruction*/) {
  // print destination
  O << " = ";
  // print first operand
  O << opcode;
  // print second operand.
   }
   if (/* unary instruction */ ) {
        ....
   }
   if (/*control instruction*/) {
  ....
   }

The question is how to write those checks for binary/unary/control/etc
instructions. Ideally, I'd like to write this in .td file:

   class Binary : ....

    def add : Binary<....>;
    def sub : Binary<....>;

It seems that X86 does something like this. The .td. file define:

   def Pseudo : Format<0>; def RawFrm : Format<1>;

and there are parallel definitions in X86InstrInfo.h:

    Pseudo = 0,
    RawFrm = 1,

Those definitions are used in codegen, and and TableGen somehow passes the
instruction format information to X86GenInstInfo.inc -- specifically, it
encodes it in the TSFlags field of the TargetInstrDescriptor class.

So the question is: how the information about format should be specified
in .td files? I've tried this:

  class Format<bits<5> val> {
     bits<5> Value = val;
  }

def F1 : Format<4>;

  class NMI<string nam> : Instruction {
     let Namespace = "NM";

     let Name = nam;

     Format Form = F1;
    bits<5> FormBits = 4;
}

But the values of the TSFlags field for did not change.

TIA,
Volodya

Hello,
I'm trying to write assembler code writer, and of course, have new questions.
I'd like the structure my implementation like this:

   if (/*binary instruction*/) {
   if (/* unary instruction */ ) {
   if (/*control instruction*/) {

Okay, that should be no problem.

The question is how to write those checks for binary/unary/control/etc
instructions. Ideally, I'd like to write this in .td file:

   class Binary : ....
    def add : Binary<....>;
    def sub : Binary<....>;

It seems that X86 does something like this. The .td. file define:

   def Pseudo : Format<0>; def RawFrm : Format<1>;

and there are parallel definitions in X86InstrInfo.h:

    Pseudo = 0,
    RawFrm = 1,

Exactly.

Those definitions are used in codegen, and and TableGen somehow passes the
instruction format information to X86GenInstInfo.inc -- specifically, it
encodes it in the TSFlags field of the TargetInstrDescriptor class.

Yup, the TSFlags field is defined to hold TargetSpecific flags of whatever
sort you want. Just the thing for holding information about how to print.

So the question is: how the information about format should be specified
in .td files? I've tried this:

But the values of the TSFlags field for did not change.

This one is definitely a tricky one. Take a look at the InstrInfo
tablegen class (in lib/Target/Target.td) and specifically the
TSFlagsFields and TSFlagsShifts lists. In the X86 backend these are
implemented in X86.td.

These specify exactly which fields of the Instruction classes should fill
in which bits of the TSFlags field. The only gross thing is that you
currently have to define a parallel enum or something to access these in
C++ code. For the X86 backend, this enum is the one you've seen defined
in X86InstrInfo.h

-Chris

Chris Lattner wrote:

> So the question is: how the information about format should be specified
> in .td files? I've tried this:
>
> But the values of the TSFlags field for did not change.

This one is definitely a tricky one. Take a look at the InstrInfo
tablegen class (in lib/Target/Target.td) and specifically the
TSFlagsFields and TSFlagsShifts lists. In the X86 backend these are
implemented in X86.td.

These specify exactly which fields of the Instruction classes should fill
in which bits of the TSFlags field. The only gross thing is that you
currently have to define a parallel enum or something to access these in
C++ code. For the X86 backend, this enum is the one you've seen defined
in X86InstrInfo.h

Thanks, this works perfectly!

- Volodya