Jump to content
IGNORED

C compilers?


zezba9000

Recommended Posts

For cross compiling you can use gcc which is fully c/c++ compliant or vbcc which is c89 (with subset of c99) compliant. Raptor Basic+ is basically bcx transpiling into C/C++ which is then compiled (gcc) and linked into a Jaguar binary. Feel free to check it out.

 

So for 3D graphics lets say, the recommended way would be to use the gcc which targets the Motorola CPU and control the GPU from there using BCX or referencing the original ASM / SDK demos?

 

You know of any pros or cons for vbcc over gcc?

Link to comment
Share on other sites

So for 3D graphics lets say, the recommended way would be to use the gcc which targets the Motorola CPU and control the GPU from there using BCX or referencing the original ASM / SDK demos?

 

Well, that's what bcx is used for in rb+, just an easy way to control program the libraries running on the J-RISCs that do the actual work.

 

You know of any pros or cons for vbcc over gcc?

Well, obviously gcc targets proper c++. Other than that, its code generation should be more mature than vbcc's. If you like you can check it out the two compilers live here: http://brownbot.mooo.com/z/XwMJ3e(you're of course free to edit the code and see the output)

Link to comment
Share on other sites

I was going to set up a c based development environment so I could try out 'the removers' jaguar library but 'Raptor' came along so I haven't got around to it yet. Also, I am not sure if anyone has 'the removers' library working on a 'Windows' based system but hey, a reason to boot linux pleases me.

Link to comment
Share on other sites

After looking at this, I must change vbcc for gcc, where can I get the binaries for OS X?

#include <stdint.h>

int16_t test1(int16_t a, int16_t b)
{
    return a + b;
}

int16_t test2(int16_t a, int16_t b)
{
    return a * b;
}

gcc

#NO_APP
test1:
        move.w 6(%sp),%d0
        add.w 10(%sp),%d0
        rts
test2:
        move.w 6(%sp),%d0
        muls.w 10(%sp),%d0
        rts

vbcc

        idnt    "/tmp/compiler-explorer-compiler1181027-4406-u2ujbe.p5jvo/example.c"
        opt     0
        opt     NQLPSMRBT
        section "CODE",code
        public  _test1
        cnop    0,4
_test1
        movem.l l11,-(a7)
        move.w  (6+l13,a7),d0
        ext.l   d0
        move.w  (10+l13,a7),d1
        ext.l   d1
        add.l   d1,d0
l11     reg
l13     equ       0
        rts
        opt     0
        opt     NQLPSMRBT
        public  _test2
        cnop    0,4
_test2
        movem.l l14,-(a7)
        move.w  (6+l16,a7),d0
        ext.l   d0
        move.w  (10+l16,a7),d1
        ext.l   d1
        move.l  d0,d2
        move.l  d1,d3
        swap    d2
        swap    d3
        mulu.w  d1,d2
        mulu.w  d0,d3
        mulu.w  d1,d0
        add.w   d3,d2
        swap    d2
        clr.w   d2
        add.l   d2,d0
l14     reg       d2/d3
        movem.l (a7)+,d2/d3
l16     equ       8
        rts
  • Like 1
Link to comment
Share on other sites

After looking at this, I must change vbcc for gcc, where can I get the binaries for OS X?


#include <stdint.h>

int16_t test1(int16_t a, int16_t b)
{
    return a + b;
}

int16_t test2(int16_t a, int16_t b)
{
    return a * b;
}

gcc


#NO_APP
test1:
        move.w 6(%sp),%d0
        add.w 10(%sp),%d0
        rts
test2:
        move.w 6(%sp),%d0
        muls.w 10(%sp),%d0
        rts
vbcc


        idnt    "/tmp/compiler-explorer-compiler1181027-4406-u2ujbe.p5jvo/example.c"
        opt     0
        opt     NQLPSMRBT
        section "CODE",code
        public  _test1
        cnop    0,4
_test1
        movem.l l11,-(a7)
        move.w  (6+l13,a7),d0
        ext.l   d0
        move.w  (10+l13,a7),d1
        ext.l   d1
        add.l   d1,d0
l11     reg
l13     equ       0
        rts
        opt     0
        opt     NQLPSMRBT
        public  _test2
        cnop    0,4
_test2
        movem.l l14,-(a7)
        move.w  (6+l16,a7),d0
        ext.l   d0
        move.w  (10+l16,a7),d1
        ext.l   d1
        move.l  d0,d2
        move.l  d1,d3
        swap    d2
        swap    d3
        mulu.w  d1,d2
        mulu.w  d0,d3
        mulu.w  d1,d0
        add.w   d3,d2
        swap    d2
        clr.w   d2
        add.l   d2,d0
l14     reg       d2/d3
        movem.l (a7)+,d2/d3
l16     equ       8
        rts

 

As usual, the truth lies inbetween (http://brownbot.mooo.com/z/KLw0Y_):

 

int16_t test1__(int32_t a, int32_t b)
{
    return a + b;
}
_test1__
        movem.l l13,-(a7)
        move.l  (8+l15,a7),d0
        add.l   (4+l15,a7),d0
l13     reg
l15     equ       0
        rts
As usual, you always need to check the compiler's output and learn all the nuances and magic compiler switches :)

 

Also, when you start diffing output code between compilers you also start wondering. (http://brownbot.mooo.com/z/-3vjKr)

Link to comment
Share on other sites

Yes, I had problems compiling the binutils and I've just seen that link from here http://beyondbrown.mooo.com/post/gcc7/a few minutes ago

 

Thanks.

Well no problem - let me know if it works for you or if you encountered any issues with the script.

 

Also worth noting is that part of the build process is compiling MiNTlib, and maybe you can use parts of it on the Jaguar as well. Of course all I/O stuff is out, but maybe there's some useful bits.

Link to comment
Share on other sites

Ok I have a good chunk more work I need to get done on my transpiler (going well) and will use this as a starting point.

Making an agnostic API that will make it easy to target almost any graphics, audio or input pipeline (so in terms of Atari lets say, you could write an app that targets 2600 and it would for the most part just work on the Jaguar etc).

Edited by zezba9000
Link to comment
Share on other sites

I got this error.

dyld: Library not loaded: /opt/local/lib/libmpfr.4.dylib

I have libmpfr.6.dylib installed, I had to uninstall it, and reinstall and now I've version 3 and 6 but no 4. but the log says that I've installed version 4.0.1 WTF?!?

swapd0$ sudo port install mfr
--->  Computing dependencies for mpfr
--->  Fetching archive for mpfr
--->  Attempting to fetch mpfr-4.0.1_0.darwin_16.x86_64.tbz2 from http://lil.fr.packages.macports.org/mpfr
--->  Attempting to fetch mpfr-4.0.1_0.darwin_16.x86_64.tbz2.rmd160 from http://lil.fr.packages.macports.org/mpfr
--->  Installing mpfr @4.0.1_0
--->  Activating mpfr @4.0.1_0
--->  Cleaning mpfr
--->  Updating database of binaries
--->  Updating database of C++ stdlib usage
--->  Scanning binaries for linking errors
--->  No broken files found.
--->  No broken ports found.

swapd0$ ls /opt/local/lib/libmp*
/opt/local/lib/libmpc.3.dylib	/opt/local/lib/libmpfr.6.dylib
/opt/local/lib/libmpc.a		/opt/local/lib/libmpfr.a
/opt/local/lib/libmpc.dylib	/opt/local/lib/libmpfr.dylib
Link to comment
Share on other sites

If you have any issues that are the script's fault, you are welcome to raise an issue at https://bitbucket.org/ggnkua/bigbrownbuild/issues. Especially if you have a fix :)

 

Also I totally forgot I have packaged up gcc 8.2 for macs (built on El Capitan) here: http://d-bug.mooo.com/various/brownart.tar.bz2. So worst case you could give this a shot!

Link to comment
Share on other sites

As usual, the truth lies inbetween (http://brownbot.mooo.com/z/KLw0Y_):

 

int16_t test1__(int32_t a, int32_t b)
{
    return a + b;
}
_test1__
        movem.l l13,-(a7)
        move.l  (8+l15,a7),d0
        add.l   (4+l15,a7),d0
l13     reg
l15     equ       0
        rts
As usual, you always need to check the compiler's output and learn all the nuances and magic compiler switches :)

 

Also, when you start diffing output code between compilers you also start wondering. (http://brownbot.mooo.com/z/-3vjKr)

 

 

I haven't do 68k code from many years now but :

How does this work without a reverse movem before the rts ?

Does that mean a post-compile process is done to add instructions that is not in this assembly output ?

Edited by SCPCD
Link to comment
Share on other sites

It might be that the compiler's code printing is single pass, so at the time the movem.l is written the compiler has no idea if there are going to be any save/restore happening. So at the time the rts is written, it has decided that no register saving needs to happen, so the movem that would pop the stack is simply omitted.

 

Just out of interest, I pasted a more complex function from another thing I'm working on here: http://brownbot.mooo.com/z/TE8Pqj. The compiler is being instructed to push l90 into the stack, which at the end of the function we see that it's defined as "reg a2/a3/d2/d3/d4/d5/d6/d7".

 

In contrast, notice that l13 at the simple function is defined as pretty much nothing.

 

So I guess that vasm knows about this and in this case simply discards the superfluous movem.

  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...

I've installed gcc 8.2 and tested with the barebones example and it looks ok.

 

So I've started to change to make it work with the jaguar.

 

I've changed the brownboot.s to remove Atari ST specific code, and replaced for a start up code for the Jaguar, but I've the following issues questions.

 

- Do I must call _libc_scu_init from the Jaguar startup code?

 

- I have the following warnings, not sure if they are important.

libcxx/browncrti.gas: Assembler messages:
libcxx/browncrti.gas:14: Warning: ignoring incorrect section type for .preinit_array
libcxx/browncrti.gas:16: Warning: ignoring incorrect section type for .init_array
libcxx/browncrti.gas:18: Warning: ignoring incorrect section type for .fini_array

- After compiling I've the following message

note: reloc [toslink] refers to non-existent elf section

- How can I tell that the code must be fixed at 0x4000? I've seen in the linker docs that with -Wtext=0x4000 it should work, also I've tried with this script file, with no luck.

ENTRY(main)

SECTIONS
{
    . = 0x4000;
    .text : { *(.text)}
    .data : { *(.data)}
    .bss : { *(.bss)}
}

After make it generates an executable code but this is the code generated. The opcode jmp $8 must be jmp $4024, also the lea $2254,a7 has the wrong source address.

post-8823-0-46838200-1544631168.png

Link to comment
Share on other sites

I've installed gcc 8.2 and tested with the barebones example and it looks ok.

 

So I've started to change to make it work with the jaguar.

 

I've changed the brownboot.s to remove Atari ST specific code, and replaced for a start up code for the Jaguar, but I've the following issues questions.

 

- Do I must call _libc_scu_init from the Jaguar startup code?

This startup code was written by dml after a lot of experimentation. I seem to recall that this has to be called when you're using c++ things (constructors/destructors). At least this and this seems to indicate that this is the case. So for C only programs you can probably get away with not calling it

 

- I have the following warnings, not sure if they are important.


libcxx/browncrti.gas: Assembler messages:
libcxx/browncrti.gas:14: Warning: ignoring incorrect section type for .preinit_array
libcxx/browncrti.gas:16: Warning: ignoring incorrect section type for .init_array
libcxx/browncrti.gas:18: Warning: ignoring incorrect section type for .fini_array

 

I think this is not a biggie

 

- After compiling I've the following message


note: reloc [toslink] refers to non-existent elf section

 

Wait, that looks like output from brownout. This is our (me and dml's) tool that converts native elf binaries to TOS PRG compatible executables. Since you'll be linking to absolute addresses you most certainly don't need this!.

 

- How can I tell that the code must be fixed at 0x4000? I've seen in the linker docs that with -Wtext=0x4000 it should work, also I've tried with this script file, with no luck.


ENTRY(main)

SECTIONS
{
    . = 0x4000;
    .text : { *(.text)}
    .data : { *(.data)}
    .bss : { *(.bss)}
}
After make it generates an executable code but this is the code generated. The opcode jmp $8 must be jmp $4024, also the lea $2254,a7 has the wrong source address.

 

At least from my experiments you don't need a script file to perform this. In one of my project I've used something like the following line to link the final program:

 

gcc -m68000 -mshort -nostartfiles -nostdlib -o $FILENAME $ALL_OBJECT_FILES -Wl,--oformat,binary,-Ttext=0x00e00000,-Tbss=0x00000400,-e,ostext -Xlinker -Map=output.map
This links all .o files, instructs the linker to produce an absolute binary with the text segment located at $e00000, data will be immediately after text and bss will be at $400. Finally output a map file of all symbol addresses. Not sure the "-m68000 -mshort -nostartfiles -nostdlib" have any effect, but I probably use them in order to be 100% compatible with the way I compiled the source.

 

 

Hope this helps!

  • Like 1
Link to comment
Share on other sites

Ok, brownout removed.

 

I've included the gcc line to link the file but I get the source (ctest.c) file first at the output, don't know why I don't get the brownboot.o first because I got it the first one of the link rule.

.text           0x0000000000004000      0xb40
 *(.text.unlikely .text.*_unlikely .text.unlikely.*)
 *(.text.exit .text.exit.*)
 .text.exit     0x0000000000004000       0x12 ctest.elf
                0x0000000000004000                _exit
 *(.text.startup .text.startup.*)
 .text.startup.main
                0x0000000000004012       0x3a ctest.elf
                0x0000000000004012                _main
 .text.startup._GLOBAL__sub_I___assert_fail
                0x000000000000404c       0x56 ctest.elf
 *(.text.hot .text.hot.*)
 *(.text .stub .text.* .gnu.linkonce.t.*)
 *fill*         0x00000000000040a2        0x2 4e714e71
 .text          0x00000000000040a4        0x0 ctest.elf
 .text.__cxa_finalize
                0x00000000000040a4       0x5a ctest.elf
 .text.atexit   0x00000000000040fe       0x50 ctest.elf
 .text.fmtint   0x000000000000414e      0x26a ctest.elf
 .text.dopr     0x00000000000043b8      0x650 ctest.elf
 .text._ZN31MicroStartupForceStaticCtorDtorD2Ev
                0x0000000000004a08        0x2 ctest.elf
 .text.debug_printf
                0x0000000000004a0a       0x9e ctest.elf
 .text.my_atexit
                0x0000000000004aa8       0x16 ctest.elf
 .text.my_atexit2
                0x0000000000004abe       0x16 ctest.elf
 .text.vsnprintf
                0x0000000000004ad4       0x32 ctest.elf
                0x0000000000004ad4                _vsnprintf
 .text.snprintf
                0x0000000000004b06       0x3a ctest.elf
                0x0000000000004b06                _snprintf
 *(.gnu.warning)

CODE            0x0000000000004b40      0x73c
                [!provide]                        PROVIDE (__start_CODE, .)
 CODE           0x0000000000004b40      0x73c ctest.elf
                0x0000000000004b40                __crt_entrypoint
                0x0000000000004b40                _start
                0x0000000000004c4c                __exit
                0x0000000000004c4e                _memcpy
                0x0000000000004d68                _memset
                0x0000000000004dd6                ___mulsi3
                0x0000000000004dfa                ___modsi3
                0x0000000000004e1c                ___udivsi3

Link to comment
Share on other sites

hmmm

 

output with the gcc -m68000...

Wrong because that it's the beginning of ctest.c file

4000    clr.l -(sp)
4002    jsr l000002
4008    move.l 8(sp),-(sp)
...

output with brownout, at $4024 it's my start up code, but the jmp it's wrong because the code it's in relocatable format.

4000         bra l000001
4002         dc.b ...
401c l000001 jmp $8
4022         nop
4024         lea l000043,sp
402a         move.w $2700,sr
Link to comment
Share on other sites

It's been a while since we messed with this so memory is a bit hazy. Your main entry point is always at _main (or __main if you're compiling with underscores), but that doesn't help you much - you need to run your startup code first (brownboot.s is what we use).

 

What we discovered while developing brownout is that the binutils elf linker doesn't necessarily put objects in the order you ask it, especially your entry point.

 

The way we solved that is to inject a "bra.w" (or "jmp") at the very start of the code and then search for the location symbol "_start" (or "__start") which is the start of brownboot.s code. Then we patch the address during final program output.

 

For your case you could do something like set your TEXT start at $4006, then after ld does its job, take the output binary, insert a "jmp" opcode in front, then search the map file for your "_start" and plug that address after the "jmp". Not elegant but it should do the trick.

 

I'm not sure if there's a more elegant way but we didn't look into it further as we did have to perform the elf->prg conversion.

 

By the way, if you want to use output from brownout on jaguar you'll have to perform relocation on startup because that's how .prg files work.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...