* config/tc-arm.c (s_arm_unwind_save_vfp_armv6): New.  Parse
	a directive saving VFP registers for ARMv6 or later.
	(s_arm_unwind_save): Add parameter arch_v6 and call
	s_arm_unwind_save_vfp or s_arm_unwind_save_vfp_armv6 as
	appropriate.
	(md_pseudo_table): Add entry for new "vsave" directive.
	* doc/c-arm.texi: Correct error in example for "save"
	directive (fstmdf -> fstmdx).  Also document "vsave" directive.
This commit is contained in:
Mark Shinwell 2006-06-21 14:20:25 +00:00
parent be2a5f717b
commit fa073d6911
3 changed files with 93 additions and 5 deletions

View File

@ -1,3 +1,14 @@
2006-06-21 Mark Shinwell <shinwell@codesourcery.com>
* config/tc-arm.c (s_arm_unwind_save_vfp_armv6): New. Parse
a directive saving VFP registers for ARMv6 or later.
(s_arm_unwind_save): Add parameter arch_v6 and call
s_arm_unwind_save_vfp or s_arm_unwind_save_vfp_armv6 as
appropriate.
(md_pseudo_table): Add entry for new "vsave" directive.
* doc/c-arm.texi: Correct error in example for "save"
directive (fstmdf -> fstmdx). Also document "vsave" directive.
2006-18-06 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
Anatoly Sokolov <aesok@post.ru>

View File

@ -3274,7 +3274,57 @@ s_arm_unwind_save_fpa (int reg)
}
/* Parse a directive saving VFP registers. */
/* Parse a directive saving VFP registers for ARMv6 and above. */
static void
s_arm_unwind_save_vfp_armv6 (void)
{
int count;
unsigned int start;
valueT op;
int num_vfpv3_regs = 0;
int num_regs_below_16;
count = parse_vfp_reg_list (&input_line_pointer, &start, REGLIST_VFP_D);
if (count == FAIL)
{
as_bad (_("expected register list"));
ignore_rest_of_line ();
return;
}
demand_empty_rest_of_line ();
/* We always generate FSTMD/FLDMD-style unwinding opcodes (rather
than FSTMX/FLDMX-style ones). */
/* Generate opcode for (VFPv3) registers numbered in the range 16 .. 31. */
if (start >= 16)
num_vfpv3_regs = count;
else if (start + count > 16)
num_vfpv3_regs = start + count - 16;
if (num_vfpv3_regs > 0)
{
int start_offset = start > 16 ? start - 16 : 0;
op = 0xc800 | (start_offset << 4) | (num_vfpv3_regs - 1);
add_unwind_opcode (op, 2);
}
/* Generate opcode for registers numbered in the range 0 .. 15. */
num_regs_below_16 = num_vfpv3_regs > 0 ? 16 - (int) start : count;
assert (num_regs_below_16 + num_vfpv3_regs == count);
if (num_regs_below_16 > 0)
{
op = 0xc900 | (start << 4) | (num_regs_below_16 - 1);
add_unwind_opcode (op, 2);
}
unwind.frame_size += count * 8;
}
/* Parse a directive saving VFP registers for pre-ARMv6. */
static void
s_arm_unwind_save_vfp (void)
@ -3512,10 +3562,11 @@ error:
}
/* Parse an unwind_save directive. */
/* Parse an unwind_save directive.
If the argument is non-zero, this is a .vsave directive. */
static void
s_arm_unwind_save (int ignored ATTRIBUTE_UNUSED)
s_arm_unwind_save (int arch_v6)
{
char *peek;
struct reg_entry *reg;
@ -3552,7 +3603,12 @@ s_arm_unwind_save (int ignored ATTRIBUTE_UNUSED)
return;
case REG_TYPE_RN: s_arm_unwind_save_core (); return;
case REG_TYPE_VFD: s_arm_unwind_save_vfp (); return;
case REG_TYPE_VFD:
if (arch_v6)
s_arm_unwind_save_vfp_armv6 ();
else
s_arm_unwind_save_vfp ();
return;
case REG_TYPE_MMXWR: s_arm_unwind_save_mmxwr (); return;
case REG_TYPE_MMXWCG: s_arm_unwind_save_mmxwcg (); return;
@ -3862,6 +3918,7 @@ const pseudo_typeS md_pseudo_table[] =
{ "personalityindex", s_arm_unwind_personalityindex, 0 },
{ "handlerdata", s_arm_unwind_handlerdata, 0 },
{ "save", s_arm_unwind_save, 0 },
{ "vsave", s_arm_unwind_save, 1 },
{ "movsp", s_arm_unwind_movsp, 0 },
{ "pad", s_arm_unwind_pad, 0 },
{ "setfp", s_arm_unwind_setfp, 0 },

View File

@ -506,7 +506,7 @@ instruction.
sfmfd f4, 2, [sp]!
@exdent @emph{VFP registers}
.save @{d8, d9, d10@}
fstmdf sp!, @{d8, d9, d10@}
fstmdx sp!, @{d8, d9, d10@}
@exdent @emph{iWMMXt registers}
.save @{wr10, wr11@}
wstrd wr11, [sp, #-8]!
@ -518,6 +518,26 @@ or
wstrd wr10, [sp, #-8]!
@end smallexample
@cindex @code{.vsave} directive, ARM
@item .vsave @var{vfp-reglist}
Generate unwinder annotations to restore the VFP registers in @var{vfp-reglist}
using FLDMD. Also works for VFPv3 registers
that are to be restored using VLDM.
The format of @var{vfp-reglist} is the same as the corresponding store-multiple
instruction.
@smallexample
@exdent @emph{VFP registers}
.vsave @{d8, d9, d10@}
fstmdd sp!, @{d8, d9, d10@}
@exdent @emph{VFPv3 registers}
.vsave @{d15, d16, d17@}
vstm sp!, @{d15, d16, d17@}
@end smallexample
Since FLDMX and FSTMX are now deprecated, this directive should be
used in favour of @code{.save} for saving VFP registers for ARMv6 and above.
@cindex @code{.pad} directive, ARM
@item .pad #@var{count}
Generate unwinder annotations for a stack adjustment of @var{count} bytes.