1 /* 2 * MIPS DSPr2 optimizations for libjpeg-turbo 3 * 4 * Copyright (C) 2013, MIPS Technologies, Inc., California. 5 * Copyright (C) 2018, Matthieu Darbois. 6 * All Rights Reserved. 7 * Authors: Teodora Novkovic (teodora.novkovic@imgtec.com) 8 * Darko Laus (darko.laus@imgtec.com) 9 * This software is provided 'as-is', without any express or implied 10 * warranty. In no event will the authors be held liable for any damages 11 * arising from the use of this software. 12 * 13 * Permission is granted to anyone to use this software for any purpose, 14 * including commercial applications, and to alter it and redistribute it 15 * freely, subject to the following restrictions: 16 * 17 * 1. The origin of this software must not be misrepresented; you must not 18 * claim that you wrote the original software. If you use this software 19 * in a product, an acknowledgment in the product documentation would be 20 * appreciated but is not required. 21 * 2. Altered source versions must be plainly marked as such, and must not be 22 * misrepresented as being the original software. 23 * 3. This notice may not be removed or altered from any source distribution. 24 */ 25 26 #define zero $0 27 #define AT $1 28 #define v0 $2 29 #define v1 $3 30 #define a0 $4 31 #define a1 $5 32 #define a2 $6 33 #define a3 $7 34 #define t0 $8 35 #define t1 $9 36 #define t2 $10 37 #define t3 $11 38 #define t4 $12 39 #define t5 $13 40 #define t6 $14 41 #define t7 $15 42 #define s0 $16 43 #define s1 $17 44 #define s2 $18 45 #define s3 $19 46 #define s4 $20 47 #define s5 $21 48 #define s6 $22 49 #define s7 $23 50 #define t8 $24 51 #define t9 $25 52 #define k0 $26 53 #define k1 $27 54 #define gp $28 55 #define sp $29 56 #define fp $30 57 #define s8 $30 58 #define ra $31 59 60 #define f0 $f0 61 #define f1 $f1 62 #define f2 $f2 63 #define f3 $f3 64 #define f4 $f4 65 #define f5 $f5 66 #define f6 $f6 67 #define f7 $f7 68 #define f8 $f8 69 #define f9 $f9 70 #define f10 $f10 71 #define f11 $f11 72 #define f12 $f12 73 #define f13 $f13 74 #define f14 $f14 75 #define f15 $f15 76 #define f16 $f16 77 #define f17 $f17 78 #define f18 $f18 79 #define f19 $f19 80 #define f20 $f20 81 #define f21 $f21 82 #define f22 $f22 83 #define f23 $f23 84 #define f24 $f24 85 #define f25 $f25 86 #define f26 $f26 87 #define f27 $f27 88 #define f28 $f28 89 #define f29 $f29 90 #define f30 $f30 91 #define f31 $f31 92 93 #ifdef __ELF__ 94 #define HIDDEN_SYMBOL(symbol) .hidden symbol; 95 #else 96 #define HIDDEN_SYMBOL(symbol) 97 #endif 98 99 /* 100 * LEAF_MIPS32R2 - declare leaf routine for MIPS32r2 101 */ 102 #define LEAF_MIPS32R2(symbol) \ 103 .globl symbol; \ 104 HIDDEN_SYMBOL(symbol) \ 105 .align 2; \ 106 .type symbol, @function; \ 107 .ent symbol, 0; \ 108 symbol: \ 109 .frame sp, 0, ra; \ 110 .set push; \ 111 .set arch = mips32r2; \ 112 .set noreorder; \ 113 .set noat; 114 115 /* 116 * LEAF_DSPR2 - declare leaf routine for MIPS DSPr2 117 */ 118 #define LEAF_DSPR2(symbol) \ 119 LEAF_MIPS32R2(symbol) \ 120 .set dspr2; 121 122 /* 123 * END - mark end of function 124 */ 125 #define END(function) \ 126 .set pop; \ 127 .end function; \ 128 .size function, .-function 129 130 /* 131 * Checks if stack offset is big enough for storing/restoring regs_num 132 * number of register to/from stack. Stack offset must be greater than 133 * or equal to the number of bytes needed for storing registers (regs_num*4). 134 * Since MIPS ABI allows usage of first 16 bytes of stack frame (this is 135 * preserved for input arguments of the functions, already stored in a0-a3), 136 * stack size can be further optimized by utilizing this space. 137 */ 138 .macro CHECK_STACK_OFFSET regs_num, stack_offset 139 .if \stack_offset < \regs_num * 4 - 16 140 .error "Stack offset too small." 141 .endif 142 .endm 143 144 /* 145 * Saves set of registers on stack. Maximum number of registers that 146 * can be saved on stack is limitted to 14 (a0-a3, v0-v1 and s0-s7). 147 * Stack offset is number of bytes that are added to stack pointer (sp) 148 * before registers are pushed in order to provide enough space on stack 149 * (offset must be multiple of 4, and must be big enough, as described by 150 * CHECK_STACK_OFFSET macro). This macro is intended to be used in 151 * combination with RESTORE_REGS_FROM_STACK macro. Example: 152 * SAVE_REGS_ON_STACK 4, v0, v1, s0, s1 153 * RESTORE_REGS_FROM_STACK 4, v0, v1, s0, s1 154 */ 155 .macro SAVE_REGS_ON_STACK stack_offset = 0, r1, \ 156 r2 = 0, r3 = 0, r4 = 0, \ 157 r5 = 0, r6 = 0, r7 = 0, \ 158 r8 = 0, r9 = 0, r10 = 0, \ 159 r11 = 0, r12 = 0, r13 = 0, \ 160 r14 = 0 161 .if (\stack_offset < 0) || (\stack_offset - (\stack_offset / 4) * 4) 162 .error "Stack offset must be pozitive and multiple of 4." 163 .endif 164 .if \stack_offset != 0 165 addiu sp, sp, -\stack_offset 166 .endif 167 sw \r1, 0(sp) 168 .if \r2 != 0 169 sw \r2, 4(sp) 170 .endif 171 .if \r3 != 0 172 sw \r3, 8(sp) 173 .endif 174 .if \r4 != 0 175 sw \r4, 12(sp) 176 .endif 177 .if \r5 != 0 178 CHECK_STACK_OFFSET 5, \stack_offset 179 sw \r5, 16(sp) 180 .endif 181 .if \r6 != 0 182 CHECK_STACK_OFFSET 6, \stack_offset 183 sw \r6, 20(sp) 184 .endif 185 .if \r7 != 0 186 CHECK_STACK_OFFSET 7, \stack_offset 187 sw \r7, 24(sp) 188 .endif 189 .if \r8 != 0 190 CHECK_STACK_OFFSET 8, \stack_offset 191 sw \r8, 28(sp) 192 .endif 193 .if \r9 != 0 194 CHECK_STACK_OFFSET 9, \stack_offset 195 sw \r9, 32(sp) 196 .endif 197 .if \r10 != 0 198 CHECK_STACK_OFFSET 10, \stack_offset 199 sw \r10, 36(sp) 200 .endif 201 .if \r11 != 0 202 CHECK_STACK_OFFSET 11, \stack_offset 203 sw \r11, 40(sp) 204 .endif 205 .if \r12 != 0 206 CHECK_STACK_OFFSET 12, \stack_offset 207 sw \r12, 44(sp) 208 .endif 209 .if \r13 != 0 210 CHECK_STACK_OFFSET 13, \stack_offset 211 sw \r13, 48(sp) 212 .endif 213 .if \r14 != 0 214 CHECK_STACK_OFFSET 14, \stack_offset 215 sw \r14, 52(sp) 216 .endif 217 .endm 218 219 /* 220 * Restores set of registers from stack. Maximum number of registers that 221 * can be restored from stack is limitted to 14 (a0-a3, v0-v1 and s0-s7). 222 * Stack offset is number of bytes that are added to stack pointer (sp) 223 * after registers are restored (offset must be multiple of 4, and must 224 * be big enough, as described by CHECK_STACK_OFFSET macro). This macro is 225 * intended to be used in combination with RESTORE_REGS_FROM_STACK macro. 226 * Example: 227 * SAVE_REGS_ON_STACK 4, v0, v1, s0, s1 228 * RESTORE_REGS_FROM_STACK 4, v0, v1, s0, s1 229 */ 230 .macro RESTORE_REGS_FROM_STACK stack_offset = 0, r1, \ 231 r2 = 0, r3 = 0, r4 = 0, \ 232 r5 = 0, r6 = 0, r7 = 0, \ 233 r8 = 0, r9 = 0, r10 = 0, \ 234 r11 = 0, r12 = 0, r13 = 0, \ 235 r14 = 0 236 .if (\stack_offset < 0) || (\stack_offset - (\stack_offset / 4) * 4) 237 .error "Stack offset must be pozitive and multiple of 4." 238 .endif 239 lw \r1, 0(sp) 240 .if \r2 != 0 241 lw \r2, 4(sp) 242 .endif 243 .if \r3 != 0 244 lw \r3, 8(sp) 245 .endif 246 .if \r4 != 0 247 lw \r4, 12(sp) 248 .endif 249 .if \r5 != 0 250 CHECK_STACK_OFFSET 5, \stack_offset 251 lw \r5, 16(sp) 252 .endif 253 .if \r6 != 0 254 CHECK_STACK_OFFSET 6, \stack_offset 255 lw \r6, 20(sp) 256 .endif 257 .if \r7 != 0 258 CHECK_STACK_OFFSET 7, \stack_offset 259 lw \r7, 24(sp) 260 .endif 261 .if \r8 != 0 262 CHECK_STACK_OFFSET 8, \stack_offset 263 lw \r8, 28(sp) 264 .endif 265 .if \r9 != 0 266 CHECK_STACK_OFFSET 9, \stack_offset 267 lw \r9, 32(sp) 268 .endif 269 .if \r10 != 0 270 CHECK_STACK_OFFSET 10, \stack_offset 271 lw \r10, 36(sp) 272 .endif 273 .if \r11 != 0 274 CHECK_STACK_OFFSET 11, \stack_offset 275 lw \r11, 40(sp) 276 .endif 277 .if \r12 != 0 278 CHECK_STACK_OFFSET 12, \stack_offset 279 lw \r12, 44(sp) 280 .endif 281 .if \r13 != 0 282 CHECK_STACK_OFFSET 13, \stack_offset 283 lw \r13, 48(sp) 284 .endif 285 .if \r14 != 0 286 CHECK_STACK_OFFSET 14, \stack_offset 287 lw \r14, 52(sp) 288 .endif 289 .if \stack_offset != 0 290 addiu sp, sp, \stack_offset 291 .endif 292 .endm 293