Inline Assembly, use-msasm and fasm-blocks


Problem : 

I was looking for "fasm-blocks" decription in "Intel C++ Compiler User & Reference Guide" (304968-022US) which seems to be the latest document with release of ICC-v11.0. The agnostic about it is "fasm-blocks" works with ICC-11.0 on Linux x86_64 but the descriptions about "fasm-blocks" is missing.

Could Intel describe it's meaning, uses, also demonstrate with an example currently and latter incorporate in it's feature forthcoming ICC documents.

Can I have Intel Assembler latest documents or it's links to download w.r.t Intel 64 on Linux x86_64 where one can understand and analyze Intel Assembly language?


Environment : 

Linux* and MacOS X*

Resolution : 


Intel C++ compiler uses gcc development environment on Linux and MAC. It supports GNU inline style assembly.

Intel C++ compiler also supports Microsoft style inline assembly format in Linux. You can use -use-msasm to tell the compiler. The -fasm-blocks is also seems to be working.

The -fasm-blocks option is provided on MAC for Microsoft style inline assembly.

These options are described in Intel C++ compiler documentation, Document number: 304968-022US. There is small description of the inline assembly implementation in Intel C++ compiler in "Inline Assembly" topic.

I am providing the code sample from the Intel C++ compiler documentation below for easy reference:

---------------------------------------- gnu style inline assembly ------------------
$ cat tstcase_gnu.cpp
// inline assembly
// tstcase_gnu.cpp

#ifdef _WIN64
#define INT64_PRINTF_FORMAT "I64"
#else
#define __int64 long long
#define INT64_PRINTF_FORMAT "L"
#endif
#include <stdio.h>
typedef struct {
__int64 lo64;
__int64 hi64;
} my_i128;
#define ADD128(out, in1, in2) \
__asm__("addq %2, %0; adcq %3, %1" :\
"=r"(out.lo64), "=r"(out.hi64) : \
"emr" (in2.lo64), "emr"(in2.hi64), \
"0" (in1.lo64), "1" (in1.hi64));
extern int main()
{
my_i128 val1, val2, result;
val1.lo64 = ~0;
val1.hi64 = 0;
val2.hi64 = 65;
ADD128(result, val1, val2);
printf("0x%016" INT64_PRINTF_FORMAT "x%016" INT64_PRINTF_FORMAT "x\n",
val1.hi64, val1.lo64);
printf("+0x%016" INT64_PRINTF_FORMAT "x%016" INT64_PRINTF_FORMAT "x\n",
val2.hi64, val2.lo64);
printf("------------------------------------\n");
printf("0x%016" INT64_PRINTF_FORMAT "x%016" INT64_PRINTF_FORMAT "x\n",
result.hi64, result.lo64);
return 0;
}


---------------------------------------- Microsoft style inline assembly ------------------

$ cat tstcase_msasm.cpp
// inline assembly
// tstcase_msasm.cpp

#ifdef _WIN64
#define INT64_PRINTF_FORMAT "I64"
#else
#define __int64 long long
#define INT64_PRINTF_FORMAT "L"
#endif
#include <stdio.h>
typedef struct {
__int64 lo64;
__int64 hi64;
} my_i128;
#define ADD128(out, in1, in2) \
{ \
__asm mov rax, in1.lo64 \
__asm mov rdx, in1.hi64 \
__asm add rax, in2.lo64 \
__asm adc rdx, in2.hi64 \
__asm mov out.lo64, rax \
__asm mov out.hi64, rdx \
}

extern int main()
{
my_i128 val1, val2, result;
val1.lo64 = ~0;
val1.hi64 = 0;
val2.hi64 = 65;
ADD128(result, val1, val2);
printf("0x%016" INT64_PRINTF_FORMAT "x%016" INT64_PRINTF_FORMAT "x\n",
val1.hi64, val1.lo64);
printf("+0x%016" INT64_PRINTF_FORMAT "x%016" INT64_PRINTF_FORMAT "x\n",
val2.hi64, val2.lo64);
printf("------------------------------------\n");
printf("0x%016" INT64_PRINTF_FORMAT "x%016" INT64_PRINTF_FORMAT "x\n",
result.hi64, result.lo64);
return 0;
}

You would need -use-msasm compiler option to compile tstcase_msasm.cpp. The -fasm-blocks is also seems to be working on Linux but this is intended for MAC OS.
Pour de plus amples informations sur les optimisations de compilation, consultez notre Avertissement concernant les optimisations.