GCC as a Cross Compiler for CPU32 target

Olivier Carmona olivier.carmona@di.epfl.ch
Thu Nov 20 03:22:00 GMT 1997

First of all, I would like to know if there is any official archive site
for this mailing list .

Second, I have several questions about GCC / GAS / LD and I hope these
questions have not been asked before...

I am working with GCC configured as a cross-compiler on
a Sun host (but also on a PC host thanks to canadian cross compile)
and a motorola CPU32 target corresponding to m68k-none-aout in GCC jargon.

My first problem was when compiling libgcc due to an optimized "tstl
a4" incorporated in _floatdixf : I have seen some unofficial patches
but I hope next version of GCC will suppress this bug.

My second problem was that tst[bwl] definition in binutils/opcodes/m68k-opc.c
is not correct instead of :

{"tstb",        one(0045000),  
one(0177700), ";b", m68020up|cpu32|mcf5200 },
{"tstb",        one(0045000),  
one(0177700), "@b", m68000up },
{"tstw",        one(0045100),  
one(0177700), "*w", m68020up|cpu32|mcf5200 },
{"tstw",        one(0045100),  
one(0177700), "@w", m68000up },
{"tstl",        one(0045200),  
one(0177700), "*l", m68020up|cpu32|mcf5200 },
{"tstl",        one(0045200),  
one(0177700), "@l", m68000up },

I think, it should be :

{"tstb",        one(0045000),  
one(0177700), ";b", m68020up|mcf5200 },
{"tstb",        one(0045000),  
one(0177700), "@b", m68000up },
{"tstw",        one(0045100),  
one(0177700), "*w", m68020up|mcf5200 },
{"tstw",        one(0045100),  
one(0177700), "@w", m68000up },
{"tstl",        one(0045200),  
one(0177700), "*l", m68020up|mcf5200 },
{"tstl",        one(0045200),  
one(0177700), "@l", m68000up },

My next problem was that I cannot use the CPU32 special instructions.
I have tried the MIT and the MOTOROLA notation but no way, it allways
answers :

Error: operands mismatch -- statement `tblu.l a2,d2' ignored

I fixed by using directly the opcode but is there any correct solution

Another problem was the generation of position independent code for
this target. Is there any solutions which is not using 68020 addressing

My last problem is the creation of some "org" like macro for assembler.
I don't want to modify definitively the location counter as "org" does
in GAS but instead manipulate data structure like the following :

H.pc1   lo.l    1
H.pc2   lo.l    1

4  Stack Offset Definition
S.a5    do.l    1 caller's a5
S.a6    do.l    1 caller's a6
S.func do.w    1 trap function code
S.vect   do.w    1 vector number
S.pc    do.l    1 return pc
which would give the following value :

H.pc1 = 0

H.pc2 = 4

S.a5 = 4

S.a6 = 0

S.func = -4

S.vect = -6

S.pc = -8

Thanks in advance for your help,

Olivier Carmona
Assistant de Recherche au Laboratoire de Micro-Informatique
IN-F-132, LAMI-EPFL, 1015 Lausanne, Suisse
Configuration de binutils :

./configure --target=m68k-none-aout --prefix=/home/new_gcc68k/binutils

Configuration de gcc :

./configure --target=m68k-none-aout --prefix=/home/new_gcc68k 

mv /home/new_gcc68k/binutils/m68k-none-aout /home/new_gcc68k

Mis dans /usr/local/m68k=none-aout tout le necessaire

Pour lire les fichiers assembleurs generes par l'ancien compilateur C (sun2-gcc) :

as --register-prefix-optional -o essai.o essai.s

Il est possible de compiler avec une virgule fixe grace l'option -msoft-float dans le cas ou l'unite flottante n'est pas disponible.

Cette version compile aussi en C++.

Mais ou se trouve les crt0.o ?

-fPIC : Option GCC pour Position Independent Code ? marche sur 68020 pas 68000 ou 68010

-m68332 = -m68020 + -m68332 pb avec les tstl a3

-m68302 = -m68000 + -m68302

Modif de insn-output.c pour que tstl a0 soit supprime meme si 68020

Bug : supprimer _floatdixf de la librairie libgcc2.a (dans Makefile) en fait genere un tstl a4 indesirable pour le 68000.
      autre solution (ne marche pas) :
For some strange reason GCC 2.7.2.x generates bad assembler code
for the M68000 during optimization.  Try adding this flag to the
compiler make process:
        make TARGET_LIBGCC2_CFLAGS=-oO

Modifie dans binutils/opcodes/m68k-opc.c tst[bwl] valable pour 6820up & mfc500 & cpu32:
{"tstb",        one(0045000),   one(0177700), ";b", m68020up|cpu32|mcf5200 },
{"tstb",        one(0045000),   one(0177700), "@b", m68000up },
{"tstw",        one(0045100),   one(0177700), "*w", m68020up|cpu32|mcf5200 },
{"tstw",        one(0045100),   one(0177700), "@w", m68000up },
{"tstl",        one(0045200),   one(0177700), "*l", m68020up|cpu32|mcf5200 },
{"tstl",        one(0045200),   one(0177700), "@l", m68000up },
au lieu de :
{"tstb",        one(0045000),   one(0177700), ";b", m68020up|mcf5200 },
{"tstb",        one(0045000),   one(0177700), "@b", m68000up },
{"tstw",        one(0045100),   one(0177700), "*w", m68020up|mcf5200 },
{"tstw",        one(0045100),   one(0177700), "@w", m68000up },
{"tstl",        one(0045200),   one(0177700), "*l", m68020up|mcf5200 },
{"tstl",        one(0045200),   one(0177700), "@l", m68000up },

Modif dans Makefile de GCC :
LIBGCC2_INCLUDES = -I/usr/include
CC = gcc
-fPIC impossible car genere des jbsr label,a1 : Label Sun (cf config/m68k/m68k.md) definir MOTOROLA et USE_GAS dans C_FLAGS

Modif de *crt0.s pour supprimer le jump. et ajout des variables ROF_DATA, ROF_TEXT et ROF_BSS corectement mises plus suppression de _rof_data, _rof_text et _rof_bss en lieu et place.

Seul elf supporte l'ecriture en PIC. D'ou la recompil de binutils puis gcc :

./configure --target=m68k-none-elf --prefix=/home/new_gcc68k/binutils

./configure --target=m68k-none-sysv4 --prefix=/home/new_gcc68k

PIC Information :

;; For PIC calls, in order to be able to support
;; dynamic linker LAZY BINDING, all the procedure calls need to go
;; through the PLT (Procedure Linkage Table) section in PIC mode.
;; PIC calls are handled by loading the address of the function into a
;; register (via movsi), then emitting a register indirect call using
;; the "jsr" function call syntax.
;; When outputting MIT syntax (e.g. on Suns), we add a bogus extra
;; operand to the jbsr statement to indicate that this call should
;; go through the PLT (why? because this is the way that Sun does it).
;; We have different patterns for PIC calls and non-PIC calls.  The
;; different patterns are only used to choose the right syntax.
;; The svr4 m68k assembler recognizes this syntax: `bsr FUNC@PLTPC' and it
;; will create the correct relocation entry (R_68K_PLT32) for `FUNC',
;; that tells the linker editor to create an entry for `FUNC' in PLT
;; section at link time. However, all global objects reference are still
;; done by using `OBJ@GOT'. So, the goal here is to output the function
;; call operand as `FUNC@PLTPC', but output object operand as `OBJ@GOT'.
;; We need to have a way to differentiate these two different operands.
;; The strategy I use here is to use SYMBOL_REF_FLAG to differentiate
;; these two different operands. The macro LEGITIMATE_PIC_OPERAND_P needs
;; to be changed to recognize function calls symbol_ref operand as a valid
;; PIC operand (by checking whether SYMBOL_REF_FLAG is set). This will
;; avoid the compiler to load this symbol_ref operand into a register.
;; Remember, the operand "foo@PLTPC" cannot be called via jsr directly
;; since the value is a PC relative offset, not a real address.
;; All global objects are treated in the similar way as in SUN3. The only
;; difference is: on m68k svr4, the reference of such global object needs
;; to end with a suffix "@GOT" so the assembler and linker know to create
;; an entry for it in GOT (Global Offset Table) section. This is done in
;; m68k.c.

;; General case of fullword move.
;; This is the main "hook" for PIC code.  When generating
;; PIC, movsi is responsible for determining when the source address
;; needs PIC relocation and appropriately calling legitimize_pic_address
;; to perform the actual relocation.
;; In both the PIC and non-PIC cases the patterns generated will
;; matched by the next define_insn.

;; This is the second "hook" for PIC code (in addition to movsi). See
;; comment of movsi for a description of PIC handling.
(define_expand "cmpsi"

/* Emit a (use pic_offset_table_rtx) if we used PIC relocation in the
   function at any time during the compilation process.  In the future
   we should try and eliminate the USE if we can easily determine that
   all PIC references were deleted from the current function.  That would
   save an address register */

finalize_pic ()

      asm_fprintf (stream, "\t%Olea (%Rpc, %U_GLOBAL_OFFSET_TABLE_@GOTPC), %s\n"
      asm_fprintf (stream, "\tmovel %0I__GLOBAL_OFFSET_TABLE_, %s\n",
      asm_fprintf (stream, "\tlea %Rpc@(0,%s:l),%s\n",

/* A C compound statement to output to stdio stream STREAM the
   assembler syntax for an instruction operand that is a memory
   reference whose address is ADDR.  ADDR is an RTL expression.

   Note that this contains a kludge that knows that the only reason
   we have an address (plus (label_ref...) (reg...)) when not generating
   PIC code is in the insn before a tablejump, and we know that m68k.md
   generates a label LInnn: on such an insn.

   It is possible for PIC to generate a (plus (label_ref...) (reg...))
   and we handle that just like we would a (plus (symbol_ref...) (reg...)).

   Some SGS assemblers have a bug such that "Lnnn-LInnn-2.b(pc,d0.l*2)"
   fails to assemble.  Luckily "Lnnn(pc,d0.l*2)" produces the results
   we want.  This difference can be accommodated by using an assembler
   define such "LDnnn" to be either "Lnnn-LInnn-2.b", "Lnnn", or any other
   string, as necessary.  This is accomplished via the ASM_OUTPUT_CASE_END
   macro.  See m68k/sgs.h for an example; for versions without the bug.
   Some assemblers refuse all the above solutions.  The workaround is to
   emit "K(pc,d0.l*2)" with K being a small constant known to give the
   right behaviour.

   They also do not like things like "pea 1.w", so we simple leave off
   the .w on small constants.

   This routine is responsible for distinguishing between -fpic and -fPIC
   style relocations in an address.  When generating -fpic code the
   offset is output in word mode (eg movel a5@(_foo:w), a0).  When generating
   -fPIC code the offset is output in long mode (eg movel a5@(_foo:l), a0) */

/* Legitimize PIC addresses.  If the address is already
   position-independent, we return ORIG.  Newly generated
   position-independent addresses go to REG.  If we need more
   than one register, we lose.

   An address is legitimized by making an indirect reference
   through the Global Offset Table with the name of the symbol
   used as an offset.

   The assembler and linker are responsible for placing the
   address of the symbol in the GOT.  The function prologue
   is responsible for initializing a5 to the starting address
   of the GOT.

   The assembler is also responsible for translating a symbol name
   into a constant displacement from the start of the GOT.

   A quick example may make things a little clearer:

   When not generating PIC code to store the value 12345 into _foo
   we would generate the following code:

        movel #12345, _foo

   When generating PIC two transformations are made.  First, the compiler
   loads the address of foo into a register.  So the first transformation makes:

        lea     _foo, a0
        movel   #12345, a0@

   The code in movsi will intercept the lea instruction and call this
   routine which will transform the instructions into:

        movel   a5@(_foo:w), a0
        movel   #12345, a0@

   That (in a nutshell) is how *all* symbol and label references are
   handled.  */

Il est possible de gerer soit meme le Position Independent Code.

Pour cela il faut mettre avant l'assembleur un traitement des @GOT en exces et
creer la Global Offset Table.
Il faut aussi faire des crt0 adaptes ainsi que les bouts de librairies en assembleur et l'ajout du symbole __GLOBAL_OFFSET_TABLE_.

Il serait interessant de faire des librairies trigonometriques adaptes au cpu32.

glibc : --nfp needed, probleme avec ENOMSG (errno.h) modif de errno.h a la racine ajout de la valeur de ENOMSG i.e 35,

Pour generer du code ROMable, il faut utiliser le format binary ieee : le seul a
supporter les sauts de .data au meme point que le .text.

More information about the crossgcc mailing list