4.2.6.5 Interrupt/Exception processing handler

The CC-RH can describe an "Interrupt handler" or "Exception handler" that is called if an interrupt or exception occurs. This section explains how to describe these handlers.

(1)

Occurrence of interrupt/exception

If an interrupt or exception occurs in the RH850 family, the program jumps to a handler address corresponding to the interrupt or exception.

The arrangement of the handler addresses and the available interrupts vary depending on the device of the RH850. See the Relevant Device's User's Manual of each device for details.

 

How to describe interrupt servicing is explained specifically in "(3) Describing interrupt/exception handler".

(2)

Processing necessary in case of interrupt/exception

If an interrupt/exception occurs while a function is being executed, interrupt/exception processing must be immediately executed. When the interrupt/exception processing is completed, execution must return to the function that was interrupted.

Therefore, the register information at that time must be saved when an interrupt/exception occurs, and the register information must be restored when interrupt/exception processing is complete.

(3)

Describing interrupt/exception handler

The format in which an interrupt/exception handler is described does not differ from ordinary C functions, but the functions described in C must be recognized as an interrupt/exception handler by the CC-RH. With the CC-RH, an interrupt/exception handler is specified using the #pragma interrupt directive.

#pragma interrupt ( function-specification [, function-specification]... )Note
  function-specification: function-name [(interrupt specification [, interrupt 
  specification]...)]

Note

The outer parentheses can be omitted.

 

Describe functions that are described in the C language. In the case of a function, "void func1() {}", specify "func1".

The function exit code of an interrupt function is different from that of an ordinary function. You must therefore not call them in the same way as ordinary functions.

 

(a)

interrupt specification

The following interrupt specification can be specified.

enable=

Specifies whether multiplex interrupts are enabled. This can be set to true, false, or manual.

-

true

Output ei/di.

Outputs code to save or restore eipc/eipsw.

-

false (default)

Does not output ei/di.

Does not output code to save or restore eipc/eipsw.

-

manual

Does not output ei/di.

Outputs code to save or restore eipc/eipsw.

priority=

channel=

You can only specify one of either "priority" or "channel", but not both (writing both will cause a compilation error).

-

priority=

Specifies the exception trigger. You can write only one of the following tokens.

SYSERR/FETRAP/TRAP0/TRAP1/RIE/FPPNote 1/FPINote 1/FPINTNote 2/FPENote 3/ FXENote 3/UCPOP/MIP/MDP/PIE/MAE/FENMI/FEINT/EIINT_PRIORITYX (X is 0 -15)

-

channel=

Specifies the interrupt channel. Select this if you are using the extended specification for interrupts.

Generates code determining the EI compiler to be used.

If you did not specify either "priority" or "channel", it will determine the EIINT.

fpu=

Specifies saving and restoration of fpepc/fpsr in the fpu context. This can be set to true, false, or auto.

-

true

Saves and restores fpepc/fpsr.

-

false

Does not save or restore fpepc/fpsr.

-

auto (default)

Interpreted as true when the -Xfloat=fpu option is specified.

Interpreted as false when -Xfloat=soft is specified.

fxu=Note 3

Specifies saving and restoration of fxsr/fxxp in the fxu context. This can be set to true, false, or auto.

-

true

Saves and restores fxsr/fxxp.

-

false

Does not save or restore fxsr/fxxp.

-

auto (default)

Saves and restores fxsr/fxxp when the -Xfxu=on option is specified.

Does not save or restore fxsr/fxxp when the -Xfxu=off option is specified.

callt=

Specifies saving/restoration of ctpc/ctpsw in the callt context. This can be set to true, false.

-

true (default)

Saves and restore ctpc/ctpsw.

-

false

Does not save or restore ctpc/ctpsw.

resbankNote3

Outputs the resbank instruction to the exit code of a function. Part of the instruction string for saving context is not output.

 

A warning is output in any of the following cases.

-

When the interrupt specification "fpu=false" was specified simultaneously

-

When -Xreg_mode=22 or -Xreg_mode=common was specified simultaneously

-

When -Xreserve_r2 was specified simultaneously

-

When -Xep=fix was specified simultaneously

 

An error will occur in the following case.

-

When a token other than EIINT was specified simultaneously for the interrupt specification "priority="

param=

Specifies the method for receiving the value of an exception source register as a formal parameter.

Specify the exception source register names in param=( ) for the number of formal parameters.

One to four exception source register names can be specified, and they should be delimited with a comma (,).

The specifiable exception source register names are as follows:

eiic, feic, fpsr, fxsrNote 3, fxxcNote 3, fxxpNote 3

 

An error will occur in any of the following cases.

-

When the number of specified exception source register names does not match the number of formal parameters

-

When the same exception source register name was specified more than once

Note 1.

An error will occur if -Xcpu=g3mh option is specified.

Note 2.

An error will occur if -Xcpu=g3mh option is not specified.

Note 3.

An error will occur if the -Xcpu=g4mh option is not specified.

 

The parameter of the interrupt specification cannot be omitted.

For example, writing only "enable=" will cause a compilation error. The default interrupt specification signifies the behavior when individual interrupt specifications are not written.

 

(b)

Definition of interrupt functions

The return type of an interrupt function should always be the void type.

For formal parameters of an interrupt function, a maximum of four can be written when the interrupt specification "param=" is specified and a maximum of one can be written when not specified.

The type of formal parameters should always be unsigned long.

When "param=" is not specified, the EIIC register value is stored in the formal parameter for an EI level exception and the FEIC register value is stored for any other exception.

When "param=" is specified, the value of each exception source register is stored in the corresponding formal parameter according to the specified contents.

 

Example

#pragma interrupt handler1 (priority=EIINT)
void handler1(unsigned long a) {  /* a = EIIC; */
    :
}
 
#pragma interrupt handler2
void handler2(unsigned long a) {  /* a = FEIC */
    :
}
 
#pragma interrupt handler3 (param=(eiic,feic,fpsr))
void handler3(unsigned long a, unsigned long b, unsigned long c) {
    /* a = EIIC, b = FEIC, c = FPSR */
    :
}

 

(c)

Output code for EI level exception

The compiler inserts the following instructions at the entrance and exit of an EI level exception interrupt function. EIINT and FPI are some of the main corresponding items.
However, this is not inserted into all interrupt functions. Necessary processing is output in accordance with user-defined #pragma statements, compiler options, etc.

 

<1>

[Entrance code of interrupt functions]

(1) Allocates stack area for saving context

(2) Saves Caller-Save register used in interrupt function

(3) Saves EIPC and EIPSW

(4) If the function has a formal parameter, set EIIC to R6

(5) Enables multiplex interrupts

(6) Saves WCTPC and CTPSW

(7) Saves WFPEPC and FPSR

 

<2>

[Exit code of interrupt functions]

(8) Sets imprecise interrupt standby

(9) Restorse FPEPC and FPSR

(10) Restores CTPC and CTPSW

(11) Disables multiplex interrupts

(12) Restores EIPC and EIPSW

(13) Restores Caller-Save register used in interrupt function

(14) Frees stack area for saving context

(15) eiret

 

Below is a specific example of the output code. Numbers (1) to (15) in the code correspond to the numbered actions above.

Note that the instructions in the output code will not necessarily be identical to this example. The instructions, general-purpose registers, and other details may differ from this example.

 

Example 1.

Sample1: output of EI level exception

#pragma interrupt func1(enable=true, callt=true, fpu=true)
void func1(unsigned long eiic)
{
        User-coded processing;
}

 

Example 2.

Sample2: output of EI level exception
If there are no formal parameters, and interrupt multiplexing is set to manual (enable=manual)

#pragma interrupt func1(enable=true, callt=true, fpu=true)
void func1(unsigned long eiic)
 {
        User-coded processing;
}

 

(d)

Output code for FE level exception

The compiler inserts the following instructions at the entrance and exit of an FE level exception interrupt function. FEINT and PIE are some of the main corresponding items.
However, this is not inserted into all interrupt functions. Necessary processing is output in accordance with user-defined #pragma statements, compiler options, etc.

 

<1>

[Entrance code of interrupt functions]

(1) Allocates stack area for saving context

(2) Saves all Caller-Save register used in interrupt function

(3) If the function has a formal parameter, sets FEIC to R6

(4) Saves CTPC and CTPSW

(5) Saves FPEPC and FPSR

 

<2>

[Exit code of interrupt functions]

(6) Restores FPEPC and FPSR

(7) Restores CTPC and CTPSW

(8) Restores all Caller-Save register used in interrupt function

(9) Frees stack area for saving context

(10) feret

 

Below is a specific example of the output code. Numbers (1) to (10) in the code correspond to the numbered actions above.

Note that the instructions in the output code will not necessarily be identical to this example. The instructions, general-purpose registers, and other details may differ from this example.

 

Example

Sample output of FE level exception

#pragma interrupt func1(priority=feint, callt=true, fpu=true)
void func1(unsigned long feic)
{
        User-coded processing;
}

 

(e)

Output code for FE level exception (cannot recover/restore)

The compiler inserts the following instructions at the entrance and exit of an FE level exception (cannot recover/restore) interrupt function. FENMI and SYSERR are some of the main corresponding items.

<1>

[Entrance code of interrupt functions]

(1) If the function has a formal parameter, sets FEIC to R6

Nothing is output if the function does not have any parameters.

<2>

[Exit code of interrupt functions]

None

 

Remark

No saving or restoration of context is output.
Code the save and restore the Callee-Save register is also not output.
Take appropriate measures in the user program, such as calling abort() in the function to terminate the program.

 

Below is a specific example of the output code. Numbers (1) in the code correspond to the numbered actions above.

Example

Sample output of FE level exception (cannot recover/restore)

#pragma interrupt func1(priority=fenmi)
void func1(unsigned long feic)
{
        User-coded processing;
}

 

(f)

Output code for EI level exception when resbank is specified

The compiler inserts the following instructions at the entrance and exit of an EI level exception interrupt function for which resbank is specified.

The instruction string differs from that output for a normal EI level exception interrupt function in the following points.

-

There is no instruction string for saving the context that is automatically saved by the register bank facility.

-

The resbank instruction is output instead of the instruction string for restoring the above context.

 

Note that information of the context to be automatically saved by the register bank facility is determined from the specified -Xresbank_mode option.

These are not always inserted in all interrupt functions, and the necessary processing is output in response to the #pragma directives written by the user or the compile options.

When resbank is not specified

When resbank is specified (-Xresbank_mode=0)

_handler:
movea 0xFFFFFFA8, r3, r3
st.w r1, 0x14[r3]     ; save r1
st.w r2, 0x18[r3]     ; save r2
st.w r5, 0x1C[r3]     ; save r5
st23.dw r6, 0x20[r3]  ; save r6,r7
st23.dw r8, 0x28[r3]  ; save r8,r9
st23.dw r10, 0x30[r3] ; save r10,r11
st23.dw r12, 0x38[r3] ; save r12,r13
st23.dw r14, 0x40[r3] ; save r14,r15
st23.dw r16, 0x48[r3] ; save r16,r17
st23.dw r18, 0x50[r3] ; save r18,r19
stsr 0x10, r8, 0x00
stsr 0x11, r9, 0x00
st23.dw r8, 0x00[r3]  ; save CTPC,CTPSW
stsr 0x06, r8, 0x00
st.w r8, 0x08[r3]     ; save FPSR
stsr 0x06, r8, 0x0A
stsr 0x0D, r9, 0x0A
st23.dw r8, 0x0C[r3]  ; save FXSR,FXXP
prepare 0x01, 0x00    ; save r31
jarl _sub, r31
dispose 0x00, 0x01    ; restore r31
ld23.dw 0x0C[r3], r8
ldsr r9, 0x0D, 0x0A   ; restore FXXP
ldsr r8, 0x06, 0x0A   ; restore FXSR
ld.w 0x08[r3], r8
ldsr r8, 6            ; restore FPSR
ld23.dw 0x00[r3], r8
ldsr r9, 0x11, 0x00   ; restore CTPSW
ldsr r8, 0x10, 0x00   ; restore CTPC
ld23.dw 0x50[r3], r18 ; restore r18,r19
ld23.dw 0x48[r3], r16 ; restore r16,r17
ld23.dw 0x40[r3], r14 ; restore r14,r15
ld23.dw 0x38[r3], r12 ; restore r12,r13
ld23.dw 0x30[r3], r10 ; restore r10,r11
ld23.dw 0x28[r3], r8  ; restore r8,r9
ld23.dw 0x20[r3], r6  ; restore r6,r7
ld.w 0x1C[r3], r5     ; restore r5
ld.w 0x18[r3], r2     ; restore r2
ld.w 0x14[r3], r1     ; restore r1
movea 0x58, r3, r3
eiret
_handler:
movea 0xFFFFFFF0, r3, r3
 
 
 
 
 
 
 
 
 
 
stsr 0x10, r8, 0x00
stsr 0x11, r9, 0x00
st23.dw r8, 0x00[r3]  ; save CTPC,CTPSW
 
 
stsr 0x06, r8, 0x0A
stsr 0x0D, r9, 0x0A
st23.dw r8, 0x08[r3]  ; save FXSR,FXXP
prepare 0x01, 0x00    ; save r31
jarl _sub, r31
dispose 0x00, 0x01    ; restore r31
ld23.dw 0x08[r3], r8
ldsr r9, 0x0D, 0x0A   ; restore FXXP
ldsr r8, 0x06, 0x0A   ; restore FXSR
 
 
ld23.dw 0x00[r3], r8
ldsr r9, 0x11, 0x00  ; restore CTPSW
ldsr r8, 0x10, 0x00  ; restore CTPC
resbank  ; restore r1-r19,r30,EIIC,FPSR
 
 
 
 
 
 
 
 
 
 
eiret

 

[Remark]

Even though the interrupt specification "resbank" is used, a code for setting a value to RBCR0 is not generated. The value must be directly set with the user program.

 

(4)

Notes on describing interrupt/exception handler

-

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

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

#pragma block_interrupt