pycparser ParseError on barrier.h - linux-kernel

I am trying to creat AST for a kernel file using pyCparser and met ParseError.
I preprocessed the file using command like, and no error generated.
clang -E -D'__attribute__(x)=' -D'__extension__=' -D'__signed__=signed' -D'__builtin_va_list=int' ...-c -o /mnt/os_tmp/cparser/test1/clk-pp.c linux/drivers/clk/xx/clk.c
I met errors when parse the file with commands:
pycparser.parse_file('/mnt/os_tmp/cparser/test1/clk-pp.c')
pycparser.plyparser.ParseError: linux/arch/arm64/include/asm/barrier.h:77:6: before: volatile
barrier.h:72
static inline unsigned long array_index_mask_nospec(unsigned long idx,
unsigned long sz)
{
unsigned long mask;
asm volatile(
" cmp %1, %2\n"
" sbc %0, xzr, xzr\n"
: "=r" (mask)
: "r" (idx), "Ir" (sz)
: "cc");
csdb();
return mask;
}
Can somebody help me on the issue?

Related

RISCV inline assembly compilation

To start with optimizing my code I have to start with adding assembly code into my C which is crosscompiled with gcc riscv toolchain, to start with I trying to implement simple riscv inline as follows
int src = 1;
int dst;
asm ("mov %1, %0\n\t"
"add $1, %0\n\t"
: "=r" (dst)
: "r" (src));
But error while crosscompiling it as
Error: unrecognized opcode `mov a1,a1'
Error: illegal operands `add $1,a1'
Should I add any specific flags for inline assembly implementation? any help would be great!

inline AT&T asm syntax for using opcode directly instead of mnemonic

For unfortunate reasons I can't get into, I have to support an ancient assembler that doesn't have a mapping for a mnemonic I need.
I know the hardware supports it, but I can't seem to find any documentation online for how to use an opcode instead of a mnemonic.
Does anyone have a reference for how to do it in inline AT&T syntax on GCC.
Try this:
long result;
char success = 0; /* make sure we don't get surprised by setc only writing 8 bits */
/* "rdrand %%rax ; setc %b1" */
asm volatile (".byte 0x48, 0x0f, 0xc7, 0xf0; setc %b1" : "=a"(result), "=qm"(success) :: "cc");
The a constraint forces the compiler to use the rax register for result. This is as general as it gets without being obnoxious. I suggest you to add a configure test to check if the assembler understands rdrand and use this code:
long result;
char success = 0;
#ifdef HAVE_RDRAND
asm volatile ("rdrand %0; setc %b1" : "=r"(result), "=qm"(success) :: "cc");
#else
asm volatile (".byte 0x48, 0x0f, 0xc7, 0xf0; setc %b1" : "=a"(result), "=qm"(success) :: "cc");
#endif
While there might be a tiny performance penalty in forcing the compiler to use the rax register if the assembler does not understand rdrand, it is far outweighted by the complicated kludges needed to allow any register to be used.
Luckily rdrand only takes a single argument and that is a register. As such you only need to cover a few cases if you want to allow the compiler to choose freely. Beware, it's still quite ugly :)
inline int rdrand()
{
int result;
__asm__ __volatile__ (
".byte 0x0f, 0xc7\n\t"
".ifc %0, %%eax\n\t"
".byte 0xf0\n\t"
".else\n\t"
".ifc %0, %%ebx\n\t"
".byte 0xf3\n\t"
".else\n\t"
".ifc %0, %%ecx\n\t"
".byte 0xf1\n\t"
".else\n\t"
".ifc %0, %%edx\n\t"
".byte 0xf2\n\t"
".else\n\t"
".ifc %0, %%esi\n\t"
".byte 0xf6\n\t"
".else\n\t"
".ifc %0, %%edi\n\t"
".byte 0xf7\n\t"
".else\n\t"
".ifc %0, %%ebp\n\t"
".byte 0xf5\n\t"
".else\n\t"
".error \"uknown register\"\n\t"
".endif\n\t"
".endif\n\t"
".endif\n\t"
".endif\n\t"
".endif\n\t"
".endif\n\t"
".endif\n\t"
: "=R" (result) : : "cc");
// "=R" excludes r8d..r15d in 64-bit mode
return result;
}
For 64-bit operand-size, you'll need a REX.W (0x48) prefix, but the "=R" constraint instead of "=r" will avoid needing any other bits set in the REX prefix.
Note that rdrand also uses the carry flag the handling for which is left as an exercise for the reader. gcc6 can use flag output operands, which is more efficient than setcc.

error: invalid 'asm': operand number missing after %-letter when using inline assembly with GCC

I'm tring to convert a simple assembly code of MS to use with gcc, the MS assembly I try to convert is right below. I have two int variables, number and _return:
mov eax, number
neg eax
return, eax
and, I have tried this:
asm("movl %eax, %0" :: "g" ( number));
asm("neg %eax");
asm("movl %0, %%eax" : "=g" ( return ));
But, the compiler gives me this error:
main.c:17:9: error: invalid 'asm': operand number missing after %-letter
Where is the error, and, how I can fix this error?
Thanks
You can't do it like that because you're overwriting registers without telling the compiler about it. Also, the % is a special character, similar to printf.
It's also better to put all the instructions in one asm or else the compiler might do something unexpected in between.
Try this instead:
asm("movl %%eax, %1\n\t"
"neg %%eax\n\t"
"movl %0, %%eax" : "=g" ( _return ) : "g" ( number) : "eax");
There's probably a better way, though:
asm("neg %0": "=a" ( _return ) : "a" ( number));
I don't know why you can't just do (in C):
_return = -number;
Try something like:
#include <stdio.h>
#include <stdlib.h>
int main(int ac,char**av)
{
int n=ac>1?atoi(av[1]):42;
asm ("movl %0, %%eax \n\t"
"neg %%eax \n\t"
"movl %%eax, %0 \n\t" : "+r" (n)::"eax");
printf("%d\n",n);
}
The issues are:
order of operands is instr src,dst
%% instead of %
no isolated lines of assembler -- the input/output/clobber list is associated to all of the assembler block
'+r' to have a parameter that works as both input & output
I doubt even MS allows using keyword "return" that way
And to make it even more efficient:
asm("neg %0" : "+r" (n) ::); // works as well

How can I compile assembly language with gcc and codeblock?

I am now trying to compile the following codes with gcc and codeblock:
#include <stdio.h>
int main()
{
char alphabet = 'X';
printf ("Type letter = ");
asm{ //line 8
mov ah, 02
mov dl, [alphabet] // line 9
int 21h
}
printf ("\n");
return (0);
}
The error messages I have got are as follows:
error: expected '(' before '{' token line 8
error: 'mov' was not declared in this scope line9
I am compiling for x86 computer, and was wondering how I could compile the above codes successfully. Thanks!
Unfortunately gcc doesn't support simple syntax like this:
asm {
mov ah, 02
mov dl, [alphabet]
int 21h
}
You can find more information on the gcc-inline-assembler with the link DCoder commented: click me
Explaining everything would be too much for an answer, so I simply write the code for gcc, which should do the job for you:
__asm__(
"movb $2, %%ah;"
"movb %0, %%dl;"
"int $0x21;"
:
: "r"(alphabet)
: "%ah", "%dl"
);
Note, that you can also use the keyword asm instead of __asm__.

arm inline assembly code and compiler optimization's options

I'm trying to du some inline assembly code.
My function is
void pixemcpy(unsigned char *im_src, unsigned char *im_dest, int npix)
{
int i;
for(i=0;i<npix;i++) *im_dest++=*im_src++;
}
My assembly inline function is
void inline_pixelcpy(unsigned char *im_src, unsigned char *im_dest, int npix){
__asm__ volatile(
"0: \n"
"ldrb r3, [%[src]], #1 \n"
"strb r3, [%[dst]], #1 \n"
"subs %[iter], %[iter], #1\n"
"bgt 0b\n"
:
: [src] "r" (im_src), [dst] "r" (im_dest), [iter] "r" (npix)
: "cc", "r3"
);
}
Both function are in the same c file!
When I compile my c file that's work's ! Both function do the same thing there is no problem.
If I use -O2 or -O3 gcc option, I have a segmentation fault when returning (not calling) my assembly function !
This problem do not occured if my 2 function are into separate files !
Is there a problem into my inline code ! How can I tell to gcc to not try to optimise my inline code !
thank's
Etienne

Resources