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


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

Re: [RFA] Provide cgen_disn and cgen_fields in disassemble_info


On 20-Jul-2001, Frank Ch. Eigler wrote:

>With me too, except for the fact that it would be nice if the basic
>print_insn() function remained behind in some form (identical to
>print_insn_default()?), to avoid breaking ports that call print_insn
>directly right now.

How about this?  In addition to putting print_insn() back in, it

  - Fixes a "assignment discards qualifiers from pointer target type"
    warning with the new disassemble_info.cgen_insn field.

  - Removes unused parameter "cd" from read_insn().  I didn't find any
    read_insn() uses in opcodes/*-dis.c other than those generated from
    dis-asm.in.

  - Encloses print_insn() within #ifdef CGEN_PRINT_INSN,
    default_decode_insn() within #ifndef CGEN_DECODE_INSN, and
    default_print_insn() within #ifndef CGEN_PRINT_INSN.  This reduces
    binary size a tiny bit, and I'm pretty sure that those functions don't
    get used without the corresponding cpp conditions being true.

Tested with m32r-elf, which calls print_insn() from CGEN_PRINT_INSN, as
well as with another platform that doesn't call print_insn().

Nick

include/ChangeLog:

2000-11-07  Nick Duffek  <nsd@redhat.com>

	* dis-asm.h (struct disassemble_info): Add cgen_insn and
	cgen_fields fields.

opcodes/ChangeLog:

2000-11-07  Nick Duffek  <nsd@redhat.com>

	* cgen-dis.in (decode_insn, default_decode_insn, decode_init,
	decode_insn_@arch@): New functions.
	(read_insn): Remove unused "cd" parameter.
	(CGEN_DECODE_INSN): Define.
	(print_insn): Mostly move into decode_insn(), enclose within
	#ifdef CGEN_PRINT_INSN.
	(default_print_insn): Enclose within #ifndef CGEN_PRINT_INSN.
	(print_insn_@arch@): Mostly move into decode_init().

Index: include/dis-asm.h
===================================================================
diff -up include/dis-asm.h include/dis-asm.h
--- include/dis-asm.h	Mon Jul 23 12:30:59 2001
+++ include/dis-asm.h	Mon Jul 23 12:27:34 2001
@@ -165,6 +165,13 @@ typedef struct disassemble_info {
 				   zero if unknown.  */
   bfd_vma target2;		/* Second target address for dref2 */
 
+  /* Results from CGEN instruction decoders.  */
+
+  const struct cgen_insn *cgen_insn; /* If non-null, pointer to CGEN_INSN
+					instruction descriptor.  */
+  struct cgen_fields *cgen_fields; /* If caller sets to non-null, receives
+				      CGEN_FIELDS operand descriptor.  */
+
   /* Command line options specific to the target disassembler.  */
   char * disassembler_options;
 
Index: opcodes/cgen-dis.in
===================================================================
diff -up opcodes/cgen-dis.in opcodes/cgen-dis.in
--- opcodes/cgen-dis.in	Mon Jul 23 12:31:07 2001
+++ opcodes/cgen-dis.in	Mon Jul 23 12:30:14 2001
@@ -47,10 +47,17 @@ static void print_keyword
 static void print_insn_normal
      PARAMS ((CGEN_CPU_DESC, PTR, const CGEN_INSN *, CGEN_FIELDS *,
 	      bfd_vma, int));
+static int decode_insn PARAMS ((CGEN_CPU_DESC, bfd_vma,
+				disassemble_info *, char *, int,
+				CGEN_FIELDS *));
 static int print_insn PARAMS ((CGEN_CPU_DESC, bfd_vma,
 			       disassemble_info *, char *, int));
+static int default_decode_insn
+     PARAMS ((CGEN_CPU_DESC, bfd_vma, disassemble_info *, CGEN_FIELDS *));
 static int default_print_insn
      PARAMS ((CGEN_CPU_DESC, bfd_vma, disassemble_info *));
+static CGEN_CPU_DESC decode_init
+     PARAMS ((disassemble_info *));
 
 /* -- disassembler routines inserted here */
 
@@ -187,12 +194,11 @@ print_insn_normal (cd, dis_info, insn, f
     }
 }
 
-/* Subroutine of print_insn. Reads an insn into the given buffers and updates
+/* Subroutine of decode_insn. Reads an insn into the given buffers and updates
    the extract info.
    Returns 0 if all is well, non-zero otherwise.  */
 static int
-read_insn (cd, pc, info, buf, buflen, ex_info, insn_value)
-     CGEN_CPU_DESC cd;
+read_insn (pc, info, buf, buflen, ex_info, insn_value)
      bfd_vma pc;
      disassemble_info *info;
      char *buf;
@@ -215,19 +221,23 @@ read_insn (cd, pc, info, buf, buflen, ex
   return 0;
 }
 
-/* Utility to print an insn.
+/* Utility to decode an insn.
+
    BUF is the base part of the insn, target byte order, BUFLEN bytes long.
    The result is the size of the insn in bytes or zero for an unknown insn
    or -1 if an error occurs fetching data (memory_error_func will have
-   been called).  */
+   been called).
+
+   FIELDS points to storage for the insn's extracted fields.  */
 
 static int
-print_insn (cd, pc, info, buf, buflen)
+decode_insn (cd, pc, info, buf, buflen, fields)
      CGEN_CPU_DESC cd;
      bfd_vma pc;
      disassemble_info *info;
      char *buf;
      int buflen;
+     CGEN_FIELDS *fields;
 {
   CGEN_INSN_INT insn_value;
   const CGEN_INSN_LIST *insn_list;
@@ -250,7 +260,6 @@ print_insn (cd, pc, info, buf, buflen)
   while (insn_list != NULL)
     {
       const CGEN_INSN *insn = insn_list->insn;
-      CGEN_FIELDS fields;
       int length;
       unsigned long insn_value_cropped;
 
@@ -290,24 +299,24 @@ print_insn (cd, pc, info, buf, buflen)
 	      (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
 	    {
 	      unsigned long full_insn_value;
-	      int rc = read_insn (cd, pc, info, buf,
+	      int rc = read_insn (pc, info, buf,
 				  CGEN_INSN_BITSIZE (insn) / 8,
 				  & ex_info, & full_insn_value);
 	      if (rc != 0)
 		return rc;
 	      length = CGEN_EXTRACT_FN (cd, insn)
-		(cd, insn, &ex_info, full_insn_value, &fields, pc);
+		(cd, insn, &ex_info, full_insn_value, fields, pc);
 	    }
 	  else
 	    length = CGEN_EXTRACT_FN (cd, insn)
-	      (cd, insn, &ex_info, insn_value_cropped, &fields, pc);
+	      (cd, insn, &ex_info, insn_value_cropped, fields, pc);
 
 	  /* length < 0 -> error */
 	  if (length < 0)
 	    return length;
 	  if (length > 0)
 	    {
-	      CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length);
+	      info->cgen_insn = insn;
 	      /* length is in bits, result is in bytes */
 	      return length / 8;
 	    }
@@ -319,19 +328,19 @@ print_insn (cd, pc, info, buf, buflen)
   return 0;
 }
 
-/* Default value for CGEN_PRINT_INSN.
+/* Default value for CGEN_DECODE_INSN.
    The result is the size of the insn in bytes or zero for an unknown insn
    or -1 if an error occured fetching bytes.  */
 
-#ifndef CGEN_PRINT_INSN
-#define CGEN_PRINT_INSN default_print_insn
-#endif
+#ifndef CGEN_DECODE_INSN
+#define CGEN_DECODE_INSN default_decode_insn
 
 static int
-default_print_insn (cd, pc, info)
+default_decode_insn (cd, pc, info, fields)
      CGEN_CPU_DESC cd;
      bfd_vma pc;
      disassemble_info *info;
+     CGEN_FIELDS *fields;
 {
   char buf[CGEN_MAX_INSN_SIZE];
   int buflen;
@@ -354,23 +363,78 @@ default_print_insn (cd, pc, info)
       return -1;
     }
 
-  return print_insn (cd, pc, info, buf, buflen);
+  return decode_insn (cd, pc, info, buf, buflen, fields);
 }
+#endif  /* !defined CGEN_DECODE_INSN */
 
-/* Main entry point.
-   Print one instruction from PC on INFO->STREAM.
-   Return the size of the instruction (in bytes).  */
+#ifdef CGEN_PRINT_INSN
+/* Utility to print an insn.
 
-int
-print_insn_@arch@ (pc, info)
+   The result is the size of the insn in bytes or zero for an unknown insn
+   or -1 if an error occurs fetching data (memory_error_func will have
+   been called).
+
+   BUF and BUFLEN are unused.  */
+
+static int
+print_insn (cd, pc, info, buf, buflen)
+     CGEN_CPU_DESC cd;
+     bfd_vma pc;
+     disassemble_info *info;
+     char *buf ATTRIBUTE_UNUSED;
+     int buflen ATTRIBUTE_UNUSED;
+{
+  CGEN_FIELDS fields;
+  int length;
+  const CGEN_INSN *insn;
+
+  length = CGEN_DECODE_INSN (cd, pc, info, &fields);
+  if (length > 0)
+    {
+      insn = info->cgen_insn;
+      CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length * 8);
+    }
+  return length;
+}
+#endif  /* defined CGEN_PRINT_INSN */
+
+/* Default value for CGEN_PRINT_INSN.
+   The result is the size of the insn in bytes or zero for an unknown insn
+   or -1 if an error occured fetching bytes.  */
+
+#ifndef CGEN_PRINT_INSN
+#define CGEN_PRINT_INSN default_print_insn
+
+static int
+default_print_insn (cd, pc, info)
+     CGEN_CPU_DESC cd;
      bfd_vma pc;
      disassemble_info *info;
 {
+  CGEN_FIELDS fields;
+  int length;
+  const CGEN_INSN *insn;
+
+  length = CGEN_DECODE_INSN (cd, pc, info, &fields);
+  if (length > 0)
+    {
+      insn = info->cgen_insn;
+      CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length * 8);
+    }
+  return length;
+}
+#endif  /* !defined CGEN_PRINT_INSN */
+
+/* Prepare to decode the instruction at PC.  */
+
+static CGEN_CPU_DESC
+decode_init (info)
+     disassemble_info *info;
+{
   static CGEN_CPU_DESC cd = 0;
   static int prev_isa;
   static int prev_mach;
   static int prev_endian;
-  int length;
   int isa,mach;
   int endian = (info->endian == BFD_ENDIAN_BIG
 		? CGEN_ENDIAN_BIG
@@ -430,6 +494,43 @@ print_insn_@arch@ (pc, info)
 	abort ();
       @arch@_cgen_init_dis (cd);
     }
+
+  return cd;
+}
+
+/* Main entry point for decoding.
+   Store in INFO information about the instruction at PC.
+   If successful, return the size of the instruction (in bytes).  Otherwise,
+   return 0 for an unknown insn and -1 if some other error occurred.  */
+
+int
+decode_insn_@arch@ (pc, info)
+     bfd_vma pc;
+     disassemble_info *info;
+{
+  CGEN_CPU_DESC cd = decode_init (info);
+
+  /* We try to have as much common code as possible.
+     But at this point some targets need to take over.  */
+  /* ??? Some targets may need a hook elsewhere.  Try to avoid this,
+     but if not possible try to move this hook elsewhere rather than
+     have two hooks.  */
+  return CGEN_DECODE_INSN (cd, pc, info, info->cgen_fields);
+}
+
+/* Main entry point for printing.
+   Print one instruction from PC on INFO->STREAM.
+   Return the size of the instruction (in bytes).  */
+
+int
+print_insn_@arch@ (pc, info)
+     bfd_vma pc;
+     disassemble_info *info;
+{
+  CGEN_CPU_DESC cd;
+  int length;
+
+  cd = decode_init (info);
 
   /* We try to have as much common code as possible.
      But at this point some targets need to take over.  */


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