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:
parent
15c46491c2
commit
62b3e31101
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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}.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,4 @@
|
|||
#name: Invalid V7M instructions
|
||||
#as: -march=armv7m
|
||||
#error-output: arch7m-bad.l
|
||||
|
|
@ -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'
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
.text
|
||||
.thumb
|
||||
.thumb_func
|
||||
label:
|
||||
cpsie a
|
||||
cpsie i, #0x10
|
||||
cps #0x10
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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':
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue