[ARM] Cirrus EP93xx Maverick Crunch Support - condexec / bugfixing / "co-processor offset out of range"

Hasjim Williams gcc@futaris.org
Thu Jun 28 06:29:00 GMT 2007


On Wed, 27 Jun 2007 12:31:42 +0200, "Rask Ingemann Lambertsen"
<rask@sygehus.dk> said:
> On Wed, Jun 27, 2007 at 06:45:26PM +1000, Hasjim Williams wrote:
> > 
> > It also fixes up the
> > "internal compiler error: output_operand: '%l' operand isn't a label"
> > error...
> > 
> > Incidentally, does anyone know if can you do something like:
> > if_then_else (ge (match_operand:!CCFP 1 "cc_register" "") (const_int 0))
> 
>    You can't (but mode macros help). As Paolo says, you will have to
>    define
> one or more new comparison modes and you will have to define branch insns
> which use the new mode(s), comparison insns which set the cc register in
> the
> new mode(s), new sCC style insns, and so on. Additionally, look at
> SELECT_CC_MODE and TARGET_CC_MODE_COMPATIBLE. If you have some sort of
> arm_output_compare_insn() function, modify that as well.
> 
>    The significance of defining a CCmode is that is says that comparisons
> done in that mode set the flags in a specific way.

Thanks.  This really clears things up for me.  For the moment, I will
leave conditional execution disabled for EVERYTHING when compiling for
MaverickCrunch.  I think the arm.md code only conditionally executes
operands if the compare was in SImode, anyway - (see "scc insns" in
gcc/config/arm/arm.md) .  Can anyone confirm this?

This just leaves me with one other major bug for MaverickCrunch.

It is related to the bugs in the Cirrus silicon.  Mainstream gcc and
older versions of gcc have a parameter -mcirrus-fix-invalid-insns.  The
patch from Nucleus Systems
(http://www.nucleusys.com/projects/crunch.php), removes this parameter,
and replaces it with two -mfix-crunch-d0 and -mfix-crunch-d1.

I've modified it and attached it to this post.  At the moment, I hard
code both to 0, to disable the bug fixes, since enabling them I think is
the cause of a "co-processor offset out of range" error, in the
assembler.  Essentially the two major bugs that the attached code fixes
are, after a branch, two nops are needed.  Secondly, the a register
written to in one instruction can not be read from in the next
instruction, without a non-MaverickCrunch operation in between, i.e. a
nop.  

Essentially this extra code is run in arm_reorg, which is always run on
ARM, since an address can only be loaded a limited distance around the
pc.  Likewise for the MaverickCrunch coprocessor, we only have an 8-bit
word offset, which means a max 1024 byte offset, minus the 8 byte
minimum jump, etc.

Now, it seems whether this patch is applied (and turned on) or not
applied I get "co-processor offset out of range" errors, because of the
extra NOPs inserted between the jump and original label point.  I think
this in turn shifts the offset.  I can't see anyway to easily
recalculate or fix the coprocessor offset instructions, since this
happens AFTER the instruction has been generated.

I tried to hack around this by putting 2 NOPs before all cirrus
instructions, and modifying the length of each instruction.  I think
this means
that the coprocessor offset will be correct, since the NOP has been
generated BEFORE the instruction was generated.  However, it will mean
that all cirrus instructions are slower, since some will have additional
unneccessary NOPs appended before them.  I don't think that alone will
work, though...

I think the "co-processor offset out of range" error is generated
because of the cfldrs and cfldrd instructions.  These are used to Load
Floating Point Values from Memory into MaverickCrunch registers
directly.  I commented out the cirrus_movsf / cirrus_movdf insn patterns
(in asm generation), and it removed the error.  Does this mean that
someone calculated the pool_range & neg_pool_range attrs incorrectly, or
are the constraints I talk about below missing?

Is there something else in arm.c/h that I should be looking at?
arm_legitimate_index_p ??? arm_coproc_mem_operand ???
EXTRA_CONSTRAINT_STR_ARM ?

'Uv' is an address valid for VFP load/store insns. - i.e. doesn't
support writeback
'Uy' is an address valid for iwmmxt load/store insns. - i.e. supports
writeback

Is there supposed to be something similar for FPA / Maverick load/store
insns?  Or should it use the Uy mode?  Only the VFP supports the
writeback modes?  Autoincrement / decrement modes?  Only VFP does this,
I think...  I think m mode is only used for r->mE and m->r.  w->UvE & Uv
-> w for VFP.  y -> yrUy & yrUy -> y for iwMMXt.  However, this isn't
done for FPA.

Is this a bug for FPA?  Or hasn't it been picked up since no-one really
uses FPA?

Also, once I get the code doing what it's supposed to do, and generate a
patch against svn HEAD, do I need to do anything else special besides
posting it to gcc-patches, and letting it go through the review process?

http://gcc.gnu.org/contribute.html mentions some forms for "Legal
Prerequisites"...
-------------- next part --------------
A non-text attachment was scrubbed...
Name: arm-crunch-cirrus-bugfixes.patch
Type: text/x-patch
Size: 18578 bytes
Desc: not available
URL: <https://gcc.gnu.org/pipermail/gcc/attachments/20070628/d1c342bc/attachment.bin>


More information about the Gcc mailing list