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]

PATCH: pa2.0 long disp float load/store



This patch adds long-displacement floating point load/store
instructions to gas.  I needed several new codes to implement them:

'q' and 'B' are autoincrement completers for these instructions.  ldw
and stw long displacement can also use them.

'l' and 'L' are 14 bit displacements in these instructions.

'e' was already correct as a float source/dest for these in gas so I
used it.  Interestingly, no other opcodes currently use it.  I also
added 'e' to the disassembler.

Changelog entry:

Sun Jun 20 17:21:52 EDT 1999  Jerry Quinn <jquinn@nortelnetworks.com>

    * include/opcode/hppa.h (pa_opcodes): Add entries for pa2.0
    opcodes fldd, fstd, fldw, and fstw.
    * gas/config/tc-hppa.c (pa_ip): Add cases for codes B, q, l, and
    L. 
    * opcodes/hppa-dis.c (print_insn_hppa):  Add cases for codes B, q, 
    e, l, and L.



*** orig/gas/config/tc-hppa.c	Mon Jun 14 09:40:53 1999
--- gas-src/gas/config/tc-hppa.c	Fri Jun 18 02:35:45 1999
***************
*** 1668,1673 ****
--- 1668,1731 ----
  		  }
  	      }
  
+ 	      /* Autoincrement completer for long displacement ldw,
+ 		 stw, fldw, fstw.  No opcode change necessary since
+ 		 only autoinc opcodes have B.  */
+ 	    case 'B':
+ 	      {
+ 		int a = 0;
+ 		int m = 0;
+ 		int op;
+ 		if (*s == ',')
+ 		  {
+ 		    s++;
+ 		    if (strncasecmp (s, "ma", 2) == 0)
+ 		      {
+ 			a = 0;
+ 			m = 1;
+ 		      }
+ 		    else if (strncasecmp (s, "mb", 2) == 0)
+ 		      {
+ 			a = 1;
+ 			m = 1;
+ 		      }
+ 		    else
+ 		      as_bad (_("Invalid Long Load/Store Completer."));
+ 		    s += 2;
+ 		  }
+ 		if (!m) break;	/* No completer found */
+ 		INSERT_FIELD_AND_CONTINUE (opcode, a, 2);
+ 	      }
+ 
+ 
+ 	      /* Autoincrement completer for long displacement ldd, fldd */
+ 	    case 'q':
+ 	      {
+ 		int a = 0;
+ 		int m = 0;
+ 		int op;
+ 		if (*s == ',')
+ 		  {
+ 		    s++;
+ 		    if (strncasecmp (s, "ma", 2) == 0)
+ 		      {
+ 			a = 0;
+ 			m = 1;
+ 		      }
+ 		    else if (strncasecmp (s, "mb", 2) == 0)
+ 		      {
+ 			a = 1;
+ 			m = 1;
+ 		      }
+ 		    else
+ 		      as_bad (_("Invalid Long Load/Store Completer."));
+ 		    s += 2;
+ 		  }
+ 		opcode |= m << 3;
+ 		INSERT_FIELD_AND_CONTINUE (opcode, a, 2);
+ 	      }
+ 
+ 
  	    /* Handle a stbys completer.  */
  	    case 'Y':
  	      {
***************
*** 2222,2227 ****
--- 2280,2313 ----
  		  s = expr_end;
  		  continue;
  		}
+ 
+ 	    /* Handle a 14 bit load/store word displacement.  */
+ 	    case 'l':
+ 	      num = pa_get_absolute_expression (&the_insn, &s);
+ 	      s = expr_end;
+ 	      if (num % 4)
+ 		{
+ 		  as_bad (_("Load/store to unaligned offset"));
+ 		  break;
+ 		}
+ 	      CHECK_FIELD (num, 8191, -8192, 0);
+ 	      sign_unext(num, 14, &num);
+ 	      opcode |= num >> 13; /* Sign goes in bit 31 */
+ 	      INSERT_FIELD_AND_CONTINUE (opcode, num & 0x1fff, 1);
+ 
+ 	    /* Handle a 14 bit load/store doubleword displacement.  */
+ 	    case 'L':
+ 	      num = pa_get_absolute_expression (&the_insn, &s);
+ 	      s = expr_end;
+ 	      if (num % 8)
+ 		{
+ 		  as_bad (_("Load/store to unaligned offset"));
+ 		  break;
+ 		}
+ 	      CHECK_FIELD (num, 8191, -8192, 0);
+ 	      sign_unext (num, 14, &num);
+ 	      opcode |= num >> 13; /* Sign goes in bit 31 */
+ 	      INSERT_FIELD_AND_CONTINUE (opcode, num & 0x1fff, 1);
  
  	    /* Handle a 17 bit branch displacement.  */
  	    case 'W':
*** orig/include/opcode/hppa.h	Mon Jun 14 09:41:45 1999
--- gas-src/include/opcode/hppa.h	Tue Jun 15 12:03:10 1999
***************
*** 81,90 ****
--- 81,94 ----
     t    integer register field at 31.
     y    floating point register field at 31
     5    5 bit immediate at 15.
+    l	14 bit load/store displacement
+    L	14 bit load/store displacement for doublewords
     s    2 bit space specifier at 17.
     S    3 bit space specifier at 18.
     c    indexed load completer.
     C    short load and store completer.
+    q	long load/store completer for pa2.0 ldd, fldd
+    B	long load/store completer for pa2.0 ldw, fldw
     Y	Store Bytes Short completer
     <    non-negated compare/subtract conditions.
     a	compare/subtract conditions
***************
*** 153,158 ****
--- 157,163 ----
     X    an 'x' operand type extended to handle L/R register halves.
     J    a 'b' operand type further extended to handle extra 1.1 registers
     K    a 'x' operand type further extended to handle extra 1.1 registers
+    e	a 'x' operand at 11:15 with L/R bit at 30.  For long disp fldw (pa2.0)
     4    a variation of the 'b' operand type for 'fmpyadd' and 'fmpysub'
     6    a variation of the 'x' operand type for 'fmpyadd' and 'fmpysub'
     7    a variation of the 't' operand type for 'fmpyadd' and 'fmpysub'
***************
*** 166,172 ****
  /* List of characters not to put a space after.  Note that
     "," is included, as the "spopN" operations use literal
     commas in their completer sections. */
! static const char *const completer_chars = ",CcY<>?!@+&U~FfGHINnOoZMadu|/=0123%e$m}";
  
  /* The order of the opcodes in this table is significant:
  
--- 171,177 ----
  /* List of characters not to put a space after.  Note that
     "," is included, as the "spopN" operations use literal
     commas in their completer sections. */
! static const char *const completer_chars = ",CcY<>?!@+&U~FfGHINnOoZMadu|/=0123%e$mqB}";
  
  /* The order of the opcodes in this table is significant:
  
***************
*** 409,414 ****
--- 414,443 ----
  
  /* Floating Point Coprocessor Instructions */
    
+ { "fldw",       0x5c000000, 0xfc000004, "l(s,b),e", pa20}, /* long disp */
+ { "fldw",       0x5c000000, 0xfc000004, "l(b),e", pa20}, /* long disp */
+ { "fldw",       0x58000000, 0xfc000000, "Bl(s,b),e", pa20}, /* long disp with base modification */
+ { "fldw",       0x58000000, 0xfc000000, "Bl(b),e", pa20}, /* long disp with base modification */
+ { "fldw",       0x24000000, 0xfc001f80, "cx(s,b),v", pa20}, /* indexed, space */
+ { "fldw",       0x24000000, 0xfc001f80, "cx(b),v", pa20}, /* indexed */
+ 
+ { "fldd",       0x50000002, 0xfc000002, "qL(s,b),X", pa20}, /* long displacement */
+ { "fldd",       0x50000002, 0xfc000002, "qL(b),X", pa20}, /* long displacement */
+ { "fldd",       0x2c000000, 0xfc001fc0, "cx(s,b),y", pa20}, /* indexed, space */
+ { "fldd",       0x2c000000, 0xfc001fc0, "cx(b),y", pa20}, /* indexed */
+ 
+ { "fstw",       0x7c000004, 0xfc000004, "e,l(s,b)", pa20}, /* long disp */
+ { "fstw",       0x7c000004, 0xfc000004, "e,l(b)", pa20}, /* long disp */
+ { "fstw",       0x78000000, 0xfc000000, "Be,l(s,b)", pa20}, /* With base modification */
+ { "fstw",       0x78000000, 0xfc000000, "Be,l(b)", pa20}, /* With base modification */
+ { "fstw",       0x24000200, 0xfc001f80, "cv,x(s,b)", pa20}, /* indexed, space */
+ { "fstw",       0x24000200, 0xfc001f80, "cv,x(b)", pa20}, /* indexed */
+ 
+ { "fstd",       0x70000002, 0xfc000002, "qX,L(s,b)", pa20}, /* long displacement */
+ { "fstd",       0x70000002, 0xfc000002, "qX,L(b)", pa20}, /* long displacement */
+ { "fstd",       0x2c000200, 0xfc001fc0, "cy,x(s,b)", pa20}, /* indexed, space */
+ { "fstd",       0x2c000200, 0xfc001fc0, "cy,x(b)", pa20}, /* indexed */
+ 
  { "fldwx",      0x24000000, 0xfc001f80, "cx(s,b),v", pa10},
  { "fldwx",      0x24000000, 0xfc001f80, "cx(b),v", pa10},
  { "flddx",      0x2c000000, 0xfc001fc0, "cx(s,b),y", pa10},
*** orig/opcodes/hppa-dis.c	Mon Jun 14 09:41:36 1999
--- gas-src/opcodes/hppa-dis.c	Mon Jun 14 22:40:08 1999
***************
*** 305,311 ****
  	  
  	  (*info->fprintf_func) (info->stream, "%s", opcode->name);
  
! 	  if (!strchr ("cfCY<?!@-+&U>~nHNZFIMadu|", opcode->args[0]))
  	    (*info->fprintf_func) (info->stream, " ");
  	  for (s = opcode->args; *s != '\0'; ++s)
  	    {
--- 305,311 ----
  	  
  	  (*info->fprintf_func) (info->stream, "%s", opcode->name);
  
! 	  if (!strchr ("qBcfCY<?!@-+&U>~nHNZFIMadu|", opcode->args[0]))
  	    (*info->fprintf_func) (info->stream, " ");
  	  for (s = opcode->args; *s != '\0'; ++s)
  	    {
***************
*** 341,346 ****
--- 341,352 ----
  		  else
  		      fput_fp_reg (GET_FIELD (insn, 27, 31), info);
  		  break;
+ 		case 'e':
+                   if (GET_FIELD (insn, 30, 30))
+ 		      fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
+ 		  else
+ 		      fput_fp_reg (GET_FIELD (insn, 11, 15), info);
+ 		  break;
  		case 'y':
  		  fput_fp_reg (GET_FIELD (insn, 27, 31), info);
  		  break;
***************
*** 387,392 ****
--- 393,412 ----
  		case '5':
  		  fput_const (extract_5_load (insn), info);
  		  break;
+ 		case 'l':
+ 		  {
+ 		    int disp = GET_FIELD (insn, 18, 28) << 2;
+ 		    disp |= GET_FIELD (insn, 31, 31) << 13;
+ 		    fput_const (sign_extend (disp, 14), info);
+ 		    break;
+ 		  }
+ 		case 'L':
+ 		  {
+ 		    int disp = GET_FIELD (insn, 18, 27) << 3;
+ 		    disp |= GET_FIELD (insn, 31, 31) << 13;
+ 		    fput_const (sign_extend (disp, 14), info);
+ 		    break;
+ 		  }
  		case 's':
  		  (*info->fprintf_func) (info->stream,
  					 "sr%d", GET_FIELD (insn, 16, 17));
***************
*** 401,406 ****
--- 421,434 ----
  		case 'C':
  		  (*info->fprintf_func) (info->stream, "%s ",
  				    short_ldst_compl_names[GET_COMPL (insn)]);
+ 		  break;
+ 		case 'q':
+ 		  (*info->fprintf_func) (info->stream, "%s ",
+ 				    short_ldst_compl_names[GET_FIELD (insn, 28, 28) | GET_FIELD (insn, 29, 29)<<1]);
+ 		  break;
+ 		case 'B':
+ 		  (*info->fprintf_func) (info->stream, "%s ",
+ 				    short_ldst_compl_names[1 | GET_FIELD (insn, 29, 29)<<1]);
  		  break;
  		case 'Y':
  		  (*info->fprintf_func) (info->stream, "%s ",

-- 
Jerry Quinn                             Tel: (514) 761-8737
jquinn@nortelnetworks.com               Fax: (514) 761-8505
Speech Recognition Research

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