This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

ARM machine description: how are pool_ranges calculated


Hi!
   I'd appreciate help with my learner's questions about GCC machine
descriptions, about the ARM code generator.
   I'm trying to fix code generation for the Cirrus MaverickCrunch FPU
by trying to understand several sets of patches, figure out which are
bogus which are buggy and which need reimplementing, and to distill
the essence of them into one "proper" set, but each day I'm ending up
confused by too many things about MDs that I am not certain of, so
some help would be appreciated.
  On with the first question...

ARM machine description and pool ranges:
   How should the value in the pool_range and neg_pool_range
attributes be calculated?
   What precisely do the values represent?

Here's how far I got:
   In the machine description, the pool_range and neg_pool_range
attributes tell how far ahead or behind the current instruction a
constant can be loaded relative to the current instruction.
The most common values are:
  - a sign bit and a 12-bit byte offset for ARM load insns (+/- 0 to
4095 bytes, max usable of 4092 for 4-byte-aligned words)
  - a sign bit and an 8-bit word offset for Maverick and VFP load
insns (+/- 0 to 1020 bytes)
  - other ranges for thumb instructions and iwmmxt, depending on insn
and addressing mode

When the offsets stored in the instructions are used, they refer to
offsets from the address of the instruction (IA) plus 8 bytes. Are the
pool_ranges also calculated from IA+8, from the address of the
instruction itself or even from the address of the following
instruction (IA+4)?

In the md, the most common pairs of values are (-4084, +4096) (-1008,
+1020) but there several other values in use for no obvious reason:
+4092, -1004, -1012, +1024
The +4096 (>4092) suggests that they are not the values as encoded in
the instruction, but are
offset by at least 4.
The full useful ranges offset by 8 would give (-4084, +4100) (-1016, +1028)

I can't find a mathematically explicit comment about it, and can't
make sense of the values.

In practice, by compiling autogenerated test programs and objdumping them -d:
32-bit integer constants use from [pc, #-4092] to [pc, #4084]
64-bit constants in pairs of ARM registers use from [pc, #-3072] to
[pc, #3068] (??)
Alternating 32- and 64-bit constants use from [pc, #-3412] to [pc, #3404] (???)
64-bit doubles in Maverick registers use from [pc, #-1020] to [pc,
#1008] (these are the exact values specified in the attributes fields
of cirrus.md for the cfldrd insn, without any IA+8 adjustment!)

Two non-issues
 - 64-bit alignment requirement for 64-bit quantities in EABI is not
applied to the constant pools - 64-bit data is 32-bit aligned there,
so no allowance of a possible extra 4 bytes for alignment is
necessary.
 - the -mcirrus-fix-invalid-insns flag, which peppers the output with
NOPs, causes no problems since the constant pool calculations are done
after the NOP-insertion.

Hoping I haven't just failed to spot some large and obvious comment...

     M


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]