English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Language > Coders. C/C++

 
 
Thread Tools
Old 16 September 2019, 23:43   #1
Hedeon
Semi-Retired
 
Join Date: Mar 2012
Location: Leiden / The Netherlands
Posts: 2,002
VBCC: How to use small code/data models with nostdlib

Hi,

I am coding a library in C with VBCC and like it to use as much 16 bit relative references as possible (and not 32 bit reloc). I believe this is done with the -sc and -sd options.

However, the linker complains about _SDA_BASE_ not being present, which I assume is in some startup.o file that is not linked due to nostdlib (which I use because it is an amiga library).

How can I use small code/data models with standard amiga (resident) libraries?
Hedeon is offline  
Old 16 September 2019, 23:47   #2
Hedeon
Semi-Retired
 
Join Date: Mar 2012
Location: Leiden / The Netherlands
Posts: 2,002
Edit:

The error only happens with small data model, not small code model.

Edit2:

While I have your attention: in the manual it states

In the small code model calls to external functions (i.e. from libraries or other object files) are done with 16bit offsets through the program counter rather than with absolute 32bit addresses.

Why not for calls to internal functions? If function A calls function B in the same object file, i see that it is done with a 32 bit reloc JSR and not PC relative.

Last edited by Hedeon; 17 September 2019 at 00:09.
Hedeon is offline  
Old 17 September 2019, 10:43   #3
bebbo
bye
 
Join Date: Jun 2016
Location: Some / Where
Posts: 680
Quote:
Originally Posted by Hedeon View Post
Hi,

I am coding a library in C with VBCC and like it to use as much 16 bit relative references as possible (and not 32 bit reloc). I believe this is done with the -sc and -sd options.

However, the linker complains about _SDA_BASE_ not being present, which I assume is in some startup.o file that is not linked due to nostdlib (which I use because it is an amiga library).

How can I use small code/data models with standard amiga (resident) libraries?

The linker has to calculate offsets. That symbol is usually the start of data+bss plus an arbitrary offset (maybe -32768).


That address must be loaded into the a4 reg.


For resident programs, you have to copy data+bss into allocated memory and set a4 to your alloceted memory...
... don't forget to patch relocations, if present.
bebbo is offline  
Old 17 September 2019, 10:44   #4
bebbo
bye
 
Join Date: Jun 2016
Location: Some / Where
Posts: 680
Quote:
Originally Posted by Hedeon View Post
Edit:

The error only happens with small data model, not small code model.

Edit2:

While I have your attention: in the manual it states

In the small code model calls to external functions (i.e. from libraries or other object files) are done with 16bit offsets through the program counter rather than with absolute 32bit addresses.

Why not for calls to internal functions? If function A calls function B in the same object file, i see that it is done with a 32 bit reloc JSR and not PC relative.

Optimizing jumps and calls inside one file is the assemblers job.
=> also have a look at the disassembly of the *.o files.
bebbo is offline  
Old 17 September 2019, 11:11   #5
Hedeon
Semi-Retired
 
Join Date: Mar 2012
Location: Leiden / The Netherlands
Posts: 2,002
Quote:
Originally Posted by bebbo View Post
Optimizing jumps and calls inside one file is the assemblers job.
=> also have a look at the disassembly of the *.o files.
Ack, so I looked at the wrong manual (vbcc). I see that vasm supports the "near code" directive to just do that. Thanks

Question is now how to add directives to assembler through c source...

Last edited by Hedeon; 17 September 2019 at 12:05.
Hedeon is offline  
Old 17 September 2019, 11:15   #6
Hedeon
Semi-Retired
 
Join Date: Mar 2012
Location: Leiden / The Netherlands
Posts: 2,002
Quote:
Originally Posted by bebbo View Post
The linker has to calculate offsets. That symbol is usually the start of data+bss plus an arbitrary offset (maybe -32768).


That address must be loaded into the a4 reg.


For resident programs, you have to copy data+bss into allocated memory and set a4 to your alloceted memory...
... don't forget to patch relocations, if present.
I had hoped on some simple switch I overlooked or a code snippet how it is handled by startup.o (could not find the source of that for vbcc)
Hedeon is offline  
Old 17 September 2019, 13:55   #7
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,500
Quote:
Originally Posted by Hedeon View Post
Ack, so I looked at the wrong manual (vbcc). I see that vasm supports the "near code" directive to just do that.
The "near code" directive does the same as vasm's -sc option: it converts all absolute JMP/JSR with external labels into PC-relative JMP/JSR.
Absolute references to known labels within the source are automatically optimized, as Bebbo already pointed out.

Quote:
Question is now how to add directives to assembler through c source...
You don't have to. vbcc's -sc option will emit the "near code" directive automatically. But if you really want assembler code or directives in your C source, you can use __asm(" ... "). Check the output (-S).

Quote:
Originally Posted by Hedeon View Post
I had hoped on some simple switch I overlooked or a code snippet how it is handled by startup.o (could not find the source of that for vbcc)
It is really simple. Bebbo already gave the answer. The Small Data model uses a base pointer in A4, which always points 32766 bytes into the merged Data-Bss section, thus covering a region of 64K. When you link several object files, then only the linker can reliably calculate this pointer for you. Most AmigaOS linkers offer the Small Data pointer via the symbol _LinkerDB. Unix-linkers prefer _SDA_BASE_. vlink defines both.

All you have to do is load this symbol into A4 to initialize the small data model. From vbcc's startup.o (if you want the full source, email me):
Code:
        xref    _LinkerDB
...

        ;------ init small data, get Exec library base pointer (phx)
        far
                lea     _LinkerDB,a4
        near    a4,-2
                move.l  sp,initialSP(a4)
You wrote in your first message that you are writing a library. If you are refering to an AmigaOS shared library (in contrast to linker library) then you have to be careful with small data. Otherwise you can ignore the rest.

Any process might call any function from your library and doesn't know about small data, so A4 is not correctly initialized. What you would have to do is to set up A4 at the beginning of all your library functions. When the functions are short and do not access much static data, then this would be unnecessary overhead. If you want to do that nevertheless, you can use the __saveds attribute, which most Amiga compilers accept for saving and reinitializing the base pointer in A4.

If I would do a shared library, then I wouldn't use any static variables. Put that data (like base-pointers to other libraries) into the library base structure.
phx is offline  
Old 17 September 2019, 14:19   #8
Hedeon
Semi-Retired
 
Join Date: Mar 2012
Location: Leiden / The Netherlands
Posts: 2,002
Well, I checked the linked result (.library) with IRA and that is where the question came from. I use -sc but I see 32 bit reloc jumps in the code. I thought that was because the vbcc manual says -sc only works for jumps to external (like in other object file) functions. I could give a small example if needed?

So far I only have 1 object file (libinit.o). The problem is that I need to move part of the code to a different memory type that is set up by the library itself (so not available at library start). It is a rewrite of my powerpc.library from asm to C for educational purposes (to start with and later for ease of maintenance). The asm is fully PC relative.

What happens is that AUTOINIT is off and the libinit function sets up the tables etc (initresident/makelibrary etc). The 68K functions remain in FAST RAM, the PPC functions need to be in a different kind of RAM (attr $2005) where also the library base will be. This memory s not available yet at the init of the library.

Regarding the answer from bebbo, it looked a lot of manual work. I thought maybe it was supposed to be easier, my bad. Can it be done in C as your example is in asm?

You're last point is a good one. I should utilize the library base better.

I am still a beginner in this kind of stuff. Changing code is a lot different from starting afresh or just copy/pasting
Hedeon is offline  
Old 17 September 2019, 15:06   #9
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,500
Quote:
Originally Posted by Hedeon View Post
Well, I checked the linked result (.library) with IRA and that is where the question came from. I use -sc but I see 32 bit reloc jumps in the code.
Hmmm... yes. The reason is in the linker libraries, not in your code. Even if you compile with -sc and -sd and link with -lvcs, the vcs.lib itself was only compiled with -sd, but not with -sc. So all calls from the vcs.lib are absolute.

I wonder if I should change that for the upcoming release. When you link with a small-data library, does it make sense to always have small-code as well? Probably.

Quote:
It is a rewrite of my powerpc.library from asm to C for educational purposes (to start with and later for ease of maintenance).
You seem to have too much time!

Quote:
What happens is that AUTOINIT is off and the libinit function sets up the tables etc (initresident/makelibrary etc). The 68K functions remain in FAST RAM, the PPC functions need to be in a different kind of RAM (attr $2005) where also the library base will be. This memory s not available yet at the init of the library.
Ok. The PowerOpen-ABI code should be more or less PC-relative anyway. As I understand you only have to allocate the library base structure in $2005-RAM and put everything in it. Doesn't that work?

Quote:
Regarding the answer from bebbo, it looked a lot of manual work. I thought maybe it was supposed to be easier, my bad. Can it be done in C as your example is in asm?
Sure. Just start your first init-function with the __saveds attribute. The code generator will emit code for setting up A4 in the function header.

Quote:
You're last point is a good one. I should utilize the library base better.
Yes. See above. Perhaps you don't even need to set up small data for m68k.
phx is offline  
Old 17 September 2019, 15:50   #10
Hedeon
Semi-Retired
 
Join Date: Mar 2012
Location: Leiden / The Netherlands
Posts: 2,002
Quote:
Originally Posted by phx View Post
Hmmm... yes. The reason is in the linker libraries, not in your code. Even if you compile with -sc and -sd and link with -lvcs, the vcs.lib itself was only compiled with -sd, but not with -sc. So all calls from the vcs.lib are absolute.
Hmm. I made a cleanup function which tests lib bases and if not zero closes it. The jumps to this function seem to be 32 bit reloc for example. I'll give a disassembly later tonight.

Quote:
Ok. The PowerOpen-ABI code should be more or less PC-relative anyway. As I understand you only have to allocate the library base structure in $2005-RAM and put everything in it. Doesn't that work?
Almost. The base structure I completely construct from scratch BUT I need to copy the ppc functions. But how to find the start and end of the memory range to copy as I understand functions can be re-ordered. Maybe just copy the whole segment (which I can find through the seglist).

Thanks for all your help.
Hedeon is offline  
Old 17 September 2019, 15:52   #11
Hedeon
Semi-Retired
 
Join Date: Mar 2012
Location: Leiden / The Netherlands
Posts: 2,002
Quote:
Originally Posted by phx View Post
You seem to have too much time!
It is more that the energy is returning

I have something to show to people coming to the ACM too (PPC software related).
Hedeon is offline  
Old 17 September 2019, 20:27   #12
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,500
Quote:
Originally Posted by Hedeon View Post
Hmm. I made a cleanup function which tests lib bases and if not zero closes it. The jumps to this function seem to be 32 bit reloc for example. I'll give a disassembly later tonight.
Please also give me all compiler-, linker-options you are using.

Quote:
But how to find the start and end of the memory range to copy as I understand functions can be re-ordered. Maybe just copy the whole segment (which I can find through the seglist).
You make that extra-hard by going the C-only route.
As long as you don't use cross-module optimizations with -O4 you should be safe when putting the first function alone into an object file, and maybe define another single dummy function in another object file, which you make sure to link as the last module.
phx is offline  
Old 17 September 2019, 22:36   #13
Hedeon
Semi-Retired
 
Join Date: Mar 2012
Location: Leiden / The Netherlands
Posts: 2,002
Line I use is

vc -cpu=68040 -nostdlib -c99 -sc -Ivincludeos3: -Iinclude_h: -O2 -S libinit.c

snippet of C code
Code:
static struct PPCBase *LibInit(__reg("d0") struct PPCBase *ppcbase,
   __reg("a0") BPTR seglist, __reg("a6") struct *ExecBase SysBase)

if (!(SysBase->AttnFlags & (AFF_68040|AFF_68060)))
{
PrintCrtErr("This library requires a 68LC040 or better");
return NULL;
}
snippet of resulting asm:

Code:
machine 68040
near code
opt 0
opt NQLPSMBT
cnop 0,4

movem.l l108,-(a7)
move.l a6,a5
moveq #0,d7
moveq #0,d0
move.w (296.w,a5),d0
and.l #136,d0
bne l26
pea l27
jsr _PrintCrtErr
addq.w #4,a7
bra L23

Last edited by Hedeon; 17 September 2019 at 22:45.
Hedeon is offline  
Old 18 September 2019, 10:28   #14
Hedeon
Semi-Retired
 
Join Date: Mar 2012
Location: Leiden / The Netherlands
Posts: 2,002
the moveq #0,dx are from initializers I did not show in the C code snippet, if anyone is wondering.

So disassembling the resulting library with IRA gives JSR LAB_00xx instead of JSR LAB_00xx(PC) if someone is wondering if the assembling in combination with 'near code' will give the wanted result in the final executable. It does not.
Hedeon is offline  
Old 18 September 2019, 11:16   #15
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,500
I cannot reproduce that. Please check your assembler, or assembler options in the config file.

Example with vasm 1.8f:
Code:
frank@altair cat tst.asm 
        machine 68040
        near    code
        opt     0
        opt     NQLPSMBT
        cnop    0,4
        jsr     _PrintCrtErr
frank@altair vasmm68k_mot -Fhunk -phxass -o tst.o tst.asm
vasm 1.8f (c) in 2002-2019 Volker Barthelmann
vasm M68k/CPU32/ColdFire cpu backend 2.3d (c) 2002-2019 Frank Wille
vasm motorola syntax module 3.12b (c) 2002-2019 Frank Wille
vasm hunk format output module 2.9c (c) 2002-2018 Frank Wille

CODE(acrx4):               4 bytes
frank@altair vda68k tst.o
...
0000001c: 0000 03e9                 ori.b   #0xe9,d0
00000020: 0000 0001                 ori.b   #0x1,d0
00000024: 4eba 0000                 jsr     0x26(pc)
00000028: 0000 03ef                 ori.b   #0xef,d0
...
The "near code" directive should work reliably since vasm 1.7a.
For the options you may call vbcc with -v to view the actual vasm-call with all options provided.
phx is offline  
Old 18 September 2019, 20:28   #16
Hedeon
Semi-Retired
 
Join Date: Mar 2012
Location: Leiden / The Netherlands
Posts: 2,002
Your code example also produces here a pc relative jump, while my code does not. Can I send you my .asm file?
Hedeon is offline  
Old 18 September 2019, 21:33   #17
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,500
Ok, looked at your example (and replied the mail). There is no bug! Everything works as expected.

vbcc was told to generate 68040 code, and for this CPU it makes no sense to optimize absolute addressing modes to PC-relative, because they would become slower.
phx is offline  
Old 19 September 2019, 00:04   #18
Hedeon
Semi-Retired
 
Join Date: Mar 2012
Location: Leiden / The Netherlands
Posts: 2,002
Thanks for all the help phx and bebbo. All is well now
Hedeon is offline  
Old 30 September 2019, 16:54   #19
Hedeon
Semi-Retired
 
Join Date: Mar 2012
Location: Leiden / The Netherlands
Posts: 2,002
Quote:
Originally Posted by phx View Post
You don't have to. vbcc's -sc option will emit the "near code" directive automatically. But if you really want assembler code or directives in your C source, you can use __asm(" ... "). Check the output (-S).
I decided to cut the library in 3 hunk parts. A 68k part, a PPC setup part and a PPC functions part. I want to use the segment pointers to reach the different code parts.

Currently, when compiled there is a 68k hunk and a PPC hunk.

I want to give the ppc parts different .section names so they are also split in separate hunks. Now, __asm does not work outside of a function. And if I place it inside a function, only that function is placed in a separate code hunk and the others in the same .c file are not.

Is there a way to give a whole .c file a certain section name so that the linker does not merge all the PPC (which are now all .text) parts?
Hedeon is offline  
Old 01 October 2019, 16:55   #20
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,500
Quote:
Originally Posted by Hedeon View Post
Is there a way to give a whole .c file a certain section name so that the linker does not merge all the PPC (which are now all .text) parts?
Not for a whole .c file, but you overwrite the section for each function by using the __section(name,attributes) attribute. Example:
Code:
__section(".mytext","acrx") int myfunc(int a,int b)
"acrx" are the standard attributes for a code-section (std-syntax): allocated, code, readable, executable.
phx is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
vbcc code generation and dbf Asman Coders. C/C++ 15 12 March 2016 01:51
How to pass data to interrupt handler with VBCC? strim Coders. System 3 18 January 2016 14:38
Debugging vbcc code tolkien Coders. C/C++ 5 14 February 2015 06:45
VBCC code generation Asman Coders. C/C++ 9 17 August 2014 09:33
Mixed 68k / PPC code on VBCC. Cowcat Coders. General 10 01 August 2013 16:01

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 05:31.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.10256 seconds with 15 queries