C/C++ Embedding large asm (.S) in gnu C++ (.cpp)

fcorbelli

Active Member

Reaction score: 61
Messages: 190

I am trying to embed in a .cpp file (gnu gcc) a rather large assembly file (300KB), containing all kinds of instructions (SSE, AVX etc).

Something like
Code:
g++   zpaqfranz.cpp   blake3_gnu.S -o zpaqfranz

Well putting (at the end of the cpp)
Code:
asm volatile (".intel_syntax noprefix\n\t"
".global blake3_hash_many_sse2\n\t"
".global _blake3_hash_many_sse2\n\t"
".global blake3_compress_in_place_sse2\n\t"
".global _blake3_compress_in_place_sse2\n\t"
".global blake3_compress_xof_sse2\n\t"
".global _blake3_compress_xof_sse2\n\t"
".section .text\n\t"
"        .p2align  6\n\t"
"_blake3_hash_many_sse2:\n\t"
"blake3_hash_many_sse2:\n\t"
"        push    r15\n\t"
"        push    r14\n\t"
"        push    r13\n\t"
"        push    r12\n\t"
"        push    rsi\n\t"
"        push    rdi\n\t"
"        push    rbx\n\t"
"        push    rbp\n\t"
(...)

and compiling with -masm=intel
Code:
g++   -masm=intel -O3 zpaqfranz.cpp   -o zpaqfranz
does not work (lot of strange errors)

Code:
C:\Users\utente\AppData\Local\Temp\ccsPhVZ3.s:92979: Error: operand type mismatch for `crc32'
C:\Users\utente\AppData\Local\Temp\ccsPhVZ3.s:93003: Error: junk `(rsi)' after expression
C:\Users\utente\AppData\Local\Temp\ccsPhVZ3.s:93004: Error: junk `(rsi)' after expression
C:\Users\utente\AppData\Local\Temp\ccsPhVZ3.s:93057: Error: junk `(rsi)' after expression
C:\Users\utente\AppData\Local\Temp\ccsPhVZ3.s:93058: Error: junk `(rsi)' after expression
C:\Users\utente\AppData\Local\Temp\ccsPhVZ3.s:93126: Error: operand type mismatch for `crc32'
C:\Users\utente\AppData\Local\Temp\ccsPhVZ3.s:93134: Error: operand type mismatch for `crc32'
C:\Users\utente\AppData\Local\Temp\ccsPhVZ3.s:93143: Error: operand type mismatch for `crc32'
C:\Users\utente\AppData\Local\Temp\ccsPhVZ3.s:93152: Error: operand type mismatch for `crc32'
C:\Users\utente\AppData\Local\Temp\ccsPhVZ3.s:93161: Error: operand type mismatch for `crc32'
C:\Users\utente\AppData\Local\Temp\ccsPhVZ3.s:93170: Error: operand type mismatch for `crc32'
C:\Users\utente\AppData\Local\Temp\ccsPhVZ3.s:93179: Error: operand type mismatch for `crc32'
C:\Users\utente\AppData\Local\Temp\ccsPhVZ3.s:102102: Error: invalid use of register
C:\Users\utente\AppData\Local\Temp\ccsPhVZ3.s:222049: Error: invalid use of register
C:\Users\utente\AppData\Local\Temp\ccsPhVZ3.s:222296: Error: invalid use of register
C:\Users\utente\AppData\Local\Temp\ccsPhVZ3.s:223188: Error: invalid use of register
C:\Users\utente\AppData\Local\Temp\ccsPhVZ3.s:223277: Error: invalid use of register
C:\Users\utente\AppData\Local\Temp\ccsPhVZ3.s:223848: Error: invalid use of register


Some advises?
Thank you
 

vigole

Daemon

Reaction score: 1,543
Messages: 1,380

It's too screwed-up in so different levels, that I don't know from where I have to start whining!

I. Are you trying to fix this issue? https://github.com/BLAKE3-team/BLAKE3/issues/182
BTW: there's more important issue: it's not Freebsd, it's FreeBSD.

II. Using GCC with MinGW and Intel syntax on the Windows machine to make BLAKE3 compile on FreeBSD?
III. If you want to assemble on Windows, you're better off using KERNEL32.LIB and ML64 assembler.
IV. How those objects have ended-up in the %LOCALAPPDATA%\Temp folder?
V. All I can see: there's bunch of "global" labels, and some 64bit regs push-ups in the code segment. Hence, ...
VI.... where's the rest of the code?

You see, with the wealth of information which was provided by OP, we know absolutely nothing about absolutely anything.
How may I help you?!

P.S. If you want to learn how to embed asm in C start with basics (if it's GW, so much the better). Here's a working GCC/ASM simple code, to begin with:

Code:
#include <stdio.h>

int
main()
{
        int var;
        __asm__ (
        "movl %%eax, %%ebx;" : "=a" (var) : "a" (0x63)
                     );
        printf( "%c%c\n", var, var+0x10 );
        return 0 ;
}

# vim casm.c && cc -o casm.out casm.c && ./casm.out
 

memreflect

Well-Known Member

Reaction score: 221
Messages: 257

Let's back up for a moment: why do you want to embed this ASM code inside the file in the first place? What makes you think that will help fix whatever problem you're encountering?
 

TempleBSD

Member

Reaction score: 14
Messages: 43

You'd tell the compiler that the functions you are calling are stored in another file. The linker will then identify functions called and obtain the correct addresses. Declare the functions you intend to call with extern "C" FUNCTION_NAME; where the "C" is quite important. OSdev has a good resource on this. Then you compile the c++ code with gcc and the assembly with an assembler of your choice and then link the two object files together. Its quite easy really although return values get a little more complicated but you can find all this quickly yourself with the search engine of your choice ... The reference is also always a good place to start off at, although if you don't know that C and asm are the same with linkage it might be a little hard to find. Their entry on the extern-keyword also explains why "C" is necessary. To let your assembly functions receive and return parameters, they must follow the C calling convention.
 
OP
fcorbelli

fcorbelli

Active Member

Reaction score: 61
Messages: 190

It's too screwed-up in so different levels, that I don't know from where I have to start whining!
whining?
I. Are you trying to fix this issue? https://github.com/BLAKE3-team/BLAKE3/issues/182
BTW: there's more important issue: it's not Freebsd, it's FreeBSD.

No, I am not
This one
and this one
This one
And this (already solved in fact, but I do not know if BLAKE3-team will fix the official release)

BTW I write FreeBSD
My name is Franco Corbelli (fcorbelli), not riktam

If you want "software" BLAKE3 on FreeBSD (g++) you can get here

II. Using GCC with MinGW and Intel syntax on the Windows machine to make BLAKE3 compile on FreeBSD?
I do not know, I do not care at all, it is not my question and/or my problem

III. If you want to assemble on Windows, you're better off using KERNEL32.LIB and ML64 assembler.
I am sorry, I do not want to do this way.
I only want to use gcc (g++ in fact)

IV. How those objects have ended-up in the %LOCALAPPDATA%\Temp folder?
I do not know, I do not care at all
V. All I can see: there's bunch of "global" labels, and some 64bit regs push-ups in the code segment. Hence, ...
VI.... where's the rest of the code?
It's a way bigger file, too big in fact to upload, but this is NOT the question
You see, with the wealth of information which was provided by OP, we know absolutely nothing about absolutely anything.
How may I help you?!
Do you ever embed (large) ASM (SSE, AVX etc) code into g++-compilable .cpp files?

P.S. If you want to learn how to embed asm in C start with basics (if it's GW, so much the better). Here's a working GCC/ASM simple code, to begin with:
Thank you, very useful (sarcastic).
 
OP
fcorbelli

fcorbelli

Active Member

Reaction score: 61
Messages: 190

Let's back up for a moment: why do you want to embed this ASM code inside the file in the first place?
because I want a SINGLE file. Not 2. Not 3, not 10.
I want 1 (one)
What makes you think that will help fix whatever problem you're encountering?
I get no problem at all, my software works great.
It is more a challenge to learn something new (a multiplatform-state-of-the-art-archiver that compile and runs on Windows, BSD, Linux, Annapurna-based NAS, vSphere servers etc with autodetected HW-instruction for BLAKE3 hashes).
But, after testing on Windows, I get no real advantage using HW-BLAKE3 vs software-SHA-1.
Then I do not think this will go any better with BSD
 
OP
fcorbelli

fcorbelli

Active Member

Reaction score: 61
Messages: 190

You'd tell the compiler that the functions you are calling are stored in another file. The linker will then identify functions called and obtain the correct addresses. Declare the functions you intend to call with extern "C" FUNCTION_NAME; where the "C" is quite important. OSdev has a good resource on this. Then you compile the c++ code with gcc and the assembly with an assembler of your choice and then link the two object files together.
yes, I do all the time.

Its quite easy really although return values get a little more complicated but you can find all this quickly yourself with the search engine of your choice ... The reference is also always a good place to start off at, although if you don't know that C and asm are the same with linkage it might be a little hard to find. Their entry on the extern-keyword also explains why "C" is necessary. To let your assembly functions receive and return parameters, they must follow the C calling convention.
MMh... I think to know just "a bit" of C and just a "bit" of C++, and a bit of ASM.
And just a bit of extern etc.
You can see here
 
OP
fcorbelli

fcorbelli

Active Member

Reaction score: 61
Messages: 190

I'll recap the question: I don't want to know how to write "hello world" in C, C ++ or assembly (I've been doing it for 35 years), or even how to write a UNIX-like OS from scratch (already done) I would like to know if

there is a not too complicated (= taking too long) method to have a SINGLE source file containing both C++ code and C code (with externs) that calls a lot of ASM functions of various type (SSE, AVX etc, Intel-style), that can be compiled straight by g++.

It seems like a simple question to me.

If the answer is "write two files, a .cpp and a .S, and then link them", thanks but this is trivial, at least for me.
Code:
g++   zpaqfranz.cpp   blake3_gnu.S -o zpaqfranz
already achived.

Even answers like "look at the asm(" docs" don't help that much
 
OP
fcorbelli

fcorbelli

Active Member

Reaction score: 61
Messages: 190

Here I attach the Windows version (for the curious) with TWO files (.cpp and .S).
I am @home today, but the FreeBSD should be just similar (with different .S file, of course)
 

Attachments

  • zpaqfranz_blake3_hw_windows.zip
    983.7 KB · Views: 20
OP
fcorbelli

fcorbelli

Active Member

Reaction score: 61
Messages: 190

I'd begin with installing FreeBSD and following the build instructions 😌
Flash: it does not work; minor fix needed (already done by me)
You can try yourself the provided Makefile, then discard it, and rewrite.
It's not that hard for a seasoned C++ developer, but does NOT work just out of the box (hint: it is C code, not C++ compatible!)

"standard style"
Code:
gcc -shared -O3 -o libblake3.so blake3.c blake3_dispatch.c blake3_portable.c \
    blake3_sse2_x86-64_unix.S blake3_sse41_x86-64_unix.S blake3_avx2_x86-64_unix.S \
    blake3_avx512_x86-64_unix.S

then

gcc -c -fPIC -O3 -msse2 blake3_sse2.c -o blake3_sse2.o
gcc -c -fPIC -O3 -msse4.1 blake3_sse41.c -o blake3_sse41.o
gcc -c -fPIC -O3 -mavx2 blake3_avx2.c -o blake3_avx2.o
gcc -c -fPIC -O3 -mavx512f -mavx512vl blake3_avx512.c -o blake3_avx512.o
gcc -shared -O3 -o libblake3.so blake3.c blake3_dispatch.c blake3_portable.c \
    blake3_avx2.o blake3_avx512.o blake3_sse41.o blake3_sse2.o

then... (whatever)


my style (in fact with #ifdef into the .S, but do not make it too hard)
for Windows/whatever that works
Code:
g++ -O3 -Dunix zpaqfranz.cpp   blake3_gnu.S -o zpaqfranz
but I want (Linux and BSD)
Code:
g++  -O3 -Dunix zpaqfranz.cpp   -o zpaqfranz
Code:
g++  -O3 zpaqfranz.cpp   -o zpaqfranz
for Windows (just as today, without ASM)

I hope the goal is clear: a SINGLE source file
Attention g++ and not gcc, they are not synonymous, especially with enums (as well as with extern)
 
Top