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