This section explains using the following extended specifications.
This extension changes the section name to be output by the compiler.
When both a section type and a new section name are specified, the section names for all functions written after the #pragma declaration are changed if the specified section type is P. If the section type is C, D, or B, the names of all sections defined after the #pragma declaration are changed.
When only a new section name is specified, the section names for the program, constant, initialized data, and uninitialized data areas after the #pragma declaration are changed. In this case, the default section name postfixed with the string specified by <new section name> is used as the new section name.
When neither a section type nor a new section name is specified, the section names for the program, constant, initialized data, and uninitialized data areas after the #pragma declaration are restored to the default section names.
The default section name for each section type is determined by the section option when specified. If the default section name is not specified by the section option, the section type name is used instead.
#pragma section B Ba int i; // Allocated to the Ba section void func(void) { (omitted) } #pragma section B Bb int j; // Allocated to the Bb section void sub(void) { (omitted) } |
#pragma section can be declared only outside the function definition.
The section name of the following items cannot be changed by this extension. The section option needs to be used.
(1) String literal and initializers for use in the dynamic initialization of aggregates
(2) Branch table of switch statement
Up to 2045 sections can be specified by #pragma section in one file.
When specifying the section for static class member variables, be sure to specify #pragma section for both the class member declaration and definition.
When si=<constant> is specified, a data section is created to be used as the stack of size <constant> with section name SI.
When su=<constant> is specified, a data section is created to be used as the stack of size <constant> with section name SU.
si and su can each be specified only once in a file.
<constant> must always be specified as a multiple of four.
A value from 4 to 2147483644(0x7ffffffc) is specifiable for <constant>.
This extension declares an interrupt function.
A global function or a static function member can be specified for the function name.
Table 4.22 lists the interrupt specifications.
An interrupt function declared by #pragma interrupt guarantees register values before and after processing (all registers used by the function are pushed onto and popped from the stack when entering and exiting the function). The RTE instruction directs execution to return from the function in most cases.
An interrupt function with no interrupt specifications is processed as a simple interrupt function.
When use of the vector table is specified (vect=), the interrupt function address is stored in the specified vector number location in the C$VECT section.
When use of fast interrupt processing is specified (fint), the RTFI instruction is used to return from the function. When the fint_register option is also specified, the registers specified through the option are used by the interrupt function without being saved or restored.
When a limitation on registers in interrupt function is specified (save), the registers that can be used in the interrupt function are limited to R1 to R5 and R14 to R15. R6 to R13 are not used and the instructions for saving and restoring them are not generated.
When enable is specified, the I flag in PSW is set to 1 at the beginning of the function to enable nested interrupts.
When Accumulator saving is specified (acc), if another function is called from the specified function or the function uses an instruction that modifies the ACC, an instruction to save and restore the ACC is generated. The save and restored code of the ACC when the ISA *1 is selected as the RXv1 or the microcomputer type is selected by the CPU *2.
When Accumulator non-saving is specified (no_acc), an instruction to save and restore the ACC is not generated.
If neither acc nor no_acc is specified, the result depends on the option settings for compilation.
A global function (in C/C++ program) or a static function member (in C++ program) can be specified as an interrupt function definition.
The function must return only void data. No return value can be specified for the return statement. If attempted, an error will be output.
*1) This means a selection by the -isa option or the ISA_RX environment variable.
*2) This means a selection by the -cpu option or the CPU_RX environment variable.
#pragma interrupt (f1, f2) void f1(){...} // Correct declaration. int f2(){...} // An error will be output // because the return value is not // void data. |
_func: PUSHM R1-R3 ; Saves the registers used in the function. .... (R1, R2, and R3 are used in the function) .... POPM R1-R3 ; Restores the registers saved at the entry. RTE |
Interrupt function that calls another function |
C source description: Compiles with the fint_register=2 option specified
#pragma interrupt func1(fint) void func1(){ a=1; } // Interrupt function void func2(){ a=2; } // General function |
void func5(void); #pragma interrupt accsaved_ih(acc) /* Specifies acc */ void accsaved_ih(void) { func5(); } |
_accsaved_ih: PUSHM R14-R15 PUSHM R1-R5 MVFACMI R4 SHLL #10H, R4 MVFACHI R5 PUSHM R4-R5 BSR _func5 POPM R4-R5 MVTACLO R4 MVTACHI R5 POPM R1-R5 POPM R14-R15 RTE |
Due to the specifications of the RX instruction set, only the upper 48 bits of ACC can be saved and restored with the acc flag. The lower 16 bits of ACC are not saved and restored.
Each interrupt specification can be specified only with alphabetical lowercase letters. When specified with uppercase letters, an error will occur.
When vect is used as an interrupt specification, the address of empty vectors for which there is no specification is 0. You can specify a desired address value or symbol for an address with the optimizing linkage editor. For details, refer to the descriptions on the VECT and VECTN options.
Parameters are not definable for #pragma interrupt functions. Although defining parameters for such functions does not lead to an error, values read out from the parameters are undefined.
Purpose of acc and no_acc:
acc and no_acc take into account the following purposes:
Solution for decrease in the interrupt response speed when compensation of ACC is performed by save_acc (no_acc) |
Control of saving and restoring of ACC through source code |
#pragma inline declares a function for which inline expansion is performed.
Even when the noinline option is specified, inline expansion is done for the function specified by #pragma inline.
#pragma noinline declares a function for which the inline option effect is canceled.
A global function or a static function member can be specified as a function name.
A function specified by #pragma inline or a function with specifier inline (C++ and C (C99)) are expanded where the function is called.
#pragma inline(func) static int func (int a, int b) { return (a+b)/2; } int x; main() { x=func(10,20); } |
Inline expansion will not be applied in the following functions even when #pragma inline is specified.
#pragma inline does not guarantee inline expansion; inline expansion might not be applied due to restrictions on increasing compilation time or memory size. If inline expansion is canceled, try specifying the noscope option; inline expansion may be applied in some cases.
Specify #pragma inline before defining a function.
An external definition is generated for a function specified by #pragma inline.
When #pragma inline is specified for a static function, the function definition is deleted after inline expansion.
The C++ compiler does not create external definitions for inline-specified functions.
The C (C99) does not create external definitions for inline-specified functions unless they include extern declarations.
This extension declares an assembly-language function for which inline expansion is performed.
The general function calling rules are also applied to the calls of assembly-language inline functions.
#pragma inline_asm func static int func(int a, int b){ ADD R2,R1 ; Assembly-language description } main(int *p){ *p = func(10,20); } |
_main: PUSH.L R6 MOV.L R1, R6 MOV.L #20, R2 MOV.L #10, R1 ADD R2,R1; Assembly-language description MOV.L R1, [R6] MOV.L #0, R1 RTSD #04H, R6-R6 |
Specify #pragma inline_asm before defining a function.
An external definition is generated for a function which is not a static function but for which #pragma inline_asm is specified.
When the registers whose values are saved and restored at the entry and exit of a function (seeTable 9.1 Rules to Use Registers) are used in an assembly-language inline function, these registers must be saved and restored at the start and end of the function.
In an assembly-language inline function, use only the RX Family instruction and temporary labels. Other labels cannot be defined and assembler directives cannot be used. |
When #pragma inline_asm is specified for a static function, the function definition is deleted after inline expansion. |
Assembly-language descriptions are processed by the preprocessor; take special care when defining through #define a macro with the same name as an instruction or a register used in the assembly language (such as MOV or R5). |
A stack information file handles the assembly code for a #pragma inline_asm directive as not consuming stack area. Be careful when the assembly code includes an instruction with R0 as an operand. |
This specifies that the function specified as <function name> is handled as an entry function.
The entry function is created without any code to save and restore the contents of registers.
When #pragma stacksize is declared, the code that makes the initial setting of the stack pointer will be output at the beginning of the function.
When the base option is specified, the base register specified by the option is set up.
.SECTION SU,DATA,ALIGN=4 .BLKB 100 .SECTION P,CODE _INIT: MVTC (TOPOF SU + SIZEOF SU),USP MOV.L #__ROM_TOP,R13 |
Be sure to specify #pragma entry before declaring a function.
Do not specify more than one entry function in a load module.
This extension switches the order of bit field assignment.
When left is specified, bit field members are assigned from the upper-bit side. When right is specified, members are assigned from the lower-bit side.
If left or right is omitted, the order is determined by the option specification.
#pragma pack specifies the boundary alignment value for structure members and class members after the #pragma pack written in the source program.
When #pragma pack is not specified or after #pragma packoption is specified, the boundary alignment value for the structure members and class members is determined by the pack option. Table 4.23 shows #pragma pack specifications and the corresponding alignment values.
The boundary alignment value for structure and class members can also be specified by the pack option. When both the option and #pragma extension specifier are specified together, the #pragma specification takes priority.
This extension allocates the specified variable to the specified address. The compiler assigns a section for each specified variable, and the variable is allocated to the specified absolute address during linkage. If variables are specified for contiguous addresses, these variables are assigned to a single section.
_main: MOV.L #0,R5 MOV.L #7F00H,R14 ; MOV.L R5,[R14] RTS .SECTION $ADDR_B_7F00 .ORG 7F00H .glb _X _X: ; static: X .blkl 1 |
If an object that is neither a structure/union member nor a variable is specified, an error will be output. |
A static variable that is validated by #pragma address and not referred from the source file may be removed by a compiler optimization. |
We recommend not applying #pragma address to a variable which has an initial value but does not have the const qualifier. If this case applies for any variables, take note of the restrictions below. |
The -rom option (RAMization of the ROM area) of the optimizing linkage editor (rlink) cannot be applied to sections containing such variables. |
When a section containing such variables is allocated to the RAM, all initial values must be written to the corresponding RAM areas when starting up the program or in advance of that. |
This extension specifies the endian for the area that stores static objects.
The specification of this extension is applied from the line containing #pragma endian to the end of the file or up to the line immediately before the line containing the next #pragma endian.
big specifies big endian. When the endian=little option is specified, data is assigned to the section with the section name postfixed with _B.
little specifies little endian. When the endian=big option is specified, data is assigned to the section with the section name postfixed with _L.
When big or little is omitted, endian is determined by the option specification.
.glb _A .glb _B .SECTION D,ROMDATA,ALIGN=4 _B: .lword 200 .SECTION D_B,ROMDATA,ALIGN=4 .ENDIAN BIG _A: .lword 100 |
If areas of the long long type, double type (when the dbl_size=8 option is specified), and long double type (when the dbl_size=8 option is specified) are included in objects to which #pragma endian (differed from the endian option) is applied, do not make indirect accesses to these areas using addresses or pointers. In such a case, correct operation will not be guaranteed. If a code that acquires an address in such an area is included, a warning message is displayed.
If bit fields of the long long type are included in objects to which #pragma endian (differed from the endian option) is applied, do not make writes to these areas. In such a case, correct operation will not be guaranteed.
The endian of the following items cannot be changed by this extension. The endian option needs to be used.
(1) String literal and initializers for use in the dynamic initialization of aggregates
(2) Branch table of switch statement
(3) Objects declared as external references (objects declared through extern without initialization expression)
(4) Objects specified as #pragma address
#pragma instalign4 [(]<function name>[(<branch destination type>)][,...][)] #pragma instalign8 [(]<function name>[(<branch destination type>)][,...][)] #pragma noinstalign [(]<function name>[,...][)] |
Specifies the function in which instructions at branch destinations are aligned for execution.
Instruction allocation addresses in the specified function are adjusted to be aligned to 4-byte boundaries when #pragma instalign4 is specified or to 8-byte boundaries when #pragma instalign8 is specified.
In the function specified with #pragma noinstalign, alignment of allocation addresses is not adjusted.
The branch destination type should be selected from the following*:
No specification: Head of function and case and default labels of switch statement
inmostloop: Head of each inmost loop, head of function, and case and default labels of switch statement
loop: Head of each loop, head of function, and case and default labels of switch statement
Alignment is adjusted only for the branch destinations listed above; alignment of the other destinations is not adjusted. For example, when loop is selected, alignment of the head of a loop is adjusted but alignment is not adjusted at the branch destination of an if statement that is used in the loop but does not generate a loop. |
Except that each #pragma extension specification is valid only in the specified function, these specifiers work in the same way as the instalign4, instalign8, and noinstalign options. When both the options and #pragma extension specifiers are specified together, the #pragma specifications take priority.
In the code section that contains a function specified with instalign4 or instalign8, the alignment value is changed to 4 (instalign4 is specified) or 8 (instalign8 is specified). If a single code section contains both a function specified with instalign4 and that specified with instalign8, the alignment value in the code section is set to 8.
The other detailed functions of these #pragma extension specifiers are the same as those of the instalign4, instalign8, and noinstalign options; refer to the description of each option.
Specification of Function for generating a code for detection of stack smashing [Professional Edition only] [V2.04.00 or later] |
#pragma stack_protector [(] function name [(num=<integer value>)] [)]
#pragma no_stack_protector [(] function name [)]
Generates a code for detection of stack smashing at the entry and the end of a function. A code for detection of stack smashing consists of instructions executing the three processes shown below.
(1) A 4-byte area is allocated just before (in the direction towards address 0xFFFFFFFF) the local variable area at the entry to a function, and the value specified by <number> is stored in the allocated area.
(2) At the end of the function, whether the 4-byte area in which <number> was stored has been rewritten is checked.
(3) If the 4-byte area has been rewritten in (2), the __stack_chk_fail function is called as the stack has been smashed.
A decimal number from 0 to 4294967295 should be specified in <number>. If the specification of <number> is omitted, the compiler automatically selects the number.
The __stack_chk_fail function needs to be defined by the user. It should contain postprocesses for the detected stack smashing.
Note the following items when defining the __stack_chk_fail function.
The __stack_chk_fail function does not generate a code for detection of stack smashing regardless of the -stack_protector and -stack_protector_all options, and #pragma stack_protector. |
In a C++ program, add extern "C" to the definition or the declaration for __stack_chk_fail function. |
Prevent returning to the caller (the function where stack smashing was detected) by taking measures such as calling abort() in __stack_chk_fail function and terminating the program. |
A code for detection of stack smashing is not generated for a function for which #pragma no_stack_protector has been specified regardless of the -stack_protector option and -stack_protector_all option.
If these options are used simultaneously with #pragma stack_protector, the -stack_protector option, or the -stack_protector_all option, the specification by #pragma becomes valid.
An error will occur when #pragma stack_protector and #pragma no_stack_protector are specified simultaneously for the same function within a single translation unit.
When the function specified by #pragma stack_protector is specified as any one of the following functions, an error message is output.