OLD | NEW |
(Empty) | |
| 1 @// -*- Mode: asm; -*- |
| 2 @// |
| 3 @// Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. |
| 4 @// |
| 5 @// Use of this source code is governed by a BSD-style license |
| 6 @// that can be found in the LICENSE file in the root of the source |
| 7 @// tree. An additional intellectual property rights grant can be found |
| 8 @// in the file PATENTS. All contributing project authors may |
| 9 @// be found in the AUTHORS file in the root of the source tree. |
| 10 @// |
| 11 @// This file was originally licensed as follows. It has been |
| 12 @// relicensed with permission from the copyright holders. |
| 13 @// |
| 14 |
| 15 @// |
| 16 @// File Name: armCOMM_s.h |
| 17 @// OpenMAX DL: v1.0.2 |
| 18 @// Last Modified Revision: 13871 |
| 19 @// Last Modified Date: Fri, 09 May 2008 |
| 20 @// |
| 21 @// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. |
| 22 @// |
| 23 @// |
| 24 @// |
| 25 @// ARM optimized OpenMAX common header file |
| 26 @// |
| 27 |
| 28 .set _RBytes, 0 @ Number of register bytes on stack |
| 29 .set _SBytes, 0 @ Number of scratch bytes on stack |
| 30 .set _Workspace, 0 @ Stack offset of scratch workspace |
| 31 |
| 32 .set _RRegList, 0 @ R saved register list (last register number) |
| 33 .set _DRegList, 0 @ D saved register list (last register number) |
| 34 |
| 35 @// Work out a list of R saved registers, and how much stack space is ne
eded. |
| 36 @// gas doesn't support setting a variable to a string, so we set _RRegL
ist to |
| 37 @// the register number. |
| 38 .macro _M_GETRREGLIST rreg |
| 39 .ifeqs "\rreg", "" |
| 40 @ Nothing needs to be saved |
| 41 .exitm |
| 42 .endif |
| 43 @ If rreg is lr or r4, save lr and r4 |
| 44 .ifeqs "\rreg", "lr" |
| 45 .set _RRegList, 4 |
| 46 .set _RBytes, _RBytes + 8 |
| 47 .exitm |
| 48 .endif |
| 49 |
| 50 .ifeqs "\rreg", "r4" |
| 51 .set _RRegList, 4 |
| 52 .set _RBytes, _RBytes + 8 |
| 53 .exitm |
| 54 .endif |
| 55 |
| 56 @ If rreg = r5 or r6, save up to register r6 |
| 57 .ifeqs "\rreg", "r5" |
| 58 .set _RRegList, 6 |
| 59 .set _RBytes, _RBytes + 16 |
| 60 .exitm |
| 61 .endif |
| 62 .ifeqs "\rreg", "r6" |
| 63 .set _RRegList, 6 |
| 64 .set _RBytes, _RBytes + 16 |
| 65 .exitm |
| 66 .endif |
| 67 |
| 68 @ If rreg = r7 or r8, save up to register r8 |
| 69 .ifeqs "\rreg", "r7" |
| 70 .set _RRegList, 8 |
| 71 .set _RBytes, _RBytes + 24 |
| 72 .exitm |
| 73 .endif |
| 74 .ifeqs "\rreg", "r8" |
| 75 .set _RRegList, 8 |
| 76 .set _RBytes, _RBytes + 24 |
| 77 .exitm |
| 78 .endif |
| 79 |
| 80 @ If rreg = r9 or r10, save up to register r10 |
| 81 .ifeqs "\rreg", "r9" |
| 82 .set _RRegList, 10 |
| 83 .set _RBytes, _RBytes + 32 |
| 84 .exitm |
| 85 .endif |
| 86 .ifeqs "\rreg", "r10" |
| 87 .set _RRegList, 10 |
| 88 .set _RBytes, _RBytes + 32 |
| 89 .exitm |
| 90 .endif |
| 91 |
| 92 @ If rreg = r11 or r12, save up to register r12 |
| 93 .ifeqs "\rreg", "r11" |
| 94 .set _RRegList, 12 |
| 95 .set _RBytes, _RBytes + 40 |
| 96 .exitm |
| 97 .endif |
| 98 .ifeqs "\rreg", "r12" |
| 99 .set _RRegList, 12 |
| 100 .set _RBytes, _RBytes + 40 |
| 101 .exitm |
| 102 .endif |
| 103 |
| 104 .warning "Unrecognized saved r register limit: \rreg" |
| 105 .endm |
| 106 |
| 107 @ Work out list of D saved registers, like for R registers. |
| 108 .macro _M_GETDREGLIST dreg |
| 109 .ifeqs "\dreg", "" |
| 110 .set _DRegList, 0 |
| 111 .exitm |
| 112 .endif |
| 113 |
| 114 .ifeqs "\dreg", "d8" |
| 115 .set _DRegList, 8 |
| 116 .set _RBytes, _RBytes + 8 |
| 117 .exitm |
| 118 .endif |
| 119 |
| 120 .ifeqs "\dreg", "d9" |
| 121 .set _DRegList, 9 |
| 122 .set _RBytes, _RBytes + 16 |
| 123 .exitm |
| 124 .endif |
| 125 |
| 126 .ifeqs "\dreg", "d10" |
| 127 .set _DRegList, 10 |
| 128 .set _RBytes, _RBytes + 24 |
| 129 .exitm |
| 130 .endif |
| 131 |
| 132 .ifeqs "\dreg", "d11" |
| 133 .set _DRegList, 11 |
| 134 .set _RBytes, _RBytes + 32 |
| 135 .exitm |
| 136 .endif |
| 137 |
| 138 .ifeqs "\dreg", "d12" |
| 139 .set _DRegList, 12 |
| 140 .set _RBytes, _RBytes + 40 |
| 141 .exitm |
| 142 .endif |
| 143 |
| 144 .ifeqs "\dreg", "d13" |
| 145 .set _DRegList, 13 |
| 146 .set _RBytes, _RBytes + 48 |
| 147 .exitm |
| 148 .endif |
| 149 |
| 150 .ifeqs "\dreg", "d14" |
| 151 .set _DRegList, 14 |
| 152 .set _RBytes, _RBytes + 56 |
| 153 .exitm |
| 154 .endif |
| 155 |
| 156 .ifeqs "\dreg", "d15" |
| 157 .set _DRegList, 15 |
| 158 .set _RBytes, _RBytes + 64 |
| 159 .exitm |
| 160 .endif |
| 161 |
| 162 .warning "Unrecognized saved d register limit: \rreg" |
| 163 .endm |
| 164 |
| 165 @////////////////////////////////////////////////////////// |
| 166 @// Function header and footer macros |
| 167 @////////////////////////////////////////////////////////// |
| 168 |
| 169 @ Function Header Macro |
| 170 @ Generates the function prologue |
| 171 @ Note that functions should all be "stack-moves-once" |
| 172 @ The FNSTART and FNEND macros should be the only places |
| 173 @ where the stack moves. |
| 174 @ |
| 175 @ name = function name |
| 176 @ rreg = "" don't stack any registers |
| 177 @ "lr" stack "lr" only |
| 178 @ "rN" stack registers "r4-rN,lr" |
| 179 @ dreg = "" don't stack any D registers |
| 180 @ "dN" stack registers "d8-dN" |
| 181 @ |
| 182 @ Note: ARM Archicture procedure call standard AAPCS |
| 183 @ states that r4-r11, sp, d8-d15 must be preserved by |
| 184 @ a compliant function. |
| 185 .macro M_START name, rreg, dreg |
| 186 .set _RBytes, 0 |
| 187 .set _Workspace, 0 |
| 188 |
| 189 @ Define the function and make it external. |
| 190 .global \name |
| 191 .func \name |
| 192 .section .text.\name,"ax",%progbits |
| 193 .align 2 |
| 194 \name : |
| 195 .fnstart |
| 196 @ Save specified R registers |
| 197 _M_GETRREGLIST \rreg |
| 198 _M_PUSH_RREG |
| 199 |
| 200 @ Save specified D registers |
| 201 _M_GETDREGLIST \dreg |
| 202 _M_PUSH_DREG |
| 203 |
| 204 @ Ensure size claimed on stack is 8-byte aligned |
| 205 .if (_SBytes & 7) != 0 |
| 206 .set _SBytes, _SBytes + (8 - (_SBytes & 7)) |
| 207 .endif |
| 208 .if _SBytes != 0 |
| 209 sub sp, sp, #_SBytes |
| 210 .endif |
| 211 .endm |
| 212 |
| 213 @ Function Footer Macro |
| 214 @ Generates the function epilogue |
| 215 .macro M_END |
| 216 @ Restore the stack pointer to its original value on function entry |
| 217 .if _SBytes != 0 |
| 218 add sp, sp, #_SBytes |
| 219 .endif |
| 220 @ Restore any saved R or D registers. |
| 221 _M_RET |
| 222 .fnend |
| 223 .endfunc |
| 224 @ Reset the global stack tracking variables back to their |
| 225 @ initial values. |
| 226 .set _SBytes, 0 |
| 227 .endm |
| 228 |
| 229 @// Based on the value of _DRegList, push the specified set of registers
|
| 230 @// to the stack. Is there a better way? |
| 231 .macro _M_PUSH_DREG |
| 232 .if _DRegList == 8 |
| 233 vpush {d8} |
| 234 .exitm |
| 235 .endif |
| 236 |
| 237 .if _DRegList == 9 |
| 238 vpush {d8-d9} |
| 239 .exitm |
| 240 .endif |
| 241 |
| 242 .if _DRegList == 10 |
| 243 vpush {d8-d10} |
| 244 .exitm |
| 245 .endif |
| 246 |
| 247 .if _DRegList == 11 |
| 248 vpush {d8-d11} |
| 249 .exitm |
| 250 .endif |
| 251 |
| 252 .if _DRegList == 12 |
| 253 vpush {d8-d12} |
| 254 .exitm |
| 255 .endif |
| 256 |
| 257 .if _DRegList == 13 |
| 258 vpush {d8-d13} |
| 259 .exitm |
| 260 .endif |
| 261 |
| 262 .if _DRegList == 14 |
| 263 vpush {d8-d14} |
| 264 .exitm |
| 265 .endif |
| 266 |
| 267 .if _DRegList == 15 |
| 268 vpush {d8-d15} |
| 269 .exitm |
| 270 .endif |
| 271 .endm |
| 272 |
| 273 @// Based on the value of _RRegList, push the specified set of registers
|
| 274 @// to the stack. Is there a better way? |
| 275 .macro _M_PUSH_RREG |
| 276 .if _RRegList == 4 |
| 277 stmfd sp!, {r4, lr} |
| 278 .exitm |
| 279 .endif |
| 280 |
| 281 .if _RRegList == 6 |
| 282 stmfd sp!, {r4-r6, lr} |
| 283 .exitm |
| 284 .endif |
| 285 |
| 286 .if _RRegList == 8 |
| 287 stmfd sp!, {r4-r8, lr} |
| 288 .exitm |
| 289 .endif |
| 290 |
| 291 .if _RRegList == 10 |
| 292 stmfd sp!, {r4-r10, lr} |
| 293 .exitm |
| 294 .endif |
| 295 |
| 296 .if _RRegList == 12 |
| 297 stmfd sp!, {r4-r12, lr} |
| 298 .exitm |
| 299 .endif |
| 300 .endm |
| 301 |
| 302 @// The opposite of _M_PUSH_DREG |
| 303 .macro _M_POP_DREG |
| 304 .if _DRegList == 8 |
| 305 vpop {d8} |
| 306 .exitm |
| 307 .endif |
| 308 |
| 309 .if _DRegList == 9 |
| 310 vpop {d8-d9} |
| 311 .exitm |
| 312 .endif |
| 313 |
| 314 .if _DRegList == 10 |
| 315 vpop {d8-d10} |
| 316 .exitm |
| 317 .endif |
| 318 |
| 319 .if _DRegList == 11 |
| 320 vpop {d8-d11} |
| 321 .exitm |
| 322 .endif |
| 323 |
| 324 .if _DRegList == 12 |
| 325 vpop {d8-d12} |
| 326 .exitm |
| 327 .endif |
| 328 |
| 329 .if _DRegList == 13 |
| 330 vpop {d8-d13} |
| 331 .exitm |
| 332 .endif |
| 333 |
| 334 .if _DRegList == 14 |
| 335 vpop {d8-d14} |
| 336 .exitm |
| 337 .endif |
| 338 |
| 339 .if _DRegList == 15 |
| 340 vpop {d8-d15} |
| 341 .exitm |
| 342 .endif |
| 343 .endm |
| 344 |
| 345 @// The opposite of _M_PUSH_RREG |
| 346 .macro _M_POP_RREG cc |
| 347 .if _RRegList == 0 |
| 348 bx\cc lr |
| 349 .exitm |
| 350 .endif |
| 351 .if _RRegList == 4 |
| 352 ldm\cc\()fd sp!, {r4, pc} |
| 353 .exitm |
| 354 .endif |
| 355 |
| 356 .if _RRegList == 6 |
| 357 ldm\cc\()fd sp!, {r4-r6, pc} |
| 358 .exitm |
| 359 .endif |
| 360 |
| 361 .if _RRegList == 8 |
| 362 ldm\cc\()fd sp!, {r4-r8, pc} |
| 363 .exitm |
| 364 .endif |
| 365 |
| 366 .if _RRegList == 10 |
| 367 ldm\cc\()fd sp!, {r4-r10, pc} |
| 368 .exitm |
| 369 .endif |
| 370 |
| 371 .if _RRegList == 12 |
| 372 ldm\cc\()fd sp!, {r4-r12, pc} |
| 373 .exitm |
| 374 .endif |
| 375 .endm |
| 376 |
| 377 @ Produce function return instructions |
| 378 .macro _M_RET cc |
| 379 _M_POP_DREG \cc |
| 380 _M_POP_RREG \cc |
| 381 .endm |
| 382 |
| 383 @// Allocate 4-byte aligned area of name |
| 384 @// |name| and size |size| bytes. |
| 385 .macro M_ALLOC4 name, size |
| 386 .if (_SBytes & 3) != 0 |
| 387 .set _SBytes, _SBytes + (4 - (_SBytes & 3)) |
| 388 .endif |
| 389 .set \name\()_F, _SBytes |
| 390 .set _SBytes, _SBytes + \size |
| 391 |
| 392 .endm |
| 393 |
| 394 @ Load word from stack |
| 395 .macro M_LDR r, a0, a1, a2, a3 |
| 396 _M_DATA "ldr", 4, \r, \a0, \a1, \a2, \a3 |
| 397 .endm |
| 398 |
| 399 @ Store word to stack |
| 400 .macro M_STR r, a0, a1, a2, a3 |
| 401 _M_DATA "str", 4, \r, \a0, \a1, \a2, \a3 |
| 402 .endm |
| 403 |
| 404 @ Macro to perform a data access operation |
| 405 @ Such as LDR or STR |
| 406 @ The addressing mode is modified such that |
| 407 @ 1. If no address is given then the name is taken |
| 408 @ as a stack offset |
| 409 @ 2. If the addressing mode is not available for the |
| 410 @ state being assembled for (eg Thumb) then a suitable |
| 411 @ addressing mode is substituted. |
| 412 @ |
| 413 @ On Entry: |
| 414 @ $i = Instruction to perform (eg "LDRB") |
| 415 @ $a = Required byte alignment |
| 416 @ $r = Register(s) to transfer (eg "r1") |
| 417 @ $a0,$a1,$a2. Addressing mode and condition. One of: |
| 418 @ label {,cc} |
| 419 @ [base] {,,,cc} |
| 420 @ [base, offset]{!} {,,cc} |
| 421 @ [base, offset, shift]{!} {,cc} |
| 422 @ [base], offset {,,cc} |
| 423 @ [base], offset, shift {,cc} |
| 424 @ |
| 425 @ WARNING: Most of the above are not supported, except the first case. |
| 426 .macro _M_DATA i, a, r, a0, a1, a2, a3 |
| 427 .set _Offset, _Workspace + \a0\()_F |
| 428 \i\a1 \r, [sp, #_Offset] |
| 429 .endm |
OLD | NEW |