[LLVMdev] INSERT_SUBREG node.

sanjiv gupta sanjiv.gupta at microchip.com
Wed Oct 15 05:29:45 PDT 2008


On Tue, 2008-10-14 at 10:19 -0700, Evan Cheng wrote:
> You need to specify sub-register == super-register, idx relationship.  
> See X86RegisterInfo.td:
> 
> def x86_subreg_8bit    : PatLeaf<(i32 1)>;
> def x86_subreg_16bit   : PatLeaf<(i32 2)>;
> def x86_subreg_32bit   : PatLeaf<(i32 3)>;
> 
> def : SubRegSet<1, [AX, CX, DX, BX, SP,  BP,  SI,  DI,
>                      R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W],
>                     [AL, CL, DL, BL, SPL, BPL, SIL, DIL,
>                      R8B, R9B, R10B, R11B, R12B, R13B, R14B, R15B]>;
> 
> I admit the way it's specified is not very elegant. We'll clean it up  
> some day.
> 
> Evan
> 
Even in that case you can not have a 0 as a SubIdx.
e.g. the code below won't work

  def x86_subreg_8bit    : PatLeaf<(i32 0)>;
 

def : SubRegSet<0, [AX, CX, DX, BX, SP,  BP,  SI,  DI,
                     R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W],
                    [AL, CL, DL, BL, SPL, BPL, SIL, DIL,
                     R8B, R9B, R10B, R11B, R12B, R13B, R14B, R15B]>;


class GR16_ ..... {
  let SubRegClassList = [GR8];
}


Refer to below functions in ScheduleDAGEmit.cpp:

-----------------------------------------------
static const TargetRegisterClass*
getSubRegisterRegClass(const TargetRegisterClass *TRC, unsigned SubIdx)
{
  // Pick the register class of the subregister
  TargetRegisterInfo::regclass_iterator I =
    TRC->subregclasses_begin() + SubIdx-1;
  assert(I < TRC->subregclasses_end() &&
         "Invalid subregister index for register class");
  return *I;
}


/// getSuperRegisterRegClass - Returns the register class of a superreg
A whose
/// "SubIdx"'th sub-register class is the specified register class and
whose
/// type matches the specified type.
static const TargetRegisterClass*
getSuperRegisterRegClass(const TargetRegisterClass *TRC,
                         unsigned SubIdx, MVT VT) {
  // Pick the register class of the superegister for this type
  for (TargetRegisterInfo::regclass_iterator I =
TRC->superregclasses_begin(),
         E = TRC->superregclasses_end(); I != E; ++I)
    if ((*I)->hasType(VT) && getSubRegisterRegClass(*I, SubIdx) == TRC)
      return *I;
  assert(false && "Couldn't find the register class");
  return 0;
}

-----------------------------------------------------------------


The getSubRegisterRegClass uses     SubIdx - 1;

so INSERT_SUBREG (IMPLICIT_DEF, AL, 0) will not work, because getSubRegisterRegClass will fail.(GR16_ does not have a SubRegClass at index -1.)

OTOH, if you use SubIdx as 1, both in SubRegSet and x86_subreg_8bit, the INSERT_SUBREG (IMPLICIT_DEF, AL, 1) will work.
 
But then INSERT_SUBREG (AX, AH, 2) will not work because getSubRegisterRegClass will fail again. (GR16_ does not have a SubRegClass at index 1.)


Hope I made it clear. Please write back if they aren't.


- Sanjiv






  
> On Oct 13, 2008, at 11:24 AM, sanjiv gupta wrote:
> 
> > On Thu, 2008-10-02 at 11:19 -0700, Evan Cheng wrote:
> >>
> >> On Oct 2, 2008, at 11:02 AM, Sanjiv.Gupta at microchip.com wrote:
> >>
> >>> What’s the value produced by an INSERT_SUBREG node? Is it a chain?
> >>
> >>
> >> No, insert_subreg returns a value:
> >>
> >>
> >> v1 = insert_subreg v2, v3, idx
> >>
> >>
> >> v1 and v2 will have the same type, e.g. i16, and v3 must have a
> >> sub-register type, e.g. i8.
> >>
> >>>
> >>> Can I use to set a superreg of i16 type with two i8 values, and use
> >>> the supperreg as an operand somewhere else?
> >>
> >>
> >> Suppose you want to use a pair of i8 v1, v2 to create a i16 v3. The
> >> way to do it is:
> >>
> >>
> >> v4 = insert_subreg implicit_def, v1, 0
> >> v3 = insert_subreg v4,                 v2, 1
> >>
> >>
> >> Evan
> >>
> >
> > This is how my register classes look like:
> >
> >  def FSR0L : Register<"FSR0L">;
> >  def FSR0H : Register<"FSR0H">;
> >  def FSR1L : Register<"FSR1L">;
> >  def FSR1H : Register<"FSR1H">;
> >
> >  def FSR0 : RegisterWithSubRegs<"FSR0", [FSR0H, FSR0L]>;
> >  def FSR1 : RegisterWithSubRegs<"FSR1", [FSR1H, FSR1L]>;
> >
> >  def FSR8RC  : RegisterClass<"PIC16", [i8], 8, [FSR0L, FSR0H, FSR0L,
> > FSR1H]>;
> >
> >  def FSR16RC  : RegisterClass<"PIC16", [i16], 8, [FSR0, FSR1]> {
> >    let SubRegClassList = [FSR8RC];
> >  }
> >
> > in my case I want to insert two values, which are available in  
> > register
> > types of FSR8RC, into a register type of FSR16RC.
> >
> > when I use and INSERT_SUBREG with an SubIdx = 0, as you mentioned in
> >
> >> v4= insert_subreg implicit_def, v1, 0
> >
> > the following function returns an incorrect subregclass:
> >
> > static const TargetRegisterClass*
> > getSubRegisterRegClass(const TargetRegisterClass *TRC, unsigned  
> > SubIdx)
> > {
> >  // Pick the register class of the subregister
> >  TargetRegisterInfo::regclass_iterator I =
> >    TRC->subregclasses_begin() + SubIdx-1;
> >  assert(I < TRC->subregclasses_end() &&
> >         "Invalid subregister index for register class");
> >  return *I;
> > }
> >
> > what does -1 do while initializing I in the above fn?
> >
> > TIA,
> > Sanjiv
> >
> >
> >
> > _______________________________________________
> > LLVM Developers mailing list
> > LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
> 
> 
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev




More information about the llvm-dev mailing list