Patch: Add cmpb to pa2.0 gas

Jerry Quinn jquinn@nortelnetworks.com
Wed Sep 22 13:32:00 GMT 1999


This patch adds cmpb and cmpib.  The only thing unorthodox is that the opcode
mask doesn't start with 0xfc on a couple of table entries.  I don't think it's
a problem, but if you know better, let me know.

Jerry


Wed Sep 22 16:17:24 EDT 1999  Jerry Quinn <jerry.quinn.adv91@alum.dartmouth.org>

    * include/opcode/hppa.h (pa_opcodes):  Add entries for cmpb and cmpib.
    * gas/config/tc-hppa.h (pa_ip):  Implement conditional codes "?N", "?Q".
      Remove unused conditional codes.
    (pa_parse_cmpb_64_cmpltr,pa_parse_cmpib_64_cmpltr):  New.
    * opcodes/hppa-dis.c (print_insn_hppa):  Implement codes "?N", "?Q".


*** orig/include/opcode/hppa.h	Wed Sep 22 11:50:40 1999
--- gas-src/include/opcode/hppa.h	Wed Sep 22 13:29:44 1999
***************
*** 203,214 ****
  
     ?s   compare/subtract conditions
     ?S	64 bit compare/subtract conditions
!    ?t   non-negated compare conditions
!    ?T	negated compare conditions
!    ?r	64 bit non-negated compare conditions
!    ?R	64 bit negated compare conditions
!    ?Q	64 bit compare conditions for CMPIB instruction
!    ?n   compare conditions followed by nullify
  
     ?l   logical conditions
     ?L	64 bit logical conditions
--- 203,212 ----
  
     ?s   compare/subtract conditions
     ?S	64 bit compare/subtract conditions
!    ?t   non-negated compare and branch conditions
!    ?n   32 bit compare and branch conditions followed by nullify
!    ?N   64 bit compare and branch conditions followed by nullify
!    ?Q	64 bit compare and branch conditions for CMPIB instruction
  
     ?l   logical conditions
     ?L	64 bit logical conditions
***************
*** 269,278 ****
--- 267,284 ----
  { "b",		0xe8000000, 0xfc00e000, "lnW,b", pa10, FLAG_STRICT},
  { "b",		0xe8000000, 0xffe0e000, "nW", pa10}, /* bl foo,r0 */
  { "ldi",	0x34000000, 0xffe0c000, "j,x", pa10},	/* ldo val(r0),r */
+ 
+ { "cmpib", 	0xec000000, 0xfc000000, "?Qn5,b,w", pa20, FLAG_STRICT},
+ { "cmpib", 	0x84000000, 0xf4000000, "?rn5,b,w", pa10, FLAG_STRICT},
+ 
  { "comib", 	0x84000000, 0xfc000000, "?nn5,b,w", pa10}, /* comib{tf}*/
  /* This entry is for the disassembler only.  It will never be used by
     assembler.  */
  { "comib", 	0x8c000000, 0xfc000000, "?nn5,b,w", pa10}, /* comib{tf}*/
+ 
+ { "cmpb",	0x9c000000, 0xdc000000, "?Rnx,b,w", pa20, FLAG_STRICT},
+ { "cmpb",	0x80000000, 0xf4000000, "?rnx,b,w", pa10, FLAG_STRICT},
+ 
  { "comb",	0x80000000, 0xfc000000, "?nnx,b,w", pa10}, /* comb{tf} */
  /* This entry is for the disassembler only.  It will never be used by
     assembler.  */
*** orig/gas/config/tc-hppa.c	Wed Sep 22 15:05:00 1999
--- gas-src/gas/config/tc-hppa.c	Wed Sep 22 15:05:19 1999
***************
*** 495,500 ****
--- 495,502 ----
  static int pa_parse_neg_cmpsub_cmpltr PARAMS ((char **, int));
  static int pa_parse_neg_add_cmpltr PARAMS ((char **, int));
  static int pa_parse_nonneg_add_cmpltr PARAMS ((char **, int));
+ static int pa_parse_cmpb_64_cmpltr PARAMS ((char **));
+ static int pa_parse_cmpib_64_cmpltr PARAMS ((char **));
  static void pa_block PARAMS ((int));
  static void pa_brtab PARAMS ((int));
  static void pa_try PARAMS ((int));
***************
*** 2449,2472 ****
  		      }
  		    INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
  
! 		  /* Handle a negated compare condition.  */
! 		  case 'T':
! 		    abort ();
!   
! 		  /* Handle a 64 bit non-negated compare condition.  */
! 		  case 'r':
! 		    abort ();
!   
! 		  /* Handle a 64 bit negated compare condition.  */
! 		  case 'R':
! 		    abort ();
!   
! 		  /* Handle a 64 bit cmpib condition.  */
! 		  case 'Q':
! 		    abort ();
!   
! 		  /* Handle a negated or non-negated compare/subtract
! 		     condition.  */
  		  case 'n':
  		    save_s = s;
  		    cmpltr = pa_parse_nonneg_cmpsub_cmpltr (&s, 1);
--- 2451,2457 ----
  		      }
  		    INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
  
! 		  /* Handle a 32 bit compare and branch condition.  */
  		  case 'n':
  		    save_s = s;
  		    cmpltr = pa_parse_nonneg_cmpsub_cmpltr (&s, 1);
***************
*** 2476,2482 ****
  			cmpltr = pa_parse_neg_cmpsub_cmpltr (&s, 1);
  			if (cmpltr < 0)
  			  {
! 			    as_bad (_("Invalid Compare/Subtract Condition."));
  			    cmpltr = 0;
  			  }
  			else
--- 2461,2467 ----
  			cmpltr = pa_parse_neg_cmpsub_cmpltr (&s, 1);
  			if (cmpltr < 0)
  			  {
! 			    as_bad (_("Invalid Compare and Branch Condition."));
  			    cmpltr = 0;
  			  }
  			else
***************
*** 2488,2493 ****
--- 2473,2505 ----
  	    
  		    INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
  
+ 		  /* Handle a 64 bit compare and branch condition.  */
+ 		  case 'N':
+ 		    cmpltr = pa_parse_cmpb_64_cmpltr (&s);
+ 		    if (cmpltr < 0)
+ 		      {
+ 			as_bad (_("Invalid 64 Bit Compare and Branch Condition."));
+ 			cmpltr = 0;
+ 		      }
+ 		    else
+ 		      {
+ 			/* Negated condition requires an opcode change. */
+ 			opcode |= (cmpltr & 8) << 26;
+ 		      }
+ 	    
+ 		    INSERT_FIELD_AND_CONTINUE (opcode, cmpltr & 7, 13);
+ 
+ 		  /* Handle a 64 bit cmpib condition.  */
+ 		  case 'Q':
+ 		    cmpltr = pa_parse_cmpib_64_cmpltr (&s);
+ 		    if (cmpltr < 0)
+ 		      {
+ 			as_bad (_("Invalid 64 Bit Compare Immediate Branch Condition."));
+ 			cmpltr = 0;
+ 		      }
+ 
+ 		    INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
+ 
  		    /* Handle a logical instruction condition.  */
  		  case 'L':
  		  case 'l':
***************
*** 3714,3720 ****
  	    }
  	  break;
  	}
! 	  
   failed:
        /* Check if the args matched.  */
        if (match == FALSE)
--- 3726,3732 ----
  	    }
  	  break;
  	}
! 
   failed:
        /* Check if the args matched.  */
        if (match == FALSE)
***************
*** 5255,5260 ****
--- 5267,5459 ----
    return cmpltr;
  }
  
+ 
+ /* Parse a 64 bit compare and branch completer returning the number (for
+    encoding in instrutions) of the given completer.
+ 
+    Nonnegated comparisons are returned as 0-7, negated comparisons are
+    returned as 8-15.  */
+ 
+ static int
+ pa_parse_cmpb_64_cmpltr (s)
+      char **s;
+ {
+   int cmpltr;
+   char *name = *s + 1;
+   char c;
+   char *save_s = *s;
+   int nullify = 0;
+ 
+   cmpltr = 0;
+   if (**s == ',')
+     {
+       *s += 1;
+       while (**s != ',' && **s != ' ' && **s != '\t')
+ 	*s += 1;
+       c = **s;
+       **s = 0x00;
+ 
+       if (strcmp (name, "*") == 0)
+ 	{
+ 	  cmpltr = 0;
+ 	}
+       else if (strcmp (name, "*=") == 0)
+ 	{
+ 	  cmpltr = 1;
+ 	}
+       else if (strcmp (name, "*<") == 0)
+ 	{
+ 	  cmpltr = 2;
+ 	}
+       else if (strcmp (name, "*<=") == 0)
+ 	{
+ 	  cmpltr = 3;
+ 	}
+       else if (strcmp (name, "*<<") == 0)
+ 	{
+ 	  cmpltr = 4;
+ 	}
+       else if (strcmp (name, "*<<=") == 0)
+ 	{
+ 	  cmpltr = 5;
+ 	}
+       else if (strcasecmp (name, "*sv") == 0)
+ 	{
+ 	  cmpltr = 6;
+ 	}
+       else if (strcasecmp (name, "*od") == 0)
+ 	{
+ 	  cmpltr = 7;
+ 	}
+       else if (strcasecmp (name, "*tr") == 0)
+ 	{
+ 	  cmpltr = 8;
+ 	}
+       else if (strcmp (name, "*<>") == 0)
+ 	{
+ 	  cmpltr = 9;
+ 	}
+       else if (strcmp (name, "*>=") == 0)
+ 	{
+ 	  cmpltr = 10;
+ 	}
+       else if (strcmp (name, "*>") == 0)
+ 	{
+ 	  cmpltr = 11;
+ 	}
+       else if (strcmp (name, "*>>=") == 0)
+ 	{
+ 	  cmpltr = 12;
+ 	}
+       else if (strcmp (name, "*>>") == 0)
+ 	{
+ 	  cmpltr = 13;
+ 	}
+       else if (strcasecmp (name, "*nsv") == 0)
+ 	{
+ 	  cmpltr = 14;
+ 	}
+       else if (strcasecmp (name, "*ev") == 0)
+ 	{
+ 	  cmpltr = 15;
+ 	}
+       /* If we have something like addb,n then there is no condition
+          completer.  */
+       else if (strcasecmp (name, "n") == 0)
+ 	{
+ 	  cmpltr = 0;
+ 	  nullify = 1;
+ 	}
+       else
+ 	{
+ 	  cmpltr = -1;
+ 	}
+       **s = c;
+     }
+ 
+   /* Reset pointers if this was really a ,n for a branch instruction.  */
+   if (nullify)
+     *s = save_s;
+ 
+ 
+   return cmpltr;
+ }
+ 
+ /* Parse a 64 bit compare immediate and branch completer returning the number
+    (for encoding in instrutions) of the given completer.  */
+ 
+ static int
+ pa_parse_cmpib_64_cmpltr (s)
+      char **s;
+ {
+   int cmpltr;
+   char *name = *s + 1;
+   char c;
+   char *save_s = *s;
+   int nullify = 0;
+ 
+   cmpltr = 0;
+   if (**s == ',')
+     {
+       *s += 1;
+       while (**s != ',' && **s != ' ' && **s != '\t')
+ 	*s += 1;
+       c = **s;
+       **s = 0x00;
+ 
+       if (strcmp (name, "*<<") == 0)
+ 	{
+ 	  cmpltr = 0;
+ 	}
+       else if (strcmp (name, "*=") == 0)
+ 	{
+ 	  cmpltr = 1;
+ 	}
+       else if (strcmp (name, "*<") == 0)
+ 	{
+ 	  cmpltr = 2;
+ 	}
+       else if (strcmp (name, "*<=") == 0)
+ 	{
+ 	  cmpltr = 3;
+ 	}
+       else if (strcmp (name, "*>>=") == 0)
+ 	{
+ 	  cmpltr = 4;
+ 	}
+       else if (strcmp (name, "*<>") == 0)
+ 	{
+ 	  cmpltr = 5;
+ 	}
+       else if (strcasecmp (name, "*>=") == 0)
+ 	{
+ 	  cmpltr = 6;
+ 	}
+       else if (strcasecmp (name, "*>") == 0)
+ 	{
+ 	  cmpltr = 7;
+ 	}
+       /* If we have something like addb,n then there is no condition
+          completer.  */
+       else if (strcasecmp (name, "n") == 0)
+ 	{
+ 	  cmpltr = 0;
+ 	  nullify = 1;
+ 	}
+       else
+ 	{
+ 	  cmpltr = -1;
+ 	}
+       **s = c;
+     }
+ 
+   /* Reset pointers if this was really a ,n for a branch instruction.  */
+   if (nullify)
+     *s = save_s;
+ 
+ 
+   return cmpltr;
+ }
  
  /* Parse a non-negated addition completer returning the number
     (for encoding in instrutions) of the given completer.
*** orig/opcodes/hppa-dis.c	Wed Sep 22 11:50:29 1999
--- gas-src/opcodes/hppa-dis.c	Wed Sep 22 13:29:39 1999
***************
*** 684,708 ****
  			fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18)],
  					info);
  			break;
! 		      case 'T':
  			fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18)
! 							  + 8], info);
! 			break;
! 		      case 'r':
! 			fputs_filtered (compare_cond_64_names[GET_FIELD (insn, 16, 18)],
! 					info);
  			break;
! 		      case 'R':
  			fputs_filtered (compare_cond_64_names[GET_FIELD (insn, 16, 18)
! 							     + 8], info);
  			break;
  		      case 'Q':
  			fputs_filtered (cmpib_cond_64_names[GET_FIELD (insn, 16, 18)],
  					info);
- 			break;
- 		      case 'n':
- 			fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18)
- 					+ GET_FIELD (insn, 4, 4) * 8], info);
  			break;
  		      case '@':
  			fputs_filtered (add_cond_names[GET_FIELD (insn, 16, 18)
--- 684,700 ----
  			fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18)],
  					info);
  			break;
! 		      case 'n':
  			fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18)
! 					+ GET_FIELD (insn, 4, 4) * 8], info);
  			break;
! 		      case 'N':
  			fputs_filtered (compare_cond_64_names[GET_FIELD (insn, 16, 18)
! 					+ GET_FIELD (insn, 2, 2) * 8], info);
  			break;
  		      case 'Q':
  			fputs_filtered (cmpib_cond_64_names[GET_FIELD (insn, 16, 18)],
  					info);
  			break;
  		      case '@':
  			fputs_filtered (add_cond_names[GET_FIELD (insn, 16, 18)



More information about the Binutils mailing list