summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@nildram.co.uk>2013-08-03 10:49:47 +0000
committerRichard Sandiford <rsandifo@nildram.co.uk>2013-08-03 10:49:47 +0000
commit4725aea56df012271db61cd6f4a00dd0d85c270f (patch)
tree44f15079841f006b2f4d5ce68bc70e09851b662e
parent427ee0f12f5f22b5372d020ad8795033caccea56 (diff)
downloadgdb-4725aea56df012271db61cd6f4a00dd0d85c270f.tar.gz
include/opcode/
* mips.h (mips_pcrel_operand): Inherit from mips_int_operand. (mips_int_operand_min, mips_int_operand_max): New functions. (mips_decode_pcrel_operand): Use mips_decode_int_operand. opcodes/ * mips-formats.h (PCREL): Reorder parameters and update the definition to match new mips_pcrel_operand layout. (JUMP, JALX, BRANCH): Update accordingly. * mips16-opc.c (decode_mips16_operand): Likewise. gas/ * config/tc-mips.c (match_int_operand): Use mips_int_operand_min and mips_int_operand_max. (mips16_immed_operand, mips16_immed_operands, MIPS16_NUM_IMMED): Delete. (mips16_immed_operand, mips16_immed_in_range_p): New functions. (mips16_immed, mips16_extended_frag): Use them. Use mips_int_operand instead of mips16_immed_operand.
-rw-r--r--include/opcode/ChangeLog6
-rw-r--r--include/opcode/mips.h35
-rw-r--r--opcodes/ChangeLog7
-rw-r--r--opcodes/mips-formats.h15
-rw-r--r--opcodes/mips16-opc.c12
5 files changed, 51 insertions, 24 deletions
diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog
index 4ef1fda89ae..9952cf85459 100644
--- a/include/opcode/ChangeLog
+++ b/include/opcode/ChangeLog
@@ -1,3 +1,9 @@
+2013-08-03 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * mips.h (mips_pcrel_operand): Inherit from mips_int_operand.
+ (mips_int_operand_min, mips_int_operand_max): New functions.
+ (mips_decode_pcrel_operand): Use mips_decode_int_operand.
+
2013-08-01 Richard Sandiford <rdsandiford@googlemail.com>
* mips.h (mips_decode_reg_operand): New function.
diff --git a/include/opcode/mips.h b/include/opcode/mips.h
index b299bd8708d..e82e4c293e1 100644
--- a/include/opcode/mips.h
+++ b/include/opcode/mips.h
@@ -537,16 +537,13 @@ struct mips_reg_pair_operand
but the rules for MIPS16 instructions like ADDIUPC are more complicated. */
struct mips_pcrel_operand
{
- struct mips_operand root;
+ /* Encodes the offset. */
+ struct mips_int_operand root;
- /* The low ALIGN_LOG2 bits of the base PC are cleared to give PC'. */
+ /* The low ALIGN_LOG2 bits of the base PC are cleared to give PC',
+ which is then added to the offset encoded by ROOT. */
unsigned int align_log2 : 8;
- /* The operand is shifted left SHIFT places and added to PC'.
- The operand is signed if IS_SIGNED. */
- unsigned int shift : 8;
- unsigned int is_signed : 1;
-
/* If INCLUDE_ISA_BIT, the ISA bit of the original base PC is then
reinstated. This is true for jumps and branches and false for
PC-relative data instructions. */
@@ -604,6 +601,25 @@ mips_decode_int_operand (const struct mips_int_operand *operand,
return uval;
}
+/* Return the maximum value that can be encoded by OPERAND. */
+
+static inline int
+mips_int_operand_max (const struct mips_int_operand *operand)
+{
+ return (operand->max_val + operand->bias) << operand->shift;
+}
+
+/* Return the minimum value that can be encoded by OPERAND. */
+
+static inline int
+mips_int_operand_min (const struct mips_int_operand *operand)
+{
+ unsigned int mask;
+
+ mask = (1 << operand->root.size) - 1;
+ return mips_int_operand_max (operand) - (mask << operand->shift);
+}
+
/* Return the register that OPERAND encodes as UVAL. */
static inline int
@@ -625,10 +641,7 @@ mips_decode_pcrel_operand (const struct mips_pcrel_operand *operand,
bfd_vma addr;
addr = base_pc & -(1 << operand->align_log2);
- if (operand->is_signed)
- addr += mips_signed_operand (&operand->root, uval) * (1 << operand->shift);
- else
- addr += uval << operand->shift;
+ addr += mips_decode_int_operand (&operand->root, uval);
if (operand->include_isa_bit)
addr |= base_pc & 1;
if (operand->flip_isa_bit)
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 0d671055f4b..2b8a9b90dcb 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,10 @@
+2013-08-03 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * mips-formats.h (PCREL): Reorder parameters and update the definition
+ to match new mips_pcrel_operand layout.
+ (JUMP, JALX, BRANCH): Update accordingly.
+ * mips16-opc.c (decode_mips16_operand): Likewise.
+
2013-08-01 Richard Sandiford <rdsandiford@googlemail.com>
* micromips-opc.c (WR_s): Delete.
diff --git a/opcodes/mips-formats.h b/opcodes/mips-formats.h
index c55bb27a033..49a0623da53 100644
--- a/opcodes/mips-formats.h
+++ b/opcodes/mips-formats.h
@@ -91,24 +91,25 @@
return &op.root; \
}
-#define PCREL(SIZE, LSB, ALIGN_LOG2, SHIFT, IS_SIGNED, INCLUDE_ISA_BIT, \
+#define PCREL(SIZE, LSB, IS_SIGNED, SHIFT, ALIGN_LOG2, INCLUDE_ISA_BIT, \
FLIP_ISA_BIT) \
{ \
static const struct mips_pcrel_operand op = { \
- { OP_PCREL, SIZE, LSB }, ALIGN_LOG2, SHIFT, IS_SIGNED, \
- INCLUDE_ISA_BIT, FLIP_ISA_BIT \
+ { { OP_PCREL, SIZE, LSB }, \
+ (1 << ((SIZE) - (IS_SIGNED))) - 1, 0, SHIFT, TRUE }, \
+ ALIGN_LOG2, INCLUDE_ISA_BIT, FLIP_ISA_BIT \
}; \
- return &op.root; \
+ return &op.root.root; \
}
#define JUMP(SIZE, LSB, SHIFT) \
- PCREL (SIZE, LSB, SIZE + SHIFT, SHIFT, FALSE, TRUE, FALSE)
+ PCREL (SIZE, LSB, FALSE, SHIFT, SIZE + SHIFT, TRUE, FALSE)
#define JALX(SIZE, LSB, SHIFT) \
- PCREL (SIZE, LSB, SIZE + SHIFT, SHIFT, FALSE, TRUE, TRUE)
+ PCREL (SIZE, LSB, FALSE, SHIFT, SIZE + SHIFT, TRUE, TRUE)
#define BRANCH(SIZE, LSB, SHIFT) \
- PCREL (SIZE, LSB, 0, SHIFT, TRUE, TRUE, FALSE)
+ PCREL (SIZE, LSB, TRUE, SHIFT, 0, TRUE, FALSE)
#define SPECIAL(SIZE, LSB, TYPE) \
{ \
diff --git a/opcodes/mips16-opc.c b/opcodes/mips16-opc.c
index f3869621a87..9948741d1de 100644
--- a/opcodes/mips16-opc.c
+++ b/opcodes/mips16-opc.c
@@ -86,11 +86,11 @@ decode_mips16_operand (char type, bfd_boolean extended_p)
case '6': SINT (16, 0);
case '8': SINT (16, 0);
- case 'A': PCREL (16, 0, 2, 0, TRUE, FALSE, FALSE);
- case 'B': PCREL (16, 0, 3, 0, TRUE, FALSE, FALSE);
+ case 'A': PCREL (16, 0, TRUE, 0, 2, FALSE, FALSE);
+ case 'B': PCREL (16, 0, TRUE, 0, 3, FALSE, FALSE);
case 'C': SINT (16, 0);
case 'D': SINT (16, 0);
- case 'E': PCREL (16, 0, 2, 0, TRUE, FALSE, FALSE);
+ case 'E': PCREL (16, 0, TRUE, 0, 2, FALSE, FALSE);
case 'H': SINT (16, 0);
case 'K': SINT (16, 0);
case 'U': UINT (16, 0);
@@ -115,11 +115,11 @@ decode_mips16_operand (char type, bfd_boolean extended_p)
case '6': UINT (6, 5);
case '8': UINT (8, 0);
- case 'A': PCREL (8, 0, 2, 2, FALSE, FALSE, FALSE);
- case 'B': PCREL (5, 0, 3, 3, FALSE, FALSE, FALSE);
+ case 'A': PCREL (8, 0, FALSE, 2, 2, FALSE, FALSE);
+ case 'B': PCREL (5, 0, FALSE, 3, 3, FALSE, FALSE);
case 'C': INT_ADJ (8, 0, 255, 3, FALSE); /* (0 .. 255) << 3 */
case 'D': INT_ADJ (5, 0, 31, 3, FALSE); /* (0 .. 31) << 3 */
- case 'E': PCREL (5, 0, 2, 2, FALSE, FALSE, FALSE);
+ case 'E': PCREL (5, 0, FALSE, 2, 2, FALSE, FALSE);
case 'H': INT_ADJ (5, 0, 31, 1, FALSE); /* (0 .. 31) << 1 */
case 'K': INT_ADJ (8, 0, 127, 3, FALSE); /* (-128 .. 127) << 3 */
case 'U': UINT (8, 0);