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