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]

Re: error compiling libgcc with ported cross-compiler


On Tue, Sep 11, 2007 at 08:52:38AM +0200, Tomas Svensson wrote:
> Thanks a lot for your input, I think I understand some of that code better now.
> 
> I stumbled upon a solution last night, on realizing that the problem
> was with the DFmode powidf2 and seeing that I had not defined the
> movsf or movdf insns (because I thought I shouldn't need them, having
> no HW floating point support).

   You shouldn't define them, they'll only hide the problem.
 
> Defining them solved the problem, but now I have a very similar one
> with the complex arithmetic __mulsc3 function in libgcc:
> 
> /cygdrive/c/home/risc/src/gcc-4.1.2/gcc/libgcc2.c:1702: error: insn
> does not satisfy its constraints:
> (insn 1468 1467 1471
> /cygdrive/c/home/risc/src/gcc-4.1.2/gcc/libgcc2.c:1701 (set
> (mem/c/i:SF (plus:SI (mem/f/c:SI (plus:SI (reg/f:SI 29 r29)
>                         (const_int -296 [0xfffffed8])) [0 D.2393+0 S4 A8])
>                 (const_int 4 [0x4])) [0 <result>+4 S4 A8])
>         (reg:SF 0 r0 [orig:51 D.2338+4 ] [51])) 8 {movsf} (nil)
>     (nil))

   This is still the same problem that you had to begin with. Register 29 is
your stack pointer, frame pointer or something like that, isn't it?

   To understand why this fails, you should compile that function manually,
adding -fdump-rtl-lreg -fdump-rtl-greg and look at that same insn in the two
dump files produced. In the lreg dump, you had something like

(set (mem (plus (reg x) (const_int 4))
     (reg 0))

where x >= FIRST_PSEUDO_REGISTER. The function memory_address_p() (see
below) must accept this address and the function strict_memory_address_p()
must reject it.

   The lreg dump file contains the output of the local-alloc pass and the
greg dump file contains the output of the global-alloc and reload passes.
All passes before reload use memory_address_p(). All passes starting with
reload use strict_memory_address_p(). It is reload which turns (reg x) into
(mem (plus (reg r29) (const_int ...)) if x >= FIRST_PSEUDO_REGISTER. That's
why strict_memory_address_p() must reject such registers in memory
addresses. Reload will then figure out how to make strict_memory_address_p()
happy with the address.

   The macro GO_IF_LEGITIMATE_ADDRESS is used in two places in GCC:

$ grep -e '^memory_address_p ' -B 1 -A 7 gcc/recog.c
int
memory_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx addr)
{
  GO_IF_LEGITIMATE_ADDRESS (mode, addr, win);
  return 0;

 win:
  return 1;
}

$ grep -e '^strict_memory_address_p ' -B 1 -A 7 gcc/reload.c
int
strict_memory_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx addr)
{
  GO_IF_LEGITIMATE_ADDRESS (mode, addr, win);
  return 0;

 win:
  return 1;
}

   These two functions are supposed to be different! To debug your problem,
maybe you should save the preprocessed source of recog.c and reload.c, grep
the two functions (and probably run them though indent), then compare them.
If that still doesn't help, use a debugger. You can use "call debug_rtx
(addr)" to pretty-print the address.

   The way the two fuctions become different is that one has REG_OK_STRICT
defined and the other does not:

$ grep -F -e '#define REG_OK_STRICT' -e '#include "tm.h"' gcc/recog.c gcc/reload.c
gcc/recog.c:#include "tm.h"
gcc/reload.c:#define REG_OK_STRICT
gcc/reload.c:#include "tm.h"

-- 
Rask Ingemann Lambertsen


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