mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-30 00:52:16 +08:00
* config/tc-arm.c (parse_vfp_reg_list): Improve register bounds
checking. (do_neon_mov): Enable several VMOV variants for VFP. Add suitable architecture version checks. (insns): Allow overlapping instructions to be used in VFP mode.
This commit is contained in:
@ -1,3 +1,11 @@
|
|||||||
|
2006-05-05 Julian Brown <julian@codesourcery.com>
|
||||||
|
|
||||||
|
* config/tc-arm.c (parse_vfp_reg_list): Improve register bounds
|
||||||
|
checking.
|
||||||
|
(do_neon_mov): Enable several VMOV variants for VFP. Add suitable
|
||||||
|
architecture version checks.
|
||||||
|
(insns): Allow overlapping instructions to be used in VFP mode.
|
||||||
|
|
||||||
2006-05-05 H.J. Lu <hongjiu.lu@intel.com>
|
2006-05-05 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
PR gas/2598
|
PR gas/2598
|
||||||
|
@ -1553,6 +1553,15 @@ parse_vfp_reg_list (char **str, unsigned int *pbase, enum reg_list_els etype)
|
|||||||
|
|
||||||
case REGLIST_VFP_D:
|
case REGLIST_VFP_D:
|
||||||
regtype = REG_TYPE_VFD;
|
regtype = REG_TYPE_VFD;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REGLIST_NEON_D:
|
||||||
|
regtype = REG_TYPE_NDQ;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (etype != REGLIST_VFP_S)
|
||||||
|
{
|
||||||
/* VFPv3 allows 32 D registers. */
|
/* VFPv3 allows 32 D registers. */
|
||||||
if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3))
|
if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3))
|
||||||
{
|
{
|
||||||
@ -1566,12 +1575,6 @@ parse_vfp_reg_list (char **str, unsigned int *pbase, enum reg_list_els etype)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
max_regs = 16;
|
max_regs = 16;
|
||||||
break;
|
|
||||||
|
|
||||||
case REGLIST_NEON_D:
|
|
||||||
regtype = REG_TYPE_NDQ;
|
|
||||||
max_regs = 32;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
base_reg = max_regs;
|
base_reg = max_regs;
|
||||||
@ -1588,6 +1591,12 @@ parse_vfp_reg_list (char **str, unsigned int *pbase, enum reg_list_els etype)
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (new_base >= max_regs)
|
||||||
|
{
|
||||||
|
first_error (_("register out of range in list"));
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Note: a value of 2 * n is returned for the register Q<n>. */
|
/* Note: a value of 2 * n is returned for the register Q<n>. */
|
||||||
if (regtype == REG_TYPE_NQ)
|
if (regtype == REG_TYPE_NQ)
|
||||||
{
|
{
|
||||||
@ -1626,6 +1635,12 @@ parse_vfp_reg_list (char **str, unsigned int *pbase, enum reg_list_els etype)
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (high_range >= max_regs)
|
||||||
|
{
|
||||||
|
first_error (_("register out of range in list"));
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
if (regtype == REG_TYPE_NQ)
|
if (regtype == REG_TYPE_NQ)
|
||||||
high_range = high_range + 1;
|
high_range = high_range + 1;
|
||||||
|
|
||||||
@ -11303,6 +11318,9 @@ do_neon_dup (void)
|
|||||||
|
|
||||||
All the encoded bits are hardcoded by this function.
|
All the encoded bits are hardcoded by this function.
|
||||||
|
|
||||||
|
Cases 4, 6 may be used with VFPv1 and above (only 32-bit transfers!).
|
||||||
|
Cases 5, 7 may be used with VFPv2 and above.
|
||||||
|
|
||||||
FIXME: Some of the checking may be a bit sloppy (in a couple of cases you
|
FIXME: Some of the checking may be a bit sloppy (in a couple of cases you
|
||||||
can specify a type where it doesn't make sense to, and is ignored).
|
can specify a type where it doesn't make sense to, and is ignored).
|
||||||
*/
|
*/
|
||||||
@ -11313,6 +11331,7 @@ do_neon_mov (void)
|
|||||||
int nargs = inst.operands[0].present + inst.operands[1].present
|
int nargs = inst.operands[0].present + inst.operands[1].present
|
||||||
+ inst.operands[2].present;
|
+ inst.operands[2].present;
|
||||||
unsigned save_cond = thumb_mode ? 0xe0000000 : inst.instruction & 0xf0000000;
|
unsigned save_cond = thumb_mode ? 0xe0000000 : inst.instruction & 0xf0000000;
|
||||||
|
const char *vfp_vers = "selected FPU does not support instruction";
|
||||||
|
|
||||||
switch (nargs)
|
switch (nargs)
|
||||||
{
|
{
|
||||||
@ -11328,6 +11347,10 @@ do_neon_mov (void)
|
|||||||
unsigned x = NEON_SCALAR_INDEX (inst.operands[1].reg);
|
unsigned x = NEON_SCALAR_INDEX (inst.operands[1].reg);
|
||||||
unsigned abcdebits = 0;
|
unsigned abcdebits = 0;
|
||||||
|
|
||||||
|
constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1),
|
||||||
|
_(vfp_vers));
|
||||||
|
constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1)
|
||||||
|
&& et.size != 32, _(vfp_vers));
|
||||||
constraint (et.type == NT_invtype, _("bad type for scalar"));
|
constraint (et.type == NT_invtype, _("bad type for scalar"));
|
||||||
constraint (x >= 64 / et.size, _("scalar index out of range"));
|
constraint (x >= 64 / et.size, _("scalar index out of range"));
|
||||||
|
|
||||||
@ -11361,6 +11384,10 @@ do_neon_mov (void)
|
|||||||
unsigned dn = NEON_SCALAR_REG (inst.operands[0].reg);
|
unsigned dn = NEON_SCALAR_REG (inst.operands[0].reg);
|
||||||
unsigned x = NEON_SCALAR_INDEX (inst.operands[0].reg);
|
unsigned x = NEON_SCALAR_INDEX (inst.operands[0].reg);
|
||||||
|
|
||||||
|
constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1),
|
||||||
|
_(vfp_vers));
|
||||||
|
constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1)
|
||||||
|
&& et.size != 32, _(vfp_vers));
|
||||||
constraint (et.type == NT_invtype, _("bad type for scalar"));
|
constraint (et.type == NT_invtype, _("bad type for scalar"));
|
||||||
constraint (x >= 64 / et.size, _("scalar index out of range"));
|
constraint (x >= 64 / et.size, _("scalar index out of range"));
|
||||||
|
|
||||||
@ -11411,6 +11438,9 @@ do_neon_mov (void)
|
|||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
/* Cases 5, 7. */
|
/* Cases 5, 7. */
|
||||||
|
constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2),
|
||||||
|
_(vfp_vers));
|
||||||
|
|
||||||
if (inst.operands[0].regisimm)
|
if (inst.operands[0].regisimm)
|
||||||
{
|
{
|
||||||
/* Case 5. */
|
/* Case 5. */
|
||||||
@ -14155,7 +14185,16 @@ static const struct asm_opcode insns[] =
|
|||||||
nUF(vcvtq, vcvt, 3, (RNQ, RNQ, oI32b), neon_cvt),
|
nUF(vcvtq, vcvt, 3, (RNQ, RNQ, oI32b), neon_cvt),
|
||||||
|
|
||||||
/* One register and an immediate value. All encoding special-cased! */
|
/* One register and an immediate value. All encoding special-cased! */
|
||||||
|
#undef THUMB_VARIANT
|
||||||
|
#define THUMB_VARIANT &fpu_vfp_ext_v1
|
||||||
|
#undef ARM_VARIANT
|
||||||
|
#define ARM_VARIANT &fpu_vfp_ext_v1
|
||||||
NCE(vmov, 0, 1, (VMOV), neon_mov),
|
NCE(vmov, 0, 1, (VMOV), neon_mov),
|
||||||
|
|
||||||
|
#undef THUMB_VARIANT
|
||||||
|
#define THUMB_VARIANT &fpu_neon_ext_v1
|
||||||
|
#undef ARM_VARIANT
|
||||||
|
#define ARM_VARIANT &fpu_neon_ext_v1
|
||||||
NCE(vmovq, 0, 1, (VMOV), neon_mov),
|
NCE(vmovq, 0, 1, (VMOV), neon_mov),
|
||||||
nUF(vmvn, vmvn, 2, (RNDQ, RNDQ_IMVNb), neon_mvn),
|
nUF(vmvn, vmvn, 2, (RNDQ, RNDQ_IMVNb), neon_mvn),
|
||||||
nUF(vmvnq, vmvn, 2, (RNQ, RNDQ_IMVNb), neon_mvn),
|
nUF(vmvnq, vmvn, 2, (RNQ, RNDQ_IMVNb), neon_mvn),
|
||||||
@ -14250,9 +14289,9 @@ static const struct asm_opcode insns[] =
|
|||||||
NUF(vtbx, 1b00840, 3, (RND, NRDLST, RND), neon_tbl_tbx),
|
NUF(vtbx, 1b00840, 3, (RND, NRDLST, RND), neon_tbl_tbx),
|
||||||
|
|
||||||
#undef THUMB_VARIANT
|
#undef THUMB_VARIANT
|
||||||
#define THUMB_VARIANT &fpu_vfp_v3_or_neon_ext
|
#define THUMB_VARIANT &fpu_vfp_ext_v1xd
|
||||||
#undef ARM_VARIANT
|
#undef ARM_VARIANT
|
||||||
#define ARM_VARIANT &fpu_vfp_v3_or_neon_ext
|
#define ARM_VARIANT &fpu_vfp_ext_v1xd
|
||||||
|
|
||||||
/* Load/store instructions. Available in Neon or VFPv3. */
|
/* Load/store instructions. Available in Neon or VFPv3. */
|
||||||
NCE(vldm, c900b00, 2, (RRw, NRDLST), neon_ldm_stm),
|
NCE(vldm, c900b00, 2, (RRw, NRDLST), neon_ldm_stm),
|
||||||
@ -14264,6 +14303,11 @@ static const struct asm_opcode insns[] =
|
|||||||
NCE(vldr, d100b00, 2, (RND, ADDR), neon_ldr_str),
|
NCE(vldr, d100b00, 2, (RND, ADDR), neon_ldr_str),
|
||||||
NCE(vstr, d000b00, 2, (RND, ADDR), neon_ldr_str),
|
NCE(vstr, d000b00, 2, (RND, ADDR), neon_ldr_str),
|
||||||
|
|
||||||
|
#undef THUMB_VARIANT
|
||||||
|
#define THUMB_VARIANT &fpu_vfp_v3_or_neon_ext
|
||||||
|
#undef ARM_VARIANT
|
||||||
|
#define ARM_VARIANT &fpu_vfp_v3_or_neon_ext
|
||||||
|
|
||||||
/* Neon element/structure load/store. */
|
/* Neon element/structure load/store. */
|
||||||
nUF(vld1, vld1, 2, (NSTRLST, ADDR), neon_ldx_stx),
|
nUF(vld1, vld1, 2, (NSTRLST, ADDR), neon_ldx_stx),
|
||||||
nUF(vst1, vst1, 2, (NSTRLST, ADDR), neon_ldx_stx),
|
nUF(vst1, vst1, 2, (NSTRLST, ADDR), neon_ldx_stx),
|
||||||
|
Reference in New Issue
Block a user