H8/300 Application Binary Interface for GCC

Glossary

aggregate
struct and union in C or C++, and class in C++.
libcall
GCC's internal library function to implement features not available on the target architecture, such as the 32-bit-by-32-bit multiplication on H8/300.
prologue
The initial part of a subroutine that saves registers that should be preserved across a call and allocates stack areas for local variables.
scalar
The antonym of aggregate, such as char, short, and int.

Argument Passing

With -mno-quickcall

With -mno-quickcall, every argument is pushed onto the stack.

Without -mno-quickcall

Functions with Fixed-Length Arguments

The first argument goes into ER0 or R0 in case of 16-bit argument. Likewise, the second and third goes into ER1 and ER2, respectively. The rest of the arguments are pushed onto the stack, from the last to first.

If a 32-bit argument is to be passed on registers on H8/300, R0 contains the upperhalf, and R1 contains the lowerhalf of the argument. Likewise, if a 64-bit argument is to be passed on registers on H8/300H or H8S, ER0 contains the upperhalf, and ER1 contains the lowerhalf of the argument.

These registers are always filled when calling functions with fixed-length arguments. For example, if one wishes to pass two arguments of type long on H8/300, the first argument is stored into a pair of R0 and R1. The upper half of the second argument is stored into R2. The lower half is pushed onto the stack.

If the return value is of an aggregate type, an invisible argument will take the first argument. For details, see Function Value below.

Every stack push is rounded to a multiple of 2 bytes on H8/300 and of 4 bytes on H8/300H and H8S. If the size of a value pushed onto the stack is different from the size of an actual push, a padding is added downward. For example, if 2 bytes of data, 0x1234, are to be pushed onto the stack on H8/300H, 4 bytes are pushed like so:

sp + 30x34
sp + 20x12
sp + 1padding (unknown value)
sp + 0padding (unknown value)

As an exception, a libcall will use R0 through R3 on H8/300 or ER0 through ER3 on H8/300H and H8S to pass arguments before resorting to the stack.

Functions with Variable-Length Arguments

To be documented.

Function Value

On H8/300, the scalar function value no larger than 4 bytes in size is returned in R0 or a pair of R0 and R1. If a pair of R0 and R1 is used to return the function value, R0 contains the upper half and R1 contains the lower half of the value.

On H8/300H and H8S, the scalar function value no larger than 8 bytes in size is returned in ER0 or a pair of ER0 and ER1.

Otherwise, the function value is always returned in memory. Specifically, the caller allocates an instance of the aggregate type and passes a pointer to the instance as an invisible argument. The caller stores the function value into the memory location pointed to by the invisible pointer. To illustrate, the following two functions behave identically (and may even be compiled into exactly the same assembly code with optimization enabled).

struct s { int a; };

struct s
foo (void)
{
  struct s s = { 0 };
  return s;
}

void
bar (struct s *p)
{
  p->a = 0;
}

Call Clobbered Registers

R0 through R3 are call clobbered on H8/300H and H8S. Likewise, ER0 through ER3 are call clobbered on H8/300H and H8S. These registers are clobbered regardless of the number of the registers used for argument passing.

Frame Pointer

On H8/300, R6 is used as the frame pointer. On H8/300H and H8S, ER6 is used as the frame pointer. -fomit-frame-pointer can be used to eliminate the use of the frame pointer in favor of the stack pointer.

Bit-Field

The memory location containing a bit-field is filled from MSB to LSB. In the following example, a will take bit 7, MSB. b will take bit 6 and bit 5.

struct s {
  int a:1;
  int b:2;
};

Structure Alignment

Unless __attribute__ ((packed)) is attached to the declaration of a struct, each structure member is aligned to a multiple of 2 bytes on H8/300 and of 4 bytes on H8/300H and H8S.

Stack Frame Layout

From gcc-2.6? up to GCC-3.4

Immediately after the prologue is setup, the stack frame layout is as follows:

Address Description Size on H8/300 Size on H8/300H and H8S
(Normal Mode)
Size on H8/300H and H8S
(Advanced Mode)
Pointed to by
High Arguments
(if any)
Multiple of 2 bytes Multiple of 4 bytes Multiple of 4 bytes  
  Program Counter 2 bytes 2 bytes 4 bytes  
  Saved Frame Pointer 2 bytes 4 bytes 4 bytes R6 or ER6
  Locals Multiple of 2 bytes Multiple of 4 bytes Multiple of 4 bytes  
Low Saved Registers Multiple of 2 bytes Multiple of 4 bytes Multiple of 4 bytes R7 or ER7
(points to the lowest address)

GCC 4.0 and later

Currently, the stack frame layout, subject to change, is as follows:

Address Description Size on H8/300 Size on H8/300H and H8S
(Normal Mode)
Size on H8/300H and H8S
(Advanced Mode)
Pointed to by
High Arguments
(if any)
Multiple of 2 bytes Multiple of 4 bytes Multiple of 4 bytes  
  Program Counter 2 bytes 2 bytes 4 bytes  
  Saved Frame Pointer
(if any)
2 bytes 4 bytes 4 bytes R6 or ER6
  Saved Registers Multiple of 2 bytes Multiple of 4 bytes Multiple of 4 bytes  
Low Locals Multiple of 2 bytes Multiple of 4 bytes Multiple of 4 bytes R7 or ER7
(points to the lowest address)

Complex Numbers

To be documented.

Static Chain

To be documented.