hi,
I want to ask a question.
How to define a macro function that can be called by C language in armasm?
I know that in GNU can be used in the following way:
.macro push_x1_x12
push x1,x2
push x3,x4
push x5,x6
push x7,x8
push x9,x10
push x11,x12
.endm
ENTRY(test)
.......
push_x1_x12 ......ENDPROC(test)
Now in armasm, I used as follow :
MACRO
push_x1_x12
MEND
But how to expand the macro that can be called by C language??
In C language, you can define macros using the #DEFINE pre-processing command.
It will do text replacement before compiling.
Here is a documentation chapter explaining ARM Inline Assembly: ARM® Compiler armcc User Guide
Here is documentation about C preprocessor and #DEFINE: C preprocessor - Wikipedia, the free encyclopedia
#DEFINE push_x1_x12 \ __asm { \ push x1,x2 \ push x3,x4 \ push x5,x6 \ push x7,x8 \ push x9,x10 \ push x11,x12 \ }
thanks,
1、I used ARMV8 that platforms is: ARM DS-5 Documentation > ARM Compiler 6 (64-bit platforms only) > armclang Reference Guide
not armcc but armclang
2、how to expand in C language?like this:
void test_tt(void)
{
push_x1_x12;
}
3、If I want to define a macro with parameters, how to deal with it ?
Replace:
.macro cpus_tst_get_opcode, _reg0
lsl \_reg0,\_reg0,#4
lsr \_reg0,\_reg0,#24
albanrampon
2. Yes. The #define is identical to replacing the text.
3. You use parameters like for a function:
#define RADTODEG(x) ((x) * 57.29578)
and in your code
y = RADTODEG(25);
will do:
y = (25) * 57.29578;
sorry,
// define:
//-------------------------------------
#define push_x1_x12 \
__asm { \
push x1,x2 \
push x3,x4 \
push x5,x6 \
push x7,x8 \
push x9,x10 \
push x11,x12 \
// call
//----------------------------------------
ARM Compiler 6 Compilation error
javascript:liveAction('org.eclipse.help.ui', 'org.eclipse.help.ui.internal.ShowInTocAction', '2_4')
Oups, can you try the following?
#DEFINE push_x1_x12 __asm("push x1,x2", "push x1,x2", "push x3,x4", "push x5,x6", "push x7,x8", "push x9,x10", "push x11,x12")
6.4 Inline assembly language syntax with the __asm keyword in C and C++
The link just above also shows how to add parameters: you need to put them outside of the " " starting with #.
There are several ways of declaring assembly instructions. One at a time, or a list. And for the list, the way I explained previously with curly brackets "{}" or like strings in round brackets "()".
I am not sure why the curly brackets didn't work. It may depend on the compiler.
As i can see, the chinese climat make you more productive Alban
Macros tend to make things difficult to debug, so if you can I would try to use a normal function and get the compiler to inline it. I try to avoid macros whenever possible; modern compilers are good enough that you can generally avoid them without a performance penalty.
HTH, Pete
albanrampon @Peter Harris
hi all,
I need to do some big test cases with macros.
read armclang's embedded assembly document. and i can define macros in c ,and expand in c function .
Now,I want to expand macros in other macros,the code as following:
//define
#define cpus_tst_code_lsl(_reg0,ret) asm("adr %[input_i],#4\n\t" \
"mov %[input_i],%[input_i]\n\t" \
"ldr %[input_i],[%[input_i]]\n\t" \
"lsl %[input_i],%[input_i],#36\n\t" \
"lsr %[input_i],%[input_i],#56\n\t" \
"cmp %[input_i],#0x80\n\t" \
"b.eq lable1\n\t" \
"mov %[result],#0x1\n\t" \
"b lable2\n\t" \
"lable1:mov %[result],#0x0\n\t" \
"lable2:\n\t" \
: [result] "=r" (ret) \
: [input_i] "r" (_reg0) \
)
//expand
#define test_cpus_l1_code_base(ret) asm("mov x5,#16\n\t" \
"mov x6,x4\n\t" \
"mov x8,#20\n\t" \
"cpus_tst_code_lsl x5,%[result] \n\t" \
........
: \
ARM Complier 6Complier error:
error: invalid instruction
<inline asm>:4:2: note: instantiated into assembly here
cpus_tst_code_lsl x5,x1
^
As described in the suggested by albanrampon to link section 6.4 Inline assembly language syntax with the __asm keyword in C and C++, the correct syntax is:
// define: //------------------------------------- #define push_x1_x12 \ __asm { \ "push x1,x2 \n" \ "push x3,x4 \n" \ "push x5,x6 \n" \ "push x7,x8 \n" \ "push x9,x10 \n" \ "push x11,x12 \n" \ } //call //---------------------------------------- void test_tt(void) { push_x1_x12; }
See lacked the quotes involving the mnemonics and the line break.
Sure. The #define does text replacement only. It does not do any evaluation of your string to then go to look for other things.