This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

x86-64 merger part 3 - extended registers


Hi
x86-64 adds 8 extended integer registers and 8 extended SSE registers.  This patch
adds these to gcc.
Constraints 'R' and 'Q' are added. 'r' now contains all registers, including
the extended, similary 'q'.  Irritantingly the symetricity is broken for uppter
halves of 8bit operations, that can be encoded only for non-extended regsiters,
so 'R' and 'Q' are corresponding classes w/o extended ones.

Documentation of these is to come in separate patch.

The x86_64 also adds support for lower 8bit halves of all registers, not only first 4.

Honza

Thu Mar  8 20:19:52 CET 2001  Jan Hubicka  <jh@suse.cz>
	* i386.h (FIRST_PSEUDO_REGISTER): Set to 53.
	(FIXED_REGISTERS, CALL_USED_REGISTERS, REG_ALLOC_ONES): Add extended ones.
	(CONDITIONAL_REGISTER_USAGE): Set proper values according to TARGET_64BIT.
	(FIRST_REX_INT_REG, LAST_REX_INT_REG, FIRST_REX_SSE_REG, LAST_REX_SSE_REG):
	define.
	(enum reg_class): Add 'LEGACY_REGS'
	(REG_CLASS_CONTENTS): Likewise; add extended registers.
	(SSE_REGNO_P): Recognize extended registers.
	(ANY_QI_REG_P, REX_INT_REGNO_P, REX_INT_REG_P): New.
	(REG_CLASS_FROM_LETTER): Add 'R' and 'Q'.
	(REGNO_OK_FOR_INDEX_P, REGNO_OK_FOR_BASE_P, REG_OK_FOR_BASE_NONSTRICT_P):
	 Recognize REX registers.
	(REG_OK_FOR_STRREG_NONSTRICT_P, REG_OK_FOR_STRREG_STRICT_P,
	 REG_OK_FOR_STRREG_P): Remove.
	(HI_REGISTER_NAMES): Add extended registers.
	(ADDITIONAL_REGISTER_NAMES): Likewise.
	(QI_REGISTER_NAMES): Add 8bit extended registers.
	(DEBUG_REG): Support extended registers.
	* i386.c (regclass_map): Add extended registers.
	(dbx_register-map): Likewise.
	(svr4_dbx_register_map): Likewise.
	(print_reg): Support extended registers.
	(print_operand): Support 64bit operands.
	
*** i386.h	Sat Mar  3 19:32:20 2001
--- /home/hubicka/x86-64/gcc/gcc/config/i386/i386.h	Thu Mar  8 12:01:37 2001
*************** extern int ix86_arch;
*** 667,673 ****
     eliminated during reloading in favor of either the stack or frame
     pointer. */
  
! #define FIRST_PSEUDO_REGISTER 37
  
  /* Number of hardware registers that go into the DWARF-2 unwind info.
     If not defined, equals FIRST_PSEUDO_REGISTER.  */
--- 749,755 ----
     eliminated during reloading in favor of either the stack or frame
     pointer. */
  
! #define FIRST_PSEUDO_REGISTER 53
  
  /* Number of hardware registers that go into the DWARF-2 unwind info.
     If not defined, equals FIRST_PSEUDO_REGISTER.  */
*************** extern int ix86_arch;
*** 676,708 ****
  
  /* 1 for registers that have pervasive standard uses
     and are not available for the register allocator.
!    On the 80386, the stack pointer is such, as is the arg pointer. */
  #define FIXED_REGISTERS						\
  /*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7*/	\
! {  0, 0, 0, 0, 0, 0, 0, 1, 0,  0,  0,  0,  0,  0,  0,  0,	\
  /*arg,flags,fpsr,dir,frame*/					\
!     1,    1,   1,  1,    1,					\
  /*xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7*/			\
       0,   0,   0,   0,   0,   0,   0,   0,			\
  /*mmx0,mmx1,mmx2,mmx3,mmx4,mmx5,mmx6,mmx7*/			\
!      0,   0,   0,   0,   0,   0,   0,   0}
  
  /* 1 for registers not available across function calls.
     These must include the FIXED_REGISTERS and also any
     registers that can be used without being saved.
     The latter must include the registers where values are returned
     and the register where structure-value addresses are passed.
!    Aside from that, you can include as many other registers as you like.  */
! 
  #define CALL_USED_REGISTERS					\
  /*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7*/	\
! {  1, 1, 1, 0, 0, 0, 0, 1, 1,  1,  1,  1,  1,  1,  1,  1,	\
  /*arg,flags,fpsr,dir,frame*/					\
!      1,   1,   1,  1,    1,					\
  /*xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7*/			\
!      1,   1,   1,   1,   1,  1,    1,   1,			\
  /*mmx0,mmx1,mmx2,mmx3,mmx4,mmx5,mmx6,mmx7*/			\
!      1,   1,   1,   1,   1,   1,   1,   1}
  
  /* Order in which to allocate registers.  Each register must be
     listed once, even those in FIXED_REGISTERS.  List frame pointer
--- 758,808 ----
  
  /* 1 for registers that have pervasive standard uses
     and are not available for the register allocator.
!    On the 80386, the stack pointer is such, as is the arg pointer.
!  
!    The value is an mask - bit 1 is set for fixed registers
!    for 32bit target, while 2 is set for fixed registers for 64bit.
!    Proper value is computed in the CONDITIONAL_REGISTER_USAGE.
!  */
  #define FIXED_REGISTERS						\
  /*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7*/	\
! {  0, 0, 0, 0, 0, 0, 0, 3, 0,  0,  0,  0,  0,  0,  0,  0,	\
  /*arg,flags,fpsr,dir,frame*/					\
!     3,    3,   3,  3,    3,					\
  /*xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7*/			\
       0,   0,   0,   0,   0,   0,   0,   0,			\
  /*mmx0,mmx1,mmx2,mmx3,mmx4,mmx5,mmx6,mmx7*/			\
!      0,   0,   0,   0,   0,   0,   0,   0,			\
! /*  r8,  r9, r10, r11, r12, r13, r14, r15*/			\
!      1,   1,   1,   1,   1,   1,   1,   1,			\
! /*xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15*/		\
!      1,   1,    1,    1,    1,    1,    1,    1}
!  
  
  /* 1 for registers not available across function calls.
     These must include the FIXED_REGISTERS and also any
     registers that can be used without being saved.
     The latter must include the registers where values are returned
     and the register where structure-value addresses are passed.
!    Aside from that, you can include as many other registers as you like. 
!  
!    The value is an mask - bit 1 is set for fixed registers
!    for 32bit target, while 2 is set for fixed registers for 64bit.
!    Proper value is computed in the CONDITIONAL_REGISTER_USAGE.
! */
  #define CALL_USED_REGISTERS					\
  /*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7*/	\
! {  3, 3, 3, 0, 2, 2, 0, 3, 3,  3,  3,  3,  3,  3,  3,  3,	\
  /*arg,flags,fpsr,dir,frame*/					\
!      3,   3,   3,  3,    3,					\
  /*xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7*/			\
!      3,   3,   3,   3,   3,  3,    3,   3,			\
  /*mmx0,mmx1,mmx2,mmx3,mmx4,mmx5,mmx6,mmx7*/			\
!      3,   3,   3,   3,   3,   3,   3,   3,			\
! /*  r8,  r9, r10, r11, r12, r13, r14, r15*/			\
!      3,   3,   3,   3,   1,   1,   1,   1,			\
! /*xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15*/		\
!      3,   3,    3,    3,    3,    3,    3,    3}		\
  
  /* Order in which to allocate registers.  Each register must be
     listed once, even those in FIXED_REGISTERS.  List frame pointer
*************** extern int ix86_arch;
*** 724,743 ****
     generated by allocating edx first, so restore the 'natural' order of things. */
  
  #define REG_ALLOC_ORDER 					\
! /*ax,dx,cx,bx,si,di,bp,sp*/					\
! {  0, 1, 2, 3, 4, 5, 6, 7,					\
! /*,arg,cc,fpsr,dir,frame*/					\
!      16,17, 18, 19,   20,					\
  /*xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7*/			\
      21,  22,  23,  24,  25,  26,  27,  28,			\
  /*st,st1,st2,st3,st4,st5,st6,st7*/				\
     8,  9, 10, 11, 12, 13, 14, 15,				\
  /*mmx0,mmx1,mmx2,mmx3,mmx4,mmx5,mmx6,mmx7*/			\
      29,  30,  31,  32,  33,  34,  35,  36 }
  
  /* Macro to conditionally modify fixed_regs/call_used_regs.  */
  #define CONDITIONAL_REGISTER_USAGE					\
    {									\
      if (flag_pic)							\
        {									\
  	fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;			\
--- 824,858 ----
     generated by allocating edx first, so restore the 'natural' order of things. */
  
  #define REG_ALLOC_ORDER 					\
! /*ax,dx,cx,*/							\
! {  0, 1, 2,							\
! /* bx,si,di,bp,sp,*/						\
!    3, 4, 5, 6, 7,						\
! /*r8,r9,r10,r11,*/						\
!   37,38, 39, 40,						\
! /*r12,r15,r14,r13*/						\
!   41, 44, 43, 42,						\
  /*xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7*/			\
      21,  22,  23,  24,  25,  26,  27,  28,			\
+ /*xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15*/		\
+     45,  46,   47,   48,   49,   50,   51,   52,		\
  /*st,st1,st2,st3,st4,st5,st6,st7*/				\
     8,  9, 10, 11, 12, 13, 14, 15,				\
+ /*,arg,cc,fpsr,dir,frame*/					\
+      16,17, 18, 19,   20,					\
  /*mmx0,mmx1,mmx2,mmx3,mmx4,mmx5,mmx6,mmx7*/			\
      29,  30,  31,  32,  33,  34,  35,  36 }
  
  /* Macro to conditionally modify fixed_regs/call_used_regs.  */
  #define CONDITIONAL_REGISTER_USAGE					\
    {									\
+     int i;								\
+     for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)				\
+       {									\
+         fixed_regs[i] = (fixed_regs[i] & (TARGET_64BIT ? 2 : 1)) != 0;	\
+         call_used_regs[i] = (call_used_regs[i]				\
+ 			     & (TARGET_64BIT ? 2 : 1)) != 0;		\
+       }									\
      if (flag_pic)							\
        {									\
  	fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;			\
*************** extern int ix86_arch;
*** 868,873 ****
--- 986,997 ----
  #define FIRST_MMX_REG  (LAST_SSE_REG + 1)
  #define LAST_MMX_REG   (FIRST_MMX_REG + 7)
  
+ #define FIRST_REX_INT_REG  (LAST_MMX_REG + 1)
+ #define LAST_REX_INT_REG   (FIRST_REX_INT_REG + 7)
+ 
+ #define FIRST_REX_SSE_REG  (LAST_REX_INT_REG + 1)
+ #define LAST_REX_SSE_REG   (FIRST_REX_SSE_REG + 7)
+ 
  /* Value should be nonzero if functions must have frame pointers.
     Zero means the frame pointer need not be set up (and parms
     may be accessed via the stack pointer) in functions that seem suitable.
*************** enum reg_class
*** 960,966 ****
    Q_REGS,			/* %eax %ebx %ecx %edx */
    NON_Q_REGS,			/* %esi %edi %ebp %esp */
    INDEX_REGS,			/* %eax %ebx %ecx %edx %esi %edi %ebp */
!   GENERAL_REGS,			/* %eax %ebx %ecx %edx %esi %edi %ebp %esp */
    FP_TOP_REG, FP_SECOND_REG,	/* %st(0) %st(1) */
    FLOAT_REGS,
    SSE_REGS,
--- 1085,1092 ----
    Q_REGS,			/* %eax %ebx %ecx %edx */
    NON_Q_REGS,			/* %esi %edi %ebp %esp */
    INDEX_REGS,			/* %eax %ebx %ecx %edx %esi %edi %ebp */
!   LEGACY_REGS,			/* %eax %ebx %ecx %edx %esi %edi %ebp %esp */
!   GENERAL_REGS,			/* %eax %ebx %ecx %edx %esi %edi %ebp %esp %r8 - %r15*/
    FP_TOP_REG, FP_SECOND_REG,	/* %st(0) %st(1) */
    FLOAT_REGS,
    SSE_REGS,
*************** enum reg_class
*** 994,999 ****
--- 1120,1126 ----
     "AD_REGS",				\
     "Q_REGS", "NON_Q_REGS",		\
     "INDEX_REGS",			\
+    "LEGACY_REGS",			\
     "GENERAL_REGS",			\
     "FP_TOP_REG", "FP_SECOND_REG",	\
     "FLOAT_REGS",			\
*************** enum reg_class
*** 1012,1037 ****
     of length N_REG_CLASSES.  */
  
  #define REG_CLASS_CONTENTS						\
! {     { 0x00,  0x0 },							\
!       { 0x01,  0x0 }, { 0x02, 0x0 },	/* AREG, DREG */		\
!       { 0x04,  0x0 }, { 0x08, 0x0 },	/* CREG, BREG */		\
!       { 0x10,  0x0 }, { 0x20, 0x0 },	/* SIREG, DIREG */		\
!       { 0x03,  0x0 },			/* AD_REGS */			\
!       { 0x0f,  0x0 },			/* Q_REGS */			\
!   { 0x1100f0,  0x0 },			/* NON_Q_REGS */		\
!       { 0x7f,  0x0 },			/* INDEX_REGS */		\
!   { 0x1100ff,  0x0 },			/* GENERAL_REGS */		\
!      { 0x100,  0x0 }, { 0x0200, 0x0 },	/* FP_TOP_REG, FP_SECOND_REG */	\
!     { 0xff00,  0x0 },			/* FLOAT_REGS */		\
! { 0x1fe00000,  0x0 },			/* SSE_REGS */			\
! { 0xe0000000, 0x1f },			/* MMX_REGS */			\
! { 0x1fe00100,  0x0 },			/* FP_TOP_SSE_REG */		\
! { 0x1fe00200,  0x0 },			/* FP_SECOND_SSE_REG */		\
! { 0x1fe0ff00,  0x0 },			/* FLOAT_SSE_REGS */		\
!    { 0x1ffff,  0x0 },			/* FLOAT_INT_REGS */		\
! { 0x1fe100ff,  0x0 },			/* INT_SSE_REGS */		\
! { 0x1fe1ffff,  0x0 },			/* FLOAT_INT_SSE_REGS */	\
! { 0xffffffff, 0x1f }							\
  }
  
  /* The same information, inverted:
--- 1139,1165 ----
     of length N_REG_CLASSES.  */
  
  #define REG_CLASS_CONTENTS						\
! {     { 0x00,     0x0 },						\
!       { 0x01,     0x0 }, { 0x02, 0x0 },	/* AREG, DREG */		\
!       { 0x04,     0x0 }, { 0x08, 0x0 },	/* CREG, BREG */		\
!       { 0x10,     0x0 }, { 0x20, 0x0 },	/* SIREG, DIREG */		\
!       { 0x03,     0x0 },		/* AD_REGS */			\
!       { 0x0f,     0x0 },		/* Q_REGS */			\
!   { 0x1100f0,  0x1fe0 },		/* NON_Q_REGS */		\
!       { 0x7f,  0x1fe0 },		/* INDEX_REGS */		\
!   { 0x1100ff,  0x0 },			/* LEGACY_REGS */		\
!   { 0x1100ff,  0x1fe0 },		/* GENERAL_REGS */		\
!      { 0x100,     0x0 }, { 0x0200, 0x0 },/* FP_TOP_REG, FP_SECOND_REG */\
!     { 0xff00,     0x0 },		/* FLOAT_REGS */		\
! { 0x1fe00000,0x1fe000 },		/* SSE_REGS */			\
! { 0xe0000000,    0x1f },		/* MMX_REGS */			\
! { 0x1fe00100,0x1fe000 },		/* FP_TOP_SSE_REG */		\
! { 0x1fe00200,0x1fe000 },		/* FP_SECOND_SSE_REG */		\
! { 0x1fe0ff00,0x1fe000 },		/* FLOAT_SSE_REGS */		\
!    { 0x1ffff,  0x1fe0 },		/* FLOAT_INT_REGS */		\
! { 0x1fe100ff,0x1fffe0 },		/* INT_SSE_REGS */		\
! { 0x1fe1ffff,0x1fffe0 },		/* FLOAT_INT_SSE_REGS */	\
! { 0xffffffff,0x1fffff }							\
  }
  
  /* The same information, inverted:
*************** enum reg_class
*** 1049,1063 ****
  
  #define QI_REG_P(X) \
    (REG_P (X) && REGNO (X) < 4)
  #define NON_QI_REG_P(X) \
    (REG_P (X) && REGNO (X) >= 4 && REGNO (X) < FIRST_PSEUDO_REGISTER)
  
  #define FP_REG_P(X) (REG_P (X) && FP_REGNO_P (REGNO (X)))
  #define FP_REGNO_P(n) ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG)
  #define ANY_FP_REG_P(X) (REG_P (X) && ANY_FP_REGNO_P (REGNO (X)))
  #define ANY_FP_REGNO_P(n) (FP_REGNO_P (n) || SSE_REGNO_P (n))
  
! #define SSE_REGNO_P(n) ((n) >= FIRST_SSE_REG && (n) <= LAST_SSE_REG)
  #define SSE_REG_P(n) (REG_P (n) && SSE_REGNO_P (REGNO (n)))
  
  #define SSE_FLOAT_MODE_P(m) \
--- 1177,1202 ----
  
  #define QI_REG_P(X) \
    (REG_P (X) && REGNO (X) < 4)
+ 
+ #define ANY_QI_REG_P(X) (TARGET_64BIT ? 1 : QI_REG_P (X))
+ 
  #define NON_QI_REG_P(X) \
    (REG_P (X) && REGNO (X) >= 4 && REGNO (X) < FIRST_PSEUDO_REGISTER)
  
+ #define REX_INT_REGNO_P(n) ((n) >= FIRST_REX_INT_REG && (n) <= LAST_REX_INT_REG)
+ #define REX_INT_REG_P(X) (REG_P (X) && REX_INT_REGNO_P (REGNO (X)))
+ 
  #define FP_REG_P(X) (REG_P (X) && FP_REGNO_P (REGNO (X)))
  #define FP_REGNO_P(n) ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG)
  #define ANY_FP_REG_P(X) (REG_P (X) && ANY_FP_REGNO_P (REGNO (X)))
  #define ANY_FP_REGNO_P(n) (FP_REGNO_P (n) || SSE_REGNO_P (n))
  
! #define SSE_REGNO_P(n) \
!   (((n) >= FIRST_SSE_REG && (n) <= LAST_SSE_REG) \
!    || ((n) >= FIRST_REX_SSE_REG && (n) <= LAST_REX_SSE_REG))
! 
! #define SSE_REGNO(n) \
!   ((n) < 8 ? FIRST_SSE_REG + (n) : FIRST_REX_SSE_REG + (n) - 8)
  #define SSE_REG_P(n) (REG_P (n) && SSE_REGNO_P (REGNO (n)))
  
  #define SSE_FLOAT_MODE_P(m) \
*************** enum reg_class
*** 1091,1097 ****
  
  #define REG_CLASS_FROM_LETTER(C)	\
    ((C) == 'r' ? GENERAL_REGS :					\
!    (C) == 'q' ? Q_REGS :					\
     (C) == 'f' ? (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387	\
  		 ? FLOAT_REGS					\
  		 : NO_REGS) :					\
--- 1230,1238 ----
  
  #define REG_CLASS_FROM_LETTER(C)	\
    ((C) == 'r' ? GENERAL_REGS :					\
!    (C) == 'R' ? LEGACY_REGS :					\
!    (C) == 'q' ? TARGET_64BIT ? GENERAL_REGS : Q_REGS :		\
!    (C) == 'Q' ? Q_REGS :					\
     (C) == 'f' ? (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387	\
  		 ? FLOAT_REGS					\
  		 : NO_REGS) :					\
*************** pop{l} %0"							\
*** 1634,1647 ****
     Since they use reg_renumber, they are safe only once reg_renumber
     has been allocated, which happens in local-alloc.c.  */
  
! #define REGNO_OK_FOR_INDEX_P(REGNO) \
!   ((REGNO) < STACK_POINTER_REGNUM \
     || (unsigned) reg_renumber[REGNO] < STACK_POINTER_REGNUM)
  
! #define REGNO_OK_FOR_BASE_P(REGNO) \
!   ((REGNO) <= STACK_POINTER_REGNUM \
!    || (REGNO) == ARG_POINTER_REGNUM \
!    || (REGNO) == FRAME_POINTER_REGNUM \
     || (unsigned) reg_renumber[REGNO] <= STACK_POINTER_REGNUM)
  
  #define REGNO_OK_FOR_SIREG_P(REGNO) ((REGNO) == 4 || reg_renumber[REGNO] == 4)
--- 1830,1851 ----
     Since they use reg_renumber, they are safe only once reg_renumber
     has been allocated, which happens in local-alloc.c.  */
  
! #define REGNO_OK_FOR_INDEX_P(REGNO) 					\
!   ((REGNO) < STACK_POINTER_REGNUM 					\
!    || (REGNO >= FIRST_REX_INT_REG					\
!        && (REGNO) <= LAST_REX_INT_REG)					\
!    || ((unsigned) reg_renumber[REGNO] >= FIRST_REX_INT_REG		\
!        && (unsigned) reg_renumber[REGNO] <= LAST_REX_INT_REG)		\
     || (unsigned) reg_renumber[REGNO] < STACK_POINTER_REGNUM)
  
! #define REGNO_OK_FOR_BASE_P(REGNO) 					\
!   ((REGNO) <= STACK_POINTER_REGNUM 					\
!    || (REGNO) == ARG_POINTER_REGNUM 					\
!    || (REGNO) == FRAME_POINTER_REGNUM 					\
!    || (REGNO >= FIRST_REX_INT_REG					\
!        && (REGNO) <= LAST_REX_INT_REG)					\
!    || ((unsigned) reg_renumber[REGNO] >= FIRST_REX_INT_REG		\
!        && (unsigned) reg_renumber[REGNO] <= LAST_REX_INT_REG)		\
     || (unsigned) reg_renumber[REGNO] <= STACK_POINTER_REGNUM)
  
  #define REGNO_OK_FOR_SIREG_P(REGNO) ((REGNO) == 4 || reg_renumber[REGNO] == 4)
*************** pop{l} %0"							\
*** 1664,1695 ****
  /* Non strict versions, pseudos are ok */
  #define REG_OK_FOR_INDEX_NONSTRICT_P(X)					\
    (REGNO (X) < STACK_POINTER_REGNUM					\
     || REGNO (X) >= FIRST_PSEUDO_REGISTER)
  
  #define REG_OK_FOR_BASE_NONSTRICT_P(X)					\
    (REGNO (X) <= STACK_POINTER_REGNUM					\
     || REGNO (X) == ARG_POINTER_REGNUM					\
!    || REGNO (X) == FRAME_POINTER_REGNUM \
     || REGNO (X) >= FIRST_PSEUDO_REGISTER)
  
- #define REG_OK_FOR_STRREG_NONSTRICT_P(X)				\
-   (REGNO (X) == 4 || REGNO (X) == 5 || REGNO (X) >= FIRST_PSEUDO_REGISTER)
- 
  /* Strict versions, hard registers only */
  #define REG_OK_FOR_INDEX_STRICT_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
  #define REG_OK_FOR_BASE_STRICT_P(X)  REGNO_OK_FOR_BASE_P (REGNO (X))
- #define REG_OK_FOR_STRREG_STRICT_P(X)					\
-   (REGNO_OK_FOR_DIREG_P (REGNO (X)) || REGNO_OK_FOR_SIREG_P (REGNO (X)))
  
  #ifndef REG_OK_STRICT
  #define REG_OK_FOR_INDEX_P(X)  REG_OK_FOR_INDEX_NONSTRICT_P(X)
  #define REG_OK_FOR_BASE_P(X)   REG_OK_FOR_BASE_NONSTRICT_P(X)
- #define REG_OK_FOR_STRREG_P(X) REG_OK_FOR_STRREG_NONSTRICT_P(X)
  
  #else
  #define REG_OK_FOR_INDEX_P(X)  REG_OK_FOR_INDEX_STRICT_P(X)
  #define REG_OK_FOR_BASE_P(X)   REG_OK_FOR_BASE_STRICT_P(X)
- #define REG_OK_FOR_STRREG_P(X) REG_OK_FOR_STRREG_STRICT_P(X)
  #endif
  
  /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
--- 1868,1896 ----
  /* Non strict versions, pseudos are ok */
  #define REG_OK_FOR_INDEX_NONSTRICT_P(X)					\
    (REGNO (X) < STACK_POINTER_REGNUM					\
+    || (REGNO (X) >= FIRST_REX_INT_REG					\
+        && REGNO (X) <= LAST_REX_INT_REG)				\
     || REGNO (X) >= FIRST_PSEUDO_REGISTER)
  
  #define REG_OK_FOR_BASE_NONSTRICT_P(X)					\
    (REGNO (X) <= STACK_POINTER_REGNUM					\
     || REGNO (X) == ARG_POINTER_REGNUM					\
!    || REGNO (X) == FRAME_POINTER_REGNUM 				\
!    || (REGNO (X) >= FIRST_REX_INT_REG					\
!        && REGNO (X) <= LAST_REX_INT_REG)				\
     || REGNO (X) >= FIRST_PSEUDO_REGISTER)
  
  /* Strict versions, hard registers only */
  #define REG_OK_FOR_INDEX_STRICT_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
  #define REG_OK_FOR_BASE_STRICT_P(X)  REGNO_OK_FOR_BASE_P (REGNO (X))
  
  #ifndef REG_OK_STRICT
  #define REG_OK_FOR_INDEX_P(X)  REG_OK_FOR_INDEX_NONSTRICT_P(X)
  #define REG_OK_FOR_BASE_P(X)   REG_OK_FOR_BASE_NONSTRICT_P(X)
  
  #else
  #define REG_OK_FOR_INDEX_P(X)  REG_OK_FOR_INDEX_STRICT_P(X)
  #define REG_OK_FOR_BASE_P(X)   REG_OK_FOR_BASE_STRICT_P(X)
  #endif
  
  /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
*************** while (0)
*** 2580,2586 ****
   "st","st(1)","st(2)","st(3)","st(4)","st(5)","st(6)","st(7)","",	\
   "flags","fpsr", "dirflag", "frame",					\
   "xmm0","xmm1","xmm2","xmm3","xmm4","xmm5","xmm6","xmm7",		\
!  "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7"	}
  
  #define REGISTER_NAMES HI_REGISTER_NAMES
  
--- 2822,2830 ----
   "st","st(1)","st(2)","st(3)","st(4)","st(5)","st(6)","st(7)","",	\
   "flags","fpsr", "dirflag", "frame",					\
   "xmm0","xmm1","xmm2","xmm3","xmm4","xmm5","xmm6","xmm7",		\
!  "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7"	,		\
!  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",			\
!  "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"}
  
  #define REGISTER_NAMES HI_REGISTER_NAMES
  
*************** while (0)
*** 2589,2594 ****
--- 2833,2840 ----
  #define ADDITIONAL_REGISTER_NAMES \
  { { "eax", 0 }, { "edx", 1 }, { "ecx", 2 }, { "ebx", 3 },	\
    { "esi", 4 }, { "edi", 5 }, { "ebp", 6 }, { "esp", 7 },	\
+   { "rax", 0 }, { "rdx", 1 }, { "rcx", 2 }, { "rbx", 3 },	\
+   { "rsi", 4 }, { "rdi", 5 }, { "rbp", 6 }, { "rsp", 7 },	\
    { "al", 0 }, { "dl", 1 }, { "cl", 2 }, { "bl", 3 },		\
    { "ah", 0 }, { "dh", 1 }, { "ch", 2 }, { "bh", 3 },		\
    { "mm0", 8},  { "mm1", 9},  { "mm2", 10}, { "mm3", 11},	\
*************** to get gcc to use these, since they want
*** 2599,2610 ****
  number as al, and ax.
  */
  
- /* note the last four are not really qi_registers, but
-    the md will have to never output movb into one of them
-    only a movw .  There is no movb into the last four regs */
- 
  #define QI_REGISTER_NAMES \
! {"al", "dl", "cl", "bl", "si", "di", "bp", "sp",}
  
  /* These parallel the array above, and can be used to access bits 8:15
     of regs 0 through 3. */
--- 2845,2852 ----
  number as al, and ax.
  */
  
  #define QI_REGISTER_NAMES \
! {"al", "dl", "cl", "bl", "sil", "dil", "bpl", "spl",}
  
  /* These parallel the array above, and can be used to access bits 8:15
     of regs 0 through 3. */
*************** do { long l;						\
*** 2783,2788 ****
--- 3032,3038 ----
     If CODE is 'w', pretend the mode is HImode.
     If CODE is 'b', pretend the mode is QImode.
     If CODE is 'k', pretend the mode is SImode.
+    If CODE is 'd', pretend the mode is DImode.
     If CODE is 'h', pretend the reg is the `high' byte register.
     If CODE is 'y', print "st(0)" instead of "st", if the reg is stack op. */
  
*************** do { long l;						\
*** 2818,2825 ****
--- 3068,3103 ----
  	 { fputs ("st(0)", FILE); break; }		\
         if (FP_REG_P (X))				\
  	 { fputs (hi_name[REGNO(X)], FILE); break; }	\
+        if (REX_INT_REG_P (X))				\
+ 	 {						\
+ 	   switch (GET_MODE_SIZE (GET_MODE (X)))	\
+ 	     {						\
+ 	     default:					\
+ 	     case 8:					\
+ 	       fprintf (FILE, "r%i", REGNO (X)		\
+ 			- FIRST_REX_INT_REG + 8);	\
+ 	       break;					\
+ 	     case 4:					\
+ 	       fprintf (FILE, "r%id", REGNO (X)		\
+ 			- FIRST_REX_INT_REG + 8);	\
+ 	       break;					\
+ 	     case 2:					\
+ 	       fprintf (FILE, "r%iw", REGNO (X)		\
+ 			- FIRST_REX_INT_REG + 8);	\
+ 	       break;					\
+ 	     case 1:					\
+ 	       fprintf (FILE, "r%ib", REGNO (X)		\
+ 			- FIRST_REX_INT_REG + 8);	\
+ 	       break;					\
+ 	     }						\
+ 	   break;					\
+ 	 }						\
         switch (GET_MODE_SIZE (GET_MODE (X)))		\
  	 {						\
+ 	 case 8:					\
+ 	   fputs ("r", FILE);				\
+ 	   fputs (hi_name[REGNO (X)], FILE);		\
+ 	   break;					\
  	 default:					\
  	   fputs ("e", FILE);				\
  	 case 2:					\
*** i386.c	Thu Mar  8 17:55:57 2001
--- /home/hubicka/x86-64/gcc/gcc/config/i386/i386.c	Thu Mar  8 18:03:28 2001
*************** enum reg_class const regclass_map[FIRST_
*** 339,358 ****
    SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
    SSE_REGS, SSE_REGS,
    MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS,
!   MMX_REGS, MMX_REGS
  };
  
! /* The "default" register map.  */
  
  int const dbx_register_map[FIRST_PSEUDO_REGISTER] =
  {
    0, 2, 1, 3, 6, 7, 4, 5,		/* general regs */
    12, 13, 14, 15, 16, 17, 18, 19,	/* fp regs */
!   -1, -1, -1, -1,			/* arg, flags, fpsr, dir */
    21, 22, 23, 24, 25, 26, 27, 28,	/* SSE */
    29, 30, 31, 32, 33, 34, 35, 36,       /* MMX */
  };
  
  /* Define the register numbers to be used in Dwarf debugging information.
     The SVR4 reference port C compiler uses the following register numbers
     in its Dwarf output code:
--- 339,355 ----
    SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
    SSE_REGS, SSE_REGS,
    MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS,
!   MMX_REGS, MMX_REGS,
!   NON_Q_REGS, NON_Q_REGS, NON_Q_REGS, NON_Q_REGS,
!   NON_Q_REGS, NON_Q_REGS, NON_Q_REGS, NON_Q_REGS,
!   SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
!   SSE_REGS, SSE_REGS,
  };
  
! /* The "default" register map used in 32bit mode.  */
  
  int const dbx_register_map[FIRST_PSEUDO_REGISTER] =
  {
    0, 2, 1, 3, 6, 7, 4, 5,		/* general regs */
    12, 13, 14, 15, 16, 17, 18, 19,	/* fp regs */
!   -1, -1, -1, -1, -1,			/* arg, flags, fpsr, dir, frame */
    21, 22, 23, 24, 25, 26, 27, 28,	/* SSE */
    29, 30, 31, 32, 33, 34, 35, 36,       /* MMX */
+   -1, -1, -1, -1, -1, -1, -1, -1,	/* extended integer registers */
+   -1, -1, -1, -1, -1, -1, -1, -1,	/* extended SSE registers */
  };
  
  /* Define the register numbers to be used in Dwarf debugging information.
     The SVR4 reference port C compiler uses the following register numbers
     in its Dwarf output code:
*************** int const svr4_dbx_register_map[FIRST_PS
*** 411,419 ****
  {
    0, 2, 1, 3, 6, 7, 5, 4,		/* general regs */
    11, 12, 13, 14, 15, 16, 17, 18,	/* fp regs */
!   -1, 9, -1, -1,			/* arg, flags, fpsr, dir */
    21, 22, 23, 24, 25, 26, 27, 28,	/* SSE registers */
    29, 30, 31, 32, 33, 34, 35, 36,	/* MMX registers */
  };
  
  /* Test and compare insns in i386.md store the information needed to
--- 435,445 ----
  {
    0, 2, 1, 3, 6, 7, 5, 4,		/* general regs */
    11, 12, 13, 14, 15, 16, 17, 18,	/* fp regs */
!   -1, 9, -1, -1, -1,			/* arg, flags, fpsr, dir, frame */
    21, 22, 23, 24, 25, 26, 27, 28,	/* SSE registers */
    29, 30, 31, 32, 33, 34, 35, 36,	/* MMX registers */
+   -1, -1, -1, -1, -1, -1, -1, -1,	/* extemded integer registers */
+   -1, -1, -1, -1, -1, -1, -1, -1,	/* extemded SSE registers */
  };
  
  /* Test and compare insns in i386.md store the information needed to
*************** print_reg (x, code, file)
*** 3315,3320 ****
--- 4792,4799 ----
      code = 1;
    else if (code == 'k')
      code = 4;
+   else if (code == 'q')
+     code = 8;
    else if (code == 'y')
      code = 3;
    else if (code == 'h')
*************** print_reg (x, code, file)
*** 3324,3329 ****
--- 4803,4835 ----
    else
      code = GET_MODE_SIZE (GET_MODE (x));
  
+   /* Irritantingly AMD extended registers use different naming convention
+      from the normal registers.  */
+   if (REX_INT_REG_P (x))
+     {
+       switch (code)
+ 	{
+ 	  case 5:
+ 	    error ("Extended registers have no high halves\n");
+ 	    break;
+ 	  case 1:
+ 	    fprintf (file, "r%ib", REGNO (x) - FIRST_REX_INT_REG + 8);
+ 	    break;
+ 	  case 2:
+ 	    fprintf (file, "r%iw", REGNO (x) - FIRST_REX_INT_REG + 8);
+ 	    break;
+ 	  case 4:
+ 	    fprintf (file, "r%id", REGNO (x) - FIRST_REX_INT_REG + 8);
+ 	    break;
+ 	  case 8:
+ 	    fprintf (file, "r%i", REGNO (x) - FIRST_REX_INT_REG + 8);
+ 	    break;
+ 	  default:
+ 	    error ("Unsupported operand size for extended register.\n");
+ 	    break;
+ 	}
+       return;
+     }
    switch (code)
      {
      case 5:
*************** print_reg (x, code, file)
*** 3336,3346 ****
  	  break;
  	}
        /* FALLTHRU */
-     case 4:
      case 8:
      case 12:
        if (! ANY_FP_REG_P (x))
! 	putc ('e', file);
        /* FALLTHRU */
      case 16:
      case 2:
--- 4842,4852 ----
  	  break;
  	}
        /* FALLTHRU */
      case 8:
+     case 4:
      case 12:
        if (! ANY_FP_REG_P (x))
! 	putc (code == 8 ? 'r' : 'e', file);
        /* FALLTHRU */
      case 16:
      case 2:
*************** print_reg (x, code, file)
*** 3372,3377 ****
--- 4878,4884 ----
  	%b0 would print %al if operands[0] is reg 0.
     w --  likewise, print the HImode name of the register.
     k --  likewise, print the SImode name of the register.
+    q --  likewise, print the DImode name of the register.
     h --  print the QImode name for a "high" register, either ah, bh, ch or dh.
     y --  print "st(0)" instead of "st" as a register.
     m --  print "st(n)" as an mmx register.
*************** print_operand (file, x, code)
*** 3495,3500 ****
--- 5002,5008 ----
  	case 'b':
  	case 'w':
  	case 'k':
+ 	case 'q':
  	case 'h':
  	case 'y':
  	case 'm':


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]