On 12/22/08, Ahmed Ammar <[email protected]> wrote:
> On Mon, 2008-11-17 at 17:21 +0000, Martin Guy wrote:
> > http://martinwguy.co.uk/martin/crunch/gcc-4.3.2-patches
> above link and i get a 403 'Forbidden' error.
Yes. I published the working set under simplemachines.it/tools and
closed that dir since its contents are the same.
> .save {mv8} <-- Error: register expected
> I don't know if the arm-crunch-unwind.patch was supposed to solve this,
No. This needs a modification to binutils, not gcc.
The "crunch unwind patch" for gcc-4.3.0 is attached, though I don't
know if it makes any sense.
I assume your optimization issue is because it changes the code to use
one of the callee-saved registers 8-15
M
diff -urN gcc-4.3.0/gcc/config/arm-original/arm/libunwind.S gcc-4.3.0/gcc/config/arm/libunwind.S
--- gcc-4.3.0/gcc/config/arm-original/arm/libunwind.S 2007-09-05 01:05:01.000000000 +1000
+++ gcc-4.3.0/gcc/config/arm/libunwind.S 2008-04-10 17:25:47.000000000 +1000
@@ -191,6 +191,52 @@
stc2 p1, cr11, [r0], #4 /* wstrw wcgr3, [r0], #4 */
RET
+
+/* Load CRUNCH registers mv0-mv15 from the address in r0. */
+ARM_FUNC_START gnu_Unwind_Restore_CRUNCH
+ /* Use the generic coprocessor form so that gas doesn't complain
+ on soft-float targets. */
+ ldcl p4, cr0, [r0], #8 /* cfldrd mv0, [r0], #8 */
+ ldcl p4, cr1, [r0], #8 /* cfldrd mv1, [r0], #8 */
+ ldcl p4, cr2, [r0], #8 /* cfldrd mv2, [r0], #8 */
+ ldcl p4, cr3, [r0], #8 /* cfldrd mv3, [r0], #8 */
+ ldcl p4, cr4, [r0], #8 /* cfldrd mv4, [r0], #8 */
+ ldcl p4, cr5, [r0], #8 /* cfldrd mv5, [r0], #8 */
+ ldcl p4, cr6, [r0], #8 /* cfldrd mv6, [r0], #8 */
+ ldcl p4, cr7, [r0], #8 /* cfldrd mv7, [r0], #8 */
+ ldcl p4, cr8, [r0], #8 /* cfldrd mv8, [r0], #8 */
+ ldcl p4, cr9, [r0], #8 /* cfldrd mv9, [r0], #8 */
+ ldcl p4, cr10, [r0], #8 /* cfldrd mv10, [r0], #8 */
+ ldcl p4, cr11, [r0], #8 /* cfldrd mv11, [r0], #8 */
+ ldcl p4, cr12, [r0], #8 /* cfldrd mv12, [r0], #8 */
+ ldcl p4, cr13, [r0], #8 /* cfldrd mv13, [r0], #8 */
+ ldcl p4, cr14, [r0], #8 /* cfldrd mv14, [r0], #8 */
+ ldcl p4, cr15, [r0], #8 /* cfldrd mv15, [r0], #8 */
+ RET
+
+/* Store CRUNCH regsters mv0-mv15 to the address in r0. */
+ARM_FUNC_START gnu_Unwind_Save_CRUNCH
+ /* Use the generic coprocessor form so that gas doesn't complain
+ on soft-float targets. */
+ stcl p4, cr0, [r0], #8 /* cfstrd mv0, [r0], #8 */
+ stcl p4, cr1, [r0], #8 /* cfstrd mv1, [r0], #8 */
+ stcl p4, cr2, [r0], #8 /* cfstrd mv2, [r0], #8 */
+ stcl p4, cr3, [r0], #8 /* cfstrd mv3, [r0], #8 */
+ stcl p4, cr4, [r0], #8 /* cfstrd mv4, [r0], #8 */
+ stcl p4, cr5, [r0], #8 /* cfstrd mv5, [r0], #8 */
+ stcl p4, cr6, [r0], #8 /* cfstrd mv6, [r0], #8 */
+ stcl p4, cr7, [r0], #8 /* cfstrd mv7, [r0], #8 */
+ stcl p4, cr8, [r0], #8 /* cfstrd mv8, [r0], #8 */
+ stcl p4, cr9, [r0], #8 /* cfstrd mv9, [r0], #8 */
+ stcl p4, cr10, [r0], #8 /* cfstrd mv10, [r0], #8 */
+ stcl p4, cr11, [r0], #8 /* cfstrd mv11, [r0], #8 */
+ stcl p4, cr12, [r0], #8 /* cfstrd mv12, [r0], #8 */
+ stcl p4, cr13, [r0], #8 /* cfstrd mv13, [r0], #8 */
+ stcl p4, cr14, [r0], #8 /* cfstrd mv14, [r0], #8 */
+ stcl p4, cr15, [r0], #8 /* cfstrd mv15, [r0], #8 */
+
+ RET
+
/* Wrappers to save core registers, then call the real routine. */
.macro UNWIND_WRAPPER name nargs
diff -urN gcc-4.3.0/gcc/config/arm-original/arm/pr-support.c gcc-4.3.0/gcc/config/arm/pr-support.c
--- gcc-4.3.0/gcc/config/arm-original/arm/pr-support.c 2006-12-14 03:32:47.000000000 +1000
+++ gcc-4.3.0/gcc/config/arm/pr-support.c 2008-04-10 17:26:11.000000000 +1000
@@ -322,6 +322,33 @@
return _URC_FAILURE;
continue;
}
+ if ((op & 0xf8) == 0xd8)
+ {
+ if (op == 0xde)
+ {
+ /* Pop CRUNCH MV registers. */
+ op = next_unwind_byte (uws);
+ op = ((op & 0xf0) << 12) | ((op & 0xf) + 1);
+ if (_Unwind_VRS_Pop (context, _UVRSC_CRUNCH, op, _UVRSD_DOUBLE)
+ != _UVRSR_OK)
+ return _URC_FAILURE;
+ continue;
+ }
+ if (op == 0xdf)
+ {
+ /* Spare. */
+ return _URC_FAILURE;
+ }
+ /* op == 0xd8 to 0xdd */
+ {
+ /* Pop CRUNCH MV[10]-MV[10+nnn]. */
+ op = 0xa0000 | ((op & 0xf) + 1);
+ if (_Unwind_VRS_Pop (context, _UVRSC_CRUNCH, op, _UVRSD_DOUBLE)
+ != _UVRSR_OK)
+ return _URC_FAILURE;
+ continue;
+ }
+ }
/* Spare. */
return _URC_FAILURE;
}
diff -urN gcc-4.3.0/gcc/config/arm-original/arm/unwind-arm.c gcc-4.3.0/gcc/config/arm/unwind-arm.c
--- gcc-4.3.0/gcc/config/arm-original/arm/unwind-arm.c 2007-09-05 01:05:01.000000000 +1000
+++ gcc-4.3.0/gcc/config/arm/unwind-arm.c 2008-04-10 17:27:25.000000000 +1000
@@ -101,6 +101,11 @@
_uw wc[4];
};
+struct crunch_regs
+{
+ _uw64 mv[16];
+};
+
/* Unwind descriptors. */
typedef struct
@@ -135,6 +140,7 @@
struct fpa_regs fpa;
struct wmmxd_regs wmmxd;
struct wmmxc_regs wmmxc;
+ struct crunch_regs crunch;
} phase1_vrs;
#define DEMAND_SAVE_VFP 1 /* VFP state has been saved if not set */
@@ -145,6 +151,8 @@
saved if not set. */
#define DEMAND_SAVE_WMMXC 16 /* iWMMXt control registers have been
saved if not set. */
+#define DEMAND_SAVE_CRUNCH 32 /* CRUNCH registers have been
+ saved if not set. */
/* This must match the structure created by the assembly wrappers. */
typedef struct
@@ -187,6 +195,10 @@
void __gnu_Unwind_Save_VFP_D_16_to_31 (struct vfpv3_regs * p);
void __gnu_Unwind_Restore_VFP_D_16_to_31 (struct vfpv3_regs * p);
+/* Routines for CRUNCH */
+void __gnu_Unwind_Save_CRUNCH (struct crunch_regs * p);
+void __gnu_Unwind_Restore_CRUNCH (struct crunch_regs * p);
+
/* Restore coprocessor state after phase1 unwinding. */
static void
restore_non_core_regs (phase1_vrs * vrs)
@@ -206,6 +218,9 @@
__gnu_Unwind_Restore_WMMXD (&vrs->wmmxd);
if ((vrs->demand_save_flags & DEMAND_SAVE_WMMXC) == 0)
__gnu_Unwind_Restore_WMMXC (&vrs->wmmxc);
+
+ if ((vrs->demand_save_flags & DEMAND_SAVE_CRUNCH) == 0)
+ __gnu_Unwind_Restore_CRUNCH (&vrs->crunch);
}
/* A better way to do this would probably be to compare the absolute address
@@ -249,6 +264,7 @@
case _UVRSC_FPA:
case _UVRSC_WMMXD:
case _UVRSC_WMMXC:
+ case _UVRSC_CRUNCH:
return _UVRSR_NOT_IMPLEMENTED;
default:
@@ -281,6 +297,7 @@
case _UVRSC_FPA:
case _UVRSC_WMMXD:
case _UVRSC_WMMXC:
+ case _UVRSC_CRUNCH:
return _UVRSR_NOT_IMPLEMENTED;
default:
@@ -521,6 +538,45 @@
}
return _UVRSR_OK;
+ case _UVRSC_CRUNCH:
+ {
+ _uw start = discriminator >> 16;
+ _uw count = discriminator & 0xffff;
+ struct crunch_regs tmp;
+ _uw *sp;
+ _uw *dest;
+
+ if ((representation != _UVRSD_DOUBLE) || start + count > 16)
+ return _UVRSR_FAILED;
+
+ if (vrs->demand_save_flags & DEMAND_SAVE_CRUNCH)
+ {
+ /* Demand-save resisters for stage1. */
+ vrs->demand_save_flags &= ~DEMAND_SAVE_CRUNCH;
+ __gnu_Unwind_Save_CRUNCH (&vrs->crunch);
+ }
+
+ /* Restore the registers from the stack. Do this by saving the
+ current CRUNCH registers to a memory area, moving the in-memory
+ values into that area, and restoring from the whole area. */
+ __gnu_Unwind_Save_CRUNCH (&tmp);
+
+ /* The stack address is only guaranteed to be word aligned, so
+ we can't use doubleword copies. */
+ sp = (_uw *) vrs->core.r[R_SP];
+ dest = (_uw *) &tmp.mv[start];
+ count *= 2;
+ while (count--)
+ *(dest++) = *(sp++);
+
+ /* Set the new stack pointer. */
+ vrs->core.r[R_SP] = (_uw) sp;
+
+ /* Reload the registers. */
+ __gnu_Unwind_Restore_CRUNCH (&tmp);
+ }
+ return _UVRSR_OK;
+
default:
return _UVRSR_FAILED;
}
--- gcc-4.3.0/gcc/config/arm/unwind-arm.h-original 2008-04-11 10:04:38.000000000 +1000
+++ gcc-4.3.0/gcc/config/arm/unwind-arm.h 2008-04-11 10:05:06.000000000 +1000
@@ -132,7 +132,8 @@
_UVRSC_VFP = 1, /* vfp */
_UVRSC_FPA = 2, /* fpa */
_UVRSC_WMMXD = 3, /* Intel WMMX data register */
- _UVRSC_WMMXC = 4 /* Intel WMMX control register */
+ _UVRSC_WMMXC = 4, /* Intel WMMX control register */
+ _UVRSC_CRUNCH = 5 /* crunch */
}
_Unwind_VRS_RegClass;