Floating-point and Double Parameters

To pass a floating-point argument into an __asm block, pass the address of the argument, and then load the argument to a register within the __asm block.

Because the __asm prototype specifies a variable argument list, passing parameters of type floating-point and double is governed by the SH-3 and SH-4 calling standard for variable argument lists.

The following list shows the SHx requirements for variable argument lists.

  • SH-3 and SH3-DSP

    If a function is declared to use variable argument lists**,** floating-point arguments are passed using integer argument registers and the stacks. SH-3 does not support floating-point operations and does not have any instructions to perform floating-point operations. The compiler for SH-3 uses emulation routines to perform floating-point operations.

  • SH-4

    If a function is declared to use variable argument lists**,** floating-point registers are unused and floating-point arguments are passed using only the integer argument registers and the stack.

In addition, the C and C++ ANSI standards require that float arguments in a variable argument list be promoted to type double. Consequently, floating point arguments are promoted to type double, and passed as word pairs in the integer registers and or on the stack.

The following SH-3 example shows how to first pass the address of float arguments to __asm call and then load the argument to a register within the __asm statement.

//
// Compute x+y+z --> result
//
float add_trig(float x, float y, float z)
{
  float result;
  void * temp_stk_space = _alloca(8);  // Reserve temp space in stack
  __asm(
    "mov.l  @(20,sp), r0  ; get pointer to temp stack space \n"
    "mov.l  r6,  @r0      ; save pointer to z on stack \n"
    "mov.l  r7,  @(4,r0)  ; save pointer to result on stack \n"
    "mov.l  @r4,  r4      ; get x  \n"
    "mov.l  @(16, sp),r0  ; get address of add routine \n"
    "jsr    @r0           ; compute x+y \n"
    "mov.l  @r5,  r5     ; get y  \n"
    "mov    r0, r4       ; get x + y \n" 
    "mov.l  @(20,sp), r1 ;\n"
    "mov.l  @(16, sp),r0 ; get address of add routine \n"
    "mov.l  @r1, r5      ; get pointer to z  \n"
    "jsr    @r0          ; compute x+y+z \n"
    "mov.l  @r5,  r5     ; get z \n"
    "mov.l  @(20,sp), r1 ; get pointer to temp stack space \n"
    "mov.l  @(4,r1),  r1 ; get pointer to result \n"
    "mov.l  r0, @r1      ; store r0 into result addr \n",
    &x,      // pointer to x passed in r4
    &y,      // pointer to y passed in r5
    &z,      // pointer to z passed in r6
    &result, // pointer to result passed in r7 
     _adds,  // pointer to _adds routine passed in @(16,sp)
    temp_stk_space);  // pointer to temp stack space passed in // @(20,sp)

  return result;
}
void main()
{
  float  retval = add_trig(1.0f, 2.0f,3.0f);
  printf("%f\n", retval);
}

See Also

SH-3 Calling Sequence Specification | SH3-DSP Calling Sequence Specifications | SH-4 Calling Sequence Specification | SHx Inline Assembly Parameters | Integer and Non-scalar Parameters

 Last updated on Thursday, April 08, 2004

© 1992-2003 Microsoft Corporation. All rights reserved.