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.
This commit is contained in:
Paul Brook 2005-08-05 12:28:23 +00:00
parent 9c3c69f2f1
commit e27ec89e51
4 changed files with 165 additions and 69 deletions

View File

@ -1,3 +1,11 @@
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

View File

@ -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);

View File

@ -1,3 +1,9 @@
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.

View File

@ -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
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
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
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