summaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2000-08-16 19:02:00 +0000
committerNick Clifton <nickc@redhat.com>2000-08-16 19:02:00 +0000
commit8c314ef661ee13adbf08886275bcd382b87c5650 (patch)
tree5cc85160865c564a17711afbcd03b2a52e374bef /gas
parentb6ffca137475f54bdb18f2c2fc6cd5e5e0a2d346 (diff)
downloadbinutils-redhat-8c314ef661ee13adbf08886275bcd382b87c5650.tar.gz
Tidy up decoding of shift based addressing modes.
Add extra tests for these addressing modes
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog17
-rw-r--r--gas/config/tc-arm.c206
-rw-r--r--gas/testsuite/ChangeLog7
-rw-r--r--gas/testsuite/gas/arm/inst.d32
-rw-r--r--gas/testsuite/gas/arm/inst.s34
5 files changed, 208 insertions, 88 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 49bce914e9..f494672e58 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,20 @@
+2000-08-16 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-arm.c (struct asm_shift): Delete.
+ (shift[]): Delete.
+ (enum asm_shift_index): New.
+ (struct asm_shift_properties): New.
+ (struct asm_shift_name): New.
+ (shift_properties[]); New.
+ (shift_names[]); New.
+
+ (decode_shift): Use new structures.
+ Issue a warning is "ROR #0" is used.
+ Issue a warning if "ASR #0" or "LSR #0" is used.
+
+ (md_begin): Initialise arm_shift_hsh table from new
+ asm_shift_name array.
+
2000-08-16 Jakub Jelinek <jakub@redhat.com>
* config/tc-sparc.c: Kill all warnings.
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 5ca0815288..a2ae26f8c5 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -166,28 +166,54 @@ struct arm_it
struct arm_it inst;
-struct asm_shift
+enum asm_shift_index
{
- CONST char * template;
- unsigned long value;
+ SHIFT_LSL = 0,
+ SHIFT_LSR,
+ SHIFT_ASR,
+ SHIFT_ROR,
+ SHIFT_RRX
+};
+
+struct asm_shift_properties
+{
+ enum asm_shift_index index;
+ unsigned long bit_field;
+ unsigned int allows_0 : 1;
+ unsigned int allows_32 : 1;
};
-static CONST struct asm_shift shift[] =
-{
- {"asl", 0},
- {"lsl", 0},
- {"lsr", 0x00000020},
- {"asr", 0x00000040},
- {"ror", 0x00000060},
- {"rrx", 0x00000060},
- {"ASL", 0},
- {"LSL", 0},
- {"LSR", 0x00000020},
- {"ASR", 0x00000040},
- {"ROR", 0x00000060},
- {"RRX", 0x00000060}
+static const struct asm_shift_properties shift_properties [] =
+{
+ { SHIFT_LSL, 0, 1, 0},
+ { SHIFT_LSR, 0x20, 0, 1},
+ { SHIFT_ASR, 0x40, 0, 1},
+ { SHIFT_ROR, 0x60, 0, 0},
+ { SHIFT_RRX, 0x60, 0, 0}
+};
+
+struct asm_shift_name
+{
+ const char * name;
+ const struct asm_shift_properties * properties;
};
+static const struct asm_shift_name shift_names [] =
+{
+ { "asl", shift_properties + SHIFT_LSL },
+ { "lsl", shift_properties + SHIFT_LSL },
+ { "lsr", shift_properties + SHIFT_LSR },
+ { "asr", shift_properties + SHIFT_ASR },
+ { "ror", shift_properties + SHIFT_ROR },
+ { "rrx", shift_properties + SHIFT_RRX },
+ { "ASL", shift_properties + SHIFT_LSL },
+ { "LSL", shift_properties + SHIFT_LSL },
+ { "LSR", shift_properties + SHIFT_LSR },
+ { "ASR", shift_properties + SHIFT_ASR },
+ { "ROR", shift_properties + SHIFT_ROR },
+ { "RRX", shift_properties + SHIFT_RRX }
+};
+
#define NO_SHIFT_RESTRICT 1
#define SHIFT_RESTRICT 0
@@ -2505,7 +2531,7 @@ decode_shift (str, unrestrict)
char ** str;
int unrestrict;
{
- struct asm_shift * shft;
+ struct asm_shift_name * shift;
char * p;
char c;
@@ -2522,83 +2548,87 @@ decode_shift (str, unrestrict)
c = * p;
* p = '\0';
- shft = (struct asm_shift *) hash_find (arm_shift_hsh, * str);
+ shift = (struct asm_shift_name *) hash_find (arm_shift_hsh, * str);
* p = c;
- if (shft)
+
+ if (shift == NULL)
{
- if ( ! strncmp (* str, "rrx", 3)
- || ! strncmp (* str, "RRX", 3))
- {
- * str = p;
- inst.instruction |= shft->value;
- return SUCCESS;
- }
+ inst.error = _("Shift expression expected");
+ return FAIL;
+ }
- skip_whitespace (p);
+ assert (shift->properties->index == shift_properties[shift->properties->index].index);
+
+ if (shift->properties->index == SHIFT_RRX)
+ {
+ * str = p;
+ inst.instruction |= shift->properties->bit_field;
+ return SUCCESS;
+ }
- if (unrestrict && reg_required_here (& p, 8) != FAIL)
- {
- inst.instruction |= shft->value | SHIFT_BY_REG;
- * str = p;
- return SUCCESS;
- }
- else if (is_immediate_prefix (* p))
- {
- inst.error = NULL;
- p ++;
+ skip_whitespace (p);
- if (my_get_expression (& inst.reloc.exp, & p))
- return FAIL;
+ if (unrestrict && reg_required_here (& p, 8) != FAIL)
+ {
+ inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
+ * str = p;
+ return SUCCESS;
+ }
+ else if (! is_immediate_prefix (* p))
+ {
+ inst.error = (unrestrict
+ ? _("shift requires register or #expression")
+ : _("shift requires #expression"));
+ * str = p;
+ return FAIL;
+ }
+
+ inst.error = NULL;
+ p ++;
+
+ if (my_get_expression (& inst.reloc.exp, & p))
+ return FAIL;
+
+ /* Validate some simple #expressions. */
+ if (inst.reloc.exp.X_op == O_constant)
+ {
+ unsigned num = inst.reloc.exp.X_add_number;
- /* Validate some simple #expressions. */
- if (inst.reloc.exp.X_op == O_constant)
+ /* Reject operations greater than 32. */
+ if (num > 32
+ /* Reject a shift of 0 unless the mode allows it. */
+ || (num == 0 && shift->properties->allows_0 == 0)
+ /* Reject a shift of 32 unless the mode allows it. */
+ || (num == 32 && shift->properties->allows_32 == 0)
+ )
+ {
+ /* As a special case we allow ROR #0, but we issue a message
+ reminding the programmer that this is actually an RRX. */
+ if (num == 0 && shift->properties->index == SHIFT_ROR)
+ as_tsktsk (_("ROR #0 is actually RRX"));
+ else
{
- unsigned num = inst.reloc.exp.X_add_number;
-
- /* Reject operations greater than 32, or lsl #32. */
- if (num > 32 || (num == 32 && shft->value == 0))
- {
- inst.error = _("Invalid immediate shift");
- return FAIL;
- }
-
- /* Shifts of zero should be converted to lsl
- (which is zero). */
- if (num == 0)
- {
- * str = p;
- return SUCCESS;
- }
-
- /* Shifts of 32 are encoded as 0, for those shifts that
- support it. */
- if (num == 32)
- num = 0;
-
- inst.instruction |= (num << 7) | shft->value;
- * str = p;
- return SUCCESS;
+ inst.error = _("Invalid immediate shift");
+ return FAIL;
}
-
- inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
- inst.reloc.pc_rel = 0;
- inst.instruction |= shft->value;
-
- * str = p;
- return SUCCESS;
- }
- else
- {
- inst.error = (unrestrict
- ? _("shift requires register or #expression")
- : _("shift requires #expression"));
- * str = p;
- return FAIL;
}
- }
- inst.error = _("Shift expression expected");
- return FAIL;
+ /* Shifts of 32 are encoded as 0, for those shifts that
+ support it. */
+ if (num == 32)
+ num = 0;
+
+ inst.instruction |= (num << 7) | shift->properties->bit_field;
+ }
+ else
+ {
+ inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
+ inst.reloc.pc_rel = 0;
+ inst.instruction |= shift->properties->bit_field;
+ }
+
+ * str = p;
+ return SUCCESS;
}
/* Do those data_ops which can take a negative immediate constant
@@ -5240,8 +5270,8 @@ md_begin ()
hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
- for (i = 0; i < sizeof (shift) / sizeof (struct asm_shift); i++)
- hash_insert (arm_shift_hsh, shift[i].template, (PTR) (shift + i));
+ for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
+ hash_insert (arm_shift_hsh, shift_names[i].name, (PTR) (shift_names + i));
for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
@@ -7388,7 +7418,7 @@ arm_parse_reloc ()
}
reloc_map[] =
{
-#define MAP(str,reloc) { str, sizeof (str)-1, reloc }
+#define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
MAP ("(got)", BFD_RELOC_ARM_GOT32),
MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
/* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index d815495219..4cdeffbfca 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2000-08-16 Nick Clifton <nickc@redhat.com>
+
+ * gas/arm/inst.s: Add tests for edge cases of shift based
+ addressing modes.
+
+ * gas/arm/inst.d: Add expected results for new tests.
+
2000-07-20 Hans-Peter Nilsson <hp@axis.com>
* gas/all/gas.exp: Don't run floating-point tests on CRIS.
diff --git a/gas/testsuite/gas/arm/inst.d b/gas/testsuite/gas/arm/inst.d
index 041f65b788..70fff23805 100644
--- a/gas/testsuite/gas/arm/inst.d
+++ b/gas/testsuite/gas/arm/inst.d
@@ -167,3 +167,35 @@ Disassembly of section .text:
[ ]*268:.*_wibble.*
0000026c <[^>]*> dafffffe ? ble 0000026c <[^>]*>
[ ]*26c:.*testerfunc.*
+00000270 <[^>]*> e1a01102 ? mov r1, r2, lsl #2
+00000274 <[^>]*> e1a01002 ? mov r1, r2
+00000278 <[^>]*> e1a01f82 ? mov r1, r2, lsl #31
+0000027c <[^>]*> e1a01312 ? mov r1, r2, lsl r3
+00000280 <[^>]*> e1a01122 ? mov r1, r2, lsr #2
+00000284 <[^>]*> e1a01fa2 ? mov r1, r2, lsr #31
+00000288 <[^>]*> e1a01022 ? mov r1, r2, lsr #32
+0000028c <[^>]*> e1a01332 ? mov r1, r2, lsr r3
+00000290 <[^>]*> e1a01142 ? mov r1, r2, asr #2
+00000294 <[^>]*> e1a01fc2 ? mov r1, r2, asr #31
+00000298 <[^>]*> e1a01042 ? mov r1, r2, asr #32
+0000029c <[^>]*> e1a01352 ? mov r1, r2, asr r3
+000002a0 <[^>]*> e1a01162 ? mov r1, r2, ror #2
+000002a4 <[^>]*> e1a01fe2 ? mov r1, r2, ror #31
+000002a8 <[^>]*> e1a01372 ? mov r1, r2, ror r3
+000002ac <[^>]*> e1a01062 ? mov r1, r2, rrx
+000002b0 <[^>]*> e1a01102 ? mov r1, r2, lsl #2
+000002b4 <[^>]*> e1a01002 ? mov r1, r2
+000002b8 <[^>]*> e1a01f82 ? mov r1, r2, lsl #31
+000002bc <[^>]*> e1a01312 ? mov r1, r2, lsl r3
+000002c0 <[^>]*> e1a01122 ? mov r1, r2, lsr #2
+000002c4 <[^>]*> e1a01fa2 ? mov r1, r2, lsr #31
+000002c8 <[^>]*> e1a01022 ? mov r1, r2, lsr #32
+000002cc <[^>]*> e1a01332 ? mov r1, r2, lsr r3
+000002d0 <[^>]*> e1a01142 ? mov r1, r2, asr #2
+000002d4 <[^>]*> e1a01fc2 ? mov r1, r2, asr #31
+000002d8 <[^>]*> e1a01042 ? mov r1, r2, asr #32
+000002dc <[^>]*> e1a01352 ? mov r1, r2, asr r3
+000002e0 <[^>]*> e1a01162 ? mov r1, r2, ror #2
+000002e4 <[^>]*> e1a01fe2 ? mov r1, r2, ror #31
+000002e8 <[^>]*> e1a01372 ? mov r1, r2, ror r3
+000002ec <[^>]*> e1a01062 ? mov r1, r2, rrx
diff --git a/gas/testsuite/gas/arm/inst.s b/gas/testsuite/gas/arm/inst.s
index f76bac9e4b..b162cfceca 100644
--- a/gas/testsuite/gas/arm/inst.s
+++ b/gas/testsuite/gas/arm/inst.s
@@ -187,3 +187,37 @@ bar:
blpl hohum
b _wibble
ble testerfunc
+
+ mov r1, r2, lsl #2
+ mov r1, r2, lsl #0
+ mov r1, r2, lsl #31
+ mov r1, r2, lsl r3
+ mov r1, r2, lsr #2
+ mov r1, r2, lsr #31
+ mov r1, r2, lsr #32
+ mov r1, r2, lsr r3
+ mov r1, r2, asr #2
+ mov r1, r2, asr #31
+ mov r1, r2, asr #32
+ mov r1, r2, asr r3
+ mov r1, r2, ror #2
+ mov r1, r2, ror #31
+ mov r1, r2, ror r3
+ mov r1, r2, rrx
+ mov r1, r2, LSL #2
+ mov r1, r2, LSL #0
+ mov r1, r2, LSL #31
+ mov r1, r2, LSL r3
+ mov r1, r2, LSR #2
+ mov r1, r2, LSR #31
+ mov r1, r2, LSR #32
+ mov r1, r2, LSR r3
+ mov r1, r2, ASR #2
+ mov r1, r2, ASR #31
+ mov r1, r2, ASR #32
+ mov r1, r2, ASR r3
+ mov r1, r2, ROR #2
+ mov r1, r2, ROR #31
+ mov r1, r2, ROR r3
+ mov r1, r2, RRX
+ \ No newline at end of file