mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-23 02:05:57 +01:00
asm: start x86 intrinsics examples
Split userland/arch/<arch>/c/ into inline_asm and intrinsics, and move programs that don't match either up.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/* https://github.com/cirosantilli/linux-kernel-module-cheat#x86-addpq-instruction
|
||||
*
|
||||
* Add a bunch of floating point numbers in one go.
|
||||
* Add a few floating point numbers in one go (P == packaged)
|
||||
*/
|
||||
|
||||
#include <lkmc.h>
|
||||
|
||||
1
userland/arch/x86_64/intrinsics/README.adoc
Normal file
1
userland/arch/x86_64/intrinsics/README.adoc
Normal file
@@ -0,0 +1 @@
|
||||
https://github.com/cirosantilli/linux-kernel-module-cheat#gcc-intrinsics
|
||||
46
userland/arch/x86_64/intrinsics/addpd.c
Normal file
46
userland/arch/x86_64/intrinsics/addpd.c
Normal file
@@ -0,0 +1,46 @@
|
||||
/* https://github.com/cirosantilli/linux-kernel-module-cheat#gcc-intrinsics */
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <x86intrin.h>
|
||||
|
||||
int main(void) {
|
||||
|
||||
/* 32-bit add (addps). */
|
||||
{
|
||||
__m128 input0 = _mm_set_ps(1.5f, 2.5f, 3.5f, 4.5f);
|
||||
__m128 input1 = _mm_set_ps(5.5f, 6.5f, 7.5f, 8.5f);
|
||||
__m128 output = _mm_add_ps(input0, input1);
|
||||
/* _mm_extract_ps returns int instead of float:
|
||||
* * https://stackoverflow.com/questions/5526658/intel-sse-why-does-mm-extract-ps-return-int-instead-of-float
|
||||
* * https://stackoverflow.com/questions/3130169/how-to-convert-a-hex-float-to-a-float-in-c-c-using-mm-extract-ps-sse-gcc-inst
|
||||
* so we must use instead: _MM_EXTRACT_FLOAT
|
||||
*/
|
||||
float f;
|
||||
_MM_EXTRACT_FLOAT(f, output, 3);
|
||||
assert(f == 7.0f);
|
||||
_MM_EXTRACT_FLOAT(f, output, 2);
|
||||
assert(f == 9.0f);
|
||||
_MM_EXTRACT_FLOAT(f, output, 1);
|
||||
assert(f == 11.0f);
|
||||
_MM_EXTRACT_FLOAT(f, output, 0);
|
||||
assert(f == 13.0f);
|
||||
}
|
||||
|
||||
/* 64-bit add (addpd). */
|
||||
{
|
||||
__m128d input0 = _mm_set_pd(1.5, 2.5);
|
||||
__m128d input1 = _mm_set_pd(5.5, 6.5);
|
||||
__m128d output = _mm_add_pd(input0, input1);
|
||||
double d;
|
||||
/* TODO: there is no _MM_EXTRACT_DOUBLE, and the asserts below fail. */
|
||||
#if 0
|
||||
_MM_EXTRACT_FLOAT(d, output, 1);
|
||||
assert(d == 7.0);
|
||||
_MM_EXTRACT_FLOAT(d, output, 0);
|
||||
assert(d == 9.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
1
userland/arch/x86_64/intrinsics/build
Symbolic link
1
userland/arch/x86_64/intrinsics/build
Symbolic link
@@ -0,0 +1 @@
|
||||
../build
|
||||
56
userland/arch/x86_64/intrinsics/paddq.c
Normal file
56
userland/arch/x86_64/intrinsics/paddq.c
Normal file
@@ -0,0 +1,56 @@
|
||||
/* https://github.com/cirosantilli/linux-kernel-module-cheat#gcc-intrinsics */
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <x86intrin.h>
|
||||
|
||||
int main(void) {
|
||||
|
||||
/* 32-bit add hello world. */
|
||||
{
|
||||
__m128i input0 = _mm_set_epi32(1, 2, 3, 4);
|
||||
__m128i input1 = _mm_set_epi32(5, 6, 7, 8);
|
||||
__m128i output = _mm_add_epi32(input0, input1);
|
||||
assert(_mm_extract_epi32(output, 3) == 6);
|
||||
assert(_mm_extract_epi32(output, 2) == 8);
|
||||
assert(_mm_extract_epi32(output, 1) == 10);
|
||||
assert(_mm_extract_epi32(output, 0) == 12);
|
||||
}
|
||||
|
||||
/* Now a bunch of other sizes. */
|
||||
{
|
||||
__m128i input0 = _mm_set_epi32(0xF1F1F1F1, 0xF2F2F2F2, 0xF3F3F3F3, 0xF4F4F4F4);
|
||||
__m128i input1 = _mm_set_epi32(0x12121212, 0x13131313, 0x14141414, 0x15151515);
|
||||
__m128i output;
|
||||
|
||||
/* 8-bit integers (paddb) */
|
||||
output = _mm_add_epi8(input0, input1);
|
||||
assert(_mm_extract_epi32(output, 3) == 0x03030303);
|
||||
assert(_mm_extract_epi32(output, 2) == 0x05050505);
|
||||
assert(_mm_extract_epi32(output, 1) == 0x07070707);
|
||||
assert(_mm_extract_epi32(output, 0) == 0x09090909);
|
||||
|
||||
/* 32-bit integers (paddw) */
|
||||
output = _mm_add_epi16(input0, input1);
|
||||
assert(_mm_extract_epi32(output, 3) == 0x04030403);
|
||||
assert(_mm_extract_epi32(output, 2) == 0x06050605);
|
||||
assert(_mm_extract_epi32(output, 1) == 0x08070807);
|
||||
assert(_mm_extract_epi32(output, 0) == 0x0A090A09);
|
||||
|
||||
/* 32-bit integers (paddd) */
|
||||
output = _mm_add_epi32(input0, input1);
|
||||
assert(_mm_extract_epi32(output, 3) == 0x04040403);
|
||||
assert(_mm_extract_epi32(output, 2) == 0x06060605);
|
||||
assert(_mm_extract_epi32(output, 1) == 0x08080807);
|
||||
assert(_mm_extract_epi32(output, 0) == 0x0A0A0A09);
|
||||
|
||||
/* 64-bit integers (paddq) */
|
||||
output = _mm_add_epi64(input0, input1);
|
||||
assert(_mm_extract_epi32(output, 3) == 0x04040404);
|
||||
assert(_mm_extract_epi32(output, 2) == 0x06060605);
|
||||
assert(_mm_extract_epi32(output, 1) == 0x08080808);
|
||||
assert(_mm_extract_epi32(output, 0) == 0x0A0A0A09);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
1
userland/arch/x86_64/intrinsics/test
Symbolic link
1
userland/arch/x86_64/intrinsics/test
Symbolic link
@@ -0,0 +1 @@
|
||||
../test
|
||||
@@ -1,8 +1,9 @@
|
||||
/* https://github.com/cirosantilli/linux-kernel-module-cheat#x86-paddq-instruction
|
||||
*
|
||||
* Add a bunch of integers in one go.
|
||||
* Add several integers in one go.
|
||||
*
|
||||
* The different variants basically determine if carries get forwarded or not.
|
||||
* The different variants basically determine integer size, which basically
|
||||
* determines if carries get forwarded or not.
|
||||
*/
|
||||
|
||||
#include <lkmc.h>
|
||||
|
||||
Reference in New Issue
Block a user