github.com/prattmic/llgo-embedded@v0.0.0-20150820070356-41cfecea0e1e/third_party/gofrontend/libffi/src/avr32/sysv.S (about)

     1  /* -----------------------------------------------------------------------
     2     sysv.S - Copyright (c) 2009  Bradley Smith <brad@brad-smith.co.uk>
     3  
     4     AVR32 Foreign Function Interface
     5  
     6     Permission is hereby granted, free of charge, to any person obtaining
     7     a copy of this software and associated documentation files (the
     8     ``Software''), to deal in the Software without restriction, including
     9     without limitation the rights to use, copy, modify, merge, publish,
    10     distribute, sublicense, and/or sell copies of the Software, and to
    11     permit persons to whom the Software is furnished to do so, subject to
    12     the following conditions:
    13  
    14     The above copyright notice and this permission notice shall be included
    15     in all copies or substantial portions of the Software.
    16  
    17     THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
    18     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    19     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    20     IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    21     CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    22     TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    23     SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    24     --------------------------------------------------------------------- */
    25  
    26  #define LIBFFI_ASM
    27  #include <fficonfig.h>
    28  #include <ffi.h>
    29  
    30      /* r12:  ffi_prep_args
    31       * r11:  &ecif
    32       * r10:  size
    33       * r9:   cif->flags
    34       * r8:   ecif.rvalue
    35       * sp+0: cif->rstruct_flag
    36       * sp+4: fn */
    37  
    38      .text
    39      .align  1
    40      .globl  ffi_call_SYSV
    41      .type   ffi_call_SYSV, @function
    42  ffi_call_SYSV:
    43      stm     --sp, r0,r1,lr
    44      stm     --sp, r8-r12
    45      mov     r0, sp
    46  
    47      /* Make room for all of the new args. */
    48      sub     sp, r10
    49      /* Pad to make way for potential skipped registers */
    50      sub     sp, 20
    51  
    52      /* Call ffi_prep_args(stack, &ecif). */
    53      /* r11 already set */
    54      mov     r1, r12
    55      mov     r12, sp
    56      icall   r1
    57  
    58      /* Save new argument size */
    59      mov     r1, r12
    60  
    61      /* Move first 5 parameters in registers. */
    62      ldm     sp++, r8-r12
    63  
    64      /* call (fn) (...). */
    65      ld.w    r1, r0[36]
    66      icall   r1
    67  
    68      /* Remove the space we pushed for the args. */
    69      mov     sp, r0
    70  
    71      /* Load r1 with the rstruct flag. */
    72      ld.w    r1, sp[32]
    73  
    74      /* Load r9 with the return type code. */
    75      ld.w    r9, sp[12]
    76  
    77      /* Load r8 with the return value pointer. */
    78      ld.w    r8, sp[16]
    79  
    80      /* If the return value pointer is NULL, assume no return value. */
    81      cp.w    r8, 0
    82      breq    .Lend
    83  
    84      /* Check if return type is actually a struct */
    85      cp.w    r1, 0
    86      breq    1f
    87  
    88      /* Return 8bit */
    89      cp.w    r9, FFI_TYPE_UINT8
    90      breq    .Lstore8
    91  
    92      /* Return 16bit */
    93      cp.w    r9, FFI_TYPE_UINT16
    94      breq    .Lstore16
    95  
    96  1:
    97      /* Return 32bit */
    98      cp.w    r9, FFI_TYPE_UINT32
    99      breq    .Lstore32
   100      cp.w    r9, FFI_TYPE_UINT16
   101      breq    .Lstore32
   102      cp.w    r9, FFI_TYPE_UINT8
   103      breq    .Lstore32
   104  
   105      /* Return 64bit */
   106      cp.w    r9, FFI_TYPE_UINT64
   107      breq    .Lstore64
   108  
   109      /* Didn't match anything */
   110      bral    .Lend
   111  
   112  .Lstore64:
   113      st.w    r8[0], r11
   114      st.w    r8[4], r10
   115      bral    .Lend
   116  
   117  .Lstore32:
   118      st.w    r8[0], r12
   119      bral    .Lend
   120  
   121  .Lstore16:
   122      st.h    r8[0], r12
   123      bral    .Lend
   124  
   125  .Lstore8:
   126      st.b    r8[0], r12
   127      bral    .Lend
   128  
   129  .Lend:
   130      sub     sp, -20
   131      ldm     sp++, r0,r1,pc
   132  
   133      .size   ffi_call_SYSV, . - ffi_call_SYSV
   134  
   135  
   136      /* r12:  __ctx
   137       * r11:  __rstruct_flag
   138       * r10:  __inner */
   139  
   140      .align  1
   141      .globl  ffi_closure_SYSV
   142      .type   ffi_closure_SYSV, @function
   143  ffi_closure_SYSV:
   144      stm     --sp, r0,lr
   145      mov     r0, r11
   146      mov     r8, r10
   147      sub     r10, sp, -8
   148      sub     sp, 12
   149      st.w    sp[8], sp
   150      sub     r11, sp, -8
   151      icall   r8
   152  
   153      /* Check if return type is actually a struct */
   154      cp.w    r0, 0
   155      breq    1f
   156  
   157      /* Return 8bit */
   158      cp.w    r12, FFI_TYPE_UINT8
   159      breq    .Lget8
   160  
   161      /* Return 16bit */
   162      cp.w    r12, FFI_TYPE_UINT16
   163      breq    .Lget16
   164  
   165  1:
   166      /* Return 32bit */
   167      cp.w    r12, FFI_TYPE_UINT32
   168      breq    .Lget32
   169      cp.w    r12, FFI_TYPE_UINT16
   170      breq    .Lget32
   171      cp.w    r12, FFI_TYPE_UINT8
   172      breq    .Lget32
   173  
   174      /* Return 64bit */
   175      cp.w    r12, FFI_TYPE_UINT64
   176      breq    .Lget64
   177  
   178      /* Didn't match anything */
   179      bral    .Lclend
   180  
   181  .Lget64:
   182      ld.w    r11, sp[0]
   183      ld.w    r10, sp[4]
   184      bral    .Lclend
   185  
   186  .Lget32:
   187      ld.w    r12, sp[0]
   188      bral    .Lclend
   189  
   190  .Lget16:
   191      ld.uh   r12, sp[0]
   192      bral    .Lclend
   193  
   194  .Lget8:
   195      ld.ub   r12, sp[0]
   196      bral    .Lclend
   197  
   198  .Lclend:
   199      sub     sp, -12
   200      ldm     sp++, r0,lr
   201      sub     sp, -20
   202      mov     pc, lr
   203  
   204      .size   ffi_closure_SYSV, . - ffi_closure_SYSV
   205  
   206  #if defined __ELF__ && defined __linux__
   207      .section    .note.GNU-stack,"",@progbits
   208  #endif