It's basically set at the beginning of the __MERGED segment, or, if that grows larger than 32K, right in the middle so data can be accessed with positive or negative offsets. I don't think the manual states that, at least I don't remeber having it seen there. The trick for library code is that it is reloaded relative to the library base, and not relative to the __MERGED segment, so the data is allocated by exec when the library is created, allowing the lib to be placed in ROM.
It looks like vlink for the 68k Amiga will use the value 0x7ffe (32766) for the small data __MERGED section offset unless overridden.
No, look, the lea __NEAR(a4),a6 is never seen by the assembler. The __NEAR section is generated by the linker (or not generated at all, in case of the library), and SLink is smart about to which point of the segment a4 will point, depending on how large the data is. Thus, in the end, __NEAR can be zero, or 0x8000, or some other value, if constant data is moved into the __MERGED segment that is addressed by absolute addresses rather than relative to a4. Thus, it is only the linker that knows what the symbol will be, and it is the linker that puts it in. For layers, the library base is so small that it is just put at the beginning and __NEAR remains zero, but when the linker puts in the zero offset, it is too late to patch up the code for a smaller move instruction as the linker would have to resolve all relative branches around such lea's. Which, of course, it cannot do since the references are simply lost at this point. The best it could do is to replace it by a move and a NOP, but that's not exactly an improvement either (in fact, it spills the pipeline).
I see what you mean about the lea __NEAR(a4),a6 optimization now. The symbol isn't evaluated until link time after the assembler. Vbcc does have cross-module optimizations (high optimization levels have bugs so I don't generally use more than -O2) which could take care of the JSR->BSR and JMP->BRA optimization I talked about earlier but it's highly doubtful it would be able to take care of symbols that are defined for the linker. Vbcc's 68k backend generated assembler code for loading the small data base looks like this.
xref t_LinkerDB
lea t_LinkerDB,a4
That's not going to work as the library base is dynamically allocated making it impossible to put a label (t_LinkerDB) there. I believe it would need a "MOVE.L custom_DB,a4" or similar. So much for my hopes of being able to use most of the small data handling. It looks like it would need some custom work in the backend to make it happen and it's tricky. Here are links to the vbcc 68k backend (machine.c) and startup.asm so you can have a look.
http://www.heywheel.com/matthey/Amiga/machine.chttp://www.heywheel.com/matthey/Amiga/startup.asmFrank Wille can be e-mailed for the latest version of the vbcc sources.
if you think vbcc is lacking in comparison with sas/c it might be work to talk to phx personally. perhaps there is room for improvement. i have a feeling he is open for suggestions and it would be great to have an up to date compiler for amiga-m68k that is actively maintained and aware of system requirements, which apparently is not the simplest case when going with gcc.
If we could figure out what to do, we could make the changes and do the testing but Volker would need to look it over and ok it. The backend is complex enough that it's easy to have unintended consequences with changes.
This was an optimizing 'C' compiler intended for use on Sun 2 / Sun 3 workstations, which was adapted so that it emitted Amiga compatible 68k assembly language source code (as an intermediate language). That source code was then translated using a 'C' language precursor version of the ancient "assem" assembler into object code format suitable for linking. Mind you, this was not an optimizing assembler, just a plain translator. All optimizations happened strictly within the 'C' compiler.
What exactly rubs you the wrong way with Intuition?
There isn't anything wrong with how the Green Hill's compiler works but there are signs of lack of maturity in the compiler like this:
movea.w ($c,a3),a0 ; movea.w moves and then sign extends to a longword
move.l a0,d7 ; d7 is used later so this is needed
ext.l d7 ; Unnecessary instruction! We are already sign extended!
movea.l d7,a0 ; Unnecessary instruction! We are already sign extended!
Waste: 2 instructions, 4 bytes
movea.w ($1c,a0),a1 ; movea.w moves and then sign extends to a longword
move.l a1,d1 ; Unnecessary instruction! d1 is not used later!
ext.l d1 ; Unnecessary instruction! We are already sign extended!
movea.l d1,a1 ; Unnecessary instruction! We are already sign extended!
cmpa.l a3,a1
Waste: 3 instructions, 6 bytes, 1 scratch register
cmpi.l #$f3333334,d2
blt lab_1521c
cmpi.l #$f3333334,d2 ; Unnecessary big instruction! CC from first cmpi still valid
bne lab_1521c
Waste: 1 instruction, 6 bytes
divs.w #2,d0 ; could be asr.l #1,d0 as the remainder is unused
Waste: 2 bytes and a bunch of cycles
move.l d0,d0 ; funny or should we say scary way to do a tst.l
seq d0 ; the next 3 instructions could be replaced with and.l #1,d0
neg.b d0
ext.w d0 ; 68020 extb.l could replace next 2 instructions
ext.l d0
lea ($c,sp),sp
ext.l d0 ; Unnecessary instruction!
Waste: 3 instructions, 2 bytes
When I see MOVE.L Dn,Dn, I know the compiler has problems with it's register management. Compilers repeat the same mistakes of course. Add in all the function stubs because it can't do registerized function parameters and it's pretty ugly. It might be passable for a 68000 but for a 68020+ there are a lot of places that EXTB.L could be used, MOVE.L mem,mem instead of MOVE.B mem,mem and index register scaling in addressing modes.