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