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]

Re: VIA PadLock support


Alan Modra told me that:
On Thu, Mar 11, 2004 at 04:08:10PM +0100, Michal Ludvig wrote:

I think it would be better to warn if a rep prefix is given with these
instructions.

Hmm, I wanted to be able to pass the output of 'objdump -d' back to gas and get the same output. In the revised patch I'm doing a special handling of the REPE prefix now.


Also, do any of these instructions take a lock prefix?
Since rep and lock are mutually exclusive on other x86 archs, the
assembler warns if you use both.

Assuming lock isn't allowed,
- then your changes aren't correct as you'll lose the lock warning. - you could dipense with the add_prefix change, and instead check
i.prefix[LOCKREP_PREFIX] in the following code before calling
add_prefix.

OK, now it complains if lock is used and the new parameter of add_prefix is removed again.


+      if (i.tm.cpu_flags & CpuPadLock) {
+	if (i.tm.base_opcode & 0xff000000)
+	  add_prefix ((i.tm.base_opcode >> 24) & 0xff, 1);
+      }	else {
+	if (i.tm.base_opcode & 0xff0000)
+	  add_prefix ((i.tm.base_opcode >> 16) & 0xff, 0);
+      }

Formatting here and elsewhere. Braces go on separate lines.

Fixed (hopefully :-)


Any other problems with my patch or can I commit it?

Michal Ludvig
--
SUSE Labs                    mludvig@suse.cz | Cray is the only computer
(+420) 296.545.373        http://www.suse.cz | that runs an endless loop
Personal homepage http://www.logix.cz/michal | in just four hours.
2004-03-11  Michal Ludvig  <mludvig@suse.cz>

	* gas/config/tc-i386.c (output_insn): Handle PadLock instructions.
	* gas/config/tc-i386.h (CpuPadLock): New define.
	(CpuUnknownFlags): Added CpuPadLock.
	* include/opcode/i386.h (i386_optab): Added xstore/xcrypt insns.
	* opcodes/i386-dis.c (PADLOCK_SPECIAL, PADLOCK_0): New defines.
	(dis386_twobyte): Opcode 0xa7 is PADLOCK_0.
	(padlock_table): New struct with PadLock instructions.
	(print_insn): Handle PADLOCK_SPECIAL.

Index: gas/config/tc-i386.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-i386.c,v
retrieving revision 1.149
diff -u -p -r1.149 tc-i386.c
--- gas/config/tc-i386.c	22 Nov 2003 02:35:30 -0000	1.149
+++ gas/config/tc-i386.c	11 Mar 2004 16:59:36 -0000
@@ -3123,7 +3123,6 @@ output_interseg_jump ()
   md_number_to_chars (p + size, (valueT) i.op[0].imms->X_add_number, 2);
 }
 
-
 static void
 output_insn ()
 {
@@ -3151,10 +3150,21 @@ output_insn ()
       char *p;
       unsigned char *q;
 
-      /* All opcodes on i386 have either 1 or 2 bytes.  We may use third
-	 byte for the SSE instructions to specify a prefix they require.  */
-      if (i.tm.base_opcode & 0xff0000)
-	add_prefix ((i.tm.base_opcode >> 16) & 0xff);
+      /* All opcodes on i386 have either 1 or 2 bytes, PadLock instructions
+         have 3 bytes.  We may use one more higher byte to specify a prefix
+	 the instruction require.  */
+      if ((i.tm.cpu_flags & CpuPadLock) && (i.tm.base_opcode & 0xff000000))
+	{
+	  unsigned int prefix;
+	  prefix = (i.tm.base_opcode >> 24) & 0xff;
+
+	  if (prefix != REPE_PREFIX_OPCODE ||
+	      i.prefix[LOCKREP_PREFIX] != REPE_PREFIX_OPCODE)
+	    add_prefix (prefix);
+	}
+      else
+	if (! (i.tm.cpu_flags & CpuPadLock) && (i.tm.base_opcode & 0xff0000))
+	  add_prefix ((i.tm.base_opcode >> 16) & 0xff);
 
       /* The prefix bytes.  */
       for (q = i.prefix;
@@ -3175,7 +3185,14 @@ output_insn ()
 	}
       else
 	{
-	  p = frag_more (2);
+	  if (i.tm.cpu_flags & CpuPadLock)
+	    {
+	      p = frag_more (3);
+	      *p++ = (i.tm.base_opcode >> 16) & 0xff;
+	    }
+	  else
+	    p = frag_more (2);
+
 	  /* Put out high byte first: can't use md_number_to_chars!  */
 	  *p++ = (i.tm.base_opcode >> 8) & 0xff;
 	  *p = i.tm.base_opcode & 0xff;
Index: gas/config/tc-i386.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-i386.h,v
retrieving revision 1.45
diff -u -p -r1.45 tc-i386.h
--- gas/config/tc-i386.h	21 Nov 2003 14:38:06 -0000	1.45
+++ gas/config/tc-i386.h	11 Mar 2004 16:59:36 -0000
@@ -194,13 +194,14 @@ typedef struct
 #define CpuSSE2	       0x2000	/* Streaming SIMD extensions 2 required */
 #define Cpu3dnow       0x4000	/* 3dnow! support required */
 #define CpuPNI	       0x8000	/* Prescott New Instructions required */
+#define CpuPadLock    0x10000	/* VIA PadLock required */
 
   /* These flags are set by gas depending on the flag_code.  */
 #define Cpu64	     0x4000000   /* 64bit support required  */
 #define CpuNo64      0x8000000   /* Not supported in the 64bit mode  */
 
   /* The default value for unknown CPUs - enable all features to avoid problems.  */
-#define CpuUnknownFlags (Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuSledgehammer|CpuMMX|CpuSSE|CpuSSE2|CpuPNI|Cpu3dnow|CpuK6|CpuAthlon)
+#define CpuUnknownFlags (Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuP4|CpuSledgehammer|CpuMMX|CpuSSE|CpuSSE2|CpuPNI|Cpu3dnow|CpuK6|CpuAthlon|CpuPadLock)
 
   /* the bits in opcode_modifier are used to generate the final opcode from
      the base_opcode.  These bits also are used to detect alternate forms of
Index: include/opcode/i386.h
===================================================================
RCS file: /cvs/src/src/include/opcode/i386.h,v
retrieving revision 1.40
diff -u -p -r1.40 i386.h
--- include/opcode/i386.h	23 Jun 2003 20:15:33 -0000	1.40
+++ include/opcode/i386.h	11 Mar 2004 16:59:37 -0000
@@ -1361,6 +1361,13 @@ static const template i386_optab[] = {
 {"sysret",   0, 0x0f07,    X, CpuK6,	lq_Suf|DefaultSize,	{ 0, 0, 0} },
 {"swapgs",   0, 0x0f01, 0xf8, Cpu64,	NoSuf|ImmExt,		{ 0, 0, 0} },
 
+/* VIA PadLock extensions. */
+{"xstorerng", 0, 0x0fa7c0, X, Cpu686|CpuPadLock, NoSuf|IsString, { 0, 0, 0} },
+{"xcryptecb", 0, 0xf30fa7c8, X, Cpu686|CpuPadLock, NoSuf|IsString, { 0, 0, 0} },
+{"xcryptcbc", 0, 0xf30fa7d0, X, Cpu686|CpuPadLock, NoSuf|IsString, { 0, 0, 0} },
+{"xcryptcfb", 0, 0xf30fa7e0, X, Cpu686|CpuPadLock, NoSuf|IsString, { 0, 0, 0} },
+{"xcryptofb", 0, 0xf30fa7e8, X, Cpu686|CpuPadLock, NoSuf|IsString, { 0, 0, 0} },
+
 /* sentinel */
 {NULL, 0, 0, 0, 0, 0, { 0, 0, 0} }
 };
Index: opcodes/i386-dis.c
===================================================================
RCS file: /cvs/src/src/opcodes/i386-dis.c,v
retrieving revision 1.42
diff -u -p -r1.42 i386-dis.c
--- opcodes/i386-dis.c	18 Jan 2004 23:12:47 -0000	1.42
+++ opcodes/i386-dis.c	11 Mar 2004 16:59:37 -0000
@@ -362,6 +362,7 @@ fetch_data (struct disassemble_info *inf
 #define USE_GROUPS 2
 #define USE_PREFIX_USER_TABLE 3
 #define X86_64_SPECIAL 4
+#define PADLOCK_SPECIAL 5
 
 #define FLOAT	  NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
 
@@ -388,6 +389,7 @@ fetch_data (struct disassemble_info *inf
 #define GRP13	  NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0
 #define GRP14	  NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0
 #define GRPAMD	  NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0
+#define GRPPLOCK  NULL, NULL, USE_GROUPS, NULL, 23, NULL, 0
 
 #define PREGRP0   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  0, NULL, 0
 #define PREGRP1   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  1, NULL, 0
@@ -425,6 +427,8 @@ fetch_data (struct disassemble_info *inf
 
 #define X86_64_0  NULL, NULL, X86_64_SPECIAL, NULL,  0, NULL, 0
 
+#define PADLOCK_0  NULL, NULL, PADLOCK_SPECIAL, NULL,  0, NULL, 0
+
 typedef void (*op_rtn) (int bytemode, int sizeflag);
 
 struct dis386 {
@@ -948,7 +952,7 @@ static const struct dis386 dis386_twobyt
   { "shldS",		Ev, Gv, Ib },
   { "shldS",		Ev, Gv, CL },
   { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
+  { PADLOCK_0 },
   /* a8 */
   { "pushT",		gs, XX, XX },
   { "popT",		gs, XX, XX },
@@ -1450,6 +1454,17 @@ static const struct dis386 grps[][8] = {
     { "(bad)",	XX, XX, XX },
     { "(bad)",	XX, XX, XX },
     { "(bad)",	XX, XX, XX },
+  },
+  /* GRPPLOCK */
+  {
+    { "xstore", XX, XX, XX },
+    { "xcryptecb", XX, XX, XX },
+    { "xcryptcbc", XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "xcryptcfb", XX, XX, XX },
+    { "xcryptofb", XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
+    { "(bad)",	XX, XX, XX },
   }
 };
 
@@ -1694,6 +1709,19 @@ static const struct dis386 x86_64_table[
   },
 };
 
+static const struct dis386 padlock_table[][8] = {
+  {
+    { "xstorerng", XX, XX, XX },
+    { "xcryptecb", XX, XX, XX },
+    { "xcryptcbc", XX, XX, XX },
+    { "(bad)", XX, XX, XX },
+    { "xcryptcfb", XX, XX, XX },
+    { "xcryptofb", XX, XX, XX },
+    { "(bad)", XX, XX, XX },
+    { "(bad)", XX, XX, XX },
+  },
+};
+
 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
 
 static void
@@ -2190,6 +2218,12 @@ print_insn (bfd_vma pc, disassemble_info
 
 	    case X86_64_SPECIAL:
 	      dp = &x86_64_table[dp->bytemode2][mode_64bit];
+	      break;
+
+	    case PADLOCK_SPECIAL:
+	      FETCH_DATA (info, codep + 1);
+	      index = (*codep++ >> 3) & 0x07;
+	      dp = &padlock_table[dp->bytemode2][index];
 	      break;
 
 	    default:

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