Compilation error with %hi() and %lo() with inline assembly code - c

I have below in-line assembly code. I am getting a compilation error "error: invalid 'asm': operand number missing after %-letter" at each line where %hi, %lo present.
void func()
{
__asm__ (
"lis %%r4, %hi(%0);"
"ori %%r4,%%r4,%lo(%0);"
"stw r3, 0(%%r4);"
"lis %%r4, %hi(%0);"
"ori %%r4,%%r4,%lo(%0);"
"lis %%r3, %hi(%1);"
"ori %%r3,%%r3,%lo(%1);"
"stw %%r3, 0(%%r4);"
::"r"(var1), "r"(var2));
}
On further analysis i found that inline assembly expects a number(%0, %1...) whenever it finds a % symbol. So changed all % to %%(its just a blind shot), then ended up in getting many like the one shown below.
{standard input}: Assembler messages:
{standard input}:3394: Error: bad expression
{standard input}:3394: Error: syntax error; found `h', expected `,'
{standard input}:3394: Error: junk at end of line: `hi(%r9)'
{standard input}:3394: Error: bad expression
{standard input}:3394: Error: syntax error; found `l', expected `,'
{standard input}:3394: Error: junk at end of line: `lo(%r9)'
{standard input}:3394: Error: bad expression
after a lot of efforts i came to know that there is some problem if we use %hi() or %lo in inline assembly code. If i remove %hi and %lo from my code its getting compiled. Can anyone suggest me how to use %hi() and %lo inside a inline assembly code?

GNU AS does not support %hi() and %lo(). Instead, it uses #h and #l suffixes on the symbols to denote the high and low parts. Also note you can't use that with register operands, and you used r constraint.

Related

Clang gives confusing error message "expected value in expression"

I'm getting the following error message from Clang 10:
error: expected value in expression
#if FOOBAR
^
1 error generated.
No further info. What could be the cause for this?
What could be the cause for this?
When the macro is defined to nothing
#define FOOBAR
then
#if FOOBAR
expands to just:
#if
And compiler prints an error - if needs an expression #if something-here.

How to compile C functions that start with __asm in arm-none-eabi?

I'm trying to compile this PTPD code https://github.com/mpthompson/stm32_f4_ptpd . Unfortunately, it requires premium version of Keil. Therefore, I am migrating it to use arm-none-eabi and Makefile.
I have managed to get the rest of the program to compile, except for https://github.com/mpthompson/stm32_f4_ptpd/blob/master/libraries/RTX-v4.73/SRC/ARM/HAL_CM4.c .
Example problem place:
__asm void rt_set_PSP (U32 stack) {
MSR PSP,R0
BX LR
}
This file fails with:
../libraries/rtx-v4.73/SRC/ARM/HAL_CM4.c:50:7: error: expected '(' before 'void'
__asm void rt_set_PSP (U32 stack) {
^~~~
../libraries/rtx-v4.73/SRC/ARM/HAL_CM4.c:72:20: error: stray '#' in program
LSLS R0,#31
It seems like it is related to the compiler (GNU compiler not supporting this syntax?) or some flags, but googling hasn't been fertile so far.

"Error: unsupported relocation against <register>" error with inline PPC assembly code in .c file

I have below inline assembly code. But when i try to compile it, It throws error mentioned after the code snippet.
unsigned int func(void)
{
__asm__ ("mfspr r3, svr;");
}
Below are the errors.
{standard input}: Assembler messages:
{standard input}:3349: Error: unsupported relocation against r3
{standard input}:3349: Error: unsupported relocation against svr
{standard input}:3375: Error: unsupported relocation against r3
{standard input}:3375: Error: unsupported relocation against svr
{standard input}:3510: Error: unsupported relocation against r3
{standard input}:3510: Error: unsupported relocation against svr
{standard input}:3517: Error: unsupported relocation against r3
{standard input}:3517: Error: unsupported relocation against svr
Can anyone help me fixing these?
Apparently gas has no built-in support for these registers. In order to use those you should either define them yourself or use their indexes explicitly like:
mfspr 3, <some_index_here>
Alternatively you could include: ppc_asm.tmpl.
If your core is an e500 then svr index would be 1023.
You should specify inputs and outputs explicitly. As written, your ASM block may be optimized out!
unsigned int func(void)
{
unsigned x;
__asm__("mfspr %0, svr" : "=b"(x));
return x;
}
The compiler is smart enough to figure out that the register should be r3. (That's one of the compiler's main jobs: register allocation to minimize extra moves.)
If you leave out the output specification, and then compile with optimization enabled, you may find that your function is empty, without the mfspr opcode anywhere to be found.
At least some of the errors will go away if you pass -mregnames option to the assembler. (-Wa,-mregnames). gas 2.19 supports the following symbolic register names for PPC (from binutils-2.19/gas/config/tc-ppc.c):
/* List of registers that are pre-defined:
Each general register has predefined names of the form:
1. r<reg_num> which has the value <reg_num>.
2. r.<reg_num> which has the value <reg_num>.
Each floating point register has predefined names of the form:
1. f<reg_num> which has the value <reg_num>.
2. f.<reg_num> which has the value <reg_num>.
Each vector unit register has predefined names of the form:
1. v<reg_num> which has the value <reg_num>.
2. v.<reg_num> which has the value <reg_num>.
Each condition register has predefined names of the form:
1. cr<reg_num> which has the value <reg_num>.
2. cr.<reg_num> which has the value <reg_num>.
There are individual registers as well:
sp or r.sp has the value 1
rtoc or r.toc has the value 2
fpscr has the value 0
xer has the value 1
lr has the value 8
ctr has the value 9
pmr has the value 0
dar has the value 19
dsisr has the value 18
dec has the value 22
sdr1 has the value 25
srr0 has the value 26
srr1 has the value 27
The table is sorted. Suitable for searching by a binary search. */
This is the helpful error message that gas emits when it is trying to say that it doesn't know that "r3" and "svr" are the names of registers. gas expects numbers instead of register names for register operands. You'd get similar error messages if you tried
__asm__ ("mfspr foo, fum;");
In other words, gas is interpreting the register names as arbitrary symbols.

if else syntax error in C

if(aptr[i] < bptr[i])
a->used = BI_LESS_THAN;
else
return BI_GREATER_THAN;
I can not figure out why this code will not compile. It says that it is expecting a '}' before the start of the else. Is this invalid in C? I am compiling in Netbeans using GCC.
The error is consistent with your BI_LESS_THAN macro being malformed. Before the file is actually compiled, the C preprocessor will substitute BI_LESS_THAN with whatever you have defined it to, exactly as it's written. That's why the compiler error seems a little cryptic.

Why my .c coding can't be compile in GCC?

I have a simple code in c :
#include <stdio.h>
main()
{
printf(“Hello, world! /n”);
}
but I can't compile it in GCC. The warning when i try to compile it :
1. gcc hello.c -o hello
2. hello.c: In function 'main:
3. hello.c:4:1: error: stray '\342' in program
4. hello.c:4:1: error: stray '\200' in program
5. hello.c:4:1: error: stray '\234' in program
6. hello.c:4:11: error: 'Hello' undeclared (first use in this function)
7. hello.c:4:11: note: each undeclared identifier is reported only once for each function
it appears in
8. hello.c:4:18: error: 'world' undeclared (first use in this function)
9. hello.c:4:23: error: expected ')' before '!' token
10. hello.c:4:23: error: stray '\342' in program
11. hello.c:4:23: error: stray '\200' in program
12. hello.c:4:23: error: stray '\235' in program
anyone can help me please?
You get those errors because you presumably copy and pasted that code from a formatted source. “ and ” aren't the same as ". Change them to that and the code will compile.
You should probably also follow the convention of having main defined as:
int main(void)
and therefore returning an int.
You probably also want to change /n to \n

Resources