aboutsummaryrefslogtreecommitdiff
path: root/opcodes
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@imgtec.com>2016-12-23 19:40:09 +0000
committerMaciej W. Rozycki <macro@imgtec.com>2016-12-23 19:42:28 +0000
commitbdd152861ce75c36828904cf3d10f8ce14da6cf5 (patch)
treedf5b28e1503eb0ead27b616c07f1a40a8be31ed4 /opcodes
parent1da43accb4f8e2a19dc033b617982e3c2dc83a08 (diff)
downloadfsf-binutils-gdb-bdd152861ce75c36828904cf3d10f8ce14da6cf5.zip
fsf-binutils-gdb-bdd152861ce75c36828904cf3d10f8ce14da6cf5.tar.gz
fsf-binutils-gdb-bdd152861ce75c36828904cf3d10f8ce14da6cf5.tar.bz2
MIPS16: Simplify extended operand handling
Simplify extended operand handling and only specially process immediates which require bit shuffling, using the generic operand insertion and extraction handlers for the '<' (5-bit shift amount) operand code in particular. Require the least significant bit of all extended operand forms to be (artificially) set to 0 for their special processing to trigger. gas/ * config/tc-mips.c (mips16_immed): Limit `mips16_immed_extend' use to operands whose LSB position is zero. opcodes/ * mips-dis.c (print_mips16_insn_arg): Simplify processing of extended operands. * mips16-opc.c (decode_mips16_operand): Switch the extended form of the `<' operand type to LSB position 22.
Diffstat (limited to 'opcodes')
-rw-r--r--opcodes/ChangeLog7
-rw-r--r--opcodes/mips-dis.c36
-rw-r--r--opcodes/mips16-opc.c2
3 files changed, 25 insertions, 20 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 0df9632..469113f 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,5 +1,12 @@
2016-12-23 Maciej W. Rozycki <macro@imgtec.com>
+ * mips-dis.c (print_mips16_insn_arg): Simplify processing of
+ extended operands.
+ * mips16-opc.c (decode_mips16_operand): Switch the extended
+ form of the `<' operand type to LSB position 22.
+
+2016-12-23 Maciej W. Rozycki <macro@imgtec.com>
+
* mips16-opc.c (decode_mips16_operand): Replace `0' and `4'
operand codes with `.' and `F' respectively.
(mips16_opcodes): Likewise.
diff --git a/opcodes/mips-dis.c b/opcodes/mips-dis.c
index ade5136..a1152cd 100644
--- a/opcodes/mips-dis.c
+++ b/opcodes/mips-dis.c
@@ -1823,6 +1823,7 @@ print_mips16_insn_arg (struct disassemble_info *info,
const fprintf_ftype infprintf = info->fprintf_func;
void *is = info->stream;
const struct mips_operand *operand, *ext_operand;
+ unsigned short ext_size;
unsigned int uval;
bfd_vma baseaddr;
@@ -1927,29 +1928,26 @@ print_mips16_insn_arg (struct disassemble_info *info,
info->data_size = 1 << int_op->shift;
}
- if (operand->size == 26)
- uval = ((extend & 0x1f) << 21) | ((extend & 0x3e0) << 11) | insn;
- else
+ ext_size = 0;
+ if (use_extend)
{
- /* Calculate the full field value. */
- uval = mips_extract_operand (operand, (extend << 16) | insn);
- if (use_extend)
+ ext_operand = decode_mips16_operand (type, TRUE);
+ if (ext_operand != operand)
{
- ext_operand = decode_mips16_operand (type, TRUE);
- if (ext_operand != operand)
- {
- operand = ext_operand;
- if (operand->size == 16)
- uval = (((extend & 0x1f) << 11) | (extend & 0x7e0)
- | (uval & 0x1f));
- else if (operand->size == 15)
- uval |= ((extend & 0xf) << 11) | (extend & 0x7f0);
- else
- uval = ((((extend >> 6) & 0x1f) | (extend & 0x20))
- & ((1U << operand->size) - 1));
- }
+ ext_size = ext_operand->size;
+ operand = ext_operand;
}
}
+ if (operand->size == 26)
+ uval = ((extend & 0x1f) << 21) | ((extend & 0x3e0) << 11) | insn;
+ else if (ext_size == 16)
+ uval = ((extend & 0x1f) << 11) | (extend & 0x7e0) | (insn & 0x1f);
+ else if (ext_size == 15)
+ uval = ((extend & 0xf) << 11) | (extend & 0x7f0) | (insn & 0xf);
+ else if (ext_size == 6)
+ uval = ((extend >> 6) & 0x1f) | (extend & 0x20);
+ else
+ uval = mips_extract_operand (operand, (extend << 16) | insn);
baseaddr = memaddr + 2;
if (operand->type == OP_PCREL)
diff --git a/opcodes/mips16-opc.c b/opcodes/mips16-opc.c
index fb0e0b7..d102b8c 100644
--- a/opcodes/mips16-opc.c
+++ b/opcodes/mips16-opc.c
@@ -77,7 +77,7 @@ decode_mips16_operand (char type, bfd_boolean extended_p)
if (extended_p)
switch (type)
{
- case '<': UINT (5, 0);
+ case '<': UINT (5, 22);
case '[': UINT (6, 0);
case ']': UINT (6, 0);