aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorPaul Brook <paul@codesourcery.com>2005-08-05 12:28:23 +0000
committerPaul Brook <paul@codesourcery.com>2005-08-05 12:28:23 +0000
commite27ec89e51e1db97b276d427f8fd3d8abe57631f (patch)
treee7eaafe74dde86f7e89bee72e60335232f857316 /gas
parent9c3c69f2f1d2925a08837d4c18b5e9ffd1aff301 (diff)
downloadgdb-e27ec89e51e1db97b276d427f8fd3d8abe57631f.zip
gdb-e27ec89e51e1db97b276d427f8fd3d8abe57631f.tar.gz
gdb-e27ec89e51e1db97b276d427f8fd3d8abe57631f.tar.bz2
2005-08-05 Paul Brook <paul@codesourcery.com>
gas/ * config/tc-arm.c (current_it_mask, current_cc): New variables. (do_t_add_sub): Use correct encodings inside IT block. (do_t_arit3c): Ditto. (do_t_it): Simplify logic. Set current_it_mask and current_cc. (md_assemble): Verify conditional suffixes agains IT blocks. gas/testsuite/ * gas/arm/thumb32.s: Use correct conditional suffixes inside IT blocks. * gas/arm/thumb2_it.d, gas/arm/thumb2_it.s: New test.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog8
-rw-r--r--gas/config/tc-arm.c100
-rw-r--r--gas/testsuite/ChangeLog6
-rw-r--r--gas/testsuite/gas/arm/thumb32.s122
4 files changed, 166 insertions, 70 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 1329e33..789e035 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,13 @@
2005-08-05 Paul Brook <paul@codesourcery.com>
+ * config/tc-arm.c (current_it_mask, current_cc): New variables.
+ (do_t_add_sub): Use correct encodings inside IT block.
+ (do_t_arit3c): Ditto.
+ (do_t_it): Simplify logic. Set current_it_mask and current_cc.
+ (md_assemble): Verify conditional suffixes agains IT blocks.
+
+2005-08-05 Paul Brook <paul@codesourcery.com>
+
* config/tc-arm.c (encode_thumb32_immediate): Only accept shifted
constants.
(encode_thumb32_shifted_operand): Prohibit register shifts.
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 5ef6a41..6a587f3 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -535,6 +535,11 @@ typedef struct literal_pool
/* Pointer to a linked list of literal pools. */
literal_pool * list_of_pools = NULL;
+
+/* State variables for IT block handling. */
+static bfd_boolean current_it_mask = 0;
+static int current_cc;
+
/* Pure syntax. */
@@ -5863,6 +5868,8 @@ do_t_add_sub (void)
{
if (!inst.operands[2].isreg)
{
+ /* ??? Convert large immediates to addw/subw. */
+ /* ??? 16-bit adds with small immediates. */
/* For an immediate, we always generate a 32-bit opcode;
section relaxation will shrink it later if possible. */
inst.instruction = THUMB_OP32 (inst.instruction);
@@ -5877,11 +5884,20 @@ do_t_add_sub (void)
/* See if we can do this with a 16-bit instruction. */
if (!inst.operands[2].shifted && inst.size_req != 4)
{
- if (Rd <= 7 && Rn <= 7 && Rn <= 7
- && (inst.instruction == T_MNEM_adds
- || inst.instruction == T_MNEM_subs))
+ bfd_boolean narrow;
+
+ if (inst.instruction == T_MNEM_adds
+ || inst.instruction == T_MNEM_subs)
+ narrow = (current_it_mask == 0);
+ else
+ narrow = (current_it_mask != 0);
+ if (Rd > 7 || Rs > 7 || Rn > 7)
+ narrow = FALSE;
+
+ if (narrow)
{
- inst.instruction = (inst.instruction == T_MNEM_adds
+ inst.instruction = ((inst.instruction == T_MNEM_adds
+ || inst.instruction == T_MNEM_add)
? T_OPCODE_ADD_R3
: T_OPCODE_SUB_R3);
inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
@@ -6018,10 +6034,22 @@ do_t_arit3 (void)
}
else
{
+ bfd_boolean narrow;
+
/* See if we can do this with a 16-bit instruction. */
- if (THUMB_SETS_FLAGS (inst.instruction)
- && !inst.operands[2].shifted
- && inst.size_req != 4
+ if (THUMB_SETS_FLAGS (inst.instruction))
+ narrow = current_it_mask == 0;
+ else
+ narrow = current_it_mask != 0;
+
+ if (Rd > 7 || Rn > 7 || Rs > 7)
+ narrow = FALSE;
+ if (inst.operands[2].shifted)
+ narrow = FALSE;
+ if (inst.size_req == 4)
+ narrow = FALSE;
+
+ if (narrow
&& Rd == Rs)
{
inst.instruction = THUMB_OP16 (inst.instruction);
@@ -6089,10 +6117,22 @@ do_t_arit3c (void)
}
else
{
+ bfd_boolean narrow;
+
/* See if we can do this with a 16-bit instruction. */
- if (THUMB_SETS_FLAGS (inst.instruction)
- && !inst.operands[2].shifted
- && inst.size_req != 4)
+ if (THUMB_SETS_FLAGS (inst.instruction))
+ narrow = current_it_mask == 0;
+ else
+ narrow = current_it_mask != 0;
+
+ if (Rd > 7 || Rn > 7 || Rs > 7)
+ narrow = FALSE;
+ if (inst.operands[2].shifted)
+ narrow = FALSE;
+ if (inst.size_req == 4)
+ narrow = FALSE;
+
+ if (narrow)
{
if (Rd == Rs)
{
@@ -6363,21 +6403,26 @@ static void
do_t_it (void)
{
unsigned int cond = inst.operands[0].imm;
+
+ current_it_mask = (inst.instruction & 0xf) | 0x10;
+ current_cc = cond;
+
+ /* If the condition is a negative condition, invert the mask. */
if ((cond & 0x1) == 0x0)
{
unsigned int mask = inst.instruction & 0x000f;
- inst.instruction &= 0xfff0;
if ((mask & 0x7) == 0)
/* no conversion needed */;
else if ((mask & 0x3) == 0)
- mask = (~(mask & 0x8) & 0x8) | 0x4;
- else if ((mask & 1) == 0)
- mask = (~(mask & 0xC) & 0xC) | 0x2;
+ mask ^= 0x8;
+ else if ((mask & 0x1) == 0)
+ mask ^= 0xC;
else
- mask = (~(mask & 0xE) & 0xE) | 0x1;
+ mask ^= 0xE;
- inst.instruction |= (mask & 0xF);
+ inst.instruction &= 0xfff0;
+ inst.instruction |= mask;
}
inst.instruction |= cond << 4;
@@ -7687,12 +7732,35 @@ md_assemble (char *str)
return;
}
+ /* Check conditional suffixes. */
+ if (current_it_mask)
+ {
+ int cond;
+ cond = current_cc ^ ((current_it_mask >> 4) & 1) ^ 1;
+ if (cond != inst.cond)
+ {
+ as_bad (_("incorrect condition in IT block"));
+ return;
+ }
+ current_it_mask <<= 1;
+ current_it_mask &= 0x1f;
+ }
+ else if (inst.cond != COND_ALWAYS && opcode->tencode != do_t_branch)
+ {
+ as_bad (_("thumb conditional instrunction not in IT block"));
+ return;
+ }
+
mapping_state (MAP_THUMB);
inst.instruction = opcode->tvalue;
if (!parse_operands (p, opcode->operands))
opcode->tencode ();
+ /* Clear current_it_mask at the end of an IT block. */
+ if (current_it_mask == 0x10)
+ current_it_mask = 0;
+
if (!inst.error)
{
assert (inst.instruction < 0xe800 || inst.instruction > 0xffff);
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index f565aed..0f41a71 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,5 +1,11 @@
2005-08-05 Paul Brook <paul@codesourcery.com>
+ * gas/arm/thumb32.s: Use correct conditional suffixes inside IT
+ blocks.
+ * gas/arm/thumb2_it.d, gas/arm/thumb2_it.s: New test.
+
+2005-08-05 Paul Brook <paul@codesourcery.com>
+
* gas/arm/thumb32.d: Update ldm/stm dests.
* gas/arm/thumb32.s: Ditto.
diff --git a/gas/testsuite/gas/arm/thumb32.s b/gas/testsuite/gas/arm/thumb32.s
index ff01068..be9f95f 100644
--- a/gas/testsuite/gas/arm/thumb32.s
+++ b/gas/testsuite/gas/arm/thumb32.s
@@ -275,62 +275,76 @@ nop_hint:
nop {129}
it:
- .macro itx opc cond n
- \opc \cond
- .rept \n
- nop
- .endr
+ .macro nop1 cond ncond a
+ .ifc \a,t
+ nop\cond
+ .else
+ nop\ncond
+ .endif
+ .endm
+ .macro it0 cond m=
+ it\m \cond
+ nop\cond
+ .endm
+ .macro it1 cond ncond a m=
+ it0 \cond \a\m
+ nop1 \cond \ncond \a
+ .endm
+ .macro it2 cond ncond a b m=
+ it1 \cond \ncond \a \b\m
+ nop1 \cond \ncond \b
+ .endm
+ .macro it3 cond ncond a b c
+ it2 \cond \ncond \a \b \c
+ nop1 \cond \ncond \c
.endm
- itx it eq 1
- itx it ne 1
- itx it cs 1
- itx it hs 1
- itx it cc 1
- itx it ul 1
- itx it lo 1
- itx it mi 1
- itx it pl 1
- itx it vs 1
- itx it vc 1
- itx it hi 1
- itx it ge 1
- itx it lt 1
- itx it gt 1
- itx it le 1
- itx it al 1
-
- itx itt eq 2
- itx ite eq 2
- itx ittt eq 3
- itx itet eq 3
- itx itte eq 3
- itx itee eq 3
- itx itttt eq 4
- itx itett eq 4
- itx ittet eq 4
- itx ittte eq 4
- itx ittee eq 4
- itx itete eq 4
- itx iteet eq 4
- itx iteee eq 4
-
- itx itt ne 2
- itx ite ne 2
- itx ittt ne 3
- itx itet ne 3
- itx itte ne 3
- itx itee ne 3
- itx itttt ne 4
- itx itett ne 4
- itx ittet ne 4
- itx ittte ne 4
- itx ittee ne 4
- itx itete ne 4
- itx iteet ne 4
- itx iteee ne 4
-
- .purgem itx
+ it0 eq
+ it0 ne
+ it0 cs
+ it0 hs
+ it0 cc
+ it0 ul
+ it0 lo
+ it0 mi
+ it0 pl
+ it0 vs
+ it0 vc
+ it0 hi
+ it0 ge
+ it0 lt
+ it0 gt
+ it0 le
+ it0 al
+ it1 eq ne t
+ it1 eq ne e
+ it2 eq ne t t
+ it2 eq ne e t
+ it2 eq ne t e
+ it2 eq ne e e
+ it3 eq ne t t t
+ it3 eq ne e t t
+ it3 eq ne t e t
+ it3 eq ne t t e
+ it3 eq ne t e e
+ it3 eq ne e t e
+ it3 eq ne e e t
+ it3 eq ne e e e
+
+ it1 ne eq t
+ it1 ne eq e
+ it2 ne eq t t
+ it2 ne eq e t
+ it2 ne eq t e
+ it2 ne eq e e
+ it3 ne eq t t t
+ it3 ne eq e t t
+ it3 ne eq t e t
+ it3 ne eq t t e
+ it3 ne eq t e e
+ it3 ne eq e t e
+ it3 ne eq e e t
+ it3 ne eq e e e
ldst:
.macro ls op