4.2.4.2 Describing assembler instruction

With the CC-RH, assembler instruction can be described in the functions of a C source program.

(1)

#pragma directives

One of the #pragma directives to embed assembler instructions is #pragma inline_asm.

This treats the function itself as an assembler instruction only, and performs inline expansion at the call site.

#pragma inline_asm ( function-specification [, function-specification]... )Note
  function-specification: function-name [(size=numerical value)]

Note

The outer parentheses can be omitted.

 

Performs inline expansion on functions coded in assembly and declared with #pragma inline_asm.

The calling conventions for an inline function with embedded assembly are the same as for ordinary function calls.

Specifying (size = numerical value) does not affect the result of compilation.

Example

-

C source

#pragma inline_asm      func_add
static int      func_add(int a, int b){
        add     r6, r7
        mov     r7, r10
}
void func(int *p){
        *p = func_add(10,20);
}

-

Output codes

_func:
prepare r20, 0
mov     r6, r20
movea   0x0014, r0, r7
mov     10, r6
add     r6, r7
mov     r7, r10

(2)

Notes for Use of #pragma inline_asm

-

Specify #pragma inline_asm before the definition of the function body.

-

Also generate external definitions of functions specified with #pragma inline_asm.

-

If you use a register to guarantee the entrance and exit of an inline function with embedded assembly, you must save and restore this register at the beginning and end of the function.

-

The compiler passes strings in #pragma inline_asm to the assembler as-is, without checking or modifying them.

-

Only positive integer constants are specifiable for (size = numerical value). Specifying a floating-point number or value less than 0 will cause an error.

-

If #pragma inline_asm is specified for a static function, then the function definition will be deleted after inline expansion.

-

Assembly code is targeted by the preprocessor. Caution is therefore needed when using #define to define a macro with the same name as an instruction or register used in assembly language (e.g. "MOV" or "r5").

-

Although it is possible to use comments starting with a hash ("#") in RH850 assembly language, if you use this comment, do not use # comments inside functions coded in assembly, because the preprocessor will interpret these as preprocessing directives.

-

#pragma inline_asm cannot be specified simultaneously with the following #pragma directives.

#pragma inline_asm, #pragma inline, #pragma noinline, #pragma interrupt,

#pragma block_interrupt, #pragma stack_protector,

-

When a label is written in an assembly-language function, labels having the same name are generated for the number of times the function is expanded inline.

In this case, take any of the following actions.

-

Use a local label written in the assembly language. A local label has a single name in the assembly-language code, but the assembler automatically converts it into separate names.

-

Write a code so that a label is expanded only in one location.

-

When calling an assembly-language function within the current source file, define the function as static and call it only from a single location. Do not obtain the address of the assembly-language function.

-

When not calling an assembly-language function within the current source file, code the function as an external function.

The following shows a sample output code.

-

C source

#pragma inline_asm func1
static void func1(void)  /* When calling within the current file a */
{                        /* function that includes a label definition and */
                         /* is specified with inline_asm, code it as */
                         /* a static function. */
  .PUBLIC _label1
  add 1, r6
_label1:
  add -1, r6
}
 
void main(void) {
  func1();              /* Calls the function that includes a label */
                        /* definition and is specified with inline_asm. */
}
 
#pragma inline_asm func2
void func2(void)       /* When not calling within the current file a */
                       /* function that includes a label definition and */
                       /* is specified with inline_asm, code it as an */
                       /* external function. */
  .PUBLIC _label2
  add -1, r6
_label2:
  add 1, r6
}

-

Output assembly source code

_main:
  .stack _main = 0
  ._line_top inline_asm
  .PUBLIC _label1
  add 1, r6
_label1:
  add -1, r6
  ._line_end inline_asm
  jmp [r31]
 
_func2:
  ._line_top inline_asm
  .PUBLIC _label2
  add -1, r6
_label2:
  add 1, r6
  ._line_end inline_asm
  jmp [r31]