- /* Handle permutation completer. */
- case '*':
- if (*s++ == ',')
- {
- int permloc[4];
- int perm = 0;
- int i = 0;
- permloc[0] = 13;
- permloc[1] = 10;
- permloc[2] = 8;
- permloc[3] = 6;
- for (; i < 4; i++)
- {
- switch (*s++)
- {
- case '0':
- perm = 0;
- break;
- case '1':
- perm = 1;
- break;
- case '2':
- perm = 2;
- break;
- case '3':
- perm = 3;
- break;
- default:
- as_bad(_("Invalid permutation completer"));
- }
- opcode |= perm << permloc[i];
- }
- continue;
- }
- else
- as_bad(_("Invalid permutation completer"));
- break;
-
- default:
- abort ();
- }
- break;
-
- /* Handle all conditions. */
- case '?':
- {
- args++;
- switch (*args)
- {
- /* Handle FP compare conditions. */
- case 'f':
- cond = pa_parse_fp_cmp_cond (&s);
- INSERT_FIELD_AND_CONTINUE (opcode, cond, 0);
-
- /* Handle an add condition. */
- case 'A':
- case 'a':
- cmpltr = 0;
- flag = 0;
- if (*s == ',')
- {
- s++;
-
- /* 64 bit conditions. */
- if (*args == 'A')
- {
- if (*s == '*')
- s++;
- else
- break;
- }
- else if (*s == '*')
- break;
- name = s;
-
- name = s;
- while (*s != ',' && *s != ' ' && *s != '\t')
- s += 1;
- c = *s;
- *s = 0x00;
- if (strcmp (name, "=") == 0)
- cmpltr = 1;
- else if (strcmp (name, "<") == 0)
- cmpltr = 2;
- else if (strcmp (name, "<=") == 0)
- cmpltr = 3;
- else if (strcasecmp (name, "nuv") == 0)
- cmpltr = 4;
- else if (strcasecmp (name, "znv") == 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 = 0;
- flag = 1;
- }
- else if (strcmp (name, "<>") == 0)
- {
- cmpltr = 1;
- flag = 1;
- }
- else if (strcmp (name, ">=") == 0)
- {
- cmpltr = 2;
- flag = 1;
- }
- else if (strcmp (name, ">") == 0)
- {
- cmpltr = 3;
- flag = 1;
- }
- else if (strcasecmp (name, "uv") == 0)
- {
- cmpltr = 4;
- flag = 1;
- }
- else if (strcasecmp (name, "vnz") == 0)
- {
- cmpltr = 5;
- flag = 1;
- }
- else if (strcasecmp (name, "nsv") == 0)
- {
- cmpltr = 6;
- flag = 1;
- }
- else if (strcasecmp (name, "ev") == 0)
- {
- cmpltr = 7;
- flag = 1;
- }
- /* ",*" is a valid condition. */
- else if (*args == 'a')
- as_bad (_("Invalid Add Condition: %s"), name);
- *s = c;
- }
- opcode |= cmpltr << 13;
- INSERT_FIELD_AND_CONTINUE (opcode, flag, 12);
-
- /* Handle non-negated add and branch condition. */
- case 'd':
- cmpltr = pa_parse_nonneg_add_cmpltr (&s, 1);
- if (cmpltr < 0)
- {
- as_bad (_("Invalid Add and Branch Condition: %c"), *s);
- cmpltr = 0;
- }
- INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
-
- /* Handle 64 bit wide-mode add and branch condition. */
- case 'W':
- cmpltr = pa_parse_addb_64_cmpltr (&s);
- if (cmpltr < 0)
- {
- as_bad (_("Invalid Add and Branch Condition: %c"), *s);
- cmpltr = 0;
- }
- else
- {
- /* Negated condition requires an opcode change. */
- opcode |= (cmpltr & 8) << 24;
- }
- INSERT_FIELD_AND_CONTINUE (opcode, cmpltr & 7, 13);
-
- /* Handle a negated or non-negated add and branch
- condition. */
- case '@':
- save_s = s;
- cmpltr = pa_parse_nonneg_add_cmpltr (&s, 1);
- if (cmpltr < 0)
- {
- s = save_s;
- cmpltr = pa_parse_neg_add_cmpltr (&s, 1);
- if (cmpltr < 0)
- {
- as_bad (_("Invalid Compare/Subtract Condition"));
- cmpltr = 0;
- }
- else
- {
- /* Negated condition requires an opcode change. */
- opcode |= 1 << 27;
- }
- }
- INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
-
- /* Handle branch on bit conditions. */
- case 'B':
- case 'b':
- cmpltr = 0;
- if (*s == ',')
- {
- s++;
-
- if (*args == 'B')
- {
- if (*s == '*')
- s++;
- else
- break;
- }
- else if (*s == '*')
- break;
-
- if (strncmp (s, "<", 1) == 0)
- {
- cmpltr = 0;
- s++;
- }
- else if (strncmp (s, ">=", 2) == 0)
- {
- cmpltr = 1;
- s += 2;
- }
- else
- as_bad (_("Invalid Bit Branch Condition: %c"), *s);
- }
- INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 15);
-
- /* Handle a compare/subtract condition. */
- case 'S':
- case 's':
- cmpltr = 0;
- flag = 0;
- if (*s == ',')
- {
- s++;
-
- /* 64 bit conditions. */
- if (*args == 'S')
- {
- if (*s == '*')
- s++;
- else
- break;
- }
- else if (*s == '*')
- break;
- name = s;
-
- name = s;
- while (*s != ',' && *s != ' ' && *s != '\t')
- s += 1;
- c = *s;
- *s = 0x00;
- if (strcmp (name, "=") == 0)
- cmpltr = 1;
- else if (strcmp (name, "<") == 0)
- cmpltr = 2;
- else if (strcmp (name, "<=") == 0)
- cmpltr = 3;
- else if (strcasecmp (name, "<<") == 0)
- cmpltr = 4;
- else if (strcasecmp (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 = 0;
- flag = 1;
- }
- else if (strcmp (name, "<>") == 0)
- {
- cmpltr = 1;
- flag = 1;
- }
- else if (strcmp (name, ">=") == 0)
- {
- cmpltr = 2;
- flag = 1;
- }
- else if (strcmp (name, ">") == 0)
- {
- cmpltr = 3;
- flag = 1;
- }
- else if (strcasecmp (name, ">>=") == 0)
- {
- cmpltr = 4;
- flag = 1;
- }
- else if (strcasecmp (name, ">>") == 0)
- {
- cmpltr = 5;
- flag = 1;
- }
- else if (strcasecmp (name, "nsv") == 0)
- {
- cmpltr = 6;
- flag = 1;
- }
- else if (strcasecmp (name, "ev") == 0)
- {
- cmpltr = 7;
- flag = 1;
- }
- /* ",*" is a valid condition. */
- else if (*args != 'S')
- as_bad (_("Invalid Compare/Subtract Condition: %s"),
- name);
- *s = c;
- }
- opcode |= cmpltr << 13;
- INSERT_FIELD_AND_CONTINUE (opcode, flag, 12);
-
- /* Handle a non-negated compare condition. */
- case 't':
- cmpltr = pa_parse_nonneg_cmpsub_cmpltr (&s, 1);
- if (cmpltr < 0)
- {
- as_bad (_("Invalid Compare/Subtract Condition: %c"), *s);
- cmpltr = 0;
- }
- 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);
- if (cmpltr < 0)
- {
- s = save_s;
- cmpltr = pa_parse_neg_cmpsub_cmpltr (&s, 1);
- if (cmpltr < 0)
- {
- as_bad (_("Invalid Compare and Branch Condition."));
- cmpltr = 0;
- }
- else
- {
- /* Negated condition requires an opcode change. */
- opcode |= 1 << 27;
- }
- }
-
- 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)
- {
- /* Negated condition requires an opcode change. */
- opcode |= (cmpltr & 8) << 26;
- }
- else
- /* Not a 64 bit cond. Give 32 bit a chance. */
- break;
-
- 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)
- /* Not a 64 bit cond. Give 32 bit a chance. */
- break;
-
- INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
-
- /* Handle a logical instruction condition. */
- case 'L':
- case 'l':
- cmpltr = 0;
- flag = 0;
- if (*s == ',')
- {
- s++;
-
- /* 64 bit conditions. */
- if (*args == 'L')
- {
- if (*s == '*')
- s++;
- else
- break;
- }
- else if (*s == '*')
- break;
-
- name = s;
- while (*s != ',' && *s != ' ' && *s != '\t')
- s += 1;
- c = *s;
- *s = 0x00;
-
- if (strcmp (name, "=") == 0)
- cmpltr = 1;
- else if (strcmp (name, "<") == 0)
- cmpltr = 2;
- else if (strcmp (name, "<=") == 0)
- cmpltr = 3;
- else if (strcasecmp (name, "od") == 0)
- cmpltr = 7;
- else if (strcasecmp (name, "tr") == 0)
- {
- cmpltr = 0;
- flag = 1;
- }
- else if (strcmp (name, "<>") == 0)
- {
- cmpltr = 1;
- flag = 1;
- }
- else if (strcmp (name, ">=") == 0)
- {
- cmpltr = 2;
- flag = 1;
- }
- else if (strcmp (name, ">") == 0)
- {
- cmpltr = 3;
- flag = 1;
- }
- else if (strcasecmp (name, "ev") == 0)
- {
- cmpltr = 7;
- flag = 1;
- }
- /* ",*" is a valid condition. */
- else if (*args != 'L')
- as_bad (_("Invalid Logical Instruction Condition."));
- *s = c;
- }
- opcode |= cmpltr << 13;
- INSERT_FIELD_AND_CONTINUE (opcode, flag, 12);
-
- /* Handle a shift/extract/deposit condition. */
- case 'X':
- case 'x':
- case 'y':
- cmpltr = 0;
- if (*s == ',')
- {
- save_s = s++;
-
- /* 64 bit conditions. */
- if (*args == 'X')
- {
- if (*s == '*')
- s++;
- else
- break;
- }
- else if (*s == '*')
- break;
-
- name = s;
- while (*s != ',' && *s != ' ' && *s != '\t')
- s += 1;
- c = *s;
- *s = 0x00;
- if (strcmp (name, "=") == 0)
- cmpltr = 1;
- else if (strcmp (name, "<") == 0)
- cmpltr = 2;
- else if (strcasecmp (name, "od") == 0)
- cmpltr = 3;
- else if (strcasecmp (name, "tr") == 0)
- cmpltr = 4;
- else if (strcmp (name, "<>") == 0)
- cmpltr = 5;
- else if (strcmp (name, ">=") == 0)
- cmpltr = 6;
- else if (strcasecmp (name, "ev") == 0)
- cmpltr = 7;
- /* Handle movb,n. Put things back the way they were.
- This includes moving s back to where it started. */
- else if (strcasecmp (name, "n") == 0 && *args == 'y')
- {
- *s = c;
- s = save_s;
- continue;
- }
- /* ",*" is a valid condition. */
- else if (*args != 'X')
- as_bad (_("Invalid Shift/Extract/Deposit Condition."));
- *s = c;
- }
- INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
-
- /* Handle a unit instruction condition. */
- case 'U':
- case 'u':
- cmpltr = 0;
- flag = 0;
- if (*s == ',')
- {
- s++;
-
- /* 64 bit conditions. */
- if (*args == 'U')
- {
- if (*s == '*')
- s++;
- else
- break;
- }
- else if (*s == '*')
- break;
-
- if (strncasecmp (s, "sbz", 3) == 0)
- {
- cmpltr = 2;
- s += 3;
- }
- else if (strncasecmp (s, "shz", 3) == 0)
- {
- cmpltr = 3;
- s += 3;
- }
- else if (strncasecmp (s, "sdc", 3) == 0)
- {
- cmpltr = 4;
- s += 3;
- }
- else if (strncasecmp (s, "sbc", 3) == 0)
- {
- cmpltr = 6;
- s += 3;
- }
- else if (strncasecmp (s, "shc", 3) == 0)
- {
- cmpltr = 7;
- s += 3;
- }
- else if (strncasecmp (s, "tr", 2) == 0)
- {
- cmpltr = 0;
- flag = 1;
- s += 2;
- }
- else if (strncasecmp (s, "nbz", 3) == 0)
- {
- cmpltr = 2;
- flag = 1;
- s += 3;
- }
- else if (strncasecmp (s, "nhz", 3) == 0)
- {
- cmpltr = 3;
- flag = 1;
- s += 3;
- }
- else if (strncasecmp (s, "ndc", 3) == 0)
- {
- cmpltr = 4;
- flag = 1;
- s += 3;
- }
- else if (strncasecmp (s, "nbc", 3) == 0)
- {
- cmpltr = 6;
- flag = 1;
- s += 3;
- }
- else if (strncasecmp (s, "nhc", 3) == 0)
- {
- cmpltr = 7;
- flag = 1;
- s += 3;
- }
- else if (strncasecmp (s, "swz", 3) == 0)
- {
- cmpltr = 1;
- flag = 0;
- s += 3;
- }
- else if (strncasecmp (s, "swc", 3) == 0)
- {
- cmpltr = 5;
- flag = 0;
- s += 3;
- }
- else if (strncasecmp (s, "nwz", 3) == 0)
- {
- cmpltr = 1;
- flag = 1;
- s += 3;
- }
- else if (strncasecmp (s, "nwc", 3) == 0)
- {
- cmpltr = 5;
- flag = 1;
- s += 3;
- }
- /* ",*" is a valid condition. */
- else if (*args != 'U')
- as_bad (_("Invalid Unit Instruction Condition."));
- }
- opcode |= cmpltr << 13;
- INSERT_FIELD_AND_CONTINUE (opcode, flag, 12);
-
- default:
- abort ();
- }
- break;
- }