shithub: dav1d

ref: 7ef74ca1005785f0791874d52217aecc76f190cd
dir: /tests/checkasm/arm/checkasm_64.S/

View raw version
/******************************************************************************
 * Copyright © 2018, VideoLAN and dav1d authors
 * Copyright © 2015 Martin Storsjo
 * Copyright © 2015 Janne Grunau
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *****************************************************************************/

#define PRIVATE_PREFIX checkasm_

#include "src/arm/asm.S"
#include "src/arm/64/util.S"

const register_init, align=4
    .quad 0x21f86d66c8ca00ce
    .quad 0x75b6ba21077c48ad
    .quad 0xed56bb2dcb3c7736
    .quad 0x8bda43d3fd1a7e06
    .quad 0xb64a9c9e5d318408
    .quad 0xdf9a54b303f1d3a3
    .quad 0x4a75479abd64e097
    .quad 0x249214109d5d1c88
    .quad 0x1a1b2550a612b48c
    .quad 0x79445c159ce79064
    .quad 0x2eed899d5a28ddcd
    .quad 0x86b2536fcd8cf636
    .quad 0xb0856806085e7943
    .quad 0x3f2bf84fc0fcca4e
    .quad 0xacbd382dcf5b8de2
    .quad 0xd229e1f5b281303f
    .quad 0x71aeaff20b095fd9
    .quad 0xab63e2e11fa38ed9
endconst


const error_message
    .asciz "failed to preserve register"
endconst


// max number of args used by any asm function.
#define MAX_ARGS 15

#define CLOBBER_STACK ((8*MAX_ARGS + 15) & ~15)

function stack_clobber, export=1
    mov         x3,  sp
    mov         x2,  #CLOBBER_STACK
1:
    stp         x0,  x1,  [sp, #-16]!
    subs        x2,  x2,  #16
    b.gt        1b
    mov         sp,  x3
    ret
endfunc

#define ARG_STACK ((8*(MAX_ARGS - 8) + 15) & ~15)

function checked_call, export=1
    stp         x29, x30, [sp, #-16]!
    mov         x29, sp
    stp         x19, x20, [sp, #-16]!
    stp         x21, x22, [sp, #-16]!
    stp         x23, x24, [sp, #-16]!
    stp         x25, x26, [sp, #-16]!
    stp         x27, x28, [sp, #-16]!
    stp         d8,  d9,  [sp, #-16]!
    stp         d10, d11, [sp, #-16]!
    stp         d12, d13, [sp, #-16]!
    stp         d14, d15, [sp, #-16]!

    movrel      x9, register_init
    ldp         d8,  d9,  [x9], #16
    ldp         d10, d11, [x9], #16
    ldp         d12, d13, [x9], #16
    ldp         d14, d15, [x9], #16
    ldp         x19, x20, [x9], #16
    ldp         x21, x22, [x9], #16
    ldp         x23, x24, [x9], #16
    ldp         x25, x26, [x9], #16
    ldp         x27, x28, [x9], #16

    sub         sp,  sp,  #ARG_STACK
.equ pos, 0
.rept MAX_ARGS-8
    // Skip the first 8 args, that are loaded into registers
    ldr         x9, [x29, #16 + 8*8 + pos]
    str         x9, [sp, #pos]
.equ pos, pos + 8
.endr

    mov         x12, x0
    ldp         x0,  x1,  [x29, #16]
    ldp         x2,  x3,  [x29, #32]
    ldp         x4,  x5,  [x29, #48]
    ldp         x6,  x7,  [x29, #64]
    blr         x12
    add         sp,  sp,  #ARG_STACK
    stp         x0,  x1,  [sp, #-16]!
    movrel      x9, register_init
    movi        v3.8h,  #0

.macro check_reg_neon reg1, reg2
    ldr         q0,  [x9], #16
    uzp1        v1.2d,  v\reg1\().2d, v\reg2\().2d
    eor         v0.16b, v0.16b, v1.16b
    orr         v3.16b, v3.16b, v0.16b
.endm
    check_reg_neon  8,  9
    check_reg_neon  10, 11
    check_reg_neon  12, 13
    check_reg_neon  14, 15
    uqxtn       v3.8b,  v3.8h
    umov        x3,  v3.d[0]

.macro check_reg reg1, reg2
    ldp         x0,  x1,  [x9], #16
    eor         x0,  x0,  \reg1
    eor         x1,  x1,  \reg2
    orr         x3,  x3,  x0
    orr         x3,  x3,  x1
.endm
    check_reg   x19, x20
    check_reg   x21, x22
    check_reg   x23, x24
    check_reg   x25, x26
    check_reg   x27, x28

    cbz         x3,  0f

    movrel      x0, error_message
#ifdef PREFIX
    bl          _checkasm_fail_func
#else
    bl          checkasm_fail_func
#endif
0:
    ldp         x0,  x1,  [sp], #16
    ldp         d14, d15, [sp], #16
    ldp         d12, d13, [sp], #16
    ldp         d10, d11, [sp], #16
    ldp         d8,  d9,  [sp], #16
    ldp         x27, x28, [sp], #16
    ldp         x25, x26, [sp], #16
    ldp         x23, x24, [sp], #16
    ldp         x21, x22, [sp], #16
    ldp         x19, x20, [sp], #16
    ldp         x29, x30, [sp], #16
    ret
endfunc