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# 29DEFINE_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# 64DEFINE_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# 126DEFINE_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# 235DEFINE_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. 323DEFINE_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// 334DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) 335 336// store register (GPR) 337#define PPC64_STR(n) \ 338 std n, (8 * (n + 2))(3) 339 340 // save GPRs 341 PPC64_STR(0) 342 mflr 0 343 std 0, PPC64_OFFS_SRR0(3) // 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 0 377 std 0, PPC64_OFFS_CR(3) 378 mfxer 0 379 std 0, PPC64_OFFS_XER(3) 380 mflr 0 381 std 0, PPC64_OFFS_LR(3) 382 mfctr 0 383 std 0, PPC64_OFFS_CTR(3) 384 mfvrsave 0 385 std 0, PPC64_OFFS_VRSAVE(3) 386 387#if defined(__VSX__) 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 4, 3, PPC64_OFFS_FP 393 394// store VS register 395#define PPC64_STVS(n) \ 396 stxvd2x n, 0, 4 ;\ 397 addi 4, 4, 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 n, (PPC64_OFFS_FP + n * 16)(3) 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#if defined(__ALTIVEC__) 505 // save vector registers 506 507 // Use 16-bytes below the stack pointer as an 508 // aligned buffer to save each vector register. 509 // Note that the stack pointer is always 16-byte aligned. 510 subi 4, 1, 16 511 512#define PPC64_STV_UNALIGNED(n) \ 513 stvx n, 0, 4 ;\ 514 ld 5, 0(4) ;\ 515 std 5, (PPC64_OFFS_V + n * 16)(3) ;\ 516 ld 5, 8(4) ;\ 517 std 5, (PPC64_OFFS_V + n * 16 + 8)(3) 518 519 PPC64_STV_UNALIGNED(0) 520 PPC64_STV_UNALIGNED(1) 521 PPC64_STV_UNALIGNED(2) 522 PPC64_STV_UNALIGNED(3) 523 PPC64_STV_UNALIGNED(4) 524 PPC64_STV_UNALIGNED(5) 525 PPC64_STV_UNALIGNED(6) 526 PPC64_STV_UNALIGNED(7) 527 PPC64_STV_UNALIGNED(8) 528 PPC64_STV_UNALIGNED(9) 529 PPC64_STV_UNALIGNED(10) 530 PPC64_STV_UNALIGNED(11) 531 PPC64_STV_UNALIGNED(12) 532 PPC64_STV_UNALIGNED(13) 533 PPC64_STV_UNALIGNED(14) 534 PPC64_STV_UNALIGNED(15) 535 PPC64_STV_UNALIGNED(16) 536 PPC64_STV_UNALIGNED(17) 537 PPC64_STV_UNALIGNED(18) 538 PPC64_STV_UNALIGNED(19) 539 PPC64_STV_UNALIGNED(20) 540 PPC64_STV_UNALIGNED(21) 541 PPC64_STV_UNALIGNED(22) 542 PPC64_STV_UNALIGNED(23) 543 PPC64_STV_UNALIGNED(24) 544 PPC64_STV_UNALIGNED(25) 545 PPC64_STV_UNALIGNED(26) 546 PPC64_STV_UNALIGNED(27) 547 PPC64_STV_UNALIGNED(28) 548 PPC64_STV_UNALIGNED(29) 549 PPC64_STV_UNALIGNED(30) 550 PPC64_STV_UNALIGNED(31) 551 552#endif 553#endif 554 555 li 3, 0 // return UNW_ESUCCESS 556 blr 557 558 559#elif defined(__ppc__) 560 561// 562// extern int unw_getcontext(unw_context_t* thread_state) 563// 564// On entry: 565// thread_state pointer is in r3 566// 567DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) 568 stw 0, 8(3) 569 mflr 0 570 stw 0, 0(3) // store lr as ssr0 571 stw 1, 12(3) 572 stw 2, 16(3) 573 stw 3, 20(3) 574 stw 4, 24(3) 575 stw 5, 28(3) 576 stw 6, 32(3) 577 stw 7, 36(3) 578 stw 8, 40(3) 579 stw 9, 44(3) 580 stw 10, 48(3) 581 stw 11, 52(3) 582 stw 12, 56(3) 583 stw 13, 60(3) 584 stw 14, 64(3) 585 stw 15, 68(3) 586 stw 16, 72(3) 587 stw 17, 76(3) 588 stw 18, 80(3) 589 stw 19, 84(3) 590 stw 20, 88(3) 591 stw 21, 92(3) 592 stw 22, 96(3) 593 stw 23,100(3) 594 stw 24,104(3) 595 stw 25,108(3) 596 stw 26,112(3) 597 stw 27,116(3) 598 stw 28,120(3) 599 stw 29,124(3) 600 stw 30,128(3) 601 stw 31,132(3) 602 603 // save VRSave register 604 mfspr 0, 256 605 stw 0, 156(3) 606 // save CR registers 607 mfcr 0 608 stw 0, 136(3) 609 // save CTR register 610 mfctr 0 611 stw 0, 148(3) 612 613#if !defined(__NO_FPRS__) 614 // save float registers 615 stfd 0, 160(3) 616 stfd 1, 168(3) 617 stfd 2, 176(3) 618 stfd 3, 184(3) 619 stfd 4, 192(3) 620 stfd 5, 200(3) 621 stfd 6, 208(3) 622 stfd 7, 216(3) 623 stfd 8, 224(3) 624 stfd 9, 232(3) 625 stfd 10,240(3) 626 stfd 11,248(3) 627 stfd 12,256(3) 628 stfd 13,264(3) 629 stfd 14,272(3) 630 stfd 15,280(3) 631 stfd 16,288(3) 632 stfd 17,296(3) 633 stfd 18,304(3) 634 stfd 19,312(3) 635 stfd 20,320(3) 636 stfd 21,328(3) 637 stfd 22,336(3) 638 stfd 23,344(3) 639 stfd 24,352(3) 640 stfd 25,360(3) 641 stfd 26,368(3) 642 stfd 27,376(3) 643 stfd 28,384(3) 644 stfd 29,392(3) 645 stfd 30,400(3) 646 stfd 31,408(3) 647#endif 648 649#if defined(__ALTIVEC__) 650 // save vector registers 651 652 subi 4, 1, 16 653 rlwinm 4, 4, 0, 0, 27 // mask low 4-bits 654 // r4 is now a 16-byte aligned pointer into the red zone 655 656#define SAVE_VECTOR_UNALIGNED(_vec, _offset) \ 657 stvx _vec, 0, 4 SEPARATOR \ 658 lwz 5, 0(4) SEPARATOR \ 659 stw 5, _offset(3) SEPARATOR \ 660 lwz 5, 4(4) SEPARATOR \ 661 stw 5, _offset+4(3) SEPARATOR \ 662 lwz 5, 8(4) SEPARATOR \ 663 stw 5, _offset+8(3) SEPARATOR \ 664 lwz 5, 12(4) SEPARATOR \ 665 stw 5, _offset+12(3) 666 667 SAVE_VECTOR_UNALIGNED( 0, 424+0x000) 668 SAVE_VECTOR_UNALIGNED( 1, 424+0x010) 669 SAVE_VECTOR_UNALIGNED( 2, 424+0x020) 670 SAVE_VECTOR_UNALIGNED( 3, 424+0x030) 671 SAVE_VECTOR_UNALIGNED( 4, 424+0x040) 672 SAVE_VECTOR_UNALIGNED( 5, 424+0x050) 673 SAVE_VECTOR_UNALIGNED( 6, 424+0x060) 674 SAVE_VECTOR_UNALIGNED( 7, 424+0x070) 675 SAVE_VECTOR_UNALIGNED( 8, 424+0x080) 676 SAVE_VECTOR_UNALIGNED( 9, 424+0x090) 677 SAVE_VECTOR_UNALIGNED(10, 424+0x0A0) 678 SAVE_VECTOR_UNALIGNED(11, 424+0x0B0) 679 SAVE_VECTOR_UNALIGNED(12, 424+0x0C0) 680 SAVE_VECTOR_UNALIGNED(13, 424+0x0D0) 681 SAVE_VECTOR_UNALIGNED(14, 424+0x0E0) 682 SAVE_VECTOR_UNALIGNED(15, 424+0x0F0) 683 SAVE_VECTOR_UNALIGNED(16, 424+0x100) 684 SAVE_VECTOR_UNALIGNED(17, 424+0x110) 685 SAVE_VECTOR_UNALIGNED(18, 424+0x120) 686 SAVE_VECTOR_UNALIGNED(19, 424+0x130) 687 SAVE_VECTOR_UNALIGNED(20, 424+0x140) 688 SAVE_VECTOR_UNALIGNED(21, 424+0x150) 689 SAVE_VECTOR_UNALIGNED(22, 424+0x160) 690 SAVE_VECTOR_UNALIGNED(23, 424+0x170) 691 SAVE_VECTOR_UNALIGNED(24, 424+0x180) 692 SAVE_VECTOR_UNALIGNED(25, 424+0x190) 693 SAVE_VECTOR_UNALIGNED(26, 424+0x1A0) 694 SAVE_VECTOR_UNALIGNED(27, 424+0x1B0) 695 SAVE_VECTOR_UNALIGNED(28, 424+0x1C0) 696 SAVE_VECTOR_UNALIGNED(29, 424+0x1D0) 697 SAVE_VECTOR_UNALIGNED(30, 424+0x1E0) 698 SAVE_VECTOR_UNALIGNED(31, 424+0x1F0) 699#endif 700 701 li 3, 0 // return UNW_ESUCCESS 702 blr 703 704 705#elif defined(__aarch64__) 706 707// 708// extern int __unw_getcontext(unw_context_t* thread_state) 709// 710// On entry: 711// thread_state pointer is in x0 712// 713 .p2align 2 714DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) 715 stp x0, x1, [x0, #0x000] 716 stp x2, x3, [x0, #0x010] 717 stp x4, x5, [x0, #0x020] 718 stp x6, x7, [x0, #0x030] 719 stp x8, x9, [x0, #0x040] 720 stp x10,x11, [x0, #0x050] 721 stp x12,x13, [x0, #0x060] 722 stp x14,x15, [x0, #0x070] 723 stp x16,x17, [x0, #0x080] 724 stp x18,x19, [x0, #0x090] 725 stp x20,x21, [x0, #0x0A0] 726 stp x22,x23, [x0, #0x0B0] 727 stp x24,x25, [x0, #0x0C0] 728 stp x26,x27, [x0, #0x0D0] 729 stp x28,x29, [x0, #0x0E0] 730 str x30, [x0, #0x0F0] 731 mov x1,sp 732 str x1, [x0, #0x0F8] 733 str x30, [x0, #0x100] // store return address as pc 734 // skip cpsr 735 stp d0, d1, [x0, #0x110] 736 stp d2, d3, [x0, #0x120] 737 stp d4, d5, [x0, #0x130] 738 stp d6, d7, [x0, #0x140] 739 stp d8, d9, [x0, #0x150] 740 stp d10,d11, [x0, #0x160] 741 stp d12,d13, [x0, #0x170] 742 stp d14,d15, [x0, #0x180] 743 stp d16,d17, [x0, #0x190] 744 stp d18,d19, [x0, #0x1A0] 745 stp d20,d21, [x0, #0x1B0] 746 stp d22,d23, [x0, #0x1C0] 747 stp d24,d25, [x0, #0x1D0] 748 stp d26,d27, [x0, #0x1E0] 749 stp d28,d29, [x0, #0x1F0] 750 str d30, [x0, #0x200] 751 str d31, [x0, #0x208] 752 mov x0, #0 // return UNW_ESUCCESS 753 ret 754 755#elif defined(__arm__) && !defined(__APPLE__) 756 757#if !defined(__ARM_ARCH_ISA_ARM) 758#if (__ARM_ARCH_ISA_THUMB == 2) 759 .syntax unified 760#endif 761 .thumb 762#endif 763 764@ 765@ extern int __unw_getcontext(unw_context_t* thread_state) 766@ 767@ On entry: 768@ thread_state pointer is in r0 769@ 770@ Per EHABI #4.7 this only saves the core integer registers. 771@ EHABI #7.4.5 notes that in general all VRS registers should be restored 772@ however this is very hard to do for VFP registers because it is unknown 773@ to the library how many registers are implemented by the architecture. 774@ Instead, VFP registers are demand saved by logic external to __unw_getcontext. 775@ 776 .p2align 2 777DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) 778#if !defined(__ARM_ARCH_ISA_ARM) && __ARM_ARCH_ISA_THUMB == 1 779 stm r0!, {r0-r7} 780 mov r1, r8 781 mov r2, r9 782 mov r3, r10 783 stm r0!, {r1-r3} 784 mov r1, r11 785 mov r2, sp 786 mov r3, lr 787 str r1, [r0, #0] @ r11 788 @ r12 does not need storing, it it the intra-procedure-call scratch register 789 str r2, [r0, #8] @ sp 790 str r3, [r0, #12] @ lr 791 str r3, [r0, #16] @ store return address as pc 792 @ T1 does not have a non-cpsr-clobbering register-zeroing instruction. 793 @ It is safe to use here though because we are about to return, and cpsr is 794 @ not expected to be preserved. 795 movs r0, #0 @ return UNW_ESUCCESS 796#else 797 @ 32bit thumb-2 restrictions for stm: 798 @ . the sp (r13) cannot be in the list 799 @ . the pc (r15) cannot be in the list in an STM instruction 800 stm r0, {r0-r12} 801 str sp, [r0, #52] 802 str lr, [r0, #56] 803 str lr, [r0, #60] @ store return address as pc 804 mov r0, #0 @ return UNW_ESUCCESS 805#endif 806 JMP(lr) 807 808@ 809@ static void libunwind::Registers_arm::saveVFPWithFSTMD(unw_fpreg_t* values) 810@ 811@ On entry: 812@ values pointer is in r0 813@ 814 .p2align 2 815#if defined(__ELF__) 816 .fpu vfpv3-d16 817#endif 818DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMDEPv) 819 vstmia r0, {d0-d15} 820 JMP(lr) 821 822@ 823@ static void libunwind::Registers_arm::saveVFPWithFSTMX(unw_fpreg_t* values) 824@ 825@ On entry: 826@ values pointer is in r0 827@ 828 .p2align 2 829#if defined(__ELF__) 830 .fpu vfpv3-d16 831#endif 832DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMXEPv) 833 vstmia r0, {d0-d15} @ fstmiax is deprecated in ARMv7+ and now behaves like vstmia 834 JMP(lr) 835 836@ 837@ static void libunwind::Registers_arm::saveVFPv3(unw_fpreg_t* values) 838@ 839@ On entry: 840@ values pointer is in r0 841@ 842 .p2align 2 843#if defined(__ELF__) 844 .fpu vfpv3 845#endif 846DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPv) 847 @ VFP and iwMMX instructions are only available when compiling with the flags 848 @ that enable them. We do not want to do that in the library (because we do not 849 @ want the compiler to generate instructions that access those) but this is 850 @ only accessed if the personality routine needs these registers. Use of 851 @ these registers implies they are, actually, available on the target, so 852 @ it's ok to execute. 853 @ So, generate the instructions using the corresponding coprocessor mnemonic. 854 vstmia r0, {d16-d31} 855 JMP(lr) 856 857#if defined(_LIBUNWIND_ARM_WMMX) 858 859@ 860@ static void libunwind::Registers_arm::saveiWMMX(unw_fpreg_t* values) 861@ 862@ On entry: 863@ values pointer is in r0 864@ 865 .p2align 2 866#if defined(__ELF__) 867 .arch armv5te 868#endif 869DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm9saveiWMMXEPv) 870 stcl p1, cr0, [r0], #8 @ wstrd wR0, [r0], #8 871 stcl p1, cr1, [r0], #8 @ wstrd wR1, [r0], #8 872 stcl p1, cr2, [r0], #8 @ wstrd wR2, [r0], #8 873 stcl p1, cr3, [r0], #8 @ wstrd wR3, [r0], #8 874 stcl p1, cr4, [r0], #8 @ wstrd wR4, [r0], #8 875 stcl p1, cr5, [r0], #8 @ wstrd wR5, [r0], #8 876 stcl p1, cr6, [r0], #8 @ wstrd wR6, [r0], #8 877 stcl p1, cr7, [r0], #8 @ wstrd wR7, [r0], #8 878 stcl p1, cr8, [r0], #8 @ wstrd wR8, [r0], #8 879 stcl p1, cr9, [r0], #8 @ wstrd wR9, [r0], #8 880 stcl p1, cr10, [r0], #8 @ wstrd wR10, [r0], #8 881 stcl p1, cr11, [r0], #8 @ wstrd wR11, [r0], #8 882 stcl p1, cr12, [r0], #8 @ wstrd wR12, [r0], #8 883 stcl p1, cr13, [r0], #8 @ wstrd wR13, [r0], #8 884 stcl p1, cr14, [r0], #8 @ wstrd wR14, [r0], #8 885 stcl p1, cr15, [r0], #8 @ wstrd wR15, [r0], #8 886 JMP(lr) 887 888@ 889@ static void libunwind::Registers_arm::saveiWMMXControl(unw_uint32_t* values) 890@ 891@ On entry: 892@ values pointer is in r0 893@ 894 .p2align 2 895#if defined(__ELF__) 896 .arch armv5te 897#endif 898DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveiWMMXControlEPj) 899 stc2 p1, cr8, [r0], #4 @ wstrw wCGR0, [r0], #4 900 stc2 p1, cr9, [r0], #4 @ wstrw wCGR1, [r0], #4 901 stc2 p1, cr10, [r0], #4 @ wstrw wCGR2, [r0], #4 902 stc2 p1, cr11, [r0], #4 @ wstrw wCGR3, [r0], #4 903 JMP(lr) 904 905#endif 906 907#elif defined(__or1k__) 908 909# 910# extern int __unw_getcontext(unw_context_t* thread_state) 911# 912# On entry: 913# thread_state pointer is in r3 914# 915DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) 916 l.sw 0(r3), r0 917 l.sw 4(r3), r1 918 l.sw 8(r3), r2 919 l.sw 12(r3), r3 920 l.sw 16(r3), r4 921 l.sw 20(r3), r5 922 l.sw 24(r3), r6 923 l.sw 28(r3), r7 924 l.sw 32(r3), r8 925 l.sw 36(r3), r9 926 l.sw 40(r3), r10 927 l.sw 44(r3), r11 928 l.sw 48(r3), r12 929 l.sw 52(r3), r13 930 l.sw 56(r3), r14 931 l.sw 60(r3), r15 932 l.sw 64(r3), r16 933 l.sw 68(r3), r17 934 l.sw 72(r3), r18 935 l.sw 76(r3), r19 936 l.sw 80(r3), r20 937 l.sw 84(r3), r21 938 l.sw 88(r3), r22 939 l.sw 92(r3), r23 940 l.sw 96(r3), r24 941 l.sw 100(r3), r25 942 l.sw 104(r3), r26 943 l.sw 108(r3), r27 944 l.sw 112(r3), r28 945 l.sw 116(r3), r29 946 l.sw 120(r3), r30 947 l.sw 124(r3), r31 948 # store ra to pc 949 l.sw 128(r3), r9 950 # zero epcr 951 l.sw 132(r3), r0 952 953#elif defined(__hexagon__) 954# 955# extern int unw_getcontext(unw_context_t* thread_state) 956# 957# On entry: 958# thread_state pointer is in r0 959# 960#define OFFSET(offset) (offset/4) 961DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) 962 memw(r0+#32) = r8 963 memw(r0+#36) = r9 964 memw(r0+#40) = r10 965 memw(r0+#44) = r11 966 967 memw(r0+#48) = r12 968 memw(r0+#52) = r13 969 memw(r0+#56) = r14 970 memw(r0+#60) = r15 971 972 memw(r0+#64) = r16 973 memw(r0+#68) = r17 974 memw(r0+#72) = r18 975 memw(r0+#76) = r19 976 977 memw(r0+#80) = r20 978 memw(r0+#84) = r21 979 memw(r0+#88) = r22 980 memw(r0+#92) = r23 981 982 memw(r0+#96) = r24 983 memw(r0+#100) = r25 984 memw(r0+#104) = r26 985 memw(r0+#108) = r27 986 987 memw(r0+#112) = r28 988 memw(r0+#116) = r29 989 memw(r0+#120) = r30 990 memw(r0+#124) = r31 991 r1 = c4 // Predicate register 992 memw(r0+#128) = r1 993 r1 = memw(r30) // *FP == Saved FP 994 r1 = r31 995 memw(r0+#132) = r1 996 997 jumpr r31 998 999#elif defined(__sparc__) 1000 1001# 1002# extern int __unw_getcontext(unw_context_t* thread_state) 1003# 1004# On entry: 1005# thread_state pointer is in o0 1006# 1007DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) 1008 ta 3 1009 add %o7, 8, %o7 1010 std %g0, [%o0 + 0] 1011 std %g2, [%o0 + 8] 1012 std %g4, [%o0 + 16] 1013 std %g6, [%o0 + 24] 1014 std %o0, [%o0 + 32] 1015 std %o2, [%o0 + 40] 1016 std %o4, [%o0 + 48] 1017 std %o6, [%o0 + 56] 1018 std %l0, [%o0 + 64] 1019 std %l2, [%o0 + 72] 1020 std %l4, [%o0 + 80] 1021 std %l6, [%o0 + 88] 1022 std %i0, [%o0 + 96] 1023 std %i2, [%o0 + 104] 1024 std %i4, [%o0 + 112] 1025 std %i6, [%o0 + 120] 1026 jmp %o7 1027 clr %o0 // return UNW_ESUCCESS 1028 1029#elif defined(__riscv) 1030 1031# 1032# extern int __unw_getcontext(unw_context_t* thread_state) 1033# 1034# On entry: 1035# thread_state pointer is in a0 1036# 1037DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) 1038 ISTORE x1, (RISCV_ISIZE * 0)(a0) // store ra as pc 1039 ISTORE x1, (RISCV_ISIZE * 1)(a0) 1040 ISTORE x2, (RISCV_ISIZE * 2)(a0) 1041 ISTORE x3, (RISCV_ISIZE * 3)(a0) 1042 ISTORE x4, (RISCV_ISIZE * 4)(a0) 1043 ISTORE x5, (RISCV_ISIZE * 5)(a0) 1044 ISTORE x6, (RISCV_ISIZE * 6)(a0) 1045 ISTORE x7, (RISCV_ISIZE * 7)(a0) 1046 ISTORE x8, (RISCV_ISIZE * 8)(a0) 1047 ISTORE x9, (RISCV_ISIZE * 9)(a0) 1048 ISTORE x10, (RISCV_ISIZE * 10)(a0) 1049 ISTORE x11, (RISCV_ISIZE * 11)(a0) 1050 ISTORE x12, (RISCV_ISIZE * 12)(a0) 1051 ISTORE x13, (RISCV_ISIZE * 13)(a0) 1052 ISTORE x14, (RISCV_ISIZE * 14)(a0) 1053 ISTORE x15, (RISCV_ISIZE * 15)(a0) 1054 ISTORE x16, (RISCV_ISIZE * 16)(a0) 1055 ISTORE x17, (RISCV_ISIZE * 17)(a0) 1056 ISTORE x18, (RISCV_ISIZE * 18)(a0) 1057 ISTORE x19, (RISCV_ISIZE * 19)(a0) 1058 ISTORE x20, (RISCV_ISIZE * 20)(a0) 1059 ISTORE x21, (RISCV_ISIZE * 21)(a0) 1060 ISTORE x22, (RISCV_ISIZE * 22)(a0) 1061 ISTORE x23, (RISCV_ISIZE * 23)(a0) 1062 ISTORE x24, (RISCV_ISIZE * 24)(a0) 1063 ISTORE x25, (RISCV_ISIZE * 25)(a0) 1064 ISTORE x26, (RISCV_ISIZE * 26)(a0) 1065 ISTORE x27, (RISCV_ISIZE * 27)(a0) 1066 ISTORE x28, (RISCV_ISIZE * 28)(a0) 1067 ISTORE x29, (RISCV_ISIZE * 29)(a0) 1068 ISTORE x30, (RISCV_ISIZE * 30)(a0) 1069 ISTORE x31, (RISCV_ISIZE * 31)(a0) 1070 1071# if defined(__riscv_flen) 1072 FSTORE f0, (RISCV_FOFFSET + RISCV_FSIZE * 0)(a0) 1073 FSTORE f1, (RISCV_FOFFSET + RISCV_FSIZE * 1)(a0) 1074 FSTORE f2, (RISCV_FOFFSET + RISCV_FSIZE * 2)(a0) 1075 FSTORE f3, (RISCV_FOFFSET + RISCV_FSIZE * 3)(a0) 1076 FSTORE f4, (RISCV_FOFFSET + RISCV_FSIZE * 4)(a0) 1077 FSTORE f5, (RISCV_FOFFSET + RISCV_FSIZE * 5)(a0) 1078 FSTORE f6, (RISCV_FOFFSET + RISCV_FSIZE * 6)(a0) 1079 FSTORE f7, (RISCV_FOFFSET + RISCV_FSIZE * 7)(a0) 1080 FSTORE f8, (RISCV_FOFFSET + RISCV_FSIZE * 8)(a0) 1081 FSTORE f9, (RISCV_FOFFSET + RISCV_FSIZE * 9)(a0) 1082 FSTORE f10, (RISCV_FOFFSET + RISCV_FSIZE * 10)(a0) 1083 FSTORE f11, (RISCV_FOFFSET + RISCV_FSIZE * 11)(a0) 1084 FSTORE f12, (RISCV_FOFFSET + RISCV_FSIZE * 12)(a0) 1085 FSTORE f13, (RISCV_FOFFSET + RISCV_FSIZE * 13)(a0) 1086 FSTORE f14, (RISCV_FOFFSET + RISCV_FSIZE * 14)(a0) 1087 FSTORE f15, (RISCV_FOFFSET + RISCV_FSIZE * 15)(a0) 1088 FSTORE f16, (RISCV_FOFFSET + RISCV_FSIZE * 16)(a0) 1089 FSTORE f17, (RISCV_FOFFSET + RISCV_FSIZE * 17)(a0) 1090 FSTORE f18, (RISCV_FOFFSET + RISCV_FSIZE * 18)(a0) 1091 FSTORE f19, (RISCV_FOFFSET + RISCV_FSIZE * 19)(a0) 1092 FSTORE f20, (RISCV_FOFFSET + RISCV_FSIZE * 20)(a0) 1093 FSTORE f21, (RISCV_FOFFSET + RISCV_FSIZE * 21)(a0) 1094 FSTORE f22, (RISCV_FOFFSET + RISCV_FSIZE * 22)(a0) 1095 FSTORE f23, (RISCV_FOFFSET + RISCV_FSIZE * 23)(a0) 1096 FSTORE f24, (RISCV_FOFFSET + RISCV_FSIZE * 24)(a0) 1097 FSTORE f25, (RISCV_FOFFSET + RISCV_FSIZE * 25)(a0) 1098 FSTORE f26, (RISCV_FOFFSET + RISCV_FSIZE * 26)(a0) 1099 FSTORE f27, (RISCV_FOFFSET + RISCV_FSIZE * 27)(a0) 1100 FSTORE f28, (RISCV_FOFFSET + RISCV_FSIZE * 28)(a0) 1101 FSTORE f29, (RISCV_FOFFSET + RISCV_FSIZE * 29)(a0) 1102 FSTORE f30, (RISCV_FOFFSET + RISCV_FSIZE * 30)(a0) 1103 FSTORE f31, (RISCV_FOFFSET + RISCV_FSIZE * 31)(a0) 1104# endif 1105 1106 li a0, 0 // return UNW_ESUCCESS 1107 ret // jump to ra 1108#endif 1109 1110 WEAK_ALIAS(__unw_getcontext, unw_getcontext) 1111 1112#endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */ 1113 1114NO_EXEC_STACK_DIRECTIVE 1115