How to use clang -intergrated-as to compile cross-(os/target) assembly file.

For example, I execute the following command sequences:

H:\CI\bld\compilers\musl\src\math\i386>type sqrt.s
#.globl _sqrt
.global sqrt
#.type sqrt,@function
#_sqrt:
sqrt: fldl 4(%esp)
fsqrt
fstsw %ax
sub $12,%esp
fld %st(0)
fstpt (%esp)
mov (%esp),%ecx
and $0x7ff,%ecx
cmp $0x400,%ecx
jnz 1f
and $0x200,%eax
sub $0x100,%eax
sub %eax,(%esp)
fstp %st(0)
fldt (%esp)
1: add $12,%esp
fstpl 4(%esp)
fldl 4(%esp)
ret

H:\CI\bld\compilers\musl\src\math\i386>type sqrt.c
float __cdecl sqrt(float z)
{
return 0.0;
}
H:\CI\bld\compilers\musl\src\math\i386>clang -integrated-as -c -v --target=i686
-pc-win32 sqrt.s
clang version 3.4 (trunk)
Target: i686-pc-win32
Thread model: posix
“C:\Program Files (x86)\LLVM 3.4.svn\bin\clang.exe” -cc1as -triple i686-pc-win3
2 -filetype obj -main-file-name sqrt.s -target-cpu pentium4 -fdebug-compilation-
dir “H:\CI\bld\compilers\musl\src\math\i386” -dwarf-debug-producer clang
version 3.4 (trunk) -o sqrt.o sqrt.s

H:\CI\bld\compilers\musl\src\math\i386>llvm-objdump -s -r -t sqrt.o

sqrt.o: file format COFF-i386

Contents of section .text:
0000 dd442404 d9fa9bdf e083ec0c d9c0db3c .D$…<
0010 248b0c24 81e1ff07 000081f9 00040000 $…$…
0020 75122500 0200002d 00010000 290424dd u.%…-…).$.
0030 d8db2c24 83c40cdd 5c2404dd 442404c3 …,$…$…D$…
SYMBOL TABLE:
[ 0](sec 1)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .text
AUX scnlen 0x40 nreloc 0 nlnno 0 checksum 0x0 assoc 1 comdat 0
[ 2](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 sqrt

H:\CI\bld\compilers\musl\src\math\i386>clang --target=i686-pc-win32 -c sqrt.c
sqrt.c:1:15: warning: incompatible redeclaration of library function ‘sqrt’
[-Wincompatible-library-redeclaration]
float __cdecl sqrt(float z)
^
sqrt.c:1:15: note: ‘sqrt’ is a builtin with type ‘double (double)’
1 warning generated.

H:\CI\bld\compilers\musl\src\math\i386>llvm-objdump -s -r -t sqrt.o

sqrt.o: file format COFF-i386

Contents of section .text:
0000 5589e583 ec08f30f 1045080f 57c9f30f U…E…W…
0010 1145fcd9 eef30f11 4df883c4 085dc3 .E…M…].
SYMBOL TABLE:
[ 0](sec 1)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .text
AUX scnlen 0x1f nreloc 0 nlnno 0 checksum 0x0 assoc 1 comdat 0
[ 2](sec -1)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000001 @feat.00
[ 3](sec 1)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x00000000 _sqrt

H:\CI\bld\compilers\musl\src\math\i386>
H:\CI\bld\compilers\musl\src\math\i386>clang -integrated-as -c -v --target=amd6
4-pc-win32 sqrt.s
clang version 3.4 (trunk)
Target: amd64-pc-win32
Thread model: posix
“C:\Program Files (x86)\LLVM 3.4.svn\bin\clang.exe” -cc1as -triple amd64-pc-win
32 -filetype obj -main-file-name sqrt.s -target-cpu x86-64 -fdebug-compilation-d
ir “H:\CI\bld\compilers\musl\src\math\i386” -dwarf-debug-producer clang v
ersion 3.4 (trunk) -o sqrt.o sqrt.s

H:\CI\bld\compilers\musl\src\math\i386>llvm-objdump -s -r -t sqrt.o

sqrt.o: file format COFF-x86-64

Contents of section .text:
0000 67dd4424 04d9fa9b dfe083ec 0cd9c067 g.D$…g
0010 db3c2467 8b0c2481 e1ff0700 0081f900 .<$g…$…
0020 04000075 14250002 00002d00 01000067 …u.%…-…g
0030 290424dd d867db2c 2483c40c 67dd5c24 ).$…g.,$…g.$
0040 0467dd44 2404c3 .g.D$…
SYMBOL TABLE:
[ 0](sec 1)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .text
AUX scnlen 0x47 nreloc 0 nlnno 0 checksum 0x0 assoc 1 comdat 0
[ 2](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 sqrt

H:\CI\bld\compilers\musl\src\math\i386>clang --target=amd64-pc-win32 -c sqrt.c
sqrt.c:1:15: warning: incompatible redeclaration of library function ‘sqrt’
[-Wincompatible-library-redeclaration]
float __cdecl sqrt(float z)
^
sqrt.c:1:15: note: ‘sqrt’ is a builtin with type ‘double (double)’
1 warning generated.

H:\CI\bld\compilers\musl\src\math\i386>llvm-objdump -s -r -t sqrt.o

sqrt.o: file format COFF-x86-64

Contents of section .text:
0000 554889e5 50f30f11 45fc0f57 c04883c4 UH…P…E…W.H…
0010 085dc3 .].
SYMBOL TABLE:
[ 0](sec 1)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .text
AUX scnlen 0x13 nreloc 0 nlnno 0 checksum 0x0 assoc 1 comdat 0
[ 2](sec 1)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x00000000 sqrt

H:\CI\bld\compilers\musl\src\math\i386>

My problem is:

Because C __cdecl calling convention vary on x86/amd64 architecture under win32.
for example, the sqrt function in is expressed as
float __cdecl sqrt(float)

but in the compiled object file, the final COFF symbol table:
on x86/win32(i686-pc-win32), it’s named with “_sqrt
on amd64/win32(amd64-pc-win32), it’s named with “sqrt

on linux(*-pc-linux), in ELF symbol table, it’s named with “sqrt”,

So I want to control the function name in assembly file, by the means of Assembly macros,
but I don’t know LLVM-MC support which kinds of macros to control the assembly directives so that I can unified the assembly function name can match the c function name in object symbol table under different CPU(x86/x64) and different OS(Win32/Linux/MacOS).
The simplest way is to duplicate the function name is to duplicate the function name in two form:
.globl _sqrt

.global sqrt
#.type sqrt,@function
_sqrt:
sqrt: fldl 4(%esp)
But that will leading redundant object symbol name.
besides, the .type didn’t support under COFF symbol table, so how did I use assembly macro to comment it out when we are targeting COFF object but reserved when we are targeting ELF.
didn’t know if Mach-O support for this directive.

I don’t think we should attempt to mangle symbols declared in assembly source files. If you’re writing assembly, you will need to handle ABI portability, including the _ prefix on win32 x86.

clang will run the C preprocessor for you if you use the .S file suffix (case matters).

I don't think we should attempt to mangle symbols declared in assembly
source files. If you're writing assembly, you will need to handle ABI

Sorry for the unclear statements, I didn't means the assembler to mangle
symbols declared in assembly source files, I means directly use assembly
directive to choice which symbol should be used. The compiler just need to
follow the directive.
For example, in assembly files, there is a directive
https://sourceware.org/binutils/docs-2.23.1/as/If.html#If
to act like C macro #ifdef #if, so i wanna to know how to use this
directive to detect if it's target to x86/win32. if that's true, then I can
control which code to be generate.

Sorry for the unclear statements, I didn't means the assembler to mangle
symbols declared in assembly source files, I means directly use assembly
directive to choice which symbol should be used. The compiler just need to
follow the directive.
For example, in assembly files, there is a directive
https://sourceware.org/binutils/docs-2.23.1/as/If.html#If
to act like C macro #ifdef #if, so i wanna to know how to use this directive
to detect if it's target to x86/win32. if that's true, then I can control
which code to be generate.

I don't think there is anything in plain .s files. In .S files you can
use any of the C predefined macros, in particular,
__USER_LABEL_PREFIX__ might be what you want.

Cheers,
Rafael

> Sorry for the unclear statements, I didn't means the assembler to mangle
> symbols declared in assembly source files, I means directly use assembly
> directive to choice which symbol should be used. The compiler just need
to
> follow the directive.
> For example, in assembly files, there is a directive
> https://sourceware.org/binutils/docs-2.23.1/as/If.html#If
> to act like C macro #ifdef #if, so i wanna to know how to use this
directive
> to detect if it's target to x86/win32. if that's true, then I can control
> which code to be generate.
>>

I don't think there is anything in plain .s files. In .S files you can
use any of the C predefined macros, in particular,
__USER_LABEL_PREFIX__ might be what you want.

Thanks, Rafael, this is acceptable if GCC/binutils also support for this, I
want to keep compatible with GCC/binutils,
besides, is there any command option to force use C predefined macros?
because use .S is too tricky.

Use the flags “-x assembler-with-cpp” to force clang to think it needs preprocessing. That should work with gcc.