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