"", ",*=", ",*<", ",*<=", 0, 0, 0, ",*od",
",*tr", ",*<>", ",*>=", ",*>", 0, 0, 0, ",*ev"};
static const char *const unit_cond_names[] = {
- "", 0, ",sbz", ",shz", ",sdc", 0, ",sbc", ",shc",
- ",tr", 0, ",nbz", ",nhz", ",ndc", 0, ",nbc", ",nhc"
+ "", ",swz", ",sbz", ",shz", ",sdc", ",swc", ",sbc", ",shc",
+ ",tr", ",nwz", ",nbz", ",nhz", ",ndc", ",nwc", ",nbc", ",nhc"
};
static const char *const unit_cond_64_names[] = {
"", ",*swz", ",*sbz", ",*shz", ",*sdc", ",*swc", ",*sbc", ",*shc",
(word & 0x1) << 16, 17) << 2;
}
+static int
+extract_22 (word)
+ unsigned word;
+{
+ return sign_extend (GET_FIELD (word, 19, 28) |
+ GET_FIELD (word, 29, 29) << 10 |
+ GET_FIELD (word, 11, 15) << 11 |
+ GET_FIELD (word, 6, 10) << 16 |
+ (word & 0x1) << 21, 22) << 2;
+}
+
/* Print one instruction. */
int
print_insn_hppa (memaddr, info)
(*info->fprintf_func) (info->stream, "%s", opcode->name);
- if (!strchr ("cfCY?-+nHNZFIu", opcode->args[0]))
+ if (!strchr ("cfCY?-+nHNZFIuv", opcode->args[0]))
(*info->fprintf_func) (info->stream, " ");
for (s = opcode->args; *s != '\0'; ++s)
{
else
fput_fp_reg (GET_FIELD (insn, 6, 10), info);
break;
+
+ /* 'fA' will not generate a space before the regsiter
+ name. Normally that is fine. Except that it
+ causes problems with xmpyu which has no FP format
+ completer. */
+ case 'X':
+ fputs_filtered (" ", info);
+
+ /* FALLTHRU */
+
case 'A':
if (GET_FIELD (insn, 24, 24))
fput_fp_reg_r (GET_FIELD (insn, 6, 10), info);
fput_fp_reg (reg, info);
break;
}
+ case 'e':
+ if (GET_FIELD (insn, 25, 25))
+ fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
+ else
+ fput_fp_reg (GET_FIELD (insn, 11, 15), info);
+ break;
+
}
break;
(*info->fprintf_func) (info->stream, "%s ",
short_bytes_compl_names[GET_COMPL (insn)]);
break;
+ case 'c':
+ case 'C':
+ switch (GET_FIELD (insn, 20, 21))
+ {
+ case 1:
+ (*info->fprintf_func) (info->stream, ",bc ");
+ break;
+ case 2:
+ (*info->fprintf_func) (info->stream, ",sl ");
+ break;
+ default:
+ (*info->fprintf_func) (info->stream, " ");
+ }
+ break;
+ case 'd':
+ switch (GET_FIELD (insn, 20, 21))
+ {
+ case 1:
+ (*info->fprintf_func) (info->stream, ",co ");
+ break;
+ default:
+ (*info->fprintf_func) (info->stream, " ");
+ }
+ break;
+ case 'o':
+ (*info->fprintf_func) (info->stream, ",o");
+ break;
+ case 'g':
+ (*info->fprintf_func) (info->stream, ",gate");
+ break;
+ case 'p':
+ (*info->fprintf_func) (info->stream, ",l,push");
+ break;
+ case 'P':
+ (*info->fprintf_func) (info->stream, ",pop");
+ break;
+ case 'l':
case 'L':
(*info->fprintf_func) (info->stream, ",l");
break;
GET_FIELD (insn, 17, 18), GET_FIELD (insn, 20, 21),
GET_FIELD (insn, 22, 23), GET_FIELD (insn, 24, 25));
break;
+
+ case 'q':
+ {
+ int m, a;
+
+ m = GET_FIELD (insn, 28, 28);
+ a = GET_FIELD (insn, 29, 29);
+
+ if (m && !a)
+ fputs_filtered (",ma ", info);
+ else if (m && a)
+ fputs_filtered (",mb ", info);
+ else
+ fputs_filtered (" ", info);
+ break;
+ }
+
+ case 'J':
+ {
+ int opcode = GET_FIELD (insn, 0, 5);
+
+ if (opcode == 0x16 || opcode == 0x1e)
+ {
+ if (GET_FIELD (insn, 29, 29) == 0)
+ fputs_filtered (",ma ", info);
+ else
+ fputs_filtered (",mb ", info);
+ }
+ else
+ fputs_filtered (" ", info);
+ break;
+ }
+
+ case 'e':
+ {
+ int opcode = GET_FIELD (insn, 0, 5);
+
+ if (opcode == 0x13 || opcode == 0x1b)
+ {
+ if (GET_FIELD (insn, 18, 18) == 1)
+ fputs_filtered (",mb ", info);
+ else
+ fputs_filtered (",ma ", info);
+ }
+ else if (opcode == 0x17 || opcode == 0x1f)
+ {
+ if (GET_FIELD (insn, 31, 31) == 1)
+ fputs_filtered (",ma ", info);
+ else
+ fputs_filtered (",mb ", info);
+ }
+ else
+ fputs_filtered (" ", info);
+
+ break;
+ }
}
break;
fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18)],
info);
break;
- case 'T':
+ case 'n':
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);
+ + GET_FIELD (insn, 4, 4) * 8], info);
break;
- case 'R':
+ case 'N':
fputs_filtered (compare_cond_64_names[GET_FIELD (insn, 16, 18)
- + 8], info);
+ + GET_FIELD (insn, 2, 2) * 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)
+ GET_FIELD (insn, 4, 4) * 8], info);
add_cond_names[GET_FIELD (insn, 16, 18)]);
break;
- case 'D':
- (*info->fprintf_func) (info->stream, "%s",
- add_cond_names[GET_FIELD (insn, 16, 18)
- + 8]);
- break;
- case 'w':
- (*info->fprintf_func)
- (info->stream, "%s",
- wide_add_cond_names[GET_FIELD (insn, 16, 18)]);
- break;
-
case 'W':
(*info->fprintf_func)
(info->stream, "%s",
- wide_add_cond_names[GET_FIELD (insn, 16, 18) + 8]);
+ wide_add_cond_names[GET_FIELD (insn, 16, 18) +
+ GET_FIELD (insn, 4, 4) * 8]);
break;
case 'l':
(*info->fprintf_func) (info->stream, " ");
break;
case 'X':
- (*info->fprintf_func) (info->stream, "%s",
+ (*info->fprintf_func) (info->stream, "%s ",
shift_cond_64_names[GET_FIELD (insn, 16, 18)]);
break;
case 'B':
case 'U':
fput_const (extract_10U_store (insn), info);
break;
+ case 'B':
case 'Q':
fput_const (extract_5Q_store (insn), info);
break;
/* addil %r1 implicit output. */
(*info->fprintf_func) (info->stream, "%%r1");
break;
+
+ case 'Y':
+ /* be,l %sr0,%r31 implicit output. */
+ (*info->fprintf_func) (info->stream, "%%sr0,%%r31");
+ break;
+ case '@':
+ (*info->fprintf_func) (info->stream, "0");
+ break;
+
case '.':
(*info->fprintf_func) (info->stream, "%d",
GET_FIELD (insn, 24, 25));
float_format_names[GET_FIELD
(insn, 20, 20)]);
break;
+
+ case 'J':
+ fput_const (extract_14 (insn), info);
+ break;
+
+ case '#':
+ {
+ int sign = GET_FIELD (insn, 31, 31);
+ int imm10 = GET_FIELD (insn, 18, 27);
+ int disp;
+
+ if (sign)
+ disp = (-1 << 10) | imm10;
+ else
+ disp = imm10;
+
+ disp <<= 3;
+ fput_const (disp, info);
+ break;
+ }
+ case 'K':
+ case 'd':
+ {
+ int sign = GET_FIELD (insn, 31, 31);
+ int imm11 = GET_FIELD (insn, 18, 28);
+ int disp;
+
+ if (sign)
+ disp = (-1 << 11) | imm11;
+ else
+ disp = imm11;
+
+ disp <<= 2;
+ fput_const (disp, info);
+ break;
+ }
+
+ /* ?!? FIXME */
+ case '_':
+ case '{':
+ fputs_filtered ("Disassembler botch.\n", info);
+ break;
+
+ case 'm':
+ {
+ int y = GET_FIELD (insn, 16, 18);
+
+ if (y != 1)
+ fput_const ((y ^ 1) - 1, info);
+ }
+ break;
+
+ case 'h':
+ {
+ int cbit;
+
+ cbit = GET_FIELD (insn, 16, 18);
+
+ if (cbit > 0)
+ (*info->fprintf_func) (info->stream, ",%d", cbit - 1);
+ break;
+ }
+
+ case '=':
+ {
+ int cond = GET_FIELD (insn, 27, 31);
+
+ if (cond == 0)
+ fputs_filtered (" ", info);
+ else if (cond == 1)
+ fputs_filtered ("acc ", info);
+ else if (cond == 2)
+ fputs_filtered ("rej ", info);
+ else if (cond == 5)
+ fputs_filtered ("acc8 ", info);
+ else if (cond == 6)
+ fputs_filtered ("rej8 ", info);
+ else if (cond == 9)
+ fputs_filtered ("acc6 ", info);
+ else if (cond == 13)
+ fputs_filtered ("acc4 ", info);
+ else if (cond == 17)
+ fputs_filtered ("acc2 ", info);
+ break;
+ }
+
+ case 'X':
+ (*info->print_address_func) ((memaddr + 8
+ + extract_22 (insn)),
+ info);
+ break;
+ case 'L':
+ fputs_filtered (",%r2", info);
+ break;
default:
(*info->fprintf_func) (info->stream, "%c", *s);
break;