diff options
author | Maciej W. Rozycki <macro@imgtec.com> | 2016-12-23 19:40:09 +0000 |
---|---|---|
committer | Maciej W. Rozycki <macro@imgtec.com> | 2016-12-23 19:42:28 +0000 |
commit | bdd152861ce75c36828904cf3d10f8ce14da6cf5 (patch) | |
tree | df5b28e1503eb0ead27b616c07f1a40a8be31ed4 | |
parent | 1da43accb4f8e2a19dc033b617982e3c2dc83a08 (diff) | |
download | gdb-bdd152861ce75c36828904cf3d10f8ce14da6cf5.zip gdb-bdd152861ce75c36828904cf3d10f8ce14da6cf5.tar.gz 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.
-rw-r--r-- | gas/ChangeLog | 5 | ||||
-rw-r--r-- | gas/config/tc-mips.c | 2 | ||||
-rw-r--r-- | opcodes/ChangeLog | 7 | ||||
-rw-r--r-- | opcodes/mips-dis.c | 36 | ||||
-rw-r--r-- | opcodes/mips16-opc.c | 2 |
5 files changed, 31 insertions, 21 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 2d0f4b1..3a05d78 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,10 @@ 2016-12-23 Maciej W. Rozycki <macro@imgtec.com> + * config/tc-mips.c (mips16_immed): Limit `mips16_immed_extend' + use to operands whose LSB position is zero. + +2016-12-23 Maciej W. Rozycki <macro@imgtec.com> + * config/tc-mips.c (match_mips16_insn): Don't update `forced_insn_length' or the instruction opcode if an operand requires an extended instruction form, but an unextended one diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index 20e8020..1e7cddc 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -14023,7 +14023,7 @@ mips16_immed (const char *file, unsigned int line, int type, _("operand value out of range for instruction")); } uval = ((unsigned int) val >> operand->shift) - operand->bias; - if (length == 2) + if (length == 2 || operand->root.lsb != 0) *insn = mips_insert_operand (&operand->root, *insn, uval); else *insn |= mips16_immed_extend (uval, operand->root.size); 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); |