|
@@ -172,6 +172,31 @@ static const struct s390_operand s390_operands[];
|
|
|
the instruction may be optional. */
|
|
|
#define S390_OPERAND_OPTIONAL 0x400
|
|
|
|
|
|
+/* QEMU-ADD */
|
|
|
+/* ??? Not quite the format the assembler takes, but easy to implement
|
|
|
+ without recourse to the table generator. */
|
|
|
+#define S390_OPERAND_CCODE 0x800
|
|
|
+
|
|
|
+static const char s390_ccode_name[16][4] = {
|
|
|
+ "n", /* 0000 */
|
|
|
+ "o", /* 0001 */
|
|
|
+ "h", /* 0010 */
|
|
|
+ "nle", /* 0011 */
|
|
|
+ "l", /* 0100 */
|
|
|
+ "nhe", /* 0101 */
|
|
|
+ "lh", /* 0110 */
|
|
|
+ "ne", /* 0111 */
|
|
|
+ "e", /* 1000 */
|
|
|
+ "nlh", /* 1001 */
|
|
|
+ "he", /* 1010 */
|
|
|
+ "nl", /* 1011 */
|
|
|
+ "le", /* 1100 */
|
|
|
+ "nh", /* 1101 */
|
|
|
+ "no", /* 1110 */
|
|
|
+ "a" /* 1111 */
|
|
|
+};
|
|
|
+/* QEMU-END */
|
|
|
+
|
|
|
#endif /* S390_H */
|
|
|
|
|
|
static int init_flag = 0;
|
|
@@ -325,13 +350,16 @@ print_insn_s390 (bfd_vma memaddr, struct disassemble_info *info)
|
|
|
continue;
|
|
|
|
|
|
/* The instruction is valid. */
|
|
|
- if (opcode->operands[0] != 0)
|
|
|
- (*info->fprintf_func) (info->stream, "%s\t", opcode->name);
|
|
|
- else
|
|
|
- (*info->fprintf_func) (info->stream, "%s", opcode->name);
|
|
|
+/* QEMU-MOD */
|
|
|
+ (*info->fprintf_func) (info->stream, "%s", opcode->name);
|
|
|
+
|
|
|
+ if (s390_operands[opcode->operands[0]].flags & S390_OPERAND_CCODE)
|
|
|
+ separator = 0;
|
|
|
+ else
|
|
|
+ separator = '\t';
|
|
|
+/* QEMU-END */
|
|
|
|
|
|
/* Extract the operands. */
|
|
|
- separator = 0;
|
|
|
for (opindex = opcode->operands; *opindex != 0; opindex++)
|
|
|
{
|
|
|
unsigned int value;
|
|
@@ -363,6 +391,15 @@ print_insn_s390 (bfd_vma memaddr, struct disassemble_info *info)
|
|
|
(*info->print_address_func) (memaddr + (int) value, info);
|
|
|
else if (operand->flags & S390_OPERAND_SIGNED)
|
|
|
(*info->fprintf_func) (info->stream, "%i", (int) value);
|
|
|
+/* QEMU-ADD */
|
|
|
+ else if (operand->flags & S390_OPERAND_CCODE)
|
|
|
+ {
|
|
|
+ (*info->fprintf_func) (info->stream, "%s",
|
|
|
+ s390_ccode_name[(int) value]);
|
|
|
+ separator = '\t';
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+/* QEMU-END */
|
|
|
else
|
|
|
(*info->fprintf_func) (info->stream, "%u", value);
|
|
|
|
|
@@ -543,8 +580,16 @@ static const struct s390_operand s390_operands[] =
|
|
|
#define M_16 42 /* 4 bit optional mask starting at 16 */
|
|
|
{ 4, 16, S390_OPERAND_OPTIONAL },
|
|
|
#define RO_28 43 /* optional GPR starting at position 28 */
|
|
|
- { 4, 28, (S390_OPERAND_GPR | S390_OPERAND_OPTIONAL) }
|
|
|
-
|
|
|
+ { 4, 28, (S390_OPERAND_GPR | S390_OPERAND_OPTIONAL) },
|
|
|
+
|
|
|
+/* QEMU-ADD: */
|
|
|
+#define M4_12 44 /* 4-bit condition-code starting at 12 */
|
|
|
+ { 4, 12, S390_OPERAND_CCODE },
|
|
|
+#define M4_32 45 /* 4-bit condition-code starting at 32 */
|
|
|
+ { 4, 32, S390_OPERAND_CCODE },
|
|
|
+#define I8_32 46 /* 8 bit signed value starting at 32 */
|
|
|
+ { 8, 32, S390_OPERAND_SIGNED },
|
|
|
+/* QEMU-END */
|
|
|
};
|
|
|
|
|
|
|
|
@@ -755,6 +800,14 @@ static const struct s390_operand s390_operands[] =
|
|
|
#define MASK_S_RD { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }
|
|
|
#define MASK_SSF_RRDRD { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 }
|
|
|
|
|
|
+/* QEMU-ADD: */
|
|
|
+#define INSTR_RIE_MRRP 6, { M4_32,R_8,R_12,J16_16,0,0 } /* e.g. crj */
|
|
|
+#define MASK_RIE_MRRP { 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff }
|
|
|
+
|
|
|
+#define INSTR_RIE_MRIP 6, { M4_12,R_8,I8_32,J16_16,0,0 } /* e.g. cij */
|
|
|
+#define MASK_RIE_MRIP { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff }
|
|
|
+/* QEMU-END */
|
|
|
+
|
|
|
/* The opcode formats table (blueprints for .insn pseudo mnemonic). */
|
|
|
|
|
|
static const struct s390_opcode s390_opformats[] =
|
|
@@ -1092,6 +1145,10 @@ static const struct s390_opcode s390_opcodes[] =
|
|
|
{ "agfi", OP16(0xc208LL), MASK_RIL_RI, INSTR_RIL_RI, 2, 4},
|
|
|
{ "slfi", OP16(0xc205LL), MASK_RIL_RU, INSTR_RIL_RU, 2, 4},
|
|
|
{ "slgfi", OP16(0xc204LL), MASK_RIL_RU, INSTR_RIL_RU, 2, 4},
|
|
|
+/* QEMU-ADD: */
|
|
|
+ { "msfi", OP16(0xc201ll), MASK_RIL_RI, INSTR_RIL_RI, 3, 6},
|
|
|
+ { "msgfi", OP16(0xc200ll), MASK_RIL_RI, INSTR_RIL_RI, 3, 6},
|
|
|
+/* QEMU-END */
|
|
|
{ "jg", OP16(0xc0f4LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2},
|
|
|
{ "jgno", OP16(0xc0e4LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2},
|
|
|
{ "jgnh", OP16(0xc0d4LL), MASK_RIL_0P, INSTR_RIL_0P, 3, 2},
|
|
@@ -1716,7 +1773,23 @@ static const struct s390_opcode s390_opcodes[] =
|
|
|
{ "pfpo", OP16(0x010aLL), MASK_E, INSTR_E, 2, 5},
|
|
|
{ "sckpf", OP16(0x0107LL), MASK_E, INSTR_E, 3, 0},
|
|
|
{ "upt", OP16(0x0102LL), MASK_E, INSTR_E, 3, 0},
|
|
|
- { "pr", OP16(0x0101LL), MASK_E, INSTR_E, 3, 0}
|
|
|
+ { "pr", OP16(0x0101LL), MASK_E, INSTR_E, 3, 0},
|
|
|
+
|
|
|
+/* QEMU-ADD: */
|
|
|
+ { "crj", OP48(0xec0000000076LL), MASK_RIE_MRRP, INSTR_RIE_MRRP, 3, 6},
|
|
|
+ { "cgrj", OP48(0xec0000000064LL), MASK_RIE_MRRP, INSTR_RIE_MRRP, 3, 6},
|
|
|
+ { "clrj", OP48(0xec0000000077LL), MASK_RIE_MRRP, INSTR_RIE_MRRP, 3, 6},
|
|
|
+ { "clgrj", OP48(0xec0000000065LL), MASK_RIE_MRRP, INSTR_RIE_MRRP, 3, 6},
|
|
|
+
|
|
|
+ { "cij", OP48(0xec000000007eLL), MASK_RIE_MRIP, INSTR_RIE_MRIP, 3, 6},
|
|
|
+ { "cgij", OP48(0xec000000007cLL), MASK_RIE_MRIP, INSTR_RIE_MRIP, 3, 6},
|
|
|
+ { "clij", OP48(0xec000000007fLL), MASK_RIE_MRIP, INSTR_RIE_MRIP, 3, 6},
|
|
|
+ { "clgij", OP48(0xec000000007dLL), MASK_RIE_MRIP, INSTR_RIE_MRIP, 3, 6},
|
|
|
+
|
|
|
+ { "lrl", OP16(0xc40dll), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
|
|
|
+ { "lgrl", OP16(0xc408ll), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
|
|
|
+ { "lgfrl", OP16(0xc40cll), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
|
|
|
+/* QEMU-END */
|
|
|
};
|
|
|
|
|
|
static const int s390_num_opcodes =
|