This is the mail archive of the binutils@sourceware.cygnus.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]

Re: PATCH: fix pa disassembly bug


>> "jeff" == Jeffrey A Law <law@cygnus.com> writes:

 jeff>   In message <199906210350.XAA26342@wmtl249c.us.nortel.com>you write:
 >> This patch fixes a bug with disassembly of xmpyu, fmpyfadd, and fmpynfadd.
 >> They were using the 'E' and 'X' codes to represent their two input
 >> operands.  While the correct opcode is generated by gas, the disassembler
 >> would incorrectly read the opcode, using the wrong bit for l/r selection.
 >> The solution is to use 'J' and 'K' codes instead.
 >> 
 jeff> BTW, there is a disassembler testsuite in the gdb tree.  It may be
 jeff> worth adding a test for this problem.

As you wish :-).  It turns out that the above fix isn't complete enough.  'F'
doesn't work correctly for fmpyfadd and fmpynfadd to print the format in the
disassembler.  If the 3rd register arg is an 'R' reg, no output format is
printed.  The code needs to be 'I' to work correctly.

Also, looking at the following arg to see if it is a second float format works 
correctly for these two instructions.

I've included a test case that works correctly in the disassembler.

Jerry

ChangeLog entry:

Thu Jul 29 17:08:37 EDT 1999

    * include/opcode/hppa.h (pa_opcodes):  Change fmpyfadd, fmpynfadd, fneg,
    fnegabs to use 'I' instead of 'F'.
    * gas/config/tc-hppa.c (pa_ip):  Add case for 'I'.  
    * opcodes/hppa-dis.c (print_insn_hppa):  Look at next arg instead of bits
    to decide to print a space.
    * binutils/testsuite/binutils-all/hppa/freg.s:  New file.
    * binutils/testsuite/binutils-all/hppa/objdump.exp:  Add freg.s test.

*** pa-prev/include/opcode/hppa.h	Thu Jul 29 16:01:45 1999
--- gas-src/include/opcode/hppa.h	Thu Jul 29 17:03:06 1999
***************
*** 503,514 ****
  { "fcnvfx",     0x38010200, 0xfc1f8720, "FGJ,v", pa10},
  { "fcnvfxt",    0x30018200, 0xfc1f87e0, "FGE,v", pa10},
  { "fcnvfxt",    0x38018200, 0xfc1f8720, "FGJ,v", pa10},
! { "fmpyfadd",   0xb8000000, 0xfc000020, "FJ,K,3,v", pa20, FLAG_STRICT},
! { "fmpynfadd",  0xb8000020, 0xfc000020, "FJ,K,3,v", pa20, FLAG_STRICT},
  { "fneg",       0x3000c000, 0xfc1fe7e0, "FE,v", pa20, FLAG_STRICT},
! { "fneg",       0x3800c000, 0xfc1fe720, "FJ,v", pa20, FLAG_STRICT},
  { "fnegabs",    0x3000e000, 0xfc1fe7e0, "FE,v", pa20, FLAG_STRICT},
! { "fnegabs",    0x3800e000, 0xfc1fe720, "FJ,v", pa20, FLAG_STRICT},
  { "fcmp",       0x30000400, 0xfc00e7e0, "F?fE,X", pa10},
  { "fcmp",       0x38000400, 0xfc00e720, "I?fJ,K", pa10},
  { "xmpyu",	0x38004700, 0xfc00e720, "J,K,v", pa11},
--- 503,514 ----
  { "fcnvfx",     0x38010200, 0xfc1f8720, "FGJ,v", pa10},
  { "fcnvfxt",    0x30018200, 0xfc1f87e0, "FGE,v", pa10},
  { "fcnvfxt",    0x38018200, 0xfc1f8720, "FGJ,v", pa10},
! { "fmpyfadd",   0xb8000000, 0xfc000020, "IJ,K,3,v", pa20, FLAG_STRICT},
! { "fmpynfadd",  0xb8000020, 0xfc000020, "IJ,K,3,v", pa20, FLAG_STRICT},
  { "fneg",       0x3000c000, 0xfc1fe7e0, "FE,v", pa20, FLAG_STRICT},
! { "fneg",       0x3800c000, 0xfc1fe720, "IJ,v", pa20, FLAG_STRICT},
  { "fnegabs",    0x3000e000, 0xfc1fe7e0, "FE,v", pa20, FLAG_STRICT},
! { "fnegabs",    0x3800e000, 0xfc1fe720, "IJ,v", pa20, FLAG_STRICT},
  { "fcmp",       0x30000400, 0xfc00e7e0, "F?fE,X", pa10},
  { "fcmp",       0x38000400, 0xfc00e720, "I?fJ,K", pa10},
  { "xmpyu",	0x38004700, 0xfc00e720, "J,K,v", pa11},
*** pa-prev/gas/config/tc-hppa.c	Thu Jul 29 16:01:42 1999
--- gas-src/gas/config/tc-hppa.c	Thu Jul 29 17:03:50 1999
***************
*** 2549,2554 ****
--- 2549,2560 ----
  	      the_insn.fpof2 = flag;
  	      INSERT_FIELD_AND_CONTINUE (opcode, flag, 13);
  
+ 	    /* Handle a source FP operand format completer at 20.  */
+ 	    case 'I':
+ 	      flag = pa_parse_fp_format (&s);
+ 	      the_insn.fpof1 = flag;
+ 	      INSERT_FIELD_AND_CONTINUE (opcode, flag, 11);
+ 
  	    /* Handle L/R register halves like 't'.  */
  	    case 'v':
  	      {
*** pa-prev/opcodes/hppa-dis.c	Thu Jul 29 16:01:48 1999
--- gas-src/opcodes/hppa-dis.c	Thu Jul 29 16:58:07 1999
***************
*** 682,688 ****
  		case 'F':
  		  /* if no destination completer and not before a completer
  		     for fcmp, need a space here */
! 		  if (GET_FIELD (insn, 21, 22) == 1 || s[1] == '?')
  		    fputs_filtered (float_format_names[GET_FIELD (insn, 19, 20)],
  				    info);
  		  else
--- 682,688 ----
  		case 'F':
  		  /* if no destination completer and not before a completer
  		     for fcmp, need a space here */
! 		  if (s[1] == 'G' || s[1] == '?')
  		    fputs_filtered (float_format_names[GET_FIELD (insn, 19, 20)],
  				    info);
  		  else
***************
*** 706,712 ****
  		case 'I':
  		  /* if no destination completer and not before a completer
  		     for fcmp, need a space here */
! 		  if (GET_FIELD (insn, 21, 22) == 1 || s[1] == '?')
  		    fputs_filtered (float_format_names[GET_FIELD (insn, 20, 20)],
  				    info);
  		  else
--- 706,712 ----
  		case 'I':
  		  /* if no destination completer and not before a completer
  		     for fcmp, need a space here */
! 		  if (s[1] == '?')
  		    fputs_filtered (float_format_names[GET_FIELD (insn, 20, 20)],
  				    info);
  		  else
diff -uN pa-prev/binutils/testsuite/binutils-all/hppa/freg.s gas-src/binutils/testsuite/binutils-all/hppa/freg.s
--- pa-prev/binutils/testsuite/binutils-all/hppa/freg.s	Wed Dec 31 19:00:00 1969
+++ gas-src/binutils/testsuite/binutils-all/hppa/freg.s	Thu Jul 29 16:27:34 1999
@@ -0,0 +1,23 @@
+	.LEVEL 2.0
+	.SPACE $PRIVATE$
+	.SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+	.SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+	.SPACE $TEXT$
+	.SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+	.SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+	.IMPORT $global$,DATA
+	.IMPORT $$dyncall,MILLICODE
+; gcc_compiled.:
+	.SPACE $TEXT$
+	.SUBSPA $CODE$
+
+	.align 4
+	.NSUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+	.EXPORT main,ENTRY,PRIV_LEV=3,RTNVAL=GR
+main
+	.PROC
+	.CALLINFO FRAME=64,CALLS,SAVE_RP
+	.ENTRY
+	fmpyfadd,sgl %fr4L,%fr4R,%fr5R,%fr5L
+	.EXIT
+	.PROCEND
diff -uN pa-prev/binutils/testsuite/binutils-all/hppa/objdump.exp gas-src/binutils/testsuite/binutils-all/hppa/objdump.exp
--- pa-prev/binutils/testsuite/binutils-all/hppa/objdump.exp	Thu Jul 29 17:19:14 1999
+++ gas-src/binutils/testsuite/binutils-all/hppa/objdump.exp	Thu Jul 29 17:16:20 1999
@@ -58,3 +58,29 @@
     fail "addendbug test"
 }
 
+###########################
+# Set up the test of freg.s
+###########################
+
+if {![binutils_assemble $srcdir/$subdir/freg.s tmpdir/freg.o]} then {
+    return
+}
+
+if [is_remote host] {
+    set objfile [remote_download host tmpdir/freg.o]
+} else {
+    set objfile tmpdir/freg.o
+}
+
+# Make sure that we get R float regs like we're supposed to
+
+set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS --disassemble $objfile"]
+
+set want "fmpyfadd,sgl fr4,fr4R,fr5R,fr5"
+
+if [regexp $want $got] then {
+    pass "freg test"
+} else {
+    fail "freg test"
+}
+


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