This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix addressing prefix for x86_64


Hi,
this patch implements the 32bit addressing prefix for x86_64.  It is equivalent
to 16bit addressing used on 32bit systems, so the changes are relativly small.

Honza

Thu Jan 24 21:17:07 CET 2002  Jan Hubicka  <jh@suse.cz>
	* tc-i386.c (md_assemble): Support 32bit addressing prefix on x86_64.
	(i386_index_check): Accept 32bit addressing with prefix on x86_64
	* i386-dis.c (prefix_name): Print "add32"/"addr64" in 64bit mode.	
	(print_insn): Likewise.
	(OP_E): Likewise.
	(OP_OFF): Support addr32 prefix.
	(ptr_reg): Likewise.
	(putop): Print 'e' versus 'r' in 64bit mode.
Index: gas/config/tc-i386.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-i386.c,v
retrieving revision 1.107
diff -c -3 -p -r1.107 tc-i386.c
*** tc-i386.c	2001/11/15 21:28:55	1.107
--- tc-i386.c	2002/01/24 17:53:01
*************** md_assemble (line)
*** 1294,1299 ****
--- 1294,1300 ----
  	    /* If we are in 16-bit mode, do not allow addr16 or data16.
  	       Similarly, in 32-bit mode, do not allow addr32 or data32.  */
  	    if ((current_templates->start->opcode_modifier & (Size16 | Size32))
+ 		&& flag_code != CODE_64BIT
  		&& (((current_templates->start->opcode_modifier & Size32) != 0)
  		    ^ (flag_code == CODE_16BIT)))
  	      {
*************** md_assemble (line)
*** 2259,2264 ****
--- 2260,2273 ----
  	      return;
  	  }
  
+ 	if (i.suffix != QWORD_MNEM_SUFFIX && (flag_code == CODE_64BIT)
+ 	    && !(i.tm.opcode_modifier & IgnoreSize)
+ 	    && (i.tm.opcode_modifier & JumpByte))
+ 	  {
+ 	    if (! add_prefix (ADDR_PREFIX_OPCODE))
+ 	      return;
+ 	  }
+ 
  	/* Set mode64 for an operand.  */
  	if (i.suffix == QWORD_MNEM_SUFFIX
  	    && !(i.tm.opcode_modifier & NoRex64))
*************** md_assemble (line)
*** 2411,2423 ****
  			if (! i.index_reg)
  			  {
  			    /* Operand is just <disp>  */
! 			    if ((flag_code == CODE_16BIT) ^ (i.prefix[ADDR_PREFIX] != 0))
  			      {
  				i.rm.regmem = NO_BASE_REGISTER_16;
  				i.types[op] &= ~Disp;
  				i.types[op] |= Disp16;
  			      }
! 			    else if (flag_code != CODE_64BIT)
  			      {
  				i.rm.regmem = NO_BASE_REGISTER;
  				i.types[op] &= ~Disp;
--- 2420,2434 ----
  			if (! i.index_reg)
  			  {
  			    /* Operand is just <disp>  */
! 			    if ((flag_code == CODE_16BIT) ^ (i.prefix[ADDR_PREFIX] != 0)
! 				&& (flag_code != CODE_64BIT))
  			      {
  				i.rm.regmem = NO_BASE_REGISTER_16;
  				i.types[op] &= ~Disp;
  				i.types[op] |= Disp16;
  			      }
! 			    else if (flag_code != CODE_64BIT
! 				     || (i.prefix[ADDR_PREFIX] != 0))
  			      {
  				i.rm.regmem = NO_BASE_REGISTER;
  				i.types[op] &= ~Disp;
*************** i386_displacement (disp_start, disp_end)
*** 3434,3443 ****
  #endif
    int bigdisp = Disp32;
  
-   if ((flag_code == CODE_16BIT) ^ (i.prefix[ADDR_PREFIX] != 0))
-     bigdisp = Disp16;
    if (flag_code == CODE_64BIT)
!     bigdisp = Disp64;
    i.types[this_operand] |= bigdisp;
  
    exp = &disp_expressions[i.disp_operands];
--- 3445,3457 ----
  #endif
    int bigdisp = Disp32;
  
    if (flag_code == CODE_64BIT)
!     {
!       if (!i.prefix[ADDR_PREFIX])
!         bigdisp = Disp64;
!     }
!   else if ((flag_code == CODE_16BIT) ^ (i.prefix[ADDR_PREFIX] != 0))
!     bigdisp = Disp16;
    i.types[this_operand] |= bigdisp;
  
    exp = &disp_expressions[i.disp_operands];
*************** i386_index_check (operand_string)
*** 3592,3606 ****
    ok = 1;
    if (flag_code == CODE_64BIT)
      {
!       /* 64bit checks.  */
!       if ((i.base_reg
! 	   && ((i.base_reg->reg_type & Reg64) == 0)
! 	       && (i.base_reg->reg_type != BaseIndex
! 		   || i.index_reg))
! 	  || (i.index_reg
! 	      && ((i.index_reg->reg_type & (Reg64|BaseIndex))
! 		  != (Reg64|BaseIndex))))
! 	ok = 0;
      }
    else
      {
--- 3606,3633 ----
    ok = 1;
    if (flag_code == CODE_64BIT)
      {
!       if (i.prefix[ADDR_PREFIX] == 0)
! 	{
! 	  /* 64bit checks.  */
! 	  if ((i.base_reg
! 	       && ((i.base_reg->reg_type & Reg64) == 0)
! 		   && (i.base_reg->reg_type != BaseIndex
! 		       || i.index_reg))
! 	      || (i.index_reg
! 		  && ((i.index_reg->reg_type & (Reg64|BaseIndex))
! 		      != (Reg64|BaseIndex))))
! 	    ok = 0;
! 	}
!       else
! 	{
! 	  /* 32bit checks.  */
! 	  if ((i.base_reg
! 	       && (i.base_reg->reg_type & (Reg32 | RegRex)) != Reg32)
! 	      || (i.index_reg
! 		  && ((i.index_reg->reg_type & (Reg32|BaseIndex|RegRex))
! 		      != (Reg32|BaseIndex))))
! 	    ok = 0;
! 	}
      }
    else
      {
Index: opcodes/i386-dis.c
===================================================================
RCS file: /cvs/src/src/opcodes/i386-dis.c,v
retrieving revision 1.34
diff -c -3 -p -r1.34 i386-dis.c
*** i386-dis.c	2001/11/14 12:01:12	1.34
--- i386-dis.c	2002/01/24 17:53:22
*************** prefix_name (pref, sizeflag)
*** 1807,1813 ****
      case 0x66:
        return (sizeflag & DFLAG) ? "data16" : "data32";
      case 0x67:
!       return (sizeflag & AFLAG) ? "addr16" : "addr32";
      case FWAIT_OPCODE:
        return "fwait";
      default:
--- 1807,1816 ----
      case 0x66:
        return (sizeflag & DFLAG) ? "data16" : "data32";
      case 0x67:
!       if (mode_64bit)
!         return (sizeflag & AFLAG) ? "addr32" : "addr64";
!       else
!         return ((sizeflag & AFLAG) && !mode_64bit) ? "addr16" : "addr32";
      case FWAIT_OPCODE:
        return "fwait";
      default:
*************** print_insn (pc, info)
*** 2081,2087 ****
        sizeflag ^= AFLAG;
        if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)
  	{
! 	  if (sizeflag & AFLAG)
  	    oappend ("addr32 ");
  	  else
  	    oappend ("addr16 ");
--- 2084,2090 ----
        sizeflag ^= AFLAG;
        if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)
  	{
! 	  if ((sizeflag & AFLAG) || mode_64bit)
  	    oappend ("addr32 ");
  	  else
  	    oappend ("addr16 ");
*************** putop (template, sizeflag)
*** 2626,2633 ****
  	    *obufp++ = 'b';
  	  break;
  	case 'E':		/* For jcxz/jecxz */
! 	  if (sizeflag & AFLAG)
! 	    *obufp++ = 'e';
  	  used_prefixes |= (prefixes & PREFIX_ADDR);
  	  break;
  	case 'F':
--- 2629,2644 ----
  	    *obufp++ = 'b';
  	  break;
  	case 'E':		/* For jcxz/jecxz */
! 	  if (mode_64bit)
! 	    {
! 	      if (sizeflag & AFLAG)
! 		*obufp++ = 'r';
! 	      else
! 		*obufp++ = 'e';
! 	    }
! 	  else
! 	    if (sizeflag & AFLAG)
! 	      *obufp++ = 'e';
  	  used_prefixes |= (prefixes & PREFIX_ADDR);
  	  break;
  	case 'F':
*************** putop (template, sizeflag)
*** 2636,2644 ****
  	  if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
  	    {
  	      if (sizeflag & AFLAG)
! 		*obufp++ = 'l';
  	      else
! 		*obufp++ = 'w';
  	      used_prefixes |= (prefixes & PREFIX_ADDR);
  	    }
  	  break;
--- 2647,2655 ----
  	  if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
  	    {
  	      if (sizeflag & AFLAG)
! 		*obufp++ = mode_64bit ? 'q' : 'l';
  	      else
! 		*obufp++ = mode_64bit ? 'l' : 'w';
  	      used_prefixes |= (prefixes & PREFIX_ADDR);
  	    }
  	  break;
*************** OP_E (bytemode, sizeflag)
*** 3014,3020 ****
    disp = 0;
    append_seg ();
  
!   if (sizeflag & AFLAG) /* 32 bit address mode */
      {
        int havesib;
        int havebase;
--- 3025,3031 ----
    disp = 0;
    append_seg ();
  
!   if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */
      {
        int havesib;
        int havebase;
*************** OP_E (bytemode, sizeflag)
*** 3048,3054 ****
  	  if ((base & 7) == 5)
  	    {
  	      havebase = 0;
! 	      if (mode_64bit && !havesib)
  		riprel = 1;
  	      disp = get32s ();
  	    }
--- 3059,3065 ----
  	  if ((base & 7) == 5)
  	    {
  	      havebase = 0;
! 	      if (mode_64bit && !havesib && (sizeflag & AFLAG))
  		riprel = 1;
  	      disp = get32s ();
  	    }
*************** OP_E (bytemode, sizeflag)
*** 3115,3121 ****
  	  if (!havesib && (rex & REX_EXTZ))
  	    base += 8;
  	  if (havebase)
! 	    oappend (mode_64bit ? names64[base] : names32[base]);
  	  if (havesib)
  	    {
  	      if (index != 4)
--- 3126,3133 ----
  	  if (!havesib && (rex & REX_EXTZ))
  	    base += 8;
  	  if (havebase)
! 	    oappend (mode_64bit && (sizeflag & AFLAG)
! 		     ? names64[base] : names32[base]);
  	  if (havesib)
  	    {
  	      if (index != 4)
*************** OP_E (bytemode, sizeflag)
*** 3128,3138 ****
                            *obufp = '\0';
                          }
                        sprintf (scratchbuf, "%s",
! 			       mode_64bit ? names64[index] : names32[index]);
                      }
                    else
  		    sprintf (scratchbuf, ",%s",
! 			     mode_64bit ? names64[index] : names32[index]);
  		  oappend (scratchbuf);
  		}
                if (!intel_syntax
--- 3140,3152 ----
                            *obufp = '\0';
                          }
                        sprintf (scratchbuf, "%s",
! 			       mode_64bit && (sizeflag & AFLAG)
! 			       ? names64[index] : names32[index]);
                      }
                    else
  		    sprintf (scratchbuf, ",%s",
! 			     mode_64bit && (sizeflag & AFLAG)
! 			     ? names64[index] : names32[index]);
  		  oappend (scratchbuf);
  		}
                if (!intel_syntax
*************** OP_OFF (bytemode, sizeflag)
*** 3703,3709 ****
  
    append_seg ();
  
!   if (sizeflag & AFLAG)
      off = get32 ();
    else
      off = get16 ();
--- 3717,3723 ----
  
    append_seg ();
  
!   if ((sizeflag & AFLAG) || mode_64bit)
      off = get32 ();
    else
      off = get16 ();
*************** ptr_reg (code, sizeflag)
*** 3764,3770 ****
  
    USED_REX (REX_MODE64);
    if (rex & REX_MODE64)
!     s = names64[code - eAX_reg];
    else if (sizeflag & AFLAG)
      s = names32[code - eAX_reg];
    else
--- 3778,3789 ----
  
    USED_REX (REX_MODE64);
    if (rex & REX_MODE64)
!     {
!       if (!(sizeflag & AFLAG))
!         s = names32[code - eAX_reg];
!       else
!         s = names64[code - eAX_reg];
!     }
    else if (sizeflag & AFLAG)
      s = names32[code - eAX_reg];
    else


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