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]

z8k fixes


Hi,

I've checked in some fixes for z8k:

        - Be case insensitive when parsing control register and
          interrupt operands.
        - Comma-separated interrupt operands (EI/DI opcodes) are now
          supported. This is the syntax which is used in the Zilog
          documentation.
        - The disassembler disassembles flags (SETFLG, RESFLG, COMFLG
          opcodes) and interrupt operands now in a format the assembler
          understands.
        - Updated testsuite with new EI/DI syntax.


regards,
chris



ChangeLogs:


opcodes/ChangeLog:

2003-12-15  Christian Groessler  <chris@groessler.org>

	* z8k-dis.c (intr_names): Removed.
	(print_intr, print_flags): New functions.
	(unparse_instr): Use new functions.


gas/ChangeLog:

2003-12-15  Christian Groessler  <chris@groessler.org>

	* config/tc-z8k.c (struct z8k_exp): Remove, not used anywhere.
	(ctrl_table): Add "flags" keyword and some comments.
	(flag_table): Convert to uppercase.
	(get_flags_operand): Be case insensitive.
	(get_interrupt_operand): Be case insensitive.  Support notation
	where the inperrupt arguments are separated by commas.
	(get_operands): Check whether get_flags_operand consumed all
	arguments.  Return failure if get_ctrl_operand didn't recognize a
	valid control register.
	(get_specific): Add case CLASS_CTRL: Test for valid control
	register for ldctlb opcode.
	(build_bytes): Check for valid control registers.


gas/testsuite/ChangeLog:

2003-12-15  Christian Groessler  <chris@groessler.org>

	* gas/z8k/eidi.s: Add uppercase forms.  Add forms with comma
	separated parameters.



Index: gas/config/tc-z8k.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-z8k.c,v
retrieving revision 1.28
diff -u -p -r1.28 tc-z8k.c
--- gas/config/tc-z8k.c	10 Dec 2003 06:41:08 -0000	1.28
+++ gas/config/tc-z8k.c	15 Dec 2003 21:58:57 -0000
@@ -177,12 +177,6 @@ md_begin (void)
     }
 }
 
-struct z8k_exp {
-  char *e_beg;
-  char *e_end;
-  expressionS e_exp;
-};
-
 typedef struct z8k_op {
   /* CLASS_REG_xxx.  */
   int regsize;
@@ -399,7 +393,8 @@ struct ctrl_names {
 };
 
 static struct ctrl_names ctrl_table[] = {
-  { 0x2, "fcw" },
+  { 0x1, "flags" },   /* ldctlb only.  */
+  { 0x2, "fcw" },     /* ldctl only.  Applies to all remaining control registers.  */
   { 0x3, "refresh" },
   { 0x4, "psapseg" },
   { 0x5, "psapoff" },
@@ -441,12 +436,13 @@ struct flag_names {
 };
 
 static struct flag_names flag_table[] = {
-  { 0x1, "p" },
-  { 0x1, "v" },
-  { 0x2, "s" },
-  { 0x4, "z" },
-  { 0x8, "c" },
+  { 0x1, "P" },
+  { 0x1, "V" },
+  { 0x2, "S" },
+  { 0x4, "Z" },
+  { 0x8, "C" },
   { 0x0, "+" },
+  { 0x0, "," },
   { 0, 0 }
 };
 
@@ -454,6 +450,7 @@ static void
 get_flags_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED)
 {
   char *src = *ptr;
+  char c;
   int i;
   int j;
 
@@ -466,9 +463,10 @@ get_flags_operand (char **ptr, struct z8
     {
       if (!src[j])
 	goto done;
+      c = TOUPPER(src[j]);
       for (i = 0; flag_table[i].name; i++)
 	{
-	  if (flag_table[i].name[0] == src[j])
+	  if (flag_table[i].name[0] == c)
 	    {
 	      the_flags = the_flags | flag_table[i].value;
 	      goto match;
@@ -499,27 +497,48 @@ static void
 get_interrupt_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED)
 {
   char *src = *ptr;
-  int i;
+  int i, l;
 
   while (*src == ' ')
     src++;
 
   mode->mode = CLASS_IMM;
-  for (i = 0; intr_table[i].name; i++)
-    {
-      int j;
+  the_interrupt = 0;
 
-      for (j = 0; intr_table[i].name[j]; j++)
+  while (*src)
+    {
+      for (i = 0; intr_table[i].name; i++)
 	{
-	  if (intr_table[i].name[j] != src[j])
-	    goto fail;
+	  l = strlen (intr_table[i].name);
+	  if (! strncasecmp (intr_table[i].name, src, l))
+	    {
+	      the_interrupt |= intr_table[i].value;
+	      if (*(src + l) && *(src + l) != ',')
+		{
+		  *ptr = src + l;
+		invalid:
+		  as_bad (_("unknown interrupt %s"), src);
+		  while (**ptr && ! is_end_of_line[(unsigned char) **ptr])
+		    (*ptr)++;	 /* Consume rest of line.  */
+		  return;
+		}
+	      src += l;
+	      if (! *src)
+		{
+		  *ptr = src;
+		  return;
+		}
+	    }
+	}
+      if (*src == ',')
+	src++;
+      else
+	{
+	  *ptr = src;
+	  goto invalid;
 	}
-      the_interrupt = intr_table[i].value;
-      *ptr = src + j;
-      return;
-    fail:
-      ;
     }
+
   /* No interrupt type specified, opcode won't do anything.  */
   as_warn (_("opcode has no effect"));
   the_interrupt = 0x0;
@@ -720,7 +739,17 @@ get_operands (const opcode_entry_type *o
             }
         }
       else if (opcode->arg_info[0] == CLASS_FLAGS)
-	get_flags_operand (&ptr, operand + 0, 0);
+	{
+	  get_flags_operand (&ptr, operand + 0, 0);
+	  while (*ptr == ' ')
+	    ptr++;
+	  if (*ptr && ! is_end_of_line[(unsigned char) *ptr])
+	    {
+	      as_bad (_("invalid flag '%s'"), ptr);
+	      while (*ptr && ! is_end_of_line[(unsigned char) *ptr])
+		ptr++;	 /* Consume rest of line.  */
+	    }
+	}
       else if (opcode->arg_info[0] == (CLASS_IMM + (ARG_IMM2)))
 	get_interrupt_operand (&ptr, operand + 0, 0);
       else
@@ -760,6 +789,8 @@ get_operands (const opcode_entry_type *o
 	      if (*ptr == ',')
 		ptr++;
 	      get_ctrl_operand (&ptr, operand + 1, 1);
+	      if (the_ctrl == 0)
+		return NULL;
 	      return ptr;
 	    }
 	}
@@ -889,6 +920,10 @@ get_specific (opcode_entry_type *opcode,
 	    case CLASS_REGN0:
 	      reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg;
 	      break;
+	    case CLASS_CTRL:
+	      if (this_try->opcode == OPC_ldctlb && the_ctrl != 1)
+		as_bad (_("invalid control register name"));
+	      break;
 	    }
 	}
 
@@ -1035,9 +1070,13 @@ build_bytes (opcode_entry_type *this_try
 	  *output_ptr++ = the_cc;
 	  break;
 	case CLASS_0CCC:
+	  if (the_ctrl < 2 || the_ctrl > 7)
+	    as_bad (_("invalid control register name"));
 	  *output_ptr++ = the_ctrl;
 	  break;
 	case CLASS_1CCC:
+	  if (the_ctrl < 2 || the_ctrl > 7)
+	    as_bad (_("invalid control register name"));
 	  *output_ptr++ = the_ctrl | 0x8;
 	  break;
 	case CLASS_00II:
Index: gas/testsuite/gas/z8k/eidi.s
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/z8k/eidi.s,v
retrieving revision 1.1
diff -u -p -r1.1 eidi.s
--- gas/testsuite/gas/z8k/eidi.s	21 Jun 2003 12:20:08 -0000	1.1
+++ gas/testsuite/gas/z8k/eidi.s	15 Dec 2003 21:59:06 -0000
@@ -1,4 +1,5 @@
 .text
+
 	ei	all
 	di	all
 	ei	both
@@ -8,3 +9,22 @@
 	ei	nvi
 	di	nvi
 
+	ei	vi,nvi
+	ei	nvi,vi
+	di	vi,nvi
+	di	nvi,vi
+
+
+	EI	ALL
+	DI	ALL
+	EI	BOTH
+	DI	BOTH
+	EI	VI
+	DI	VI
+	EI	NVI
+	DI	NVI
+
+	EI	VI,NVI
+	EI	NVI,VI
+	DI	VI,NVI
+	DI	NVI,VI
Index: opcodes/z8k-dis.c
===================================================================
RCS file: /cvs/src/src/opcodes/z8k-dis.c,v
retrieving revision 1.15
diff -u -p -r1.15 z8k-dis.c
--- opcodes/z8k-dis.c	28 Nov 2003 20:12:17 -0000	1.15
+++ opcodes/z8k-dis.c	15 Dec 2003 21:59:14 -0000
@@ -26,7 +26,7 @@
 #include "z8k-opc.h"
 
 #include <setjmp.h>
-
+
 typedef struct
 {
   /* These are all indexed by nibble number (i.e only every other entry
@@ -472,12 +472,53 @@ unpack_instr (instr_data_s *instr_data, 
     }
 }
 
-static char *intr_names[] = {
-  "all",    /* 0 */
-  "vi",     /* 1 */
-  "nvi",    /* 2 */
-  "none"    /* 3 */
-};
+static void
+print_intr(char *tmp_str, unsigned long interrupts)
+{
+  int comma = 0;
+
+  *tmp_str = 0;
+  if (! (interrupts & 2))
+    {
+      strcat (tmp_str, "vi");
+      comma = 1;
+    }
+  if (! (interrupts & 1))
+    {
+      if (comma) strcat (tmp_str, ",");
+      strcat (tmp_str, "nvi");
+    }
+}
+
+static void
+print_flags(char *tmp_str, unsigned long flags)
+{
+  int comma = 0;
+
+  *tmp_str = 0;
+  if (flags & 8)
+    {
+      strcat (tmp_str, "c");
+      comma = 1;
+    }
+  if (flags & 4)
+    {
+      if (comma) strcat (tmp_str, ",");
+      strcat (tmp_str, "z");
+      comma = 1;
+    }
+  if (flags & 2)
+    {
+      if (comma) strcat (tmp_str, ",");
+      strcat (tmp_str, "s");
+      comma = 1;
+    }
+  if (flags & 1)
+    {
+      if (comma) strcat (tmp_str, ",");
+      strcat (tmp_str, "p");
+    }
+}
 
 static void
 unparse_instr (instr_data_s *instr_data, int is_segmented)
@@ -529,12 +570,12 @@ unparse_instr (instr_data_s *instr_data,
 	  strcat (out_str, tmp_str);
 	  break;
 	case CLASS_IMM:
-          if (datum_value == ARG_IMM2)  /* True with EI/DI instructions only.  */
-            {
-              sprintf (tmp_str, "%s", intr_names[instr_data->interrupts]);
-              strcat (out_str, tmp_str);
-              break;
-            }
+	  if (datum_value == ARG_IMM2)	/* True with EI/DI instructions only.  */
+	    {
+	      print_intr (tmp_str, instr_data->interrupts);
+	      strcat (out_str, tmp_str);
+	      break;
+	    }
 	  sprintf (tmp_str, "#0x%0lx", instr_data->immediate);
 	  strcat (out_str, tmp_str);
 	  break;
@@ -563,7 +604,7 @@ unparse_instr (instr_data_s *instr_data,
 	  strcat (out_str, tmp_str);
 	  break;
 	case CLASS_FLAGS:
-	  sprintf (tmp_str, "0x%0lx", instr_data->flags);
+	  print_flags(tmp_str, instr_data->flags);
 	  strcat (out_str, tmp_str);
 	  break;
 	case CLASS_REG_BYTE:


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