Welcome, Guest. Please login or register.

Author Topic: Help needed combining GCC/C++ with asm sources  (Read 5725 times)

Description:

0 Members and 1 Guest are viewing this topic.

Offline PiR

  • Full Member
  • ***
  • Join Date: Apr 2003
  • Posts: 148
    • Show only replies by PiR
Re: Help needed combining GCC/C++ with asm sources
« Reply #14 from previous page: March 25, 2004, 08:02:12 PM »
Hi again Karlos

I'm wondering why you wrote 'extern "C"' didn't work.
Why? What happend?
This would mean that some C headers are not compatible with C++ under GNU and that would be really strange. :-o

Thats great that your solution works, however repeating this for every function can mean a lot of stupid and potential buggy-introducing work.
The other thing is that simple 'jsr' makes your code position dependant always, regardles of the compiler options.

Besides this GNU asm-embeding mumbo-jumbo always scared me. :-o ;-)

Cheers
 

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show only replies by Karlos
Re: Help needed combining GCC/C++ with asm sources
« Reply #15 on: March 25, 2004, 08:20:37 PM »
Hi PiR,

Well extern "C" works, but the only downside is that you simply can't specify which registers the parameters are expected to be passed in, so you have to use the stack and change the assembler side. So work wise, it's swings and roundabouts. Either use the stack and pull the args in the asm, or inline the asm and put args in the register.

Oddly, in C mode, you can indeed specify the registers, just not with C++. Go figure...

-edit-

Slight explanation. In C mode you can have this in myheader.h, which defines your asm function's interface.

void func(int i __asm("d0"), int* j __asm("a0");

Doesn't work in C++ mode.

So you do your usual extern "C" trick to include the header, but it still refuses to take it due to the __asm() stuff.

Hence, back to square 1.

-/edit-

Not sure about your jsr comment there :-?

Every time I look at any compiler produced asm, function calls are always jsr in this fashion. I certianly havent had any problems with relocation.

-edit-

Incidentally, this is all for statically linked library code, not shared library code (if thats what you are hinting at).
int p; // A
 

Offline PiR

  • Full Member
  • ***
  • Join Date: Apr 2003
  • Posts: 148
    • Show only replies by PiR
Re: Help needed combining GCC/C++ with asm sources
« Reply #16 on: March 25, 2004, 09:06:09 PM »
Hi Karlos

Thats pretty wired that you cannot specify registers in C++, despide extern "C". I will check it as soon as I'll manage to install working GNU compiler. ;-)

Honestly that makes me curious and thats another reason to install it. ;-)

BTW - have you checked if GNU doesn't have a convention in chosing registers in:

void func(register int intarg, register char *ptrarg);

I'm only guessing... It can be not allowed with GNU.

And would it make any change, if you:

extern "C" void func(int i __asm("d0"), int* j __asm("a0"));


jsr is easy - it accepts absolute address.
In small-code option bsr is used, which accepts only offsets from PC. This means that no matter where you load the whole code, your offset won't change.

If you (or someone using the code - even from statical library) wanted to produce such code, but you put 'jsr' via back-door this could lead to some wiredness.
However changing jsr to bsr could be mayby redesigned by linker? (rough guessing - and I doubt it).

Cheers
 

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show only replies by Karlos
Re: Help needed combining GCC/C++ with asm sources
« Reply #17 on: March 25, 2004, 09:19:42 PM »
When you do the normal C++ "register" keyword, its only a hint to the compiler. It doesn't have to put the elements in registers, nor do you have any say in which ones..

Anyhow, I always code large data / code model an never had any problems relating to relocation of code at runtime. Even with shared libraries.

I'm no expert, but I believe the jsr doesn't quite evaluate to an absolute fixed address (only fixed for a given instance of the program) - it's an assembler convenience, after all...
int p; // A
 

Offline PiR

  • Full Member
  • ***
  • Join Date: Apr 2003
  • Posts: 148
    • Show only replies by PiR
Re: Help needed combining GCC/C++ with asm sources
« Reply #18 on: March 26, 2004, 10:22:43 AM »
Hi Karlos

Especially for you I investigated few things.

1. SAS C++ (just to keep this info just in case):
A0 - 'this' for all nonstatic methods
D0 - class information (internal for compiler) for constructors/destructors
A1 - address of the place where to return value for functions that return whole complex objects

2. I know that 'register' is only a hint. However it is just a hint for local variables, but must be more strict meaning for function arguments, as every call must be made with arguments in the exact places, where the function expects them and the function can be defined in the other file than the call to it.
So the compiler can have a convention and SAS for example allocates address registers for pointers and data registers for integers, beginning with A0 and D0. Once the mechnism is checked you can assume that it must be consistent every time (at least with the same compiling options).

3. I've noticed that you omited 'register' in the example function. Mayby it is only mistype here, however if you did this in the code this may be the reason why GNU C++ complains about it. Correct syntax should be:

void func(register int i __asm("d0"), register int* j __asm("a0"));

I've checked it in my GNU documentation.
Well, installation of simple guides seems to be easier than the whole environment. Surprise, surprise...  :-D

4. Problems with relocation can occur only in very specific situations, rare in real life.
Lets suppose you want your code to reside in FAST, but it was loaded to CHIP. If your code is position independed you can simply copy it from place to place byte by byte and thats it. If you use any absolute addresses you must think about all relocations afterwards.
For Amiga executables relocation is done by loader that is part of OS. Every binary, besides the code itself, has additionally so called relocation tables, that describe the places in the code that needs to be recalculated after loading (practically just by adding address of the beginning of the code to the result place) to make the code usable (famous HUNK format). Once this is done, the code must reside under this exact address.

5. Unluckilly yes. 'jsr symbolname' evaluates to jump to absolute address, as this is the syntax of this opcode. Of course it will be correctly relocated during loadtime, so do not worry about it. I'm not sure if some cleaver linker cannot change it to bsr or jsr symbol(PC), but I would worry about changing the length of the command as this could destroy all code offsets calculated and used by the compiler. I meant that if someone wanted to produce position independent code and prepared compiler options for that, but used such code, he won't get position independence, but he won't know about it.


Sorry if this was too boring. ;-)
Cheers
 

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show only replies by Karlos
Re: Help needed combining GCC/C++ with asm sources
« Reply #19 on: March 26, 2004, 02:52:28 PM »
Hi,

The register usage information for the "this" pointer is worth knowing, thanks :-)

Yeah, missing the "register" keyword in (3) was a typo. It was there in the actual sourcecode, honest guv'nor :-)

As for the relocation stuff, what I meant by the "jsr " not being a fixed value was that the expression is handled by he assembler. Jsr can take just about any old effective address you can throw at it.

What I was thinking is that between the assembler and the linker itself doesn't evaluate to a fixed expression and is only resolved to some sort of relocatable value during linking. This doesn't upset the compiler offsets because the compiler itself generates assembler (ready to be assembled and linked) - ie it doesnt generate the object code directly. Also, the code output from the compiler uses the same sort of jsr based function calls too.

However it works, it works, and as you say, it is properly relocated at runtime.

So that's me off the hook for now :lol:
int p; // A
 

Offline Georg

  • Jr. Member
  • **
  • Join Date: Feb 2002
  • Posts: 90
    • Show only replies by Georg
Re: Help needed combining GCC/C++ with asm sources
« Reply #20 on: March 26, 2004, 06:19:49 PM »
Quote

Code: [Select]

inline void func(int i, int* j)
{
      asm("move.l %0, d0\n"
          "move.l %0, a0\n"
          "jsr _asmFunction\n"
          :                         // no outputs
          : "g"(i), "g"(j)          // inputs
          : "d0", "d1", "a0", "a1"  // clobbers
      );
}



I would change that to use

Code: [Select]

  : "d0" (i), "a0" (j)


as inputs and leave out the "movel %0,d0" and "movel %0,a0" asm lines. BTW: you can tell the compiler that your asm code changes memory by using "m" in clobbers line. And "cc", to tell it that your code may change condition codes.




 

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show only replies by Karlos
Re: Help needed combining GCC/C++ with asm sources
« Reply #21 on: March 26, 2004, 08:45:23 PM »
Hi,

Thanks for the tip there :-) I'm a bit novice with GCC's inline assembler in that I only looked at it's documentation the same day I got the example I put here working ;-)
int p; // A
 

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show only replies by Karlos
Re: Help needed combining GCC/C++ with asm sources
« Reply #22 on: March 26, 2004, 09:44:45 PM »
Hmm, changes no workee...

Since I'm frightfully new to gcc's inline asm, just let me post what I got to make sure I followed (the actual real function here)

Code: [Select]
[size=x-small]
class Mem {
  // big snip...
  public:
    static void copy(void* dst, void* src, size_t len)
    {
       // call asm function...
       asm("\njsr _asmCopy\n"
       :                                   // no outputs
       : "a0"(dst), "a1"(src), "d0"(len)   // inputs
       : "d0", "d1", "a0", "a1", "cc", "m" // muchos clobber
    };
}
[/size]


The original "put the args explicitly into regs" worked fine. I now get a "matching constraint matches invalid operand" error :-?
int p; // A