real_format_for_mode[XFmode - QFmode] = &ieee_extended_motorola_format;
}
\f
+/* Structure describing stack frame layout. */
+struct m68k_frame {
+ HOST_WIDE_INT offset;
+ HOST_WIDE_INT size;
+ /* data and address register */
+ int reg_no;
+ unsigned int reg_mask;
+ unsigned int reg_rev_mask;
+ /* fpu registers */
+ int fpu_no;
+ unsigned int fpu_mask;
+ unsigned int fpu_rev_mask;
+ /* fpa registers */
+ int fpa_no;
+ /* offsets relative to ARG_POINTER. */
+ HOST_WIDE_INT frame_pointer_offset;
+ HOST_WIDE_INT stack_pointer_offset;
+};
+
+static void
+m68k_compute_frame_layout (struct m68k_frame *frame)
+{
+ int regno, saved;
+ unsigned int mask, rmask;
+
+ frame->size = (get_frame_size () + 3) & -4;
+
+ mask = rmask = saved = 0;
+ for (regno = 0; regno < 16; regno++)
+ if (m68k_save_reg (regno))
+ {
+ mask |= 1 << regno;
+ rmask |= 1 << (15 - regno);
+ saved++;
+ }
+ frame->offset = saved * 4;
+ frame->reg_no = saved;
+ frame->reg_mask = mask;
+ frame->reg_rev_mask = rmask;
+
+ if (TARGET_68881 /* || TARGET_CFV4E */)
+ {
+ mask = rmask = saved = 0;
+ for (regno = 16; regno < 24; regno++)
+ if (regs_ever_live[regno] && ! call_used_regs[regno])
+ {
+ mask |= 1 << (23 - regno);
+ rmask |= 1 << (regno - 16);
+ saved++;
+ }
+ frame->offset += saved * 12 /* (TARGET_CFV4E ? 8 : 12) */;
+ frame->fpu_no = saved;
+ frame->fpu_mask = mask;
+ frame->fpu_rev_mask = rmask;
+ }
+}
+
+HOST_WIDE_INT
+m68k_initial_elimination_offset (int from, int to)
+{
+ struct m68k_frame frame;
+
+ /* FIXME: The correct offset to compute here would appear to be
+ (frame_pointer_needed ? -UNITS_PER_WORD * 2 : -UNITS_PER_WORD);
+ but for some obscure reason, this must be 0 to get correct code. */
+ if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
+ return 0;
+
+ m68k_compute_frame_layout (&frame);
+
+ if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
+ return frame.offset + frame.size + (frame_pointer_needed ? -UNITS_PER_WORD * 2 : -UNITS_PER_WORD);
+ else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
+ return frame.offset + frame.size;
+
+ abort();
+}
+
/* Return 1 if we need to save REGNO. */
static int
m68k_save_reg (unsigned int regno)
register int mask = 0;
int num_saved_regs = 0;
HOST_WIDE_INT fsize = (size + 3) & -4;
+ HOST_WIDE_INT fsize_with_regs;
HOST_WIDE_INT cfa_offset = INCOMING_FRAME_SP_OFFSET;
/* If the stack limit is a symbol, we can check it here,
#endif
}
+ if (TARGET_COLDFIRE)
+ {
+ /* on Coldfire add register save into initial stack frame setup, if possible */
+ for (regno = 0; regno < 16; regno++)
+ if (m68k_save_reg (regno))
+ num_saved_regs++;
+
+ if (num_saved_regs <= 2)
+ num_saved_regs = 0;
+ }
+ else
+ num_saved_regs = 0;
+
+ fsize_with_regs = fsize + num_saved_regs * 4;
+
if (frame_pointer_needed)
{
if (fsize == 0 && TARGET_68040)
reg_names[FRAME_POINTER_REGNUM]);
#endif
}
- else if (fsize < 0x8000)
+ else if (fsize_with_regs < 0x8000)
{
#ifdef MOTOROLA
- asm_fprintf (stream, "\tlink.w %s,%I%wd\n",
- reg_names[FRAME_POINTER_REGNUM], -fsize);
+ asm_fprintf (stream, "\tlink.w %s,%I%wd\n",
+ reg_names[FRAME_POINTER_REGNUM], -fsize_with_regs);
#else
- asm_fprintf (stream, "\tlink %s,%I%wd\n",
- reg_names[FRAME_POINTER_REGNUM], -fsize);
+ asm_fprintf (stream, "\tlink %s,%I%wd\n",
+ reg_names[FRAME_POINTER_REGNUM], -fsize_with_regs);
#endif
}
else if (TARGET_68020)
{
#ifdef MOTOROLA
asm_fprintf (stream, "\tlink.l %s,%I%wd\n",
- reg_names[FRAME_POINTER_REGNUM], -fsize);
+ reg_names[FRAME_POINTER_REGNUM], -fsize_with_regs);
#else
asm_fprintf (stream, "\tlink %s,%I%wd\n",
- reg_names[FRAME_POINTER_REGNUM], -fsize);
+ reg_names[FRAME_POINTER_REGNUM], -fsize_with_regs);
#endif
}
else
{
- /* Adding negative number is faster on the 68040. */
+ /* Adding negative number is faster on the 68040. */
#ifdef MOTOROLA
asm_fprintf (stream, "\tlink.w %s,%I0\n\tadd.l %I%wd,%Rsp\n",
- reg_names[FRAME_POINTER_REGNUM], -fsize);
+ reg_names[FRAME_POINTER_REGNUM], -fsize_with_regs);
#else
asm_fprintf (stream, "\tlink %s,%I0\n\taddl %I%wd,%Rsp\n",
- reg_names[FRAME_POINTER_REGNUM], -fsize);
+ reg_names[FRAME_POINTER_REGNUM], -fsize_with_regs);
#endif
}
if (dwarf2out_do_frame ())
cfa_offset += fsize;
}
}
- else if (fsize)
+ else if (fsize_with_regs) /* !frame_pointer_needed */
{
- if (fsize + 4 < 0x8000)
+ if (fsize_with_regs < 0x8000)
{
- if (fsize + 4 <= 8)
+ if (fsize_with_regs <= 8)
{
if (!TARGET_COLDFIRE)
{
/* asm_fprintf() cannot handle %. */
#ifdef MOTOROLA
- asm_fprintf (stream, "\tsubq.w %I%wd,%Rsp\n", fsize + 4);
+ asm_fprintf (stream, "\tsubq.w %I%wd,%Rsp\n", fsize_with_regs);
#else
- asm_fprintf (stream, "\tsubqw %I%wd,%Rsp\n", fsize + 4);
+ asm_fprintf (stream, "\tsubqw %I%wd,%Rsp\n", fsize_with_regs);
#endif
}
else
{
/* asm_fprintf() cannot handle %. */
#ifdef MOTOROLA
- asm_fprintf (stream, "\tsubq.l %I%wd,%Rsp\n", fsize + 4);
+ asm_fprintf (stream, "\tsubq.l %I%wd,%Rsp\n", fsize_with_regs);
#else
- asm_fprintf (stream, "\tsubql %I%wd,%Rsp\n", fsize + 4);
+ asm_fprintf (stream, "\tsubql %I%wd,%Rsp\n", fsize_with_regs);
#endif
}
}
- else if (fsize + 4 <= 16 && TARGET_CPU32)
+ else if (fsize_with_regs <= 16 && TARGET_CPU32)
{
/* On the CPU32 it is faster to use two subqw instructions to
subtract a small integer (8 < N <= 16) to a register. */
#ifdef MOTOROLA
asm_fprintf (stream,
"\tsubq.w %I8,%Rsp\n\tsubq.w %I%wd,%Rsp\n",
- fsize + 4 - 8);
+ fsize_with_regs - 8);
#else
asm_fprintf (stream, "\tsubqw %I8,%Rsp\n\tsubqw %I%wd,%Rsp\n",
- fsize + 4 - 8);
+ fsize_with_regs - 8);
#endif
}
else if (TARGET_68040)
/* Adding negative number is faster on the 68040. */
/* asm_fprintf() cannot handle %. */
#ifdef MOTOROLA
- asm_fprintf (stream, "\tadd.w %I%wd,%Rsp\n", - (fsize + 4));
+ asm_fprintf (stream, "\tadd.w %I%wd,%Rsp\n", -fsize_with_regs);
#else
- asm_fprintf (stream, "\taddw %I%wd,%Rsp\n", - (fsize + 4));
+ asm_fprintf (stream, "\taddw %I%wd,%Rsp\n", -fsize_with_regs);
#endif
}
else
{
#ifdef MOTOROLA
- asm_fprintf (stream, "\tlea (%wd,%Rsp),%Rsp\n", - (fsize + 4));
+ asm_fprintf (stream, "\tlea (%wd,%Rsp),%Rsp\n", -fsize_with_regs);
#else
- asm_fprintf (stream, "\tlea %Rsp@(%wd),%Rsp\n", - (fsize + 4));
+ asm_fprintf (stream, "\tlea %Rsp@(%wd),%Rsp\n", -fsize_with_regs);
#endif
}
}
- else
+ else /* fsize_with_regs >= 0x8000 */
{
- /* asm_fprintf() cannot handle %. */
#ifdef MOTOROLA
- asm_fprintf (stream, "\tadd.l %I%wd,%Rsp\n", - (fsize + 4));
+ asm_fprintf (stream, "\tadd.l %I%wd,%Rsp\n", -fsize_with_regs);
#else
- asm_fprintf (stream, "\taddl %I%wd,%Rsp\n", - (fsize + 4));
+ asm_fprintf (stream, "\taddl %I%wd,%Rsp\n", -fsize_with_regs);
#endif
}
if (dwarf2out_do_frame ())
cfa_offset += fsize + 4;
dwarf2out_def_cfa ("", STACK_POINTER_REGNUM, cfa_offset);
}
- }
+ } /* !frame_pointer_needed */
+
+ num_saved_regs = 0;
+
if (TARGET_68881)
{
for (regno = 16; regno < 24; regno++)
then use the plain address register indirect mode. We also
have to invert the register save mask to use the new mode.
- FIXME: if num_saved_regs was calculated earlier, we could
- combine the stack pointer adjustment with any adjustment
- done when the initial stack frame is created. This would
- save an instruction */
+ The required register save space was combined earlier with
+ the fsize amount. Don't add it again. */
int newmask = 0;
int i;
newmask |= (1 << (15-i));
#ifdef MOTOROLA
- asm_fprintf (stream, "\tlea (%d,%Rsp),%Rsp\n", -num_saved_regs*4);
asm_fprintf (stream, "\tmovm.l %I0x%x,(%Rsp)\n", newmask);
#else
- asm_fprintf (stream, "\tlea %Rsp@(%d),%Rsp\n", -num_saved_regs*4);
asm_fprintf (stream, "\tmoveml %I0x%x,%Rsp@\n", newmask);
#endif
}
register int nregs;
HOST_WIDE_INT offset, foffset;
HOST_WIDE_INT fsize = (size + 3) & -4;
+ HOST_WIDE_INT fsize_with_regs;
int big = 0;
rtx insn = get_last_insn ();
int restore_from_sp = 0;
stack adjustment needed at that point. */
restore_from_sp = ! frame_pointer_needed
|| (! current_function_calls_alloca && leaf_function_p ());
+
+ /* fsize_with_regs is the size we need to adjust the sp when
+ popping the frame */
+ fsize_with_regs = fsize;
+
+ /* Because the ColdFire doesn't support moveml with
+ complex address modes, we must adjust the stack manually
+ after restoring registers. When the frame pointer isn't used,
+ we can merge movem adjustment into frame unlinking
+ made immediately after it. */
+ if (TARGET_COLDFIRE && restore_from_sp && (nregs > 2))
+ fsize_with_regs += nregs * 4;
+
if (offset + fsize >= 0x8000
&& ! restore_from_sp
&& (mask || fmask))
{
+ /* Because the ColdFire doesn't support moveml with
+ complex address modes we make an extra correction here */
+ if (TARGET_COLDFIRE)
+ {
#ifdef MOTOROLA
- asm_fprintf (stream, "\t%Omove.l %I%wd,%Ra1\n", -fsize);
+ asm_fprintf (stream, "\t%Omove.l %I%d,%Ra1\n", -fsize - offset);
#else
- asm_fprintf (stream, "\tmovel %I%wd,%Ra1\n", -fsize);
+ asm_fprintf (stream, "\tmovel %I%d,%Ra1\n", -fsize - offset);
#endif
+ }
+ else
+ {
+#ifdef MOTOROLA
+ asm_fprintf (stream, "\t%Omove.l %I%wd,%Ra1\n", -fsize);
+#else
+ asm_fprintf (stream, "\tmovel %I%wd,%Ra1\n", -fsize);
+#endif
+ }
+
fsize = 0, big = 1;
}
- if (TARGET_COLDFIRE || nregs <= 2)
+ if (nregs <= 2)
{
/* Restore each separately in the same order moveml does.
Using two movel instructions instead of a single moveml
}
else if (mask)
{
- if (big)
- {
+ /* The ColdFire requires special handling due to its limited moveml insn */
+ if (TARGET_COLDFIRE)
+ {
+ if (big)
+ {
#ifdef MOTOROLA
- asm_fprintf (stream, "\tmovm.l -%wd(%s,%Ra1.l),%I0x%x\n",
- offset + fsize,
- reg_names[FRAME_POINTER_REGNUM],
- mask);
+ asm_fprintf (stream, "\tadd.l %s,%Ra1\n", reg_names[FRAME_POINTER_REGNUM]);
+ asm_fprintf (stream, "\tmovm.l (%Ra1),%I0x%x\n", mask);
#else
- asm_fprintf (stream, "\tmoveml %s@(-%wd,%Ra1:l),%I0x%x\n",
- reg_names[FRAME_POINTER_REGNUM],
- offset + fsize, mask);
+ asm_fprintf (stream, "\taddl %s,%Ra1\n", reg_names[FRAME_POINTER_REGNUM]);
+ asm_fprintf (stream, "\tmoveml %Ra1@,%I0x%x\n", mask);
#endif
- }
- else if (restore_from_sp)
- {
+ }
+ else if (restore_from_sp)
+ {
#ifdef MOTOROLA
- asm_fprintf (stream, "\tmovm.l (%Rsp)+,%I0x%x\n", mask);
+ asm_fprintf (stream, "\tmovm.l (%Rsp),%I0x%x\n", mask);
#else
- asm_fprintf (stream, "\tmoveml %Rsp@+,%I0x%x\n", mask);
+ asm_fprintf (stream, "\tmoveml %Rsp@,%I0x%x\n", mask);
#endif
- }
- else
+ }
+ else
+ {
+#ifdef MOTOROLA
+ asm_fprintf (stream, "\tmovm.l -%wd(%s),%I0x%x\n",
+ offset + fsize,
+ reg_names[FRAME_POINTER_REGNUM],
+ mask);
+#else
+ asm_fprintf (stream, "\tmoveml %s@(-%wd),%I0x%x\n",
+ reg_names[FRAME_POINTER_REGNUM],
+ offset + fsize, mask);
+#endif
+ }
+ }
+ else /* !TARGET_COLDFIRE */
{
+ if (big)
+ {
#ifdef MOTOROLA
- asm_fprintf (stream, "\tmovm.l -%wd(%s),%I0x%x\n",
- offset + fsize,
- reg_names[FRAME_POINTER_REGNUM],
- mask);
+ asm_fprintf (stream, "\tmovm.l -%wd(%s,%Ra1.l),%I0x%x\n",
+ offset + fsize,
+ reg_names[FRAME_POINTER_REGNUM],
+ mask);
#else
- asm_fprintf (stream, "\tmoveml %s@(-%wd),%I0x%x\n",
- reg_names[FRAME_POINTER_REGNUM],
- offset + fsize, mask);
+ asm_fprintf (stream, "\tmoveml %s@(-%wd,%Ra1:l),%I0x%x\n",
+ reg_names[FRAME_POINTER_REGNUM],
+ offset + fsize, mask);
#endif
+ }
+ else if (restore_from_sp)
+ {
+#ifdef MOTOROLA
+ asm_fprintf (stream, "\tmovm.l (%Rsp)+,%I0x%x\n", mask);
+#else
+ asm_fprintf (stream, "\tmoveml %Rsp@+,%I0x%x\n", mask);
+#endif
+ }
+ else
+ {
+#ifdef MOTOROLA
+ asm_fprintf (stream, "\tmovm.l -%wd(%s),%I0x%x\n",
+ offset + fsize,
+ reg_names[FRAME_POINTER_REGNUM],
+ mask);
+#else
+ asm_fprintf (stream, "\tmoveml %s@(-%wd),%I0x%x\n",
+ reg_names[FRAME_POINTER_REGNUM],
+ offset + fsize, mask);
+#endif
+ }
}
}
if (fmask)
if (frame_pointer_needed)
fprintf (stream, "\tunlk %s\n",
reg_names[FRAME_POINTER_REGNUM]);
- else if (fsize)
+ else if (fsize_with_regs)
{
- if (fsize + 4 <= 8)
+ if (fsize_with_regs <= 8)
{
if (!TARGET_COLDFIRE)
{
#ifdef MOTOROLA
- asm_fprintf (stream, "\taddq.w %I%wd,%Rsp\n", fsize + 4);
+ asm_fprintf (stream, "\taddq.w %I%wd,%Rsp\n", fsize_with_regs);
#else
- asm_fprintf (stream, "\taddqw %I%wd,%Rsp\n", fsize + 4);
+ asm_fprintf (stream, "\taddqw %I%wd,%Rsp\n", fsize_with_regs);
#endif
}
- else
+ else /* TARGET_COLDFIRE */
{
#ifdef MOTOROLA
- asm_fprintf (stream, "\taddq.l %I%wd,%Rsp\n", fsize + 4);
+ asm_fprintf (stream, "\taddq.l %I%wd,%Rsp\n", fsize_with_regs);
#else
- asm_fprintf (stream, "\taddql %I%wd,%Rsp\n", fsize + 4);
+ asm_fprintf (stream, "\taddql %I%wd,%Rsp\n", fsize_with_regs);
#endif
}
}
- else if (fsize + 4 <= 16 && TARGET_CPU32)
+ else if (fsize_with_regs <= 16 && TARGET_CPU32)
{
/* On the CPU32 it is faster to use two addqw instructions to
add a small integer (8 < N <= 16) to a register. */
/* asm_fprintf() cannot handle %. */
#ifdef MOTOROLA
asm_fprintf (stream, "\taddq.w %I8,%Rsp\n\taddq.w %I%wd,%Rsp\n",
- fsize + 4 - 8);
+ fsize_with_regs - 8);
#else
asm_fprintf (stream, "\taddqw %I8,%Rsp\n\taddqw %I%wd,%Rsp\n",
- fsize + 4 - 8);
+ fsize_with_regs - 8);
#endif
}
- else if (fsize + 4 < 0x8000)
+ else if (fsize_with_regs < 0x8000)
{
if (TARGET_68040)
{
/* asm_fprintf() cannot handle %. */
#ifdef MOTOROLA
- asm_fprintf (stream, "\tadd.w %I%wd,%Rsp\n", fsize + 4);
+ asm_fprintf (stream, "\tadd.w %I%wd,%Rsp\n", fsize_with_regs);
#else
- asm_fprintf (stream, "\taddw %I%wd,%Rsp\n", fsize + 4);
+ asm_fprintf (stream, "\taddw %I%wd,%Rsp\n", fsize_with_regs);
#endif
}
else
{
#ifdef MOTOROLA
- asm_fprintf (stream, "\tlea (%wd,%Rsp),%Rsp\n", fsize + 4);
+ asm_fprintf (stream, "\tlea (%wd,%Rsp),%Rsp\n", fsize_with_regs);
#else
- asm_fprintf (stream, "\tlea %Rsp@(%wd),%Rsp\n", fsize + 4);
+ asm_fprintf (stream, "\tlea %Rsp@(%wd),%Rsp\n", fsize_with_regs);
#endif
}
}
{
/* asm_fprintf() cannot handle %. */
#ifdef MOTOROLA
- asm_fprintf (stream, "\tadd.l %I%wd,%Rsp\n", fsize + 4);
+ asm_fprintf (stream, "\tadd.l %I%wd,%Rsp\n", fsize_with_regs);
#else
- asm_fprintf (stream, "\taddl %I%wd,%Rsp\n", fsize + 4);
+ asm_fprintf (stream, "\taddl %I%wd,%Rsp\n", fsize_with_regs);
#endif
}
}
For the 68000, we give the data registers numbers 0-7,
the address registers numbers 010-017,
and the 68881 floating point registers numbers 020-027. */
-#define FIRST_PSEUDO_REGISTER 24
+#define FIRST_PSEUDO_REGISTER 25
/* This defines the register which is used to hold the offset table for PIC. */
#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 13 : INVALID_REGNUM)
This is computed in `reload', in reload1.c. */
#define FRAME_POINTER_REQUIRED 0
-/* Base register for access to arguments of the function. */
-#define ARG_POINTER_REGNUM 14
+/* Base register for access to arguments of the function.
+ * This isn't a hardware register. It will be eliminated to the
+ * stack pointer or frame pointer.
+ */
+#define ARG_POINTER_REGNUM 24
/* Register in which static-chain is passed to a function. */
#define STATIC_CHAIN_REGNUM 8
You should override this if you define FUNCTION_EXTRA_EPILOGUE. */
#define USE_RETURN_INSN use_return_insn ()
-/* Store in the variable DEPTH the initial difference between the
- frame pointer reg contents and the stack pointer reg contents,
- as of the start of the function body. This depends on the layout
- of the fixed parts of the stack frame and on how registers are saved.
-
- On the 68k, if we have a frame, we must add one word to its length
- to allow for the place that a6 is stored when we do have a frame pointer.
- Otherwise, we would need to compute the offset from the frame pointer
- of a local variable as a function of frame_pointer_needed, which
- is hard. */
-
-#define INITIAL_FRAME_POINTER_OFFSET(DEPTH) \
-{ int regno; \
- int offset = -4; \
- for (regno = 16; regno < FIRST_PSEUDO_REGISTER; regno++) \
- if (regs_ever_live[regno] && ! call_used_regs[regno]) \
- offset += 12; \
- for (regno = 0; regno < 16; regno++) \
- if (regs_ever_live[regno] && ! call_used_regs[regno]) \
- offset += 4; \
- if (flag_pic && current_function_uses_pic_offset_table) \
- offset += 4; \
- (DEPTH) = (offset + ((get_frame_size () + 3) & -4) \
- + (get_frame_size () == 0 ? 0 : 4)); \
-}
-
/* Output assembler code for a block containing the constant parts
of a trampoline, leaving space for the variable parts. */
asm ("rts":); \
}
\f
+/* Definitions for register eliminations.
+
+ This is an array of structures. Each structure initializes one pair
+ of eliminable registers. The "from" register number is given first,
+ followed by "to". Eliminations of the same "from" register are listed
+ in order of preference.
+
+ There are two registers that can always be eliminated on the m68k.
+ The frame pointer and the arg pointer can be replaced by either the
+ hard frame pointer or to the stack pointer, depending upon the
+ circumstances. The hard frame pointer is not used before reload and
+ so it is not eligible for elimination. */
+
+#define ELIMINABLE_REGS \
+{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
+ { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM }, \
+ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }}
+
+/* Given FROM and TO register numbers, say whether this elimination is
+ allowed. Frame pointer elimination is automatically handled.
+
+ All other eliminations are valid. */
+
+#define CAN_ELIMINATE(FROM, TO) \
+ ((TO) == STACK_POINTER_REGNUM ? ! frame_pointer_needed : 1)
+
+/* Define the offset between two registers, one to be eliminated, and the other
+ its replacement, at the start of a routine. */
+
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
+ (OFFSET) = m68k_initial_elimination_offset(FROM, TO)
+\f
/* Addressing modes, and classification of registers for them. */
#define HAVE_POST_INCREMENT 1
#define REGISTER_NAMES \
{"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \
"a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp", \
- "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7" }
+ "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7", "argptr" }
/* How to renumber registers for dbx and gdb.
On the Sun-3, the floating point registers have numbers