[LLVMdev] How to partition registers into different RegisterClass?

Tzu-Chien Chiu
Fri, 22 Jul 2005 10:08:09 -0000

All registers in my hardware are 4-element vector registers (128-bit).
Some are floating point registers, and the others are integer
registers.

I typedef two packed classes: [4 x float] and [4 x int], and add an
enum 'packed' to MVT::ValueType (ValuesTypes.h).

I declared all 'RegisterClass'es to be 'packed' (first argument
of
RegisterClass):

  def GeneralPurposeRC : RegisterClass<packed, 128, [R0, R1]>;
  def INT_ReadOnlyRC : RegisterClass<packed, 128, [I0, I1]>;
  def FP_ReadOnlyRC : RegisterClass<packed, 128, [F0, F1]>;

  def MOVgg : BinaryInst<0x51, (
    ops GeneralPurposeRC :$dest,
    ope GeneralPurposeRC :$src), "mov $dest, $src">;

  def MOVgi : BinaryInst<0x52, (
    ops GeneralPurposeRC :$dest,
    ope INT_ReadOnlyRC :$src), "mov $dest, $src">;

  def MOVgf : BinaryInst<0x52, (
    ops GeneralPurposeRC :$dest,
    ope FP_ReadOnlyRC :$src), "mov $dest, $src">;

In the instruction selector, SDOperand::getValueType() always returns
'MVT::packed' for all operands. I cannot distinguish between
GeneralPurposeRC, INT_ReadOnlyRC, FP_ReadOnlyRC. But a correct
register class is necessary for SSARegMap to create a virtual
register.












2005/7/22, Misha Brukman <brukman at cs.uiuc.edu>:
> On Fri, Jul 22, 2005 at 10:29:38AM +0800, Tzu-Chien Chiu wrote:
> > I' have three set of registers - read-only regs, general purpose
regs
> > (read and write), and write-only regs. How should I partition them
> > into different RegisterClasses so that I can easy define the
> > instruction?
> [snip]
> >   def MOV : BinaryInst<2, (ops GeneralPurposeRegClass :$dest,
> >   GeneralPurposeRegClass :$src), "mov $dest, $src">;
> >
> > There can be only one RegisterClass defined for each instruction
> > operand, but actually the destition operand could be
> > 'GeneralPurposeRegClass ' or 'WriteOnlyRegClass ', and
the source
> > operand can be 'ReadOnlyRegClass' or
'GeneralPurposeRegClass'.
>
> Presumably, when you write your instruction selector, you know when you
> want to have a write-only vs. general purpose and read-only vs. general
> purpose register.  Some things are naturally read-only, such as status
> registers that are only modified as a side effect of instructions (fp
> errors, overflow, etc.) and some are write-only registers (I'm guessing
> video and network cards have these for outputs).
>
> So a solution that may work for you would be to define permutations of
> the instructions that explicitly specify what type of operands your
> instruction takes (because different instructions need different LLVM
> opcodes) but the instructions would print out the same, so in your
> example:
>
> MOVgg : General, General
> MOVwg : Write-only, General
> MOVwr : Write-only, Read-only
>
> Note that if they all have the same "mov $dest, $src" print
string, they
> will be printed out identically, but you need to separate them anyway.
> If you look at the X86 backend, you might find many flavors of MOV
> instructions as well, but for a different reason.
>
> The best way is to lazily add permutations that you need as you go
> along, so you don't have to convert your entire .td file(s) over to a
> complete set of permutations immediately.
>
> Good luck,
> --
> Misha Brukman :: http://misha.brukman.net :: http://llvm.cs.uiuc.edu
>


--
Tzu-Chien Chiu,
3D Graphics Hardware Enginner,
<URL:http://www.csie.nctu.edu.tw/~jwchiu>