2006-02-24 Paul Brook <paul@codesourcery.com>

gas/
	* config/arm/tc-arm.c (arm_ext_v6_notm, arm_ext_div, arm_ext_v7,
	arm_ext_v7a, arm_ext_v7r, arm_ext_v7m): New variables.
	(struct asm_barrier_opt): Define.
	(arm_v7m_psr_hsh, arm_barrier_opt_hsh): New variables.
	(parse_psr): Accept V7M psr names.
	(parse_barrier): New function.
	(enum operand_parse_code): Add OP_oBARRIER.
	(parse_operands): Implement OP_oBARRIER.
	(do_barrier): New function.
	(do_dbg, do_pli, do_t_barrier, do_t_dbg, do_t_div): New functions.
	(do_t_cpsi): Add V7M restrictions.
	(do_t_mrs, do_t_msr): Validate V7M variants.
	(md_assemble): Check for NULL variants.
	(v7m_psrs, barrier_opt_names): New tables.
	(insns): Add V7 instructions.  Mark V6 instructions absent from V7M.
	(md_begin): Initialize arm_v7m_psr_hsh and arm_barrier_opt_hsh.
	(arm_cpu_option_table): Add Cortex-M3, R4 and A8.
	(arm_arch_option_table): Add armv7, armv7a, armv7r and armv7m.
	(struct cpu_arch_ver_table): Define.
	(cpu_arch_ver): New.
	(aeabi_set_public_attributes): Use cpu_arch_ver.  Set
	Tag_CPU_arch_profile.
	* doc/c-arm.texi: Document new cpu and arch options.
gas/testsuite/
	* gas/arm/thumb32.d: Fix expected msr and mrs output.
	* gas/arm/arch7.d: New test.
	* gas/arm/arch7.s: New test.
	* gas/arm/arch7m-bad.l: New test.
	* gas/arm/arch7m-bad.d: New test.
	* gas/arm/arch7m-bad.s: New test.
include/opcode/
	* arm.h: Add V7 feature bits.
opcodes/
	* arm-dis.c (arm_opcodes): Add V7 instructions.
	(thumb32_opcodes): Ditto.  Handle V7M MSR/MRS variants.
	(print_arm_address): New function.
	(print_insn_arm): Use it.  Add 'P' and 'U' cases.
	(psr_name): New function.
	(print_insn_thumb32): Add 'U', 'C' and 'D' cases.
This commit is contained in:
Paul Brook 2006-02-24 15:36:36 +00:00
parent 15c46491c2
commit 62b3e31101
14 changed files with 746 additions and 145 deletions

View File

@ -1,3 +1,29 @@
2006-02-24 Paul Brook <paul@codesourcery.com>
* config/arm/tc-arm.c (arm_ext_v6_notm, arm_ext_div, arm_ext_v7,
arm_ext_v7a, arm_ext_v7r, arm_ext_v7m): New variables.
(struct asm_barrier_opt): Define.
(arm_v7m_psr_hsh, arm_barrier_opt_hsh): New variables.
(parse_psr): Accept V7M psr names.
(parse_barrier): New function.
(enum operand_parse_code): Add OP_oBARRIER.
(parse_operands): Implement OP_oBARRIER.
(do_barrier): New function.
(do_dbg, do_pli, do_t_barrier, do_t_dbg, do_t_div): New functions.
(do_t_cpsi): Add V7M restrictions.
(do_t_mrs, do_t_msr): Validate V7M variants.
(md_assemble): Check for NULL variants.
(v7m_psrs, barrier_opt_names): New tables.
(insns): Add V7 instructions. Mark V6 instructions absent from V7M.
(md_begin): Initialize arm_v7m_psr_hsh and arm_barrier_opt_hsh.
(arm_cpu_option_table): Add Cortex-M3, R4 and A8.
(arm_arch_option_table): Add armv7, armv7a, armv7r and armv7m.
(struct cpu_arch_ver_table): Define.
(cpu_arch_ver): New.
(aeabi_set_public_attributes): Use cpu_arch_ver. Set
Tag_CPU_arch_profile.
* doc/c-arm.texi: Document new cpu and arch options.
2006-02-23 H.J. Lu <hongjiu.lu@intel.com>
* config/tc-ia64.c (operand_match): Handle IA64_OPND_IMMU5b.

View File

@ -182,6 +182,12 @@ static const arm_feature_set arm_ext_v6 = ARM_FEATURE (ARM_EXT_V6, 0);
static const arm_feature_set arm_ext_v6k = ARM_FEATURE (ARM_EXT_V6K, 0);
static const arm_feature_set arm_ext_v6z = ARM_FEATURE (ARM_EXT_V6Z, 0);
static const arm_feature_set arm_ext_v6t2 = ARM_FEATURE (ARM_EXT_V6T2, 0);
static const arm_feature_set arm_ext_v6_notm = ARM_FEATURE (ARM_EXT_V6_NOTM, 0);
static const arm_feature_set arm_ext_div = ARM_FEATURE (ARM_EXT_DIV, 0);
static const arm_feature_set arm_ext_v7 = ARM_FEATURE (ARM_EXT_V7, 0);
static const arm_feature_set arm_ext_v7a = ARM_FEATURE (ARM_EXT_V7A, 0);
static const arm_feature_set arm_ext_v7r = ARM_FEATURE (ARM_EXT_V7R, 0);
static const arm_feature_set arm_ext_v7m = ARM_FEATURE (ARM_EXT_V7M, 0);
static const arm_feature_set arm_arch_any = ARM_ANY;
static const arm_feature_set arm_arch_full = ARM_FEATURE (-1, -1);
@ -328,6 +334,12 @@ struct asm_psr
unsigned long field;
};
struct asm_barrier_opt
{
const char *template;
unsigned long value;
};
/* The bit that distinguishes CPSR and SPSR. */
#define SPSR_BIT (1 << 22)
@ -561,8 +573,10 @@ static struct hash_control *arm_ops_hsh;
static struct hash_control *arm_cond_hsh;
static struct hash_control *arm_shift_hsh;
static struct hash_control *arm_psr_hsh;
static struct hash_control *arm_v7m_psr_hsh;
static struct hash_control *arm_reg_hsh;
static struct hash_control *arm_reloc_hsh;
static struct hash_control *arm_barrier_opt_hsh;
/* Stuff needed to resolve the label ambiguity
As:
@ -3481,28 +3495,35 @@ parse_psr (char **str)
{
char *p;
unsigned long psr_field;
const struct asm_psr *psr;
char *start;
/* CPSR's and SPSR's can now be lowercase. This is just a convenience
feature for ease of use and backwards compatibility. */
p = *str;
if (*p == 's' || *p == 'S')
if (strncasecmp (p, "SPSR", 4) == 0)
psr_field = SPSR_BIT;
else if (*p == 'c' || *p == 'C')
else if (strncasecmp (p, "CPSR", 4) == 0)
psr_field = 0;
else
goto error;
{
start = p;
do
p++;
while (ISALNUM (*p) || *p == '_');
p++;
if (strncasecmp (p, "PSR", 3) != 0)
goto error;
p += 3;
psr = hash_find_n (arm_v7m_psr_hsh, start, p - start);
if (!psr)
return FAIL;
*str = p;
return psr->field;
}
p += 4;
if (*p == '_')
{
/* A suffix follows. */
const struct asm_psr *psr;
char *start;
p++;
start = p;
@ -3653,6 +3674,26 @@ parse_cond (char **str)
return c->value;
}
/* Parse an option for a barrier instruction. Returns the encoding for the
option, or FAIL. */
static int
parse_barrier (char **str)
{
char *p, *q;
const struct asm_barrier_opt *o;
p = q = *str;
while (ISALPHA (*q))
q++;
o = hash_find_n (arm_barrier_opt_hsh, p, q - p);
if (!o)
return FAIL;
*str = q;
return o->value;
}
/* Parse the operands of a table branch instruction. Similar to a memory
operand. */
static int
@ -3777,6 +3818,7 @@ enum operand_parse_code
OP_oSHar, /* ASR immediate */
OP_oSHllar, /* LSL or ASR immediate */
OP_oROR, /* ROR 0/8/16/24 */
OP_oBARRIER, /* Option argument for a barrier instruction. */
OP_FIRST_OPTIONAL = OP_oI7b
};
@ -3998,6 +4040,7 @@ parse_operands (char *str, const unsigned char *pattern)
case OP_oROR: val = parse_ror (&str); break;
case OP_PSR: val = parse_psr (&str); break;
case OP_COND: val = parse_cond (&str); break;
case OP_oBARRIER:val = parse_barrier (&str); break;
case OP_TB:
po_misc_or_fail (parse_tb (&str));
@ -4065,6 +4108,7 @@ parse_operands (char *str, const unsigned char *pattern)
case OP_oROR:
case OP_PSR:
case OP_COND:
case OP_oBARRIER:
case OP_REGLST:
case OP_VRSLST:
case OP_VRDLST:
@ -4585,6 +4629,20 @@ do_arit (void)
encode_arm_shifter_operand (2);
}
static void
do_barrier (void)
{
if (inst.operands[0].present)
{
constraint ((inst.instruction & 0xf0) != 0x40
&& inst.operands[0].imm != 0xf,
"bad barrier type");
inst.instruction |= inst.operands[0].imm;
}
else
inst.instruction |= 0xf;
}
static void
do_bfc (void)
{
@ -4813,6 +4871,12 @@ do_cpsi (void)
inst.instruction |= inst.operands[1].imm;
}
static void
do_dbg (void)
{
inst.instruction |= inst.operands[0].imm;
}
static void
do_it (void)
{
@ -5184,6 +5248,22 @@ do_pld (void)
encode_arm_addr_mode_2 (0, /*is_t=*/FALSE);
}
/* ARMv7: PLI <addr_mode> */
static void
do_pli (void)
{
constraint (!inst.operands[0].isreg,
_("'[' expected after PLI mnemonic"));
constraint (inst.operands[0].postind,
_("post-indexed expression used in preload instruction"));
constraint (inst.operands[0].writeback,
_("writeback used in preload instruction"));
constraint (!inst.operands[0].preind,
_("unindexed addressing used in preload instruction"));
encode_arm_addr_mode_2 (0, /*is_t=*/FALSE);
inst.instruction &= ~PRE_INDEX;
}
static void
do_push_pop (void)
{
@ -6444,6 +6524,20 @@ do_t_arit3c (void)
}
}
static void
do_t_barrier (void)
{
if (inst.operands[0].present)
{
constraint ((inst.instruction & 0xf0) != 0x40
&& inst.operands[0].imm != 0xf,
"bad barrier type");
inst.instruction |= inst.operands[0].imm;
}
else
inst.instruction |= 0xf;
}
static void
do_t_bfc (void)
{
@ -6618,7 +6712,8 @@ static void
do_t_cpsi (void)
{
if (unified_syntax
&& (inst.operands[1].present || inst.size_req == 4))
&& (inst.operands[1].present || inst.size_req == 4)
&& ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6_notm))
{
unsigned int imod = (inst.instruction & 0x0030) >> 4;
inst.instruction = 0xf3af8000;
@ -6629,7 +6724,11 @@ do_t_cpsi (void)
}
else
{
constraint (inst.operands[1].present,
constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1)
&& (inst.operands[0].imm & 4),
_("selected processor does not support 'A' form "
"of this instruction"));
constraint (inst.operands[1].present || inst.size_req == 4,
_("Thumb does not support the 2-argument "
"form of this instruction"));
inst.instruction |= inst.operands[0].imm;
@ -6664,6 +6763,22 @@ do_t_czb (void)
inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH7;
}
static void
do_t_dbg (void)
{
inst.instruction |= inst.operands[0].imm;
}
static void
do_t_div (void)
{
if (!inst.operands[1].present)
inst.operands[1].reg = inst.operands[0].reg;
inst.instruction |= inst.operands[0].reg << 8;
inst.instruction |= inst.operands[1].reg << 16;
inst.instruction |= inst.operands[2].reg;
}
static void
do_t_hint (void)
{
@ -7211,21 +7326,53 @@ do_t_mvn_tst (void)
static void
do_t_mrs (void)
{
/* mrs only accepts CPSR/SPSR/CPSR_all/SPSR_all. */
constraint ((inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f))
!= (PSR_c|PSR_f),
_("'CPSR' or 'SPSR' expected"));
int flags;
flags = inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f|SPSR_BIT);
if (flags == 0)
{
constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7m),
_("selected processor does not support "
"requested special purpose register"));
}
else
{
constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1),
_("selected processor does not support "
"requested special purpose register %x"));
/* mrs only accepts CPSR/SPSR/CPSR_all/SPSR_all. */
constraint ((flags & ~SPSR_BIT) != (PSR_c|PSR_f),
_("'CPSR' or 'SPSR' expected"));
}
inst.instruction |= inst.operands[0].reg << 8;
inst.instruction |= (inst.operands[1].imm & SPSR_BIT) >> 2;
inst.instruction |= (flags & SPSR_BIT) >> 2;
inst.instruction |= inst.operands[1].imm & 0xff;
}
static void
do_t_msr (void)
{
int flags;
constraint (!inst.operands[1].isreg,
_("Thumb encoding does not support an immediate here"));
inst.instruction |= (inst.operands[0].imm & SPSR_BIT) >> 2;
inst.instruction |= (inst.operands[0].imm & ~SPSR_BIT) >> 8;
flags = inst.operands[0].imm;
if (flags & ~0xff)
{
constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1),
_("selected processor does not support "
"requested special purpose register"));
}
else
{
constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7m),
_("selected processor does not support "
"requested special purpose register"));
flags |= PSR_f;
}
inst.instruction |= (flags & SPSR_BIT) >> 2;
inst.instruction |= (flags & ~SPSR_BIT) >> 8;
inst.instruction |= (flags & 0xff);
inst.instruction |= inst.operands[1].reg << 16;
}
@ -8154,8 +8301,9 @@ md_assemble (char *str)
if (!ARM_CPU_HAS_FEATURE (variant, arm_arch_t2))
ARM_CLEAR_FEATURE (variant, variant, fpu_any_hard);
/* Check that this instruction is supported for this CPU. */
if (thumb_mode == 1
&& !ARM_CPU_HAS_FEATURE (variant, *opcode->tvariant))
if (!opcode->tvariant
|| (thumb_mode == 1
&& !ARM_CPU_HAS_FEATURE (variant, *opcode->tvariant)))
{
as_bad (_("selected processor does not support `%s'"), str);
return;
@ -8220,7 +8368,8 @@ md_assemble (char *str)
else
{
/* Check that this instruction is supported for this CPU. */
if (!ARM_CPU_HAS_FEATURE (cpu_variant, *opcode->avariant))
if (!opcode->avariant ||
!ARM_CPU_HAS_FEATURE (cpu_variant, *opcode->avariant))
{
as_bad (_("selected processor does not support `%s'"), str);
return;
@ -8526,6 +8675,25 @@ static const struct asm_psr psrs[] =
{"cxsf", PSR_c | PSR_x | PSR_s | PSR_f},
};
/* Table of V7M psr names. */
static const struct asm_psr v7m_psrs[] =
{
{"apsr", 0 },
{"iapsr", 1 },
{"eapsr", 2 },
{"psr", 3 },
{"ipsr", 5 },
{"epsr", 6 },
{"iepsr", 7 },
{"msp", 8 },
{"psp", 9 },
{"primask", 16},
{"basepri", 17},
{"basepri_max", 18},
{"faultmask", 19},
{"control", 20}
};
/* Table of all shift-in-operand names. */
static const struct asm_shift_name shift_names [] =
{
@ -8575,6 +8743,14 @@ static const struct asm_cond conds[] =
{"al", 0xe}
};
static struct asm_barrier_opt barrier_opt_names[] =
{
{ "sy", 0xf },
{ "un", 0x7 },
{ "st", 0xe },
{ "unst", 0x6 }
};
/* Table of ARM-format instructions. */
/* Macros for gluing together operand strings. N.B. In all cases
@ -8971,10 +9147,17 @@ static const struct asm_opcode insns[] =
#undef THUMB_VARIANT
#define THUMB_VARIANT &arm_ext_v6t2
TUF(cps, 1020000, f3af8100, 1, (I31b), imm0, imm0),
TCE(ldrex, 1900f9f, e8500f00, 2, (RRnpc, ADDR), ldrex, t_ldrex),
TUF(mcrr2, c400000, fc400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
TUF(mrrc2, c500000, fc500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
TCE(ssat, 6a00010, f3000000, 4, (RRnpc, I32, RRnpc, oSHllar),ssat, t_ssat),
TCE(usat, 6e00010, f3800000, 4, (RRnpc, I31, RRnpc, oSHllar),usat, t_usat),
/* ARM V6 not included in V7M (eg. integer SIMD). */
#undef THUMB_VARIANT
#define THUMB_VARIANT &arm_ext_v6_notm
TUF(cps, 1020000, f3af8100, 1, (I31b), imm0, imm0),
TCE(pkhbt, 6800010, eac00000, 4, (RRnpc, RRnpc, RRnpc, oSHll), pkhbt, t_pkhbt),
TCE(pkhtb, 6800050, eac00020, 4, (RRnpc, RRnpc, RRnpc, oSHar), pkhtb, t_pkhtb),
TCE(qadd16, 6200f10, fa90f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
@ -9052,13 +9235,11 @@ static const struct asm_opcode insns[] =
UF(srsib, 9cd0500, 1, (I31w), srs),
UF(srsda, 84d0500, 1, (I31w), srs),
TUF(srsdb, 94d0500, e800c000, 1, (I31w), srs, srs),
TCE(ssat, 6a00010, f3000000, 4, (RRnpc, I32, RRnpc, oSHllar),ssat, t_ssat),
TCE(ssat16, 6a00f30, f3200000, 3, (RRnpc, I16, RRnpc), ssat16, t_ssat16),
TCE(strex, 1800f90, e8400000, 3, (RRnpc, RRnpc, ADDR), strex, t_strex),
TCE(umaal, 0400090, fbe00060, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal, t_mlal),
TCE(usad8, 780f010, fb70f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
TCE(usada8, 7800010, fb700000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
TCE(usat, 6e00010, f3800000, 4, (RRnpc, I31, RRnpc, oSHllar),usat, t_usat),
TCE(usat16, 6e00f30, f3a00000, 3, (RRnpc, I15, RRnpc), usat16, t_usat16),
#undef ARM_VARIANT
@ -9074,12 +9255,15 @@ static const struct asm_opcode insns[] =
#define THUMB_VARIANT &arm_ext_v6t2
TCE(ldrexb, 1d00f9f, e8d00f4f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
TCE(ldrexh, 1f00f9f, e8d00f5f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
TCE(ldrexd, 1b00f9f, e8d0007f, 3, (RRnpc, oRRnpc, RRnpcb), ldrexd, t_ldrexd),
TCE(strexb, 1c00f90, e8c00f40, 3, (RRnpc, RRnpc, ADDR), strex, rm_rd_rn),
TCE(strexh, 1e00f90, e8c00f50, 3, (RRnpc, RRnpc, ADDR), strex, rm_rd_rn),
TCE(strexd, 1a00f90, e8c00070, 4, (RRnpc, RRnpc, oRRnpc, RRnpcb), strexd, t_strexd),
TUF(clrex, 57ff01f, f3bf8f2f, 0, (), noargs, noargs),
#undef THUMB_VARIANT
#define THUMB_VARIANT &arm_ext_v6_notm
TCE(ldrexd, 1b00f9f, e8d0007f, 3, (RRnpc, oRRnpc, RRnpcb), ldrexd, t_ldrexd),
TCE(strexd, 1a00f90, e8c00070, 4, (RRnpc, RRnpc, oRRnpc, RRnpcb), strexd, t_strexd),
#undef ARM_VARIANT
#define ARM_VARIANT &arm_ext_v6z
TCE(smc, 1600070, f7f08000, 1, (EXPi), smc, t_smc),
@ -9129,6 +9313,23 @@ static const struct asm_opcode insns[] =
TCE(tbb, 0, e8d0f000, 1, (TB), 0, t_tb),
TCE(tbh, 0, e8d0f010, 1, (TB), 0, t_tb),
/* Thumb-2 hardware division instructions (R and M profiles only). */
#undef THUMB_VARIANT
#define THUMB_VARIANT &arm_ext_div
TCE(sdiv, 0, fb90f0f0, 3, (RR, oRR, RR), 0, t_div),
TCE(udiv, 0, fbb0f0f0, 3, (RR, oRR, RR), 0, t_div),
/* ARM V7 instructions. */
#undef ARM_VARIANT
#define ARM_VARIANT &arm_ext_v7
#undef THUMB_VARIANT
#define THUMB_VARIANT &arm_ext_v7
TUF(pli, 450f000, f910f000, 1, (ADDR), pli, t_pld),
TCE(dbg, 320f0f0, f3af80f0, 1, (I15), dbg, t_dbg),
TUF(dmb, 57ff050, f3bf8f50, 1, (oBARRIER), barrier, t_barrier),
TUF(dsb, 57ff040, f3bf8f40, 1, (oBARRIER), barrier, t_barrier),
TUF(isb, 57ff060, f3bf8f60, 1, (oBARRIER), barrier, t_barrier),
#undef ARM_VARIANT
#define ARM_VARIANT &fpu_fpa_ext_v1 /* Core FPA instruction set (V1). */
cCE(wfs, e200110, 1, (RR), rd),
@ -12503,8 +12704,10 @@ md_begin (void)
|| (arm_cond_hsh = hash_new ()) == NULL
|| (arm_shift_hsh = hash_new ()) == NULL
|| (arm_psr_hsh = hash_new ()) == NULL
|| (arm_v7m_psr_hsh = hash_new ()) == NULL
|| (arm_reg_hsh = hash_new ()) == NULL
|| (arm_reloc_hsh = hash_new ()) == NULL)
|| (arm_reloc_hsh = hash_new ()) == NULL
|| (arm_barrier_opt_hsh = hash_new ()) == NULL)
as_fatal (_("virtual memory exhausted"));
for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
@ -12515,8 +12718,15 @@ md_begin (void)
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));
for (i = 0; i < sizeof (v7m_psrs) / sizeof (struct asm_psr); i++)
hash_insert (arm_v7m_psr_hsh, v7m_psrs[i].template, (PTR) (v7m_psrs + i));
for (i = 0; i < sizeof (reg_names) / sizeof (struct reg_entry); i++)
hash_insert (arm_reg_hsh, reg_names[i].name, (PTR) (reg_names + i));
for (i = 0;
i < sizeof (barrier_opt_names) / sizeof (struct asm_barrier_opt);
i++)
hash_insert (arm_barrier_opt_hsh, barrier_opt_names[i].template,
(PTR) (barrier_opt_names + i));
#ifdef OBJ_ELF
for (i = 0; i < sizeof (reloc_names) / sizeof (struct reloc_entry); i++)
hash_insert (arm_reloc_hsh, reloc_names[i].name, (PTR) (reloc_names + i));
@ -13028,6 +13238,9 @@ static const struct arm_cpu_option_table arm_cpus[] =
{"arm1156t2f-s", ARM_ARCH_V6T2, FPU_ARCH_VFP_V2, NULL},
{"arm1176jz-s", ARM_ARCH_V6ZK, FPU_NONE, NULL},
{"arm1176jzf-s", ARM_ARCH_V6ZK, FPU_ARCH_VFP_V2, NULL},
{"cortex-a8", ARM_ARCH_V7A, FPU_ARCH_VFP_V2, NULL},
{"cortex-r4", ARM_ARCH_V7R, FPU_NONE, NULL},
{"cortex-m3", ARM_ARCH_V7M, FPU_NONE, NULL},
/* ??? XSCALE is really an architecture. */
{"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2, NULL},
/* ??? iwmmxt is not a processor. */
@ -13075,6 +13288,10 @@ static const struct arm_arch_option_table arm_archs[] =
{"armv6kt2", ARM_ARCH_V6KT2, FPU_ARCH_VFP},
{"armv6zt2", ARM_ARCH_V6ZT2, FPU_ARCH_VFP},
{"armv6zkt2", ARM_ARCH_V6ZKT2, FPU_ARCH_VFP},
{"armv7", ARM_ARCH_V7, FPU_ARCH_VFP},
{"armv7a", ARM_ARCH_V7A, FPU_ARCH_VFP},
{"armv7r", ARM_ARCH_V7R, FPU_ARCH_VFP},
{"armv7m", ARM_ARCH_V7M, FPU_ARCH_VFP},
{"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP},
{"iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP},
{NULL, ARM_ARCH_NONE, ARM_ARCH_NONE}
@ -13474,37 +13691,56 @@ md_show_usage (FILE * fp)
#ifdef OBJ_ELF
typedef struct
{
int val;
arm_feature_set flags;
} cpu_arch_ver_table;
/* Mapping from CPU features to EABI CPU arch values. Table must be sorted
least features first. */
static const cpu_arch_ver_table cpu_arch_ver[] =
{
{1, ARM_ARCH_V4},
{2, ARM_ARCH_V4T},
{3, ARM_ARCH_V5},
{4, ARM_ARCH_V5TE},
{5, ARM_ARCH_V5TEJ},
{6, ARM_ARCH_V6},
{7, ARM_ARCH_V6Z},
{8, ARM_ARCH_V6K},
{9, ARM_ARCH_V6T2},
{10, ARM_ARCH_V7A},
{10, ARM_ARCH_V7R},
{10, ARM_ARCH_V7M},
{0, ARM_ARCH_NONE}
};
/* Set the public EABI object attributes. */
static void
aeabi_set_public_attributes (void)
{
int arch;
arm_feature_set flags;
arm_feature_set tmp;
const cpu_arch_ver_table *p;
/* Choose the architecture based on the capabilities of the requested cpu
(if any) and/or the instructions actually used. */
ARM_MERGE_FEATURE_SETS (flags, arm_arch_used, thumb_arch_used);
ARM_MERGE_FEATURE_SETS (flags, flags, *mfpu_opt);
ARM_MERGE_FEATURE_SETS (flags, flags, selected_cpu);
if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v6t2))
arch = 8;
else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v6z))
arch = 7;
else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v6k))
arch = 9;
else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v6))
arch = 6;
else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v5e))
arch = 4;
else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v5)
|| ARM_CPU_HAS_FEATURE (flags, arm_ext_v5t))
arch = 3;
else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v4t))
arch = 2;
else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v4))
arch = 1;
else
arch = 0;
tmp = flags;
arch = 0;
for (p = cpu_arch_ver; p->val; p++)
{
if (ARM_CPU_HAS_FEATURE (tmp, p->flags))
{
arch = p->val;
ARM_CLEAR_FEATURE (tmp, tmp, p->flags);
}
}
/* Tag_CPU_name. */
if (selected_cpu_name[0])
@ -13524,6 +13760,13 @@ aeabi_set_public_attributes (void)
}
/* Tag_CPU_arch. */
elf32_arm_add_eabi_attr_int (stdoutput, 6, arch);
/* Tag_CPU_arch_profile. */
if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v7a))
elf32_arm_add_eabi_attr_int (stdoutput, 7, 'A');
else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v7r))
elf32_arm_add_eabi_attr_int (stdoutput, 7, 'R');
else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v7m))
elf32_arm_add_eabi_attr_int (stdoutput, 7, 'M');
/* Tag_ARM_ISA_use. */
if (ARM_CPU_HAS_FEATURE (arm_arch_used, arm_arch_full))
elf32_arm_add_eabi_attr_int (stdoutput, 8, 1);

View File

@ -107,6 +107,9 @@ recognized:
@code{arm1176jzf-s},
@code{mpcore},
@code{mpcorenovfp},
@code{cortex-a8},
@code{cortex-r4},
@code{cortex-m3},
@code{ep9312} (ARM920 with Cirrus Maverick coprocessor),
@code{i80200} (Intel XScale processor)
@code{iwmmxt} (Intel(r) XScale processor with Wireless MMX(tm) technology coprocessor)
@ -151,6 +154,10 @@ names are recognized:
@code{armv6k},
@code{armv6z},
@code{armv6zk},
@code{armv7},
@code{armv7a},
@code{armv7r},
@code{armv7m},
@code{iwmmxt}
and
@code{xscale}.

View File

@ -1,3 +1,12 @@
2006-02-24 Paul Brook <paul@codesourcery.com>
* gas/arm/thumb32.d: Fix expected msr and mrs output.
* gas/arm/arch7.d: New test.
* gas/arm/arch7.s: New test.
* gas/arm/arch7m-bad.l: New test.
* gas/arm/arch7m-bad.d: New test.
* gas/arm/arch7m-bad.s: New test.
2006-02-23 H.J. Lu <hongjiu.lu@intel.com>
* gas/ia64/opc-i.s: Add tests for tf.

View File

@ -0,0 +1,76 @@
#name: ARM V7 instructions
#as: -march=armv7r
#objdump: -dr --prefix-addresses --show-raw-insn
.*: +file format .*arm.*
Disassembly of section .text:
0+000 <[^>]*> f6d6f008 pli \[r6, r8\]
0+004 <[^>]*> f6d9f007 pli \[r9, r7\]
0+008 <[^>]*> f6d0f101 pli \[r0, r1, lsl #2\]
0+00c <[^>]*> f4d5f000 pli \[r5\]
0+010 <[^>]*> f4d5ffff pli \[r5, #4095\]
0+014 <[^>]*> f455ffff pli \[r5, #-4095\]
0+018 <[^>]*> e320f0f0 dbg #0
0+01c <[^>]*> e320f0ff dbg #15
0+020 <[^>]*> f57ff05f dmb sy
0+024 <[^>]*> f57ff05f dmb sy
0+028 <[^>]*> f57ff04f dsb sy
0+02c <[^>]*> f57ff04f dsb sy
0+030 <[^>]*> f57ff047 dsb un
0+034 <[^>]*> f57ff04e dsb st
0+038 <[^>]*> f57ff046 dsb unst
0+03c <[^>]*> f57ff06f isb sy
0+040 <[^>]*> f57ff06f isb sy
0+044 <[^>]*> f916 f008 pli \[r6, r8\]
0+048 <[^>]*> f919 f007 pli \[r9, r7\]
0+04c <[^>]*> f910 f021 pli \[r0, r1, lsl #2\]
0+050 <[^>]*> f995 f000 pli \[r5\]
0+054 <[^>]*> f995 ffff pli \[r5, #4095\]
0+058 <[^>]*> f915 fcff pli \[r5, #-255\]
0+05c <[^>]*> f99f ffff pli \[pc, #4095\] ; 0000105f <[^>]*>
0+060 <[^>]*> f91f ffff pli \[pc, #-4095\] ; fffff065 <[^>]*>
0+064 <[^>]*> f3af 80f0 dbg #0
0+068 <[^>]*> f3af 80ff dbg #15
0+06c <[^>]*> f3bf 8f5f dmb sy
0+070 <[^>]*> f3bf 8f5f dmb sy
0+074 <[^>]*> f3bf 8f4f dsb sy
0+078 <[^>]*> f3bf 8f4f dsb sy
0+07c <[^>]*> f3bf 8f47 dsb un
0+080 <[^>]*> f3bf 8f4e dsb st
0+084 <[^>]*> f3bf 8f46 dsb unst
0+088 <[^>]*> f3bf 8f6f isb sy
0+08c <[^>]*> f3bf 8f6f isb sy
0+090 <[^>]*> fb99 f6fc sdiv r6, r9, ip
0+094 <[^>]*> fb96 f9f3 sdiv r9, r6, r3
0+098 <[^>]*> fbb6 f9f3 udiv r9, r6, r3
0+09c <[^>]*> fbb9 f6fc udiv r6, r9, ip
# V7M APSR has the same encoding as V7A CPSR_f
0+0a0 <[^>]*> f3ef 8000 mrs r0, (CPSR|APSR)
0+0a4 <[^>]*> f3ef 8001 mrs r0, IAPSR
0+0a8 <[^>]*> f3ef 8002 mrs r0, EAPSR
0+0ac <[^>]*> f3ef 8003 mrs r0, PSR
0+0b0 <[^>]*> f3ef 8005 mrs r0, IPSR
0+0b4 <[^>]*> f3ef 8006 mrs r0, EPSR
0+0b8 <[^>]*> f3ef 8007 mrs r0, IEPSR
0+0bc <[^>]*> f3ef 8008 mrs r0, MSP
0+0c0 <[^>]*> f3ef 8009 mrs r0, PSP
0+0c4 <[^>]*> f3ef 8010 mrs r0, PRIMASK
0+0c8 <[^>]*> f3ef 8011 mrs r0, BASEPRI
0+0cc <[^>]*> f3ef 8012 mrs r0, BASEPRI_MASK
0+0d0 <[^>]*> f3ef 8013 mrs r0, FAULTMASK
0+0d4 <[^>]*> f3ef 8014 mrs r0, CONTROL
0+0d8 <[^>]*> f380 8800 msr (CPSR_f|APSR), r0
0+0dc <[^>]*> f380 8801 msr IAPSR, r0
0+0e0 <[^>]*> f380 8802 msr EAPSR, r0
0+0e4 <[^>]*> f380 8803 msr PSR, r0
0+0e8 <[^>]*> f380 8805 msr IPSR, r0
0+0ec <[^>]*> f380 8806 msr EPSR, r0
0+0f0 <[^>]*> f380 8807 msr IEPSR, r0
0+0f4 <[^>]*> f380 8808 msr MSP, r0
0+0f8 <[^>]*> f380 8809 msr PSP, r0
0+0fc <[^>]*> f380 8810 msr PRIMASK, r0
0+100 <[^>]*> f380 8811 msr BASEPRI, r0
0+104 <[^>]*> f380 8812 msr BASEPRI_MASK, r0
0+108 <[^>]*> f380 8813 msr FAULTMASK, r0
0+10c <[^>]*> f380 8814 msr CONTROL, r0

View File

@ -0,0 +1,79 @@
# ARMV7 instructions
.text
.arch armv7r
label1:
pli [r6, r8]
pli [r9, r7]
pli [r0, r1, lsl #2]
pli [r5]
pli [r5, #4095]
pli [r5, #-4095]
dbg #0
dbg #15
dmb
dmb sy
dsb
dsb sy
dsb un
dsb st
dsb unst
isb
isb sy
.thumb
.thumb_func
label2:
pli [r6, r8]
pli [r9, r7]
pli [r0, r1, lsl #2]
pli [r5]
pli [r5, #4095]
pli [r5, #-255]
pli [pc, #4095]
pli [pc, #-4095]
dbg #0
dbg #15
dmb
dmb sy
dsb
dsb sy
dsb un
dsb st
dsb unst
isb
isb sy
sdiv r6, r9, r12
sdiv r9, r6, r3
udiv r9, r6, r3
udiv r6, r9, r12
.arch armv7m
mrs r0, apsr
mrs r0, iapsr
mrs r0, eapsr
mrs r0, psr
mrs r0, ipsr
mrs r0, epsr
mrs r0, iepsr
mrs r0, msp
mrs r0, psp
mrs r0, primask
mrs r0, basepri
mrs r0, basepri_max
mrs r0, faultmask
mrs r0, control
msr apsr, r0
msr iapsr, r0
msr eapsr, r0
msr psr, r0
msr ipsr, r0
msr epsr, r0
msr iepsr, r0
msr msp, r0
msr psp, r0
msr primask, r0
msr basepri, r0
msr basepri_max, r0
msr faultmask, r0
msr control, r0

View File

@ -0,0 +1,4 @@
#name: Invalid V7M instructions
#as: -march=armv7m
#error-output: arch7m-bad.l

View File

@ -0,0 +1,5 @@
[^:]*: Assembler messages:
[^:]*:5: Error: selected processor does not support 'A' form of this instruction -- `cpsie a'
[^:]*:6: Error: Thumb does not support the 2-argument form of this instruction -- `cpsie i,#0x10'
[^:]*:7: Error: selected processor does not support `cps #0x10'

View File

@ -0,0 +1,7 @@
.text
.thumb
.thumb_func
label:
cpsie a
cpsie i, #0x10
cps #0x10

View File

@ -631,16 +631,16 @@ Disassembly of section .text:
0[0-9a-f]+ <[^>]+> f240 5000 movw r0, #1280 ; 0x500
0[0-9a-f]+ <[^>]+> f240 0081 movw r0, #129 ; 0x81
0[0-9a-f]+ <[^>]+> f64f 70ff movw r0, #65535 ; 0xffff
0[0-9a-f]+ <[^>]+> f3ef 8000 mrs r0, SPSR
0[0-9a-f]+ <[^>]+> f3ff 8000 mrs r0, CPSR
0[0-9a-f]+ <[^>]+> f3ef 8900 mrs r9, SPSR
0[0-9a-f]+ <[^>]+> f3ff 8900 mrs r9, CPSR
0[0-9a-f]+ <[^>]+> f380 8100 msr SPSR_c, r0
0[0-9a-f]+ <[^>]+> f390 8100 msr CPSR_c, r0
0[0-9a-f]+ <[^>]+> f389 8100 msr SPSR_c, r9
0[0-9a-f]+ <[^>]+> f380 8200 msr SPSR_x, r0
0[0-9a-f]+ <[^>]+> f380 8400 msr SPSR_s, r0
0[0-9a-f]+ <[^>]+> f380 8800 msr SPSR_f, r0
0[0-9a-f]+ <[^>]+> f3ef 8000 mrs r0, CPSR
0[0-9a-f]+ <[^>]+> f3ff 8000 mrs r0, SPSR
0[0-9a-f]+ <[^>]+> f3ef 8900 mrs r9, CPSR
0[0-9a-f]+ <[^>]+> f3ff 8900 mrs r9, SPSR
0[0-9a-f]+ <[^>]+> f380 8100 msr CPSR_c, r0
0[0-9a-f]+ <[^>]+> f390 8100 msr SPSR_c, r0
0[0-9a-f]+ <[^>]+> f389 8100 msr CPSR_c, r9
0[0-9a-f]+ <[^>]+> f380 8200 msr CPSR_x, r0
0[0-9a-f]+ <[^>]+> f380 8400 msr CPSR_s, r0
0[0-9a-f]+ <[^>]+> f380 8800 msr CPSR_f, r0
0[0-9a-f]+ <[^>]+> fb00 f000 mul\.w r0, r0, r0
0[0-9a-f]+ <[^>]+> fb09 f000 mul\.w r0, r9, r0
0[0-9a-f]+ <[^>]+> fb00 f009 mul\.w r0, r0, r9

View File

@ -1,3 +1,7 @@
2006-02-24 Paul Brook <paul@codesourcery.com>
* arm.h: Add V7 feature bits.
2006-02-23 H.J. Lu <hongjiu.lu@intel.com>
* ia64.h (ia64_opnd): Add IA64_OPND_IMMU5b.

View File

@ -35,6 +35,15 @@
#define ARM_EXT_V6K 0x00002000 /* ARM V6K. */
#define ARM_EXT_V6Z 0x00004000 /* ARM V6Z. */
#define ARM_EXT_V6T2 0x00008000 /* Thumb-2. */
#define ARM_EXT_DIV 0x00010000 /* Integer division. */
/* The 'M' in Arm V7M stands for Microcontroller.
On earlier architecture variants it stands for Multiply. */
#define ARM_EXT_V5E_NOTM 0x00020000 /* Arm V5E but not Arm V7M. */
#define ARM_EXT_V6_NOTM 0x00040000 /* Arm V6 but not Arm V7M. */
#define ARM_EXT_V7 0x00080000 /* Arm V7. */
#define ARM_EXT_V7A 0x00100000 /* Arm V7A. */
#define ARM_EXT_V7R 0x00200000 /* Arm V7R. */
#define ARM_EXT_V7M 0x00400000 /* Arm V7M. */
/* Co-processor space extensions. */
#define ARM_CEXT_XSCALE 0x00000001 /* Allow MIA etc. */
@ -75,10 +84,18 @@
#define ARM_AEXT_V6K (ARM_AEXT_V6 | ARM_EXT_V6K)
#define ARM_AEXT_V6Z (ARM_AEXT_V6 | ARM_EXT_V6Z)
#define ARM_AEXT_V6ZK (ARM_AEXT_V6 | ARM_EXT_V6K | ARM_EXT_V6Z)
#define ARM_AEXT_V6T2 (ARM_AEXT_V6 | ARM_EXT_V6T2)
#define ARM_AEXT_V6KT2 (ARM_AEXT_V6 | ARM_EXT_V6T2 | ARM_EXT_V6K)
#define ARM_AEXT_V6ZT2 (ARM_AEXT_V6 | ARM_EXT_V6T2 | ARM_EXT_V6Z)
#define ARM_AEXT_V6ZKT2 (ARM_AEXT_V6 | ARM_EXT_V6T2 | ARM_EXT_V6K | ARM_EXT_V6Z)
#define ARM_AEXT_V6T2 (ARM_AEXT_V6 | ARM_EXT_V6T2 | ARM_EXT_V6_NOTM)
#define ARM_AEXT_V6KT2 (ARM_AEXT_V6T2 | ARM_EXT_V6K)
#define ARM_AEXT_V6ZT2 (ARM_AEXT_V6T2 | ARM_EXT_V6Z)
#define ARM_AEXT_V6ZKT2 (ARM_AEXT_V6T2 | ARM_EXT_V6K | ARM_EXT_V6Z)
#define ARM_AEXT_V7_ARM (ARM_AEXT_V6T2 | ARM_EXT_V7)
#define ARM_AEXT_V7A (ARM_AEXT_V7_ARM | ARM_EXT_V7A)
#define ARM_AEXT_V7R (ARM_AEXT_V7_ARM | ARM_EXT_V7R | ARM_EXT_DIV)
#define ARM_AEXT_NOTM \
(ARM_AEXT_V4 | ARM_EXT_V5ExP | ARM_EXT_V5J | ARM_EXT_V6_NOTM)
#define ARM_AEXT_V7M \
((ARM_AEXT_V7_ARM | ARM_EXT_V7M | ARM_EXT_DIV) & ~(ARM_AEXT_NOTM))
#define ARM_AEXT_V7 (ARM_AEXT_V7A & ARM_AEXT_V7R & ARM_AEXT_V7M)
/* Processors with specific extensions in the co-processor space. */
#define ARM_ARCH_XSCALE ARM_FEATURE (ARM_AEXT_V5TE, ARM_CEXT_XSCALE)
@ -130,13 +147,17 @@
#define ARM_ARCH_V6KT2 ARM_FEATURE (ARM_AEXT_V6KT2, 0)
#define ARM_ARCH_V6ZT2 ARM_FEATURE (ARM_AEXT_V6ZT2, 0)
#define ARM_ARCH_V6ZKT2 ARM_FEATURE (ARM_AEXT_V6ZKT2, 0)
#define ARM_ARCH_V7 ARM_FEATURE (ARM_AEXT_V7, 0)
#define ARM_ARCH_V7A ARM_FEATURE (ARM_AEXT_V7A, 0)
#define ARM_ARCH_V7R ARM_FEATURE (ARM_AEXT_V7R, 0)
#define ARM_ARCH_V7M ARM_FEATURE (ARM_AEXT_V7M, 0)
/* Some useful combinations: */
#define ARM_ARCH_NONE ARM_FEATURE (0, 0)
#define FPU_NONE ARM_FEATURE (0, 0)
#define ARM_ANY ARM_FEATURE (-1, 0) /* Any basic core. */
#define FPU_ANY_HARD ARM_FEATURE (0, FPU_FPA | FPU_VFP_HARD | FPU_MAVERICK)
#define ARM_ARCH_THUMB2 ARM_FEATURE (ARM_EXT_V6T2, 0)
#define ARM_ARCH_THUMB2 ARM_FEATURE (ARM_EXT_V6T2 | ARM_EXT_V7 | ARM_EXT_V7A | ARM_EXT_V7R | ARM_EXT_V7M | ARM_EXT_DIV, 0)
/* There are too many feature bits to fit in a single word, so use a
structure. For simplicity we put all core features in one word and

View File

@ -1,3 +1,12 @@
2006-02-24 Paul Brook <paul@codesourcery.com>
* arm-dis.c (arm_opcodes): Add V7 instructions.
(thumb32_opcodes): Ditto. Handle V7M MSR/MRS variants.
(print_arm_address): New function.
(print_insn_arm): Use it. Add 'P' and 'U' cases.
(psr_name): New function.
(print_insn_thumb32): Add 'U', 'C' and 'D' cases.
2006-02-23 H.J. Lu <hongjiu.lu@intel.com>
* ia64-opc-i.c (bXc): New.

View File

@ -402,6 +402,8 @@ static const struct opcode32 coprocessor_opcodes[] =
%t print 't' iff bit 21 set and bit 24 clear
%B print arm BLX(1) destination
%C print the PSR sub type.
%U print barrier type.
%P print address for pli instruction.
%<bitfield>r print as an ARM register
%<bitfield>d print the bitfield in decimal
@ -428,6 +430,13 @@ static const struct opcode32 arm_opcodes[] =
{ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
{ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
/* V7 instructions. */
{ARM_EXT_V7, 0xf450f000, 0xfd70f000, "pli\t%P"},
{ARM_EXT_V7, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
{ARM_EXT_V7, 0xf57ff050, 0xfffffff0, "dmb\t%U"},
{ARM_EXT_V7, 0xf57ff040, 0xfffffff0, "dsb\t%U"},
{ARM_EXT_V7, 0xf57ff060, 0xfffffff0, "isb\t%U"},
/* ARM V6T2 instructions. */
{ARM_EXT_V6T2, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15r, %E"},
{ARM_EXT_V6T2, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15r, %0-3r, %E"},
@ -827,6 +836,8 @@ static const struct opcode16 thumb_opcodes[] =
%B print an unconditional branch offset
%s print the shift field of an SSAT instruction
%R print the rotation field of an SXT instruction
%U print barrier type.
%P print address for pli instruction.
%<bitfield>d print bitfield in decimal
%<bitfield>W print bitfield*4 in decimal
@ -847,6 +858,15 @@ static const struct opcode16 thumb_opcodes[] =
makes heavy use of special-case bit patterns. */
static const struct opcode32 thumb32_opcodes[] =
{
/* V7 instructions. */
{ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli\t%a"},
{ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg\t#%0-3d"},
{ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb\t%U"},
{ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb\t%U"},
{ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb\t%U"},
{ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv\t%8-11r, %16-19r, %0-3r"},
{ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv\t%8-11r, %16-19r, %0-3r"},
/* Instructions defined in the basic V6T2 set. */
{ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop.w"},
{ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield.w"},
@ -861,14 +881,14 @@ static const struct opcode32 thumb32_opcodes[] =
{ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj\t%16-19r"},
{ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb\t%16-19r%21'!"},
{ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia\t%16-19r%21'!"},
{ARM_EXT_V6T2, 0xf3ef8000, 0xffeff0ff, "mrs\t%8-11r, %20?CSPSR"},
{ARM_EXT_V6T2, 0xf3ef8000, 0xffeff000, "mrs\t%8-11r, %D"},
{ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d"},
{ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb\t[%16-19r, %0-3r]"},
{ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh\t[%16-19r, %0-3r, lsl #1]"},
{ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d"},
{ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d"},
{ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs\tpc, lr, #%0-7d"},
{ARM_EXT_V6T2, 0xf3808000, 0xffe0f0ff, "msr\t%20?CSPSR_%8'c%9'x%10's%11'f, %16-19r"},
{ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr\t%C, %16-19r"},
{ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex\t%12-15r, [%16-19r]"},
{ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb\t%12-15r, [%16-19r]"},
{ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb\t#%0-4d%21'!"},
@ -1602,6 +1622,96 @@ print_insn_coprocessor (struct disassemble_info *info, long given,
return FALSE;
}
static void
print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
{
void *stream = info->stream;
fprintf_ftype func = info->fprintf_func;
if (((given & 0x000f0000) == 0x000f0000)
&& ((given & 0x02000000) == 0))
{
int offset = given & 0xfff;
func (stream, "[pc");
if (given & 0x01000000)
{
if ((given & 0x00800000) == 0)
offset = - offset;
/* Pre-indexed. */
func (stream, ", #%d]", offset);
offset += pc + 8;
/* Cope with the possibility of write-back
being used. Probably a very dangerous thing
for the programmer to do, but who are we to
argue ? */
if (given & 0x00200000)
func (stream, "!");
}
else
{
/* Post indexed. */
func (stream, "], #%d", offset);
/* ie ignore the offset. */
offset = pc + 8;
}
func (stream, "\t; ");
info->print_address_func (offset, info);
}
else
{
func (stream, "[%s",
arm_regnames[(given >> 16) & 0xf]);
if ((given & 0x01000000) != 0)
{
if ((given & 0x02000000) == 0)
{
int offset = given & 0xfff;
if (offset)
func (stream, ", #%s%d",
(((given & 0x00800000) == 0)
? "-" : ""), offset);
}
else
{
func (stream, ", %s",
(((given & 0x00800000) == 0)
? "-" : ""));
arm_decode_shift (given, func, stream);
}
func (stream, "]%s",
((given & 0x00200000) != 0) ? "!" : "");
}
else
{
if ((given & 0x02000000) == 0)
{
int offset = given & 0xfff;
if (offset)
func (stream, "], #%s%d",
(((given & 0x00800000) == 0)
? "-" : ""), offset);
else
func (stream, "]");
}
else
{
func (stream, "], %s",
(((given & 0x00800000) == 0)
? "-" : ""));
arm_decode_shift (given, func, stream);
}
}
}
}
/* Print one ARM instruction from PC on INFO->STREAM. */
static void
@ -1642,88 +1752,13 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
break;
case 'a':
if (((given & 0x000f0000) == 0x000f0000)
&& ((given & 0x02000000) == 0))
{
int offset = given & 0xfff;
print_arm_address (pc, info, given);
break;
func (stream, "[pc");
if (given & 0x01000000)
{
if ((given & 0x00800000) == 0)
offset = - offset;
/* Pre-indexed. */
func (stream, ", #%d]", offset);
offset += pc + 8;
/* Cope with the possibility of write-back
being used. Probably a very dangerous thing
for the programmer to do, but who are we to
argue ? */
if (given & 0x00200000)
func (stream, "!");
}
else
{
/* Post indexed. */
func (stream, "], #%d", offset);
/* ie ignore the offset. */
offset = pc + 8;
}
func (stream, "\t; ");
info->print_address_func (offset, info);
}
else
{
func (stream, "[%s",
arm_regnames[(given >> 16) & 0xf]);
if ((given & 0x01000000) != 0)
{
if ((given & 0x02000000) == 0)
{
int offset = given & 0xfff;
if (offset)
func (stream, ", #%s%d",
(((given & 0x00800000) == 0)
? "-" : ""), offset);
}
else
{
func (stream, ", %s",
(((given & 0x00800000) == 0)
? "-" : ""));
arm_decode_shift (given, func, stream);
}
func (stream, "]%s",
((given & 0x00200000) != 0) ? "!" : "");
}
else
{
if ((given & 0x02000000) == 0)
{
int offset = given & 0xfff;
if (offset)
func (stream, "], #%s%d",
(((given & 0x00800000) == 0)
? "-" : ""), offset);
else
func (stream, "]");
}
else
{
func (stream, "], %s",
(((given & 0x00800000) == 0)
? "-" : ""));
arm_decode_shift (given, func, stream);
}
}
}
case 'P':
/* Set P address bit and use normal address
printing routine. */
print_arm_address (pc, info, given | (1 << 24));
break;
case 's':
@ -1913,6 +1948,19 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
func (stream, "c");
break;
case 'U':
switch (given & 0xf)
{
case 0xf: func(stream, "sy"); break;
case 0x7: func(stream, "un"); break;
case 0xe: func(stream, "st"); break;
case 0x6: func(stream, "unst"); break;
default:
func(stream, "#%d", (int)given & 0xf);
break;
}
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
@ -2292,6 +2340,30 @@ print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
abort ();
}
/* Return the name of an V7M special register. */
static const char *
psr_name (int regno)
{
switch (regno)
{
case 0: return "APSR";
case 1: return "IAPSR";
case 2: return "EAPSR";
case 3: return "PSR";
case 5: return "IPSR";
case 6: return "EPSR";
case 7: return "IEPSR";
case 8: return "MSP";
case 9: return "PSP";
case 16: return "PRIMASK";
case 17: return "BASEPRI";
case 18: return "BASEPRI_MASK";
case 19: return "FAULTMASK";
case 20: return "CONTROL";
default: return "<unknown>";
}
}
/* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
static void
@ -2638,6 +2710,45 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
}
break;
case 'U':
switch (given & 0xf)
{
case 0xf: func(stream, "sy"); break;
case 0x7: func(stream, "un"); break;
case 0xe: func(stream, "st"); break;
case 0x6: func(stream, "unst"); break;
default:
func(stream, "#%d", (int)given & 0xf);
break;
}
break;
case 'C':
if ((given & 0xff) == 0)
{
func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
if (given & 0x800)
func (stream, "f");
if (given & 0x400)
func (stream, "s");
if (given & 0x200)
func (stream, "x");
if (given & 0x100)
func (stream, "c");
}
else
{
func (stream, psr_name (given & 0xff));
}
break;
case 'D':
if ((given & 0xff) == 0)
func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
else
func (stream, psr_name (given & 0xff));
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{