aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog6
-rw-r--r--gas/config/tc-arm.c125
-rw-r--r--gas/testsuite/ChangeLog5
-rw-r--r--gas/testsuite/gas/arm/thumb2_it.d68
-rw-r--r--gas/testsuite/gas/arm/thumb2_it.s40
5 files changed, 187 insertions, 57 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index f6ca310..a17d651 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,9 @@
+2005-08-15 Paul Brook <paul@codesourcery.com>
+
+ * config/tc-arm.c (do_t_mov_cmp): Fix encoding of i16-bit conditional
+ instructions.
+ (do_t_mvn_tst, do_t_neg, do_t_shift): Ditto.
+
2005-08-15 Daniel Jacobowitz <dan@codesourcery.com>
* config/tc-ppc.c (parse_cpu): Add -me300 support.
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 7cd3db4..fd95edb 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -6696,6 +6696,18 @@ do_t_mov_cmp (void)
{
int r0off = (inst.instruction == T_MNEM_mov
|| inst.instruction == T_MNEM_movs) ? 8 : 16;
+ bfd_boolean narrow;
+ bfd_boolean low_regs;
+
+ low_regs = (inst.operands[0].reg <= 7 && inst.operands[1].reg <= 7);
+ if (current_it_mask)
+ narrow = inst.instruction != T_MNEM_movs;
+ else
+ narrow = inst.instruction != T_MNEM_movs || low_regs;
+ if (inst.size_req == 4
+ || inst.operands[1].shifted)
+ narrow = FALSE;
+
if (!inst.operands[1].isreg)
{
/* For an immediate, we always generate a 32-bit opcode;
@@ -6705,10 +6717,7 @@ do_t_mov_cmp (void)
inst.instruction |= inst.operands[0].reg << r0off;
inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
}
- else if (inst.size_req == 4
- || inst.operands[1].shifted
- || (inst.instruction == T_MNEM_movs
- && (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)))
+ else if (!narrow)
{
inst.instruction = THUMB_OP32 (inst.instruction);
inst.instruction |= inst.operands[0].reg << r0off;
@@ -6733,7 +6742,7 @@ do_t_mov_cmp (void)
break;
case T_MNEM_cmp:
- if (inst.operands[0].reg <= 7 && inst.operands[1].reg <= 7)
+ if (low_regs)
{
inst.instruction = T_OPCODE_CMP_LR;
inst.instruction |= inst.operands[0].reg;
@@ -6801,6 +6810,20 @@ do_t_mvn_tst (void)
{
int r0off = (inst.instruction == T_MNEM_mvn
|| inst.instruction == T_MNEM_mvns) ? 8 : 16;
+ bfd_boolean narrow;
+
+ if (inst.size_req == 4
+ || inst.instruction > 0xffff
+ || inst.operands[1].shifted
+ || inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
+ narrow = FALSE;
+ else if (inst.instruction == T_MNEM_cmn)
+ narrow = TRUE;
+ else if (THUMB_SETS_FLAGS (inst.instruction))
+ narrow = (current_it_mask == 0);
+ else
+ narrow = (current_it_mask != 0);
+
if (!inst.operands[1].isreg)
{
/* For an immediate, we always generate a 32-bit opcode;
@@ -6814,12 +6837,7 @@ do_t_mvn_tst (void)
else
{
/* See if we can do this with a 16-bit instruction. */
- if (inst.instruction < 0xffff
- && THUMB_SETS_FLAGS (inst.instruction)
- && !inst.operands[1].shifted
- && inst.operands[0].reg <= 7
- && inst.operands[1].reg <= 7
- && inst.size_req != 4)
+ if (narrow)
{
inst.instruction = THUMB_OP16 (inst.instruction);
inst.instruction |= inst.operands[0].reg;
@@ -6947,9 +6965,18 @@ do_t_neg (void)
{
if (unified_syntax)
{
- if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7
- || !THUMB_SETS_FLAGS (inst.instruction)
- || inst.size_req == 4)
+ bfd_boolean narrow;
+
+ if (THUMB_SETS_FLAGS (inst.instruction))
+ narrow = (current_it_mask == 0);
+ else
+ narrow = (current_it_mask != 0);
+ if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
+ narrow = FALSE;
+ if (inst.size_req == 4)
+ narrow = FALSE;
+
+ if (!narrow)
{
inst.instruction = THUMB_OP32 (inst.instruction);
inst.instruction |= inst.operands[0].reg << 8;
@@ -7127,12 +7154,38 @@ do_t_shift (void)
if (unified_syntax)
{
- if (inst.operands[0].reg > 7
- || inst.operands[1].reg > 7
- || !THUMB_SETS_FLAGS (inst.instruction)
- || (!inst.operands[2].isreg && inst.instruction == T_MNEM_rors)
- || (inst.operands[2].isreg && inst.operands[1].reg != inst.operands[0].reg)
- || inst.size_req == 4)
+ bfd_boolean narrow;
+ int shift_kind;
+
+ switch (inst.instruction)
+ {
+ case T_MNEM_asr:
+ case T_MNEM_asrs: shift_kind = SHIFT_ASR; break;
+ case T_MNEM_lsl:
+ case T_MNEM_lsls: shift_kind = SHIFT_LSL; break;
+ case T_MNEM_lsr:
+ case T_MNEM_lsrs: shift_kind = SHIFT_LSR; break;
+ case T_MNEM_ror:
+ case T_MNEM_rors: shift_kind = SHIFT_ROR; break;
+ default: abort ();
+ }
+
+ if (THUMB_SETS_FLAGS (inst.instruction))
+ narrow = (current_it_mask == 0);
+ else
+ narrow = (current_it_mask != 0);
+ if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
+ narrow = FALSE;
+ if (!inst.operands[2].isreg && shift_kind == SHIFT_ROR)
+ narrow = FALSE;
+ if (inst.operands[2].isreg
+ && (inst.operands[1].reg != inst.operands[0].reg
+ || inst.operands[2].reg > 7))
+ narrow = FALSE;
+ if (inst.size_req == 4)
+ narrow = FALSE;
+
+ if (!narrow)
{
if (inst.operands[2].isreg)
{
@@ -7144,19 +7197,7 @@ do_t_shift (void)
else
{
inst.operands[1].shifted = 1;
- switch (inst.instruction)
- {
- case T_MNEM_asr:
- case T_MNEM_asrs: inst.operands[1].shift_kind = SHIFT_ASR; break;
- case T_MNEM_lsl:
- case T_MNEM_lsls: inst.operands[1].shift_kind = SHIFT_LSL; break;
- case T_MNEM_lsr:
- case T_MNEM_lsrs: inst.operands[1].shift_kind = SHIFT_LSR; break;
- case T_MNEM_ror:
- case T_MNEM_rors: inst.operands[1].shift_kind = SHIFT_ROR; break;
- default: abort ();
- }
-
+ inst.operands[1].shift_kind = shift_kind;
inst.instruction = THUMB_OP32 (THUMB_SETS_FLAGS (inst.instruction)
? T_MNEM_movs : T_MNEM_mov);
inst.instruction |= inst.operands[0].reg << 8;
@@ -7169,12 +7210,12 @@ do_t_shift (void)
{
if (inst.operands[2].isreg)
{
- switch (inst.instruction)
+ switch (shift_kind)
{
- case T_MNEM_asrs: inst.instruction = T_OPCODE_ASR_R; break;
- case T_MNEM_lsls: inst.instruction = T_OPCODE_LSL_R; break;
- case T_MNEM_lsrs: inst.instruction = T_OPCODE_LSR_R; break;
- case T_MNEM_rors: inst.instruction = T_OPCODE_ROR_R; break;
+ case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_R; break;
+ case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_R; break;
+ case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_R; break;
+ case SHIFT_ROR: inst.instruction = T_OPCODE_ROR_R; break;
default: abort ();
}
@@ -7183,11 +7224,11 @@ do_t_shift (void)
}
else
{
- switch (inst.instruction)
+ switch (shift_kind)
{
- case T_MNEM_asrs: inst.instruction = T_OPCODE_ASR_I; break;
- case T_MNEM_lsls: inst.instruction = T_OPCODE_LSL_I; break;
- case T_MNEM_lsrs: inst.instruction = T_OPCODE_LSR_I; break;
+ case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_I; break;
+ case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_I; break;
+ case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_I; break;
default: abort ();
}
inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 7773f20..d5860c9 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2005-08-15 Paul Brook <paul@codesourcery.com>
+
+ * gas/arm/thumb2_it.s: Add more instruction variants.
+ * gas/arm/thumb2_it.d: Ditto.
+
2005-08-12 Martin Schwidefsky <schwidefsky@de.ibm.com>
* gas/testsuite/gas/s390/s390.exp: Reorganize gas testsuite for s390
diff --git a/gas/testsuite/gas/arm/thumb2_it.d b/gas/testsuite/gas/arm/thumb2_it.d
index 69df815..30a390b 100644
--- a/gas/testsuite/gas/arm/thumb2_it.d
+++ b/gas/testsuite/gas/arm/thumb2_it.d
@@ -1,24 +1,62 @@
# name: Mixed 16 and 32-bit Thumb conditional instructions
# as: -march=armv6kt2
# objdump: -dr --prefix-addresses --show-raw-insn
+# Many of these patterns use "(eq|s)". These should be changed to just "eq"
+# once the disassembler is fixed. Likewise for "(eq)?"
.*: +file format .*arm.*
Disassembly of section .text:
0+000 <[^>]+> bf05 ittet eq
-0+002 <[^>]+> 1880 add.* r0, r0, r2
-0+004 <[^>]+> 4440 add.* r0, r8
-0+006 <[^>]+> 1888 add.* r0, r1, r2
-0+008 <[^>]+> eb11 0002 adds.* r0, r1, r2
-0+00c <[^>]+> 4410 add.* r0, r2
-0+00e <[^>]+> 4440 add.* r0, r8
-0+010 <[^>]+> 1880 adds.* r0, r0, r2
-0+012 <[^>]+> eb10 0008 adds.* r0, r0, r8
-0+016 <[^>]+> 1888 adds.* r0, r1, r2
+0+002 <[^>]+> 1880 add(eq|s) r0, r0, r2
+0+004 <[^>]+> 4440 add(eq)? r0, r8
+0+006 <[^>]+> 1888 add(ne|s) r0, r1, r2
+0+008 <[^>]+> eb11 0002 adds(eq)?.w r0, r1, r2
+0+00c <[^>]+> 4410 add r0, r2
+0+00e <[^>]+> 4440 add r0, r8
+0+010 <[^>]+> 1880 adds r0, r0, r2
+0+012 <[^>]+> eb10 0008 adds.w r0, r0, r8
+0+016 <[^>]+> 1888 adds r0, r1, r2
0+018 <[^>]+> bf0a itet eq
-0+01a <[^>]+> 4310 orr.* r0, r2
-0+01c <[^>]+> ea40 0008 orr.* r0, r0, r8
-0+020 <[^>]+> ea50 0002 orrs.* r0, r0, r2
-0+024 <[^>]+> ea40 0002 orr.* r0, r0, r2
-0+028 <[^>]+> ea40 0008 orr.* r0, r0, r8
-0+02c <[^>]+> 4310 orrs.* r0, r2
+0+01a <[^>]+> 4310 orr(eq|s) r0, r2
+0+01c <[^>]+> ea40 0008 orr(ne)?.w r0, r0, r8
+0+020 <[^>]+> ea50 0002 orrs(eq)?.w r0, r0, r2
+0+024 <[^>]+> ea40 0002 orr.w r0, r0, r2
+0+028 <[^>]+> ea40 0008 orr.w r0, r0, r8
+0+02c <[^>]+> 4310 orrs r0, r2
+0+02e <[^>]+> bf01 itttt eq
+0+030 <[^>]+> 4090 lsl(eq|s) r0, r2
+0+032 <[^>]+> fa00 f008 lsl(eq)?.w r0, r0, r8
+0+036 <[^>]+> fa01 f002 lsl(eq)?.w r0, r1, r2
+0+03a <[^>]+> fa10 f002 lsls(eq)?.w r0, r0, r2
+0+03e <[^>]+> bf02 ittt eq
+0+040 <[^>]+> 0048 lsl(eq|s) r0, r1, #1
+0+042 <[^>]+> ea4f 0048 mov(eq)?.w r0, r8, lsl #1
+0+046 <[^>]+> ea5f 0040 movs(eq)?.w r0, r0, lsl #1
+0+04a <[^>]+> fa00 f002 lsl.w r0, r0, r2
+0+04e <[^>]+> 4090 lsls r0, r2
+0+050 <[^>]+> ea4f 0041 mov.w r0, r1, lsl #1
+0+054 <[^>]+> 0048 lsls r0, r1, #1
+0+056 <[^>]+> bf01 itttt eq
+0+058 <[^>]+> 4288 cmp(eq)? r0, r1
+0+05a <[^>]+> 4540 cmp(eq)? r0, r8
+0+05c <[^>]+> 4608 mov(eq)? r0, r1
+0+05e <[^>]+> ea5f 0001 movs(eq)?.w r0, r1
+0+062 <[^>]+> bf08 it eq
+0+064 <[^>]+> 4640 mov(eq)? r0, r8
+0+066 <[^>]+> 4608 mov(eq)? r0, r1
+0+068 <[^>]+> 1c08 adds r0, r1, #0
+0+06a <[^>]+> ea5f 0008 movs.w r0, r8
+0+06e <[^>]+> bf01 itttt eq
+0+070 <[^>]+> 43c8 mvn(eq|s) r0, r1
+0+072 <[^>]+> ea6f 0008 mvn(eq)?.w r0, r8
+0+076 <[^>]+> ea7f 0001 mvns(eq)?.w r0, r1
+0+07a <[^>]+> 42c8 cmn(eq)? r0, r1
+0+07c <[^>]+> ea6f 0001 mvn.w r0, r1
+0+080 <[^>]+> 43c8 mvns r0, r1
+0+082 <[^>]+> bf02 ittt eq
+0+084 <[^>]+> 4248 neg(eq|s) r0, r1
+0+086 <[^>]+> f1c8 0000 rsb(eq)? r0, r8, #0 ; 0x0
+0+08a <[^>]+> f1d1 0000 rsbs(eq)? r0, r1, #0 ; 0x0
+0+08e <[^>]+> f1c1 0000 rsb r0, r1, #0 ; 0x0
+0+092 <[^>]+> 4248 negs r0, r1
diff --git a/gas/testsuite/gas/arm/thumb2_it.s b/gas/testsuite/gas/arm/thumb2_it.s
index 2b48757..c12abb6 100644
--- a/gas/testsuite/gas/arm/thumb2_it.s
+++ b/gas/testsuite/gas/arm/thumb2_it.s
@@ -22,3 +22,43 @@ foo:
orr r0, r0, r8
orrs r0, r0, r2
+ itttt eq
+ lsleq r0, r0, r2
+ lsleq r0, r0, r8
+ lsleq r0, r1, r2
+ lslseq r0, r0, r2
+ ittt eq
+ lsleq r0, r1, #1
+ lsleq r0, r8, #1
+ lslseq r0, r0, #1
+ lsl r0, r0, r2
+ lsls r0, r0, r2
+ lsl r0, r1, #1
+ lsls r0, r1, #1
+
+ itttt eq
+ cmpeq r0, r1
+ cmpeq r0, r8
+ moveq r0, r1
+ movseq r0, r1
+ it eq
+ moveq r0, r8
+ mov r0, r1
+ movs r0, r1
+ movs r0, r8
+
+ itttt eq
+ mvneq r0, r1
+ mvneq r0, r8
+ mvnseq r0, r1
+ cmneq r0, r1
+ mvn r0, r1
+ mvns r0, r1
+
+ ittt eq
+ negeq r0, r1
+ negeq r0, r8
+ negseq r0, r1
+ neg r0, r1
+ negs r0, r1
+