1/****************************************************************************** 2 * Copyright © 2018, VideoLAN and dav1d authors 3 * Copyright © 2024, Loongson Technology Corporation Limited 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright notice, this 10 * list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 *****************************************************************************/ 27 28#define PRIVATE_PREFIX checkasm_ 29 30#include "src/loongarch/loongson_asm.S" 31 32const register_init, align=4 33.quad 0x21f86d66c8ca00ce 34.quad 0x75b6ba21077c48ad 35.quad 0xed56bb2dcb3c7736 36.quad 0x8bda43d3fd1a7e06 37.quad 0xb64a9c9e5d318408 38.quad 0xdf9a54b303f1d3a3 39.quad 0x4a75479abd64e097 40.quad 0x249214109d5d1c88 41.quad 0x1a1b2550a612b48c 42.quad 0x79445c159ce79064 43.quad 0x2eed899d5a28ddcd 44.quad 0x86b2536fcd8cf636 45.quad 0xb0856806085e7943 46.quad 0x3f2bf84fc0fcca4e 47.quad 0xacbd382dcf5b8de2 48.quad 0xd229e1f5b281303f 49.quad 0x71aeaff20b095fd9 50.quad 0xab63e2e11fa38ed9 51endconst 52 53const error_message 54.asciz "failed to preserve register" 55endconst 56 57// max number of args used by any asm function. 58#define MAX_ARGS 15 59 60#define CLOBBER_STACK ((8*MAX_ARGS + 15) & ~15) 61 62// Fill dirty data at stack space 63function stack_clobber 64 move t0, sp 65 addi.d t1, zero, CLOBBER_STACK 661: 67 st.d a0, sp, 0x00 68 st.d a1, sp, -0x08 69 addi.d sp, sp, -0x10 70 addi.d t1, t1, -0x10 71 blt zero, t1, 1b 72 move sp, t0 73endfunc 74 75#define ARG_STACK ((8*(MAX_ARGS - 8) + 15) & ~15) 76 77function checked_call 78 // Saved s0 - s8, fs0 - fs7 79 move t4, sp 80 addi.d sp, sp, -136 81 st.d s0, sp, 0 82 st.d s1, sp, 8 83 st.d s2, sp, 16 84 st.d s3, sp, 24 85 st.d s4, sp, 32 86 st.d s5, sp, 40 87 st.d s6, sp, 48 88 st.d s7, sp, 56 89 st.d s8, sp, 64 90 fst.d fs0, sp, 72 91 fst.d fs1, sp, 80 92 fst.d fs2, sp, 88 93 fst.d fs3, sp, 96 94 fst.d fs4, sp, 104 95 fst.d fs5, sp, 112 96 fst.d fs6, sp, 120 97 fst.d fs7, sp, 128 98 99 la.local t1, register_init 100 ld.d s0, t1, 0 101 ld.d s1, t1, 8 102 ld.d s2, t1, 16 103 ld.d s3, t1, 24 104 ld.d s4, t1, 32 105 ld.d s5, t1, 40 106 ld.d s6, t1, 48 107 ld.d s7, t1, 56 108 ld.d s8, t1, 64 109 fld.d fs0, t1, 72 110 fld.d fs1, t1, 80 111 fld.d fs2, t1, 88 112 fld.d fs3, t1, 96 113 fld.d fs4, t1, 104 114 fld.d fs5, t1, 112 115 fld.d fs6, t1, 120 116 fld.d fs7, t1, 128 117 118 addi.d sp, sp, -16 119 st.d a1, sp, 0 // ok 120 st.d ra, sp, 8 // Ret address 121 122 addi.d sp, sp, -ARG_STACK 123 124 addi.d t0, zero, 8*8 125 xor t1, t1, t1 126.rept MAX_ARGS - 8 127 // Skip the first 8 args, that are loaded into registers 128 ldx.d t2, t4, t0 129 stx.d t2, sp, t1 130 addi.d t0, t0, 8 131 addi.d t1, t1, 8 132.endr 133 move t3, a0 // Func 134 ld.d a0, t4, 0 135 ld.d a1, t4, 8 136 ld.d a2, t4, 16 137 ld.d a3, t4, 24 138 ld.d a4, t4, 32 139 ld.d a5, t4, 40 140 ld.d a6, t4, 48 141 ld.d a7, t4, 56 142 143 jirl ra, t3, 0 144 145 addi.d sp, sp, ARG_STACK 146 ld.d t2, sp, 0 // ok 147 ld.d ra, sp, 8 // Ret address 148 addi.d sp, sp, 16 149 150 la.local t1, register_init 151 xor t3, t3, t3 152 153.macro check_reg_gr reg1 154 ld.d t0, t1, 0 155 xor t0, $s\reg1, t0 156 or t3, t3, t0 157 addi.d t1, t1, 8 158.endm 159 check_reg_gr 0 160 check_reg_gr 1 161 check_reg_gr 2 162 check_reg_gr 3 163 check_reg_gr 4 164 check_reg_gr 5 165 check_reg_gr 6 166 check_reg_gr 7 167 check_reg_gr 8 168 169.macro check_reg_fr reg1 170 ld.d t0, t1, 0 171 movfr2gr.d t4, $fs\reg1 172 xor t0, t0, t4 173 or t3, t3, t0 174 addi.d t1, t1, 8 175.endm 176 check_reg_fr 0 177 check_reg_fr 1 178 check_reg_fr 2 179 check_reg_fr 3 180 check_reg_fr 4 181 check_reg_fr 5 182 check_reg_fr 6 183 check_reg_fr 7 184 185 beqz t3, 0f 186 187 st.d zero, t2, 0x00 // Set OK to 0 188 la.local a0, error_message 189 addi.d sp, sp, -8 190 st.d ra, sp, 0 191 bl puts 192 ld.d ra, sp, 0 193 addi.d sp, sp, 8 1940: 195 ld.d s0, sp, 0 196 ld.d s1, sp, 8 197 ld.d s2, sp, 16 198 ld.d s3, sp, 24 199 ld.d s4, sp, 32 200 ld.d s5, sp, 40 201 ld.d s6, sp, 48 202 ld.d s7, sp, 56 203 ld.d s8, sp, 64 204 fld.d fs0, sp, 72 205 fld.d fs1, sp, 80 206 fld.d fs2, sp, 88 207 fld.d fs3, sp, 96 208 fld.d fs4, sp, 104 209 fld.d fs5, sp, 112 210 fld.d fs6, sp, 120 211 fld.d fs7, sp, 128 212 addi.d sp, sp, 136 213endfunc 214