GNU Assember 'SIREG' error - gnu-assembler

I am starting to learn Asm by looking at examples and online documentation. At the moment I am having trouble with an example I got off the internet.
hat.c
.
include hat.h
.
.
hat_create(hat_desc_t* hat)
{
.
.
copy_page((void*) hat->va_pd, (void*) page);
.
return (page);
}
.
..........................................
hat.h
.
NPTE equ 1024
.
inline static void
copy_page(void* src, void* dest)
{
asm volatile
(
"cld\n\t"
"rep\n\t"
"movsl"
:
: "D" (dest), "S" (src), "c" (NPTE)
: "di", "si" <- This where the problem is.....
);
}
gcc --version
gcc (GCC) 4.6.1 20110627
gcc -fno-builtin -nostdinc -O2 -fomit-frame-pointer -c hat.c -o hat.o
error: can’t find a register in class ‘SIREG’ while reloading ‘asm’
error: ‘asm’ operand has impossible constraints
Does anyone know how to solve this error?

Simple change
:"di", "si"
to
:"0", "1"
This will fix the Problem.

Related

Error building project with make command, use of undeclared identifier '__compar_fn_t'

I'm trying to build RedisBloom and after running the make command I get the following error.
clang -dynamic -fcommon -g -ggdb -Wall -Wno-unused-function -g -ggdb -O2 -fPIC -std=gnu99 -D_GNU_SOURCE -I/Users/john/workspace/RedisBloom/contrib -I/Users/john/workspace/RedisBloom -I/Users/john/workspace/RedisBloom/src -I/Users/john/workspace/RedisBloom/deps/t-digest-c/src -c -o /Users/john/workspace/RedisBloom/src/topk.o /Users/john/workspace/RedisBloom/src/topk.c
/Users/john/workspace/RedisBloom/src/topk.c:223:50: error: use of undeclared identifier '__compar_fn_t'
qsort(heapList, topk->k, sizeof(*heapList), (__compar_fn_t)cmpHeapBucket);
^
1 error generated.
make: *** [/Users/dsesma/eclipse-workspace/RedisBloom/src/topk.o] Error 1
I'm using macOS Big Sur
The RedisBloom project uses an implementation detail (__compar_fn_t) to cast the function signature of cmpHeapBucket from a shortcut-signature to the proper signature. Relying on such implementation details is bad and tends to not be very portable.
I recommend that you download the newest version of RedisBloom. I made a patch to it that has now been merged to master which does the following:
Fix in src/topk.c:
// make the compare function have the correct signature:
int cmpHeapBucket(const void *tmp1, const void *tmp2) {
const HeapBucket *res1 = tmp1;
const HeapBucket *res2 = tmp2;
return res1->count < res2->count ? 1 : res1->count > res2->count ? -1 : 0;
}
HeapBucket *TopK_List(TopK *topk) {
HeapBucket *heapList = TOPK_CALLOC(topk->k, (sizeof(*heapList)));
memcpy(heapList, topk->heap, topk->k * sizeof(HeapBucket));
// now, no cast is needed below:
qsort(heapList, topk->k, sizeof(*heapList), cmpHeapBucket);
return heapList;
}

compilation error for avx512, is it a GCC issue?

I am trying to compile the following code with AVX512 intrinsic, but gives me the compile error.
#include <immintrin.h>
static inline __attribute__((always_inline)) void
mov64(uint8_t *dst, const uint8_t *src)
{
__m512i zmm0;
zmm0 = _mm512_load_si512((const void *)src);
_mm512_store_si512((void *)dst, zmm0);
}
The compilation error:
gcc -D_GNU_SOURCE -DINFO_LOG_DEBUG --std=c99 -march=native -O3 -DNDEBUG -m64 -mtune=native -Werror -Wall -Wundef -Wpointer-arith -Wstrict-prototypes -Wnested-externs -fomit-frame-pointer -DTRANSPORT_CONFIG_OPT_HDR='<ci/internal/transport_config_opt_extra.h>' -c src/main.c -o obj/main.o
src/main.c: In function ‘mov64’:
src/main.c:15:9: error: unknown type name ‘__m512i’
__m512i zmm0;
^
src/main.c:17:9: error: implicit declaration of function ‘_mm512_load_si512’ [-Werror=implicit-function-declaration]
zmm0 = _mm512_load_si512((const void *)src);
^
src/main.c:17:9: error: nested extern declaration of ‘_mm512_load_si512’ [-Werror=nested-externs]
src/main.c:18:9: error: implicit declaration of function ‘_mm512_store_si512’ [-Werror=implicit-function-declaration]
_mm512_store_si512((void *)dst, zmm0);
^
src/main.c:18:9: error: nested extern declaration of ‘_mm512_store_si512’ [-Werror=nested-externs]
cc1: all warnings being treated as errors
In addition, if I add -march=native,avx512f or -mavx512f or -march=skylake-avx512, it gives the following error:
src/main.c:1:0: error: bad value (skylake-avx512) for -march= switch
My GCC version is 4.8.5 20150623 and CPU is "Intel(R) Xeon(R) Gold 6154". What should I do to overcome this problem? Thanks in advance..
GCC 4.8 does not support any of the AVX-512 variants. If this is the system compiler from Red Hat Enterprise Linux 7, you can use a new GCC version from Red Hat Developer Toolset, which provides support for later CPU features. (DTS is also available for CentOS.)

How do I link Intel MKL and libdl with gold linker?

I'm having a problem linking Intel MKL and libdl using the gold linker on CentOS:
When I run this script:
#!/bin/bash
MKL_INC=$MKL_INSTALL_DIR/include
MKL_LIB=$MKL_INSTALL_DIR/lib
. /opt/rh/devtoolset-6/enable
cat > t.c << end_mkltest
#include <dlfcn.h>
#include "mkl_service.h"
int main() {
dlerror(); /* use libdl */
mkl_set_num_threads(1); /* use mkl */
}
end_mkltest
gcc -I$MKL_INC -c t.c -o t.o
gcc -L$MKL_LIB -fuse-ld=gold t.o -lmkl_rt -ldl
I get:
libmkl_rt.so: error: undefined reference to 'calloc'
libmkl_rt.so: error: undefined reference to 'realloc'
libmkl_rt.so: error: undefined reference to 'malloc'
libmkl_rt.so: error: undefined reference to 'free'
We're using:
CentOS 7.3
devtoolset-6
mkl-2017.2.174.tar.bz2
Any ideas?
This should work. Can you post the linker command shown by this command?
gcc -v -L$MKL_LIB -fuse-ld=gold t.o -lmkl_rt -ldl
(Sorry, can't post this as a comment due to lack of reputation.)

clang++ (version 5) and LNK4217 warning

I am just learning how to code.
I have installed clang version 5 on a windows 10 system using visual studio 14.
I created a hello world cpp file to test that is working.
Sample code
#include <iostream>
using namespace std;
int main()
{
cout << "Hello World!\n";
int rip{1};
int dal{4};
int kane = rip + dal;
cout << kane;
return 0;
}
command
clang++ -o .\bin\testing.exe test.cpp
Clang does compile and I get an executable which does run as expected. however I do receive this message.
test-3e53b3.o : warning LNK4217: locally defined symbol ___std_terminate imported in function "int `public: __thiscall std::basic_ostream<char,struct std::char_traits<char> >::sentry::~sentry(void)'::`1'::dtor$5" (?dtor$5#?0???1sentry#?$basic_ostream#DU?$char_traits#D#std###std##QAE#XZ#4HA)
test-3e53b3.o : warning LNK4217: locally defined symbol __CxxThrowException#8 imported in function "public: void __thiscall std::ios_base::clear(int,bool)" (?clear#ios_base#std##QAEXH_N#Z)
I have searched online and can find similar issues but they are not the same.
I realise this maybe simple to you guys, but I am at a loss I have used various IDES and GCC and this code has not produced this warning before.
Add -Xclang -flto-visibility-public-std to your compiler options.
Like so:
clang++ -Xclang -flto-visibility-public-std -o test.exe test.cpp
Edit:
Or use clang-cl instead:
clang-cl -o test.exe test.cpp

why does this bootloader only prints 'S'

I am writing a simple x86 bootloader.
this is the c program that im having trouble with: test4.c
__asm__(".code16\n");
__asm__("jmpl $0x0, $main\n");
void prints ( char* str )
{
char* pStr = str;
while( *pStr )
{
__asm__ __volatile (
"int $0x10"
:
: "a"(0x0e00 | *pStr), "b"(7)
);
pStr++;
}
}
void main ( )
{
char* str = "\n\rHello World\n\r";
char* pStr = str;
while( *pStr )
{
__asm__ __volatile (
"int $0x10"
:
: "a"(0x0e00 | *pStr)
);
pStr++;
}
prints ( str );
}
when i try to print a string within main function, it works. But when i pass the string to another function which does carry out same instructions but still prints only S to the screen. So the final output looks something like this:
Hello World
S
Here is the linker file i used: test.ld
ENTRY(main);
SECTIONS
{
. = 0x7C00;
.text : AT(0x7C00)
{
*(.text);
}
.sig : AT(0x7DFE)
{
SHORT(0xaa55);
}
}
Here are the commands i used to compile the c program and to link it
$ gcc -c -g -Os -m32 -march=i686 -ffreestanding -Wall -Werror test4.c -o test4.o
$ ld -melf_i386 -static -Ttest.ld -nostdlib --nmagic -o test4.elf test4.o
$ objcopy -O binary test4.elf test4.bin
and i used bochs emulator to test out this bootloader
You can't do this with GCC. Ignore all the tutorials that say that you can -- they are wrong.
What's most important to keep in mind is that GCC is not a 16-bit compiler. The __asm__(".code16\n") directive does not turn it into one; it merely confuses the assembler into retargeting GCC's output from 32-bit x86 to 16-bit. This will cause strange and unexpected behavior, especially in any code using pointers.
If you want to write an x86 bootloader, you will need to:
Use a C compiler that can specifically target 16-bit x86 ("real mode"). Consider the OpenWatcom toolchain, for instance.
Become very familiar with the quirks of x86 real mode -- particularly segmentation.
Write some portions of the bootloader in assembly, particularly the startup code.

Resources