1 //===------------------------ UnwindRegistersSave.S -----------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "assembly.h" 10 11 .text 12 13 #if !defined(__USING_SJLJ_EXCEPTIONS__) 14 15 #if defined(__i386__) 16 17 # 18 # extern int unw_getcontext(unw_context_t* thread_state) 19 # 20 # On entry: 21 # + + 22 # +-----------------------+ 23 # + thread_state pointer + 24 # +-----------------------+ 25 # + return address + 26 # +-----------------------+ <-- SP 27 # + + 28 # 29 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) 30 push %eax 31 movl 8(%esp), %eax 32 movl %ebx, 4(%eax) 33 movl %ecx, 8(%eax) 34 movl %edx, 12(%eax) 35 movl %edi, 16(%eax) 36 movl %esi, 20(%eax) 37 movl %ebp, 24(%eax) 38 movl %esp, %edx 39 addl $8, %edx 40 movl %edx, 28(%eax) # store what sp was at call site as esp 41 # skip ss 42 # skip eflags 43 movl 4(%esp), %edx 44 movl %edx, 40(%eax) # store return address as eip 45 # skip cs 46 # skip ds 47 # skip es 48 # skip fs 49 # skip gs 50 movl (%esp), %edx 51 movl %edx, (%eax) # store original eax 52 popl %eax 53 xorl %eax, %eax # return UNW_ESUCCESS 54 ret 55 56 #elif defined(__x86_64__) 57 58 # 59 # extern int unw_getcontext(unw_context_t* thread_state) 60 # 61 # On entry: 62 # thread_state pointer is in rdi 63 # 64 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) 65 #if defined(_WIN64) 66 #define PTR %rcx 67 #define TMP %rdx 68 #else 69 #define PTR %rdi 70 #define TMP %rsi 71 #endif 72 73 movq %rax, (PTR) 74 movq %rbx, 8(PTR) 75 movq %rcx, 16(PTR) 76 movq %rdx, 24(PTR) 77 movq %rdi, 32(PTR) 78 movq %rsi, 40(PTR) 79 movq %rbp, 48(PTR) 80 movq %rsp, 56(PTR) 81 addq $8, 56(PTR) 82 movq %r8, 64(PTR) 83 movq %r9, 72(PTR) 84 movq %r10, 80(PTR) 85 movq %r11, 88(PTR) 86 movq %r12, 96(PTR) 87 movq %r13,104(PTR) 88 movq %r14,112(PTR) 89 movq %r15,120(PTR) 90 movq (%rsp),TMP 91 movq TMP,128(PTR) # store return address as rip 92 # skip rflags 93 # skip cs 94 # skip fs 95 # skip gs 96 97 #if defined(_WIN64) 98 movdqu %xmm0,176(PTR) 99 movdqu %xmm1,192(PTR) 100 movdqu %xmm2,208(PTR) 101 movdqu %xmm3,224(PTR) 102 movdqu %xmm4,240(PTR) 103 movdqu %xmm5,256(PTR) 104 movdqu %xmm6,272(PTR) 105 movdqu %xmm7,288(PTR) 106 movdqu %xmm8,304(PTR) 107 movdqu %xmm9,320(PTR) 108 movdqu %xmm10,336(PTR) 109 movdqu %xmm11,352(PTR) 110 movdqu %xmm12,368(PTR) 111 movdqu %xmm13,384(PTR) 112 movdqu %xmm14,400(PTR) 113 movdqu %xmm15,416(PTR) 114 #endif 115 xorl %eax, %eax # return UNW_ESUCCESS 116 ret 117 118 #elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 119 120 # 121 # extern int unw_getcontext(unw_context_t* thread_state) 122 # 123 # On entry: 124 # thread_state pointer is in a0 ($4) 125 # 126 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) 127 .set push 128 .set noat 129 .set noreorder 130 .set nomacro 131 sw $1, (4 * 1)($4) 132 sw $2, (4 * 2)($4) 133 sw $3, (4 * 3)($4) 134 sw $4, (4 * 4)($4) 135 sw $5, (4 * 5)($4) 136 sw $6, (4 * 6)($4) 137 sw $7, (4 * 7)($4) 138 sw $8, (4 * 8)($4) 139 sw $9, (4 * 9)($4) 140 sw $10, (4 * 10)($4) 141 sw $11, (4 * 11)($4) 142 sw $12, (4 * 12)($4) 143 sw $13, (4 * 13)($4) 144 sw $14, (4 * 14)($4) 145 sw $15, (4 * 15)($4) 146 sw $16, (4 * 16)($4) 147 sw $17, (4 * 17)($4) 148 sw $18, (4 * 18)($4) 149 sw $19, (4 * 19)($4) 150 sw $20, (4 * 20)($4) 151 sw $21, (4 * 21)($4) 152 sw $22, (4 * 22)($4) 153 sw $23, (4 * 23)($4) 154 sw $24, (4 * 24)($4) 155 sw $25, (4 * 25)($4) 156 sw $26, (4 * 26)($4) 157 sw $27, (4 * 27)($4) 158 sw $28, (4 * 28)($4) 159 sw $29, (4 * 29)($4) 160 sw $30, (4 * 30)($4) 161 sw $31, (4 * 31)($4) 162 # Store return address to pc 163 sw $31, (4 * 32)($4) 164 # hi and lo 165 mfhi $8 166 sw $8, (4 * 33)($4) 167 mflo $8 168 sw $8, (4 * 34)($4) 169 #ifdef __mips_hard_float 170 #if __mips_fpr != 64 171 sdc1 $f0, (4 * 36 + 8 * 0)($4) 172 sdc1 $f2, (4 * 36 + 8 * 2)($4) 173 sdc1 $f4, (4 * 36 + 8 * 4)($4) 174 sdc1 $f6, (4 * 36 + 8 * 6)($4) 175 sdc1 $f8, (4 * 36 + 8 * 8)($4) 176 sdc1 $f10, (4 * 36 + 8 * 10)($4) 177 sdc1 $f12, (4 * 36 + 8 * 12)($4) 178 sdc1 $f14, (4 * 36 + 8 * 14)($4) 179 sdc1 $f16, (4 * 36 + 8 * 16)($4) 180 sdc1 $f18, (4 * 36 + 8 * 18)($4) 181 sdc1 $f20, (4 * 36 + 8 * 20)($4) 182 sdc1 $f22, (4 * 36 + 8 * 22)($4) 183 sdc1 $f24, (4 * 36 + 8 * 24)($4) 184 sdc1 $f26, (4 * 36 + 8 * 26)($4) 185 sdc1 $f28, (4 * 36 + 8 * 28)($4) 186 sdc1 $f30, (4 * 36 + 8 * 30)($4) 187 #else 188 sdc1 $f0, (4 * 36 + 8 * 0)($4) 189 sdc1 $f1, (4 * 36 + 8 * 1)($4) 190 sdc1 $f2, (4 * 36 + 8 * 2)($4) 191 sdc1 $f3, (4 * 36 + 8 * 3)($4) 192 sdc1 $f4, (4 * 36 + 8 * 4)($4) 193 sdc1 $f5, (4 * 36 + 8 * 5)($4) 194 sdc1 $f6, (4 * 36 + 8 * 6)($4) 195 sdc1 $f7, (4 * 36 + 8 * 7)($4) 196 sdc1 $f8, (4 * 36 + 8 * 8)($4) 197 sdc1 $f9, (4 * 36 + 8 * 9)($4) 198 sdc1 $f10, (4 * 36 + 8 * 10)($4) 199 sdc1 $f11, (4 * 36 + 8 * 11)($4) 200 sdc1 $f12, (4 * 36 + 8 * 12)($4) 201 sdc1 $f13, (4 * 36 + 8 * 13)($4) 202 sdc1 $f14, (4 * 36 + 8 * 14)($4) 203 sdc1 $f15, (4 * 36 + 8 * 15)($4) 204 sdc1 $f16, (4 * 36 + 8 * 16)($4) 205 sdc1 $f17, (4 * 36 + 8 * 17)($4) 206 sdc1 $f18, (4 * 36 + 8 * 18)($4) 207 sdc1 $f19, (4 * 36 + 8 * 19)($4) 208 sdc1 $f20, (4 * 36 + 8 * 20)($4) 209 sdc1 $f21, (4 * 36 + 8 * 21)($4) 210 sdc1 $f22, (4 * 36 + 8 * 22)($4) 211 sdc1 $f23, (4 * 36 + 8 * 23)($4) 212 sdc1 $f24, (4 * 36 + 8 * 24)($4) 213 sdc1 $f25, (4 * 36 + 8 * 25)($4) 214 sdc1 $f26, (4 * 36 + 8 * 26)($4) 215 sdc1 $f27, (4 * 36 + 8 * 27)($4) 216 sdc1 $f28, (4 * 36 + 8 * 28)($4) 217 sdc1 $f29, (4 * 36 + 8 * 29)($4) 218 sdc1 $f30, (4 * 36 + 8 * 30)($4) 219 sdc1 $f31, (4 * 36 + 8 * 31)($4) 220 #endif 221 #endif 222 jr $31 223 # return UNW_ESUCCESS 224 or $2, $0, $0 225 .set pop 226 227 #elif defined(__mips64) 228 229 # 230 # extern int unw_getcontext(unw_context_t* thread_state) 231 # 232 # On entry: 233 # thread_state pointer is in a0 ($4) 234 # 235 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) 236 .set push 237 .set noat 238 .set noreorder 239 .set nomacro 240 sd $1, (8 * 1)($4) 241 sd $2, (8 * 2)($4) 242 sd $3, (8 * 3)($4) 243 sd $4, (8 * 4)($4) 244 sd $5, (8 * 5)($4) 245 sd $6, (8 * 6)($4) 246 sd $7, (8 * 7)($4) 247 sd $8, (8 * 8)($4) 248 sd $9, (8 * 9)($4) 249 sd $10, (8 * 10)($4) 250 sd $11, (8 * 11)($4) 251 sd $12, (8 * 12)($4) 252 sd $13, (8 * 13)($4) 253 sd $14, (8 * 14)($4) 254 sd $15, (8 * 15)($4) 255 sd $16, (8 * 16)($4) 256 sd $17, (8 * 17)($4) 257 sd $18, (8 * 18)($4) 258 sd $19, (8 * 19)($4) 259 sd $20, (8 * 20)($4) 260 sd $21, (8 * 21)($4) 261 sd $22, (8 * 22)($4) 262 sd $23, (8 * 23)($4) 263 sd $24, (8 * 24)($4) 264 sd $25, (8 * 25)($4) 265 sd $26, (8 * 26)($4) 266 sd $27, (8 * 27)($4) 267 sd $28, (8 * 28)($4) 268 sd $29, (8 * 29)($4) 269 sd $30, (8 * 30)($4) 270 sd $31, (8 * 31)($4) 271 # Store return address to pc 272 sd $31, (8 * 32)($4) 273 # hi and lo 274 mfhi $8 275 sd $8, (8 * 33)($4) 276 mflo $8 277 sd $8, (8 * 34)($4) 278 #ifdef __mips_hard_float 279 sdc1 $f0, (8 * 35)($4) 280 sdc1 $f1, (8 * 36)($4) 281 sdc1 $f2, (8 * 37)($4) 282 sdc1 $f3, (8 * 38)($4) 283 sdc1 $f4, (8 * 39)($4) 284 sdc1 $f5, (8 * 40)($4) 285 sdc1 $f6, (8 * 41)($4) 286 sdc1 $f7, (8 * 42)($4) 287 sdc1 $f8, (8 * 43)($4) 288 sdc1 $f9, (8 * 44)($4) 289 sdc1 $f10, (8 * 45)($4) 290 sdc1 $f11, (8 * 46)($4) 291 sdc1 $f12, (8 * 47)($4) 292 sdc1 $f13, (8 * 48)($4) 293 sdc1 $f14, (8 * 49)($4) 294 sdc1 $f15, (8 * 50)($4) 295 sdc1 $f16, (8 * 51)($4) 296 sdc1 $f17, (8 * 52)($4) 297 sdc1 $f18, (8 * 53)($4) 298 sdc1 $f19, (8 * 54)($4) 299 sdc1 $f20, (8 * 55)($4) 300 sdc1 $f21, (8 * 56)($4) 301 sdc1 $f22, (8 * 57)($4) 302 sdc1 $f23, (8 * 58)($4) 303 sdc1 $f24, (8 * 59)($4) 304 sdc1 $f25, (8 * 60)($4) 305 sdc1 $f26, (8 * 61)($4) 306 sdc1 $f27, (8 * 62)($4) 307 sdc1 $f28, (8 * 63)($4) 308 sdc1 $f29, (8 * 64)($4) 309 sdc1 $f30, (8 * 65)($4) 310 sdc1 $f31, (8 * 66)($4) 311 #endif 312 jr $31 313 # return UNW_ESUCCESS 314 or $2, $0, $0 315 .set pop 316 317 # elif defined(__mips__) 318 319 # 320 # extern int unw_getcontext(unw_context_t* thread_state) 321 # 322 # Just trap for the time being. 323 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) 324 teq $0, $0 325 326 #elif defined(__powerpc64__) 327 328 // 329 // extern int unw_getcontext(unw_context_t* thread_state) 330 // 331 // On entry: 332 // thread_state pointer is in r3 333 // 334 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) 335 336 // store register (GPR) 337 #define PPC64_STR(n) \ 338 std %r##n, (8 * (n + 2))(%r3) 339 340 // save GPRs 341 PPC64_STR(0) 342 mflr %r0 343 std %r0, PPC64_OFFS_SRR0(%r3) // store lr as ssr0 344 PPC64_STR(1) 345 PPC64_STR(2) 346 PPC64_STR(3) 347 PPC64_STR(4) 348 PPC64_STR(5) 349 PPC64_STR(6) 350 PPC64_STR(7) 351 PPC64_STR(8) 352 PPC64_STR(9) 353 PPC64_STR(10) 354 PPC64_STR(11) 355 PPC64_STR(12) 356 PPC64_STR(13) 357 PPC64_STR(14) 358 PPC64_STR(15) 359 PPC64_STR(16) 360 PPC64_STR(17) 361 PPC64_STR(18) 362 PPC64_STR(19) 363 PPC64_STR(20) 364 PPC64_STR(21) 365 PPC64_STR(22) 366 PPC64_STR(23) 367 PPC64_STR(24) 368 PPC64_STR(25) 369 PPC64_STR(26) 370 PPC64_STR(27) 371 PPC64_STR(28) 372 PPC64_STR(29) 373 PPC64_STR(30) 374 PPC64_STR(31) 375 376 mfcr %r0 377 std %r0, PPC64_OFFS_CR(%r3) 378 mfxer %r0 379 std %r0, PPC64_OFFS_XER(%r3) 380 mflr %r0 381 std %r0, PPC64_OFFS_LR(%r3) 382 mfctr %r0 383 std %r0, PPC64_OFFS_CTR(%r3) 384 mfvrsave %r0 385 std %r0, PPC64_OFFS_VRSAVE(%r3) 386 387 #ifdef PPC64_HAS_VMX 388 // save VS registers 389 // (note that this also saves floating point registers and V registers, 390 // because part of VS is mapped to these registers) 391 392 addi %r4, %r3, PPC64_OFFS_FP 393 394 // store VS register 395 #define PPC64_STVS(n) \ 396 stxvd2x %vs##n, 0, %r4 ;\ 397 addi %r4, %r4, 16 398 399 PPC64_STVS(0) 400 PPC64_STVS(1) 401 PPC64_STVS(2) 402 PPC64_STVS(3) 403 PPC64_STVS(4) 404 PPC64_STVS(5) 405 PPC64_STVS(6) 406 PPC64_STVS(7) 407 PPC64_STVS(8) 408 PPC64_STVS(9) 409 PPC64_STVS(10) 410 PPC64_STVS(11) 411 PPC64_STVS(12) 412 PPC64_STVS(13) 413 PPC64_STVS(14) 414 PPC64_STVS(15) 415 PPC64_STVS(16) 416 PPC64_STVS(17) 417 PPC64_STVS(18) 418 PPC64_STVS(19) 419 PPC64_STVS(20) 420 PPC64_STVS(21) 421 PPC64_STVS(22) 422 PPC64_STVS(23) 423 PPC64_STVS(24) 424 PPC64_STVS(25) 425 PPC64_STVS(26) 426 PPC64_STVS(27) 427 PPC64_STVS(28) 428 PPC64_STVS(29) 429 PPC64_STVS(30) 430 PPC64_STVS(31) 431 PPC64_STVS(32) 432 PPC64_STVS(33) 433 PPC64_STVS(34) 434 PPC64_STVS(35) 435 PPC64_STVS(36) 436 PPC64_STVS(37) 437 PPC64_STVS(38) 438 PPC64_STVS(39) 439 PPC64_STVS(40) 440 PPC64_STVS(41) 441 PPC64_STVS(42) 442 PPC64_STVS(43) 443 PPC64_STVS(44) 444 PPC64_STVS(45) 445 PPC64_STVS(46) 446 PPC64_STVS(47) 447 PPC64_STVS(48) 448 PPC64_STVS(49) 449 PPC64_STVS(50) 450 PPC64_STVS(51) 451 PPC64_STVS(52) 452 PPC64_STVS(53) 453 PPC64_STVS(54) 454 PPC64_STVS(55) 455 PPC64_STVS(56) 456 PPC64_STVS(57) 457 PPC64_STVS(58) 458 PPC64_STVS(59) 459 PPC64_STVS(60) 460 PPC64_STVS(61) 461 PPC64_STVS(62) 462 PPC64_STVS(63) 463 464 #else 465 466 // store FP register 467 #define PPC64_STF(n) \ 468 stfd %f##n, (PPC64_OFFS_FP + n * 16)(%r3) 469 470 // save float registers 471 PPC64_STF(0) 472 PPC64_STF(1) 473 PPC64_STF(2) 474 PPC64_STF(3) 475 PPC64_STF(4) 476 PPC64_STF(5) 477 PPC64_STF(6) 478 PPC64_STF(7) 479 PPC64_STF(8) 480 PPC64_STF(9) 481 PPC64_STF(10) 482 PPC64_STF(11) 483 PPC64_STF(12) 484 PPC64_STF(13) 485 PPC64_STF(14) 486 PPC64_STF(15) 487 PPC64_STF(16) 488 PPC64_STF(17) 489 PPC64_STF(18) 490 PPC64_STF(19) 491 PPC64_STF(20) 492 PPC64_STF(21) 493 PPC64_STF(22) 494 PPC64_STF(23) 495 PPC64_STF(24) 496 PPC64_STF(25) 497 PPC64_STF(26) 498 PPC64_STF(27) 499 PPC64_STF(28) 500 PPC64_STF(29) 501 PPC64_STF(30) 502 PPC64_STF(31) 503 504 // save vector registers 505 506 // Use 16-bytes below the stack pointer as an 507 // aligned buffer to save each vector register. 508 // Note that the stack pointer is always 16-byte aligned. 509 subi %r4, %r1, 16 510 511 #define PPC64_STV_UNALIGNED(n) \ 512 stvx %v##n, 0, %r4 ;\ 513 ld %r5, 0(%r4) ;\ 514 std %r5, (PPC64_OFFS_V + n * 16)(%r3) ;\ 515 ld %r5, 8(%r4) ;\ 516 std %r5, (PPC64_OFFS_V + n * 16 + 8)(%r3) 517 518 PPC64_STV_UNALIGNED(0) 519 PPC64_STV_UNALIGNED(1) 520 PPC64_STV_UNALIGNED(2) 521 PPC64_STV_UNALIGNED(3) 522 PPC64_STV_UNALIGNED(4) 523 PPC64_STV_UNALIGNED(5) 524 PPC64_STV_UNALIGNED(6) 525 PPC64_STV_UNALIGNED(7) 526 PPC64_STV_UNALIGNED(8) 527 PPC64_STV_UNALIGNED(9) 528 PPC64_STV_UNALIGNED(10) 529 PPC64_STV_UNALIGNED(11) 530 PPC64_STV_UNALIGNED(12) 531 PPC64_STV_UNALIGNED(13) 532 PPC64_STV_UNALIGNED(14) 533 PPC64_STV_UNALIGNED(15) 534 PPC64_STV_UNALIGNED(16) 535 PPC64_STV_UNALIGNED(17) 536 PPC64_STV_UNALIGNED(18) 537 PPC64_STV_UNALIGNED(19) 538 PPC64_STV_UNALIGNED(20) 539 PPC64_STV_UNALIGNED(21) 540 PPC64_STV_UNALIGNED(22) 541 PPC64_STV_UNALIGNED(23) 542 PPC64_STV_UNALIGNED(24) 543 PPC64_STV_UNALIGNED(25) 544 PPC64_STV_UNALIGNED(26) 545 PPC64_STV_UNALIGNED(27) 546 PPC64_STV_UNALIGNED(28) 547 PPC64_STV_UNALIGNED(29) 548 PPC64_STV_UNALIGNED(30) 549 PPC64_STV_UNALIGNED(31) 550 551 #endif 552 553 li %r3, 0 // return UNW_ESUCCESS 554 blr 555 556 557 #elif defined(__ppc__) 558 559 ; 560 ; extern int unw_getcontext(unw_context_t* thread_state) 561 ; 562 ; On entry: 563 ; thread_state pointer is in r3 564 ; 565 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) 566 stw r0, 8(r3) 567 mflr r0 568 stw r0, 0(r3) ; store lr as ssr0 569 stw r1, 12(r3) 570 stw r2, 16(r3) 571 stw r3, 20(r3) 572 stw r4, 24(r3) 573 stw r5, 28(r3) 574 stw r6, 32(r3) 575 stw r7, 36(r3) 576 stw r8, 40(r3) 577 stw r9, 44(r3) 578 stw r10, 48(r3) 579 stw r11, 52(r3) 580 stw r12, 56(r3) 581 stw r13, 60(r3) 582 stw r14, 64(r3) 583 stw r15, 68(r3) 584 stw r16, 72(r3) 585 stw r17, 76(r3) 586 stw r18, 80(r3) 587 stw r19, 84(r3) 588 stw r20, 88(r3) 589 stw r21, 92(r3) 590 stw r22, 96(r3) 591 stw r23,100(r3) 592 stw r24,104(r3) 593 stw r25,108(r3) 594 stw r26,112(r3) 595 stw r27,116(r3) 596 stw r28,120(r3) 597 stw r29,124(r3) 598 stw r30,128(r3) 599 stw r31,132(r3) 600 601 ; save VRSave register 602 mfspr r0,256 603 stw r0,156(r3) 604 ; save CR registers 605 mfcr r0 606 stw r0,136(r3) 607 ; save CTR register 608 mfctr r0 609 stw r0,148(r3) 610 611 ; save float registers 612 stfd f0, 160(r3) 613 stfd f1, 168(r3) 614 stfd f2, 176(r3) 615 stfd f3, 184(r3) 616 stfd f4, 192(r3) 617 stfd f5, 200(r3) 618 stfd f6, 208(r3) 619 stfd f7, 216(r3) 620 stfd f8, 224(r3) 621 stfd f9, 232(r3) 622 stfd f10,240(r3) 623 stfd f11,248(r3) 624 stfd f12,256(r3) 625 stfd f13,264(r3) 626 stfd f14,272(r3) 627 stfd f15,280(r3) 628 stfd f16,288(r3) 629 stfd f17,296(r3) 630 stfd f18,304(r3) 631 stfd f19,312(r3) 632 stfd f20,320(r3) 633 stfd f21,328(r3) 634 stfd f22,336(r3) 635 stfd f23,344(r3) 636 stfd f24,352(r3) 637 stfd f25,360(r3) 638 stfd f26,368(r3) 639 stfd f27,376(r3) 640 stfd f28,384(r3) 641 stfd f29,392(r3) 642 stfd f30,400(r3) 643 stfd f31,408(r3) 644 645 646 ; save vector registers 647 648 subi r4,r1,16 649 rlwinm r4,r4,0,0,27 ; mask low 4-bits 650 ; r4 is now a 16-byte aligned pointer into the red zone 651 652 #define SAVE_VECTOR_UNALIGNED(_vec, _offset) \ 653 stvx _vec,0,r4 @\ 654 lwz r5, 0(r4) @\ 655 stw r5, _offset(r3) @\ 656 lwz r5, 4(r4) @\ 657 stw r5, _offset+4(r3) @\ 658 lwz r5, 8(r4) @\ 659 stw r5, _offset+8(r3) @\ 660 lwz r5, 12(r4) @\ 661 stw r5, _offset+12(r3) 662 663 SAVE_VECTOR_UNALIGNED( v0, 424+0x000) 664 SAVE_VECTOR_UNALIGNED( v1, 424+0x010) 665 SAVE_VECTOR_UNALIGNED( v2, 424+0x020) 666 SAVE_VECTOR_UNALIGNED( v3, 424+0x030) 667 SAVE_VECTOR_UNALIGNED( v4, 424+0x040) 668 SAVE_VECTOR_UNALIGNED( v5, 424+0x050) 669 SAVE_VECTOR_UNALIGNED( v6, 424+0x060) 670 SAVE_VECTOR_UNALIGNED( v7, 424+0x070) 671 SAVE_VECTOR_UNALIGNED( v8, 424+0x080) 672 SAVE_VECTOR_UNALIGNED( v9, 424+0x090) 673 SAVE_VECTOR_UNALIGNED(v10, 424+0x0A0) 674 SAVE_VECTOR_UNALIGNED(v11, 424+0x0B0) 675 SAVE_VECTOR_UNALIGNED(v12, 424+0x0C0) 676 SAVE_VECTOR_UNALIGNED(v13, 424+0x0D0) 677 SAVE_VECTOR_UNALIGNED(v14, 424+0x0E0) 678 SAVE_VECTOR_UNALIGNED(v15, 424+0x0F0) 679 SAVE_VECTOR_UNALIGNED(v16, 424+0x100) 680 SAVE_VECTOR_UNALIGNED(v17, 424+0x110) 681 SAVE_VECTOR_UNALIGNED(v18, 424+0x120) 682 SAVE_VECTOR_UNALIGNED(v19, 424+0x130) 683 SAVE_VECTOR_UNALIGNED(v20, 424+0x140) 684 SAVE_VECTOR_UNALIGNED(v21, 424+0x150) 685 SAVE_VECTOR_UNALIGNED(v22, 424+0x160) 686 SAVE_VECTOR_UNALIGNED(v23, 424+0x170) 687 SAVE_VECTOR_UNALIGNED(v24, 424+0x180) 688 SAVE_VECTOR_UNALIGNED(v25, 424+0x190) 689 SAVE_VECTOR_UNALIGNED(v26, 424+0x1A0) 690 SAVE_VECTOR_UNALIGNED(v27, 424+0x1B0) 691 SAVE_VECTOR_UNALIGNED(v28, 424+0x1C0) 692 SAVE_VECTOR_UNALIGNED(v29, 424+0x1D0) 693 SAVE_VECTOR_UNALIGNED(v30, 424+0x1E0) 694 SAVE_VECTOR_UNALIGNED(v31, 424+0x1F0) 695 696 li r3, 0 ; return UNW_ESUCCESS 697 blr 698 699 700 #elif defined(__arm64__) || defined(__aarch64__) 701 702 // 703 // extern int unw_getcontext(unw_context_t* thread_state) 704 // 705 // On entry: 706 // thread_state pointer is in x0 707 // 708 .p2align 2 709 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) 710 stp x0, x1, [x0, #0x000] 711 stp x2, x3, [x0, #0x010] 712 stp x4, x5, [x0, #0x020] 713 stp x6, x7, [x0, #0x030] 714 stp x8, x9, [x0, #0x040] 715 stp x10,x11, [x0, #0x050] 716 stp x12,x13, [x0, #0x060] 717 stp x14,x15, [x0, #0x070] 718 stp x16,x17, [x0, #0x080] 719 stp x18,x19, [x0, #0x090] 720 stp x20,x21, [x0, #0x0A0] 721 stp x22,x23, [x0, #0x0B0] 722 stp x24,x25, [x0, #0x0C0] 723 stp x26,x27, [x0, #0x0D0] 724 stp x28,x29, [x0, #0x0E0] 725 str x30, [x0, #0x0F0] 726 mov x1,sp 727 str x1, [x0, #0x0F8] 728 str x30, [x0, #0x100] // store return address as pc 729 // skip cpsr 730 stp d0, d1, [x0, #0x110] 731 stp d2, d3, [x0, #0x120] 732 stp d4, d5, [x0, #0x130] 733 stp d6, d7, [x0, #0x140] 734 stp d8, d9, [x0, #0x150] 735 stp d10,d11, [x0, #0x160] 736 stp d12,d13, [x0, #0x170] 737 stp d14,d15, [x0, #0x180] 738 stp d16,d17, [x0, #0x190] 739 stp d18,d19, [x0, #0x1A0] 740 stp d20,d21, [x0, #0x1B0] 741 stp d22,d23, [x0, #0x1C0] 742 stp d24,d25, [x0, #0x1D0] 743 stp d26,d27, [x0, #0x1E0] 744 stp d28,d29, [x0, #0x1F0] 745 str d30, [x0, #0x200] 746 str d31, [x0, #0x208] 747 mov x0, #0 // return UNW_ESUCCESS 748 ret 749 750 #elif defined(__arm__) && !defined(__APPLE__) 751 752 #if !defined(__ARM_ARCH_ISA_ARM) 753 .thumb 754 #endif 755 756 @ 757 @ extern int unw_getcontext(unw_context_t* thread_state) 758 @ 759 @ On entry: 760 @ thread_state pointer is in r0 761 @ 762 @ Per EHABI #4.7 this only saves the core integer registers. 763 @ EHABI #7.4.5 notes that in general all VRS registers should be restored 764 @ however this is very hard to do for VFP registers because it is unknown 765 @ to the library how many registers are implemented by the architecture. 766 @ Instead, VFP registers are demand saved by logic external to unw_getcontext. 767 @ 768 .p2align 2 769 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) 770 #if !defined(__ARM_ARCH_ISA_ARM) && __ARM_ARCH_ISA_THUMB == 1 771 stm r0!, {r0-r7} 772 mov r1, r8 773 mov r2, r9 774 mov r3, r10 775 stm r0!, {r1-r3} 776 mov r1, r11 777 mov r2, sp 778 mov r3, lr 779 str r1, [r0, #0] @ r11 780 @ r12 does not need storing, it it the intra-procedure-call scratch register 781 str r2, [r0, #8] @ sp 782 str r3, [r0, #12] @ lr 783 str r3, [r0, #16] @ store return address as pc 784 @ T1 does not have a non-cpsr-clobbering register-zeroing instruction. 785 @ It is safe to use here though because we are about to return, and cpsr is 786 @ not expected to be preserved. 787 movs r0, #0 @ return UNW_ESUCCESS 788 #else 789 @ 32bit thumb-2 restrictions for stm: 790 @ . the sp (r13) cannot be in the list 791 @ . the pc (r15) cannot be in the list in an STM instruction 792 stm r0, {r0-r12} 793 str sp, [r0, #52] 794 str lr, [r0, #56] 795 str lr, [r0, #60] @ store return address as pc 796 mov r0, #0 @ return UNW_ESUCCESS 797 #endif 798 JMP(lr) 799 800 @ 801 @ static void libunwind::Registers_arm::saveVFPWithFSTMD(unw_fpreg_t* values) 802 @ 803 @ On entry: 804 @ values pointer is in r0 805 @ 806 .p2align 2 807 #if defined(__ELF__) 808 .fpu vfpv3-d16 809 #endif 810 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMDEPv) 811 vstmia r0, {d0-d15} 812 JMP(lr) 813 814 @ 815 @ static void libunwind::Registers_arm::saveVFPWithFSTMX(unw_fpreg_t* values) 816 @ 817 @ On entry: 818 @ values pointer is in r0 819 @ 820 .p2align 2 821 #if defined(__ELF__) 822 .fpu vfpv3-d16 823 #endif 824 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMXEPv) 825 vstmia r0, {d0-d15} @ fstmiax is deprecated in ARMv7+ and now behaves like vstmia 826 JMP(lr) 827 828 @ 829 @ static void libunwind::Registers_arm::saveVFPv3(unw_fpreg_t* values) 830 @ 831 @ On entry: 832 @ values pointer is in r0 833 @ 834 .p2align 2 835 #if defined(__ELF__) 836 .fpu vfpv3 837 #endif 838 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPv) 839 @ VFP and iwMMX instructions are only available when compiling with the flags 840 @ that enable them. We do not want to do that in the library (because we do not 841 @ want the compiler to generate instructions that access those) but this is 842 @ only accessed if the personality routine needs these registers. Use of 843 @ these registers implies they are, actually, available on the target, so 844 @ it's ok to execute. 845 @ So, generate the instructions using the corresponding coprocessor mnemonic. 846 vstmia r0, {d16-d31} 847 JMP(lr) 848 849 #if defined(_LIBUNWIND_ARM_WMMX) 850 851 @ 852 @ static void libunwind::Registers_arm::saveiWMMX(unw_fpreg_t* values) 853 @ 854 @ On entry: 855 @ values pointer is in r0 856 @ 857 .p2align 2 858 #if defined(__ELF__) 859 .arch armv5te 860 #endif 861 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveiWMMXEPv) 862 stcl p1, cr0, [r0], #8 @ wstrd wR0, [r0], #8 863 stcl p1, cr1, [r0], #8 @ wstrd wR1, [r0], #8 864 stcl p1, cr2, [r0], #8 @ wstrd wR2, [r0], #8 865 stcl p1, cr3, [r0], #8 @ wstrd wR3, [r0], #8 866 stcl p1, cr4, [r0], #8 @ wstrd wR4, [r0], #8 867 stcl p1, cr5, [r0], #8 @ wstrd wR5, [r0], #8 868 stcl p1, cr6, [r0], #8 @ wstrd wR6, [r0], #8 869 stcl p1, cr7, [r0], #8 @ wstrd wR7, [r0], #8 870 stcl p1, cr8, [r0], #8 @ wstrd wR8, [r0], #8 871 stcl p1, cr9, [r0], #8 @ wstrd wR9, [r0], #8 872 stcl p1, cr10, [r0], #8 @ wstrd wR10, [r0], #8 873 stcl p1, cr11, [r0], #8 @ wstrd wR11, [r0], #8 874 stcl p1, cr12, [r0], #8 @ wstrd wR12, [r0], #8 875 stcl p1, cr13, [r0], #8 @ wstrd wR13, [r0], #8 876 stcl p1, cr14, [r0], #8 @ wstrd wR14, [r0], #8 877 stcl p1, cr15, [r0], #8 @ wstrd wR15, [r0], #8 878 JMP(lr) 879 880 @ 881 @ static void libunwind::Registers_arm::saveiWMMXControl(unw_uint32_t* values) 882 @ 883 @ On entry: 884 @ values pointer is in r0 885 @ 886 .p2align 2 887 #if defined(__ELF__) 888 .arch armv5te 889 #endif 890 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveiWMMXControlEPj) 891 stc2 p1, cr8, [r0], #4 @ wstrw wCGR0, [r0], #4 892 stc2 p1, cr9, [r0], #4 @ wstrw wCGR1, [r0], #4 893 stc2 p1, cr10, [r0], #4 @ wstrw wCGR2, [r0], #4 894 stc2 p1, cr11, [r0], #4 @ wstrw wCGR3, [r0], #4 895 JMP(lr) 896 897 #endif 898 899 #elif defined(__or1k__) 900 901 # 902 # extern int unw_getcontext(unw_context_t* thread_state) 903 # 904 # On entry: 905 # thread_state pointer is in r3 906 # 907 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) 908 l.sw 0(r3), r0 909 l.sw 4(r3), r1 910 l.sw 8(r3), r2 911 l.sw 12(r3), r3 912 l.sw 16(r3), r4 913 l.sw 20(r3), r5 914 l.sw 24(r3), r6 915 l.sw 28(r3), r7 916 l.sw 32(r3), r8 917 l.sw 36(r3), r9 918 l.sw 40(r3), r10 919 l.sw 44(r3), r11 920 l.sw 48(r3), r12 921 l.sw 52(r3), r13 922 l.sw 56(r3), r14 923 l.sw 60(r3), r15 924 l.sw 64(r3), r16 925 l.sw 68(r3), r17 926 l.sw 72(r3), r18 927 l.sw 76(r3), r19 928 l.sw 80(r3), r20 929 l.sw 84(r3), r21 930 l.sw 88(r3), r22 931 l.sw 92(r3), r23 932 l.sw 96(r3), r24 933 l.sw 100(r3), r25 934 l.sw 104(r3), r26 935 l.sw 108(r3), r27 936 l.sw 112(r3), r28 937 l.sw 116(r3), r29 938 l.sw 120(r3), r30 939 l.sw 124(r3), r31 940 # store ra to pc 941 l.sw 128(r3), r9 942 # zero epcr 943 l.sw 132(r3), r0 944 945 #elif defined(__sparc__) 946 947 # 948 # extern int unw_getcontext(unw_context_t* thread_state) 949 # 950 # On entry: 951 # thread_state pointer is in o0 952 # 953 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) 954 ta 3 955 add %o7, 8, %o7 956 std %g0, [%o0 + 0] 957 std %g2, [%o0 + 8] 958 std %g4, [%o0 + 16] 959 std %g6, [%o0 + 24] 960 std %o0, [%o0 + 32] 961 std %o2, [%o0 + 40] 962 std %o4, [%o0 + 48] 963 std %o6, [%o0 + 56] 964 std %l0, [%o0 + 64] 965 std %l2, [%o0 + 72] 966 std %l4, [%o0 + 80] 967 std %l6, [%o0 + 88] 968 std %i0, [%o0 + 96] 969 std %i2, [%o0 + 104] 970 std %i4, [%o0 + 112] 971 std %i6, [%o0 + 120] 972 jmp %o7 973 clr %o0 // return UNW_ESUCCESS 974 #endif 975 #endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */ 976 977 NO_EXEC_STACK_DIRECTIVE 978