1//===-------------------- UnwindRegistersRestore.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__) 16DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_x866jumptoEv) 17# 18# void libunwind::Registers_x86::jumpto() 19# 20#if defined(_WIN32) 21# On windows, the 'this' pointer is passed in ecx instead of on the stack 22 movl %ecx, %eax 23#else 24# On entry: 25# + + 26# +-----------------------+ 27# + thread_state pointer + 28# +-----------------------+ 29# + return address + 30# +-----------------------+ <-- SP 31# + + 32 movl 4(%esp), %eax 33#endif 34 # set up eax and ret on new stack location 35 movl 28(%eax), %edx # edx holds new stack pointer 36 subl $8,%edx 37 movl %edx, 28(%eax) 38 movl 0(%eax), %ebx 39 movl %ebx, 0(%edx) 40 movl 40(%eax), %ebx 41 movl %ebx, 4(%edx) 42 # we now have ret and eax pushed onto where new stack will be 43 # restore all registers 44 movl 4(%eax), %ebx 45 movl 8(%eax), %ecx 46 movl 12(%eax), %edx 47 movl 16(%eax), %edi 48 movl 20(%eax), %esi 49 movl 24(%eax), %ebp 50 movl 28(%eax), %esp 51 # skip ss 52 # skip eflags 53 pop %eax # eax was already pushed on new stack 54 ret # eip was already pushed on new stack 55 # skip cs 56 # skip ds 57 # skip es 58 # skip fs 59 # skip gs 60 61#elif defined(__x86_64__) 62 63DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind16Registers_x86_646jumptoEv) 64# 65# void libunwind::Registers_x86_64::jumpto() 66# 67#if defined(_WIN64) 68# On entry, thread_state pointer is in rcx; move it into rdi 69# to share restore code below. Since this routine restores and 70# overwrites all registers, we can use the same registers for 71# pointers and temporaries as on unix even though win64 normally 72# mustn't clobber some of them. 73 movq %rcx, %rdi 74#else 75# On entry, thread_state pointer is in rdi 76#endif 77 78 movq 56(%rdi), %rax # rax holds new stack pointer 79 subq $16, %rax 80 movq %rax, 56(%rdi) 81 movq 32(%rdi), %rbx # store new rdi on new stack 82 movq %rbx, 0(%rax) 83 movq 128(%rdi), %rbx # store new rip on new stack 84 movq %rbx, 8(%rax) 85 # restore all registers 86 movq 0(%rdi), %rax 87 movq 8(%rdi), %rbx 88 movq 16(%rdi), %rcx 89 movq 24(%rdi), %rdx 90 # restore rdi later 91 movq 40(%rdi), %rsi 92 movq 48(%rdi), %rbp 93 # restore rsp later 94 movq 64(%rdi), %r8 95 movq 72(%rdi), %r9 96 movq 80(%rdi), %r10 97 movq 88(%rdi), %r11 98 movq 96(%rdi), %r12 99 movq 104(%rdi), %r13 100 movq 112(%rdi), %r14 101 movq 120(%rdi), %r15 102 # skip rflags 103 # skip cs 104 # skip fs 105 # skip gs 106 107#if defined(_WIN64) 108 movdqu 176(%rdi),%xmm0 109 movdqu 192(%rdi),%xmm1 110 movdqu 208(%rdi),%xmm2 111 movdqu 224(%rdi),%xmm3 112 movdqu 240(%rdi),%xmm4 113 movdqu 256(%rdi),%xmm5 114 movdqu 272(%rdi),%xmm6 115 movdqu 288(%rdi),%xmm7 116 movdqu 304(%rdi),%xmm8 117 movdqu 320(%rdi),%xmm9 118 movdqu 336(%rdi),%xmm10 119 movdqu 352(%rdi),%xmm11 120 movdqu 368(%rdi),%xmm12 121 movdqu 384(%rdi),%xmm13 122 movdqu 400(%rdi),%xmm14 123 movdqu 416(%rdi),%xmm15 124#endif 125 movq 56(%rdi), %rsp # cut back rsp to new location 126 pop %rdi # rdi was saved here earlier 127 ret # rip was saved here 128 129 130#elif defined(__powerpc64__) 131 132DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv) 133// 134// void libunwind::Registers_ppc64::jumpto() 135// 136// On entry: 137// thread_state pointer is in r3 138// 139 140// load register (GPR) 141#define PPC64_LR(n) \ 142 ld %r##n, (8 * (n + 2))(%r3) 143 144 // restore integral registers 145 // skip r0 for now 146 // skip r1 for now 147 PPC64_LR(2) 148 // skip r3 for now 149 // skip r4 for now 150 // skip r5 for now 151 PPC64_LR(6) 152 PPC64_LR(7) 153 PPC64_LR(8) 154 PPC64_LR(9) 155 PPC64_LR(10) 156 PPC64_LR(11) 157 PPC64_LR(12) 158 PPC64_LR(13) 159 PPC64_LR(14) 160 PPC64_LR(15) 161 PPC64_LR(16) 162 PPC64_LR(17) 163 PPC64_LR(18) 164 PPC64_LR(19) 165 PPC64_LR(20) 166 PPC64_LR(21) 167 PPC64_LR(22) 168 PPC64_LR(23) 169 PPC64_LR(24) 170 PPC64_LR(25) 171 PPC64_LR(26) 172 PPC64_LR(27) 173 PPC64_LR(28) 174 PPC64_LR(29) 175 PPC64_LR(30) 176 PPC64_LR(31) 177 178#ifdef PPC64_HAS_VMX 179 180 // restore VS registers 181 // (note that this also restores floating point registers and V registers, 182 // because part of VS is mapped to these registers) 183 184 addi %r4, %r3, PPC64_OFFS_FP 185 186// load VS register 187#define PPC64_LVS(n) \ 188 lxvd2x %vs##n, 0, %r4 ;\ 189 addi %r4, %r4, 16 190 191 // restore the first 32 VS regs (and also all floating point regs) 192 PPC64_LVS(0) 193 PPC64_LVS(1) 194 PPC64_LVS(2) 195 PPC64_LVS(3) 196 PPC64_LVS(4) 197 PPC64_LVS(5) 198 PPC64_LVS(6) 199 PPC64_LVS(7) 200 PPC64_LVS(8) 201 PPC64_LVS(9) 202 PPC64_LVS(10) 203 PPC64_LVS(11) 204 PPC64_LVS(12) 205 PPC64_LVS(13) 206 PPC64_LVS(14) 207 PPC64_LVS(15) 208 PPC64_LVS(16) 209 PPC64_LVS(17) 210 PPC64_LVS(18) 211 PPC64_LVS(19) 212 PPC64_LVS(20) 213 PPC64_LVS(21) 214 PPC64_LVS(22) 215 PPC64_LVS(23) 216 PPC64_LVS(24) 217 PPC64_LVS(25) 218 PPC64_LVS(26) 219 PPC64_LVS(27) 220 PPC64_LVS(28) 221 PPC64_LVS(29) 222 PPC64_LVS(30) 223 PPC64_LVS(31) 224 225 // use VRSAVE to conditionally restore the remaining VS regs, 226 // that are where the V regs are mapped 227 228 ld %r5, PPC64_OFFS_VRSAVE(%r3) // test VRsave 229 cmpwi %r5, 0 230 beq Lnovec 231 232// conditionally load VS 233#define PPC64_CLVS_BOTTOM(n) \ 234 beq Ldone##n ;\ 235 addi %r4, %r3, PPC64_OFFS_FP + n * 16 ;\ 236 lxvd2x %vs##n, 0, %r4 ;\ 237Ldone##n: 238 239#define PPC64_CLVSl(n) \ 240 andis. %r0, %r5, (1<<(47-n)) ;\ 241PPC64_CLVS_BOTTOM(n) 242 243#define PPC64_CLVSh(n) \ 244 andi. %r0, %r5, (1<<(63-n)) ;\ 245PPC64_CLVS_BOTTOM(n) 246 247 PPC64_CLVSl(32) 248 PPC64_CLVSl(33) 249 PPC64_CLVSl(34) 250 PPC64_CLVSl(35) 251 PPC64_CLVSl(36) 252 PPC64_CLVSl(37) 253 PPC64_CLVSl(38) 254 PPC64_CLVSl(39) 255 PPC64_CLVSl(40) 256 PPC64_CLVSl(41) 257 PPC64_CLVSl(42) 258 PPC64_CLVSl(43) 259 PPC64_CLVSl(44) 260 PPC64_CLVSl(45) 261 PPC64_CLVSl(46) 262 PPC64_CLVSl(47) 263 PPC64_CLVSh(48) 264 PPC64_CLVSh(49) 265 PPC64_CLVSh(50) 266 PPC64_CLVSh(51) 267 PPC64_CLVSh(52) 268 PPC64_CLVSh(53) 269 PPC64_CLVSh(54) 270 PPC64_CLVSh(55) 271 PPC64_CLVSh(56) 272 PPC64_CLVSh(57) 273 PPC64_CLVSh(58) 274 PPC64_CLVSh(59) 275 PPC64_CLVSh(60) 276 PPC64_CLVSh(61) 277 PPC64_CLVSh(62) 278 PPC64_CLVSh(63) 279 280#else 281 282// load FP register 283#define PPC64_LF(n) \ 284 lfd %f##n, (PPC64_OFFS_FP + n * 16)(%r3) 285 286 // restore float registers 287 PPC64_LF(0) 288 PPC64_LF(1) 289 PPC64_LF(2) 290 PPC64_LF(3) 291 PPC64_LF(4) 292 PPC64_LF(5) 293 PPC64_LF(6) 294 PPC64_LF(7) 295 PPC64_LF(8) 296 PPC64_LF(9) 297 PPC64_LF(10) 298 PPC64_LF(11) 299 PPC64_LF(12) 300 PPC64_LF(13) 301 PPC64_LF(14) 302 PPC64_LF(15) 303 PPC64_LF(16) 304 PPC64_LF(17) 305 PPC64_LF(18) 306 PPC64_LF(19) 307 PPC64_LF(20) 308 PPC64_LF(21) 309 PPC64_LF(22) 310 PPC64_LF(23) 311 PPC64_LF(24) 312 PPC64_LF(25) 313 PPC64_LF(26) 314 PPC64_LF(27) 315 PPC64_LF(28) 316 PPC64_LF(29) 317 PPC64_LF(30) 318 PPC64_LF(31) 319 320 // restore vector registers if any are in use 321 ld %r5, PPC64_OFFS_VRSAVE(%r3) // test VRsave 322 cmpwi %r5, 0 323 beq Lnovec 324 325 subi %r4, %r1, 16 326 // r4 is now a 16-byte aligned pointer into the red zone 327 // the _vectorScalarRegisters may not be 16-byte aligned 328 // so copy via red zone temp buffer 329 330#define PPC64_CLV_UNALIGNED_BOTTOM(n) \ 331 beq Ldone##n ;\ 332 ld %r0, (PPC64_OFFS_V + n * 16)(%r3) ;\ 333 std %r0, 0(%r4) ;\ 334 ld %r0, (PPC64_OFFS_V + n * 16 + 8)(%r3) ;\ 335 std %r0, 8(%r4) ;\ 336 lvx %v##n, 0, %r4 ;\ 337Ldone ## n: 338 339#define PPC64_CLV_UNALIGNEDl(n) \ 340 andis. %r0, %r5, (1<<(15-n)) ;\ 341PPC64_CLV_UNALIGNED_BOTTOM(n) 342 343#define PPC64_CLV_UNALIGNEDh(n) \ 344 andi. %r0, %r5, (1<<(31-n)) ;\ 345PPC64_CLV_UNALIGNED_BOTTOM(n) 346 347 PPC64_CLV_UNALIGNEDl(0) 348 PPC64_CLV_UNALIGNEDl(1) 349 PPC64_CLV_UNALIGNEDl(2) 350 PPC64_CLV_UNALIGNEDl(3) 351 PPC64_CLV_UNALIGNEDl(4) 352 PPC64_CLV_UNALIGNEDl(5) 353 PPC64_CLV_UNALIGNEDl(6) 354 PPC64_CLV_UNALIGNEDl(7) 355 PPC64_CLV_UNALIGNEDl(8) 356 PPC64_CLV_UNALIGNEDl(9) 357 PPC64_CLV_UNALIGNEDl(10) 358 PPC64_CLV_UNALIGNEDl(11) 359 PPC64_CLV_UNALIGNEDl(12) 360 PPC64_CLV_UNALIGNEDl(13) 361 PPC64_CLV_UNALIGNEDl(14) 362 PPC64_CLV_UNALIGNEDl(15) 363 PPC64_CLV_UNALIGNEDh(16) 364 PPC64_CLV_UNALIGNEDh(17) 365 PPC64_CLV_UNALIGNEDh(18) 366 PPC64_CLV_UNALIGNEDh(19) 367 PPC64_CLV_UNALIGNEDh(20) 368 PPC64_CLV_UNALIGNEDh(21) 369 PPC64_CLV_UNALIGNEDh(22) 370 PPC64_CLV_UNALIGNEDh(23) 371 PPC64_CLV_UNALIGNEDh(24) 372 PPC64_CLV_UNALIGNEDh(25) 373 PPC64_CLV_UNALIGNEDh(26) 374 PPC64_CLV_UNALIGNEDh(27) 375 PPC64_CLV_UNALIGNEDh(28) 376 PPC64_CLV_UNALIGNEDh(29) 377 PPC64_CLV_UNALIGNEDh(30) 378 PPC64_CLV_UNALIGNEDh(31) 379 380#endif 381 382Lnovec: 383 ld %r0, PPC64_OFFS_CR(%r3) 384 mtcr %r0 385 ld %r0, PPC64_OFFS_SRR0(%r3) 386 mtctr %r0 387 388 PPC64_LR(0) 389 PPC64_LR(5) 390 PPC64_LR(4) 391 PPC64_LR(1) 392 PPC64_LR(3) 393 bctr 394 395#elif defined(__ppc__) 396 397DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv) 398// 399// void libunwind::Registers_ppc::jumpto() 400// 401// On entry: 402// thread_state pointer is in r3 403// 404 405 // restore integral registerrs 406 // skip r0 for now 407 // skip r1 for now 408 lwz %r2, 16(%r3) 409 // skip r3 for now 410 // skip r4 for now 411 // skip r5 for now 412 lwz %r6, 32(%r3) 413 lwz %r7, 36(%r3) 414 lwz %r8, 40(%r3) 415 lwz %r9, 44(%r3) 416 lwz %r10, 48(%r3) 417 lwz %r11, 52(%r3) 418 lwz %r12, 56(%r3) 419 lwz %r13, 60(%r3) 420 lwz %r14, 64(%r3) 421 lwz %r15, 68(%r3) 422 lwz %r16, 72(%r3) 423 lwz %r17, 76(%r3) 424 lwz %r18, 80(%r3) 425 lwz %r19, 84(%r3) 426 lwz %r20, 88(%r3) 427 lwz %r21, 92(%r3) 428 lwz %r22, 96(%r3) 429 lwz %r23,100(%r3) 430 lwz %r24,104(%r3) 431 lwz %r25,108(%r3) 432 lwz %r26,112(%r3) 433 lwz %r27,116(%r3) 434 lwz %r28,120(%r3) 435 lwz %r29,124(%r3) 436 lwz %r30,128(%r3) 437 lwz %r31,132(%r3) 438 439 // restore float registers 440 lfd %f0, 160(%r3) 441 lfd %f1, 168(%r3) 442 lfd %f2, 176(%r3) 443 lfd %f3, 184(%r3) 444 lfd %f4, 192(%r3) 445 lfd %f5, 200(%r3) 446 lfd %f6, 208(%r3) 447 lfd %f7, 216(%r3) 448 lfd %f8, 224(%r3) 449 lfd %f9, 232(%r3) 450 lfd %f10,240(%r3) 451 lfd %f11,248(%r3) 452 lfd %f12,256(%r3) 453 lfd %f13,264(%r3) 454 lfd %f14,272(%r3) 455 lfd %f15,280(%r3) 456 lfd %f16,288(%r3) 457 lfd %f17,296(%r3) 458 lfd %f18,304(%r3) 459 lfd %f19,312(%r3) 460 lfd %f20,320(%r3) 461 lfd %f21,328(%r3) 462 lfd %f22,336(%r3) 463 lfd %f23,344(%r3) 464 lfd %f24,352(%r3) 465 lfd %f25,360(%r3) 466 lfd %f26,368(%r3) 467 lfd %f27,376(%r3) 468 lfd %f28,384(%r3) 469 lfd %f29,392(%r3) 470 lfd %f30,400(%r3) 471 lfd %f31,408(%r3) 472 473 // restore vector registers if any are in use 474 lwz %r5, 156(%r3) // test VRsave 475 cmpwi %r5, 0 476 beq Lnovec 477 478 subi %r4, %r1, 16 479 rlwinm %r4, %r4, 0, 0, 27 // mask low 4-bits 480 // r4 is now a 16-byte aligned pointer into the red zone 481 // the _vectorRegisters may not be 16-byte aligned so copy via red zone temp buffer 482 483 484#define LOAD_VECTOR_UNALIGNEDl(_index) \ 485 andis. %r0, %r5, (1<<(15-_index)) SEPARATOR \ 486 beq Ldone ## _index SEPARATOR \ 487 lwz %r0, 424+_index*16(%r3) SEPARATOR \ 488 stw %r0, 0(%r4) SEPARATOR \ 489 lwz %r0, 424+_index*16+4(%r3) SEPARATOR \ 490 stw %r0, 4(%r4) SEPARATOR \ 491 lwz %r0, 424+_index*16+8(%r3) SEPARATOR \ 492 stw %r0, 8(%r4) SEPARATOR \ 493 lwz %r0, 424+_index*16+12(%r3) SEPARATOR \ 494 stw %r0, 12(%r4) SEPARATOR \ 495 lvx %v ## _index, 0, %r4 SEPARATOR \ 496 Ldone ## _index: 497 498#define LOAD_VECTOR_UNALIGNEDh(_index) \ 499 andi. %r0, %r5, (1<<(31-_index)) SEPARATOR \ 500 beq Ldone ## _index SEPARATOR \ 501 lwz %r0, 424+_index*16(%r3) SEPARATOR \ 502 stw %r0, 0(%r4) SEPARATOR \ 503 lwz %r0, 424+_index*16+4(%r3) SEPARATOR \ 504 stw %r0, 4(%r4) SEPARATOR \ 505 lwz %r0, 424+_index*16+8(%r3) SEPARATOR \ 506 stw %r0, 8(%r4) SEPARATOR \ 507 lwz %r0, 424+_index*16+12(%r3) SEPARATOR \ 508 stw %r0, 12(%r4) SEPARATOR \ 509 lvx %v ## _index, 0, %r4 SEPARATOR \ 510 Ldone ## _index: 511 512 513 LOAD_VECTOR_UNALIGNEDl(0) 514 LOAD_VECTOR_UNALIGNEDl(1) 515 LOAD_VECTOR_UNALIGNEDl(2) 516 LOAD_VECTOR_UNALIGNEDl(3) 517 LOAD_VECTOR_UNALIGNEDl(4) 518 LOAD_VECTOR_UNALIGNEDl(5) 519 LOAD_VECTOR_UNALIGNEDl(6) 520 LOAD_VECTOR_UNALIGNEDl(7) 521 LOAD_VECTOR_UNALIGNEDl(8) 522 LOAD_VECTOR_UNALIGNEDl(9) 523 LOAD_VECTOR_UNALIGNEDl(10) 524 LOAD_VECTOR_UNALIGNEDl(11) 525 LOAD_VECTOR_UNALIGNEDl(12) 526 LOAD_VECTOR_UNALIGNEDl(13) 527 LOAD_VECTOR_UNALIGNEDl(14) 528 LOAD_VECTOR_UNALIGNEDl(15) 529 LOAD_VECTOR_UNALIGNEDh(16) 530 LOAD_VECTOR_UNALIGNEDh(17) 531 LOAD_VECTOR_UNALIGNEDh(18) 532 LOAD_VECTOR_UNALIGNEDh(19) 533 LOAD_VECTOR_UNALIGNEDh(20) 534 LOAD_VECTOR_UNALIGNEDh(21) 535 LOAD_VECTOR_UNALIGNEDh(22) 536 LOAD_VECTOR_UNALIGNEDh(23) 537 LOAD_VECTOR_UNALIGNEDh(24) 538 LOAD_VECTOR_UNALIGNEDh(25) 539 LOAD_VECTOR_UNALIGNEDh(26) 540 LOAD_VECTOR_UNALIGNEDh(27) 541 LOAD_VECTOR_UNALIGNEDh(28) 542 LOAD_VECTOR_UNALIGNEDh(29) 543 LOAD_VECTOR_UNALIGNEDh(30) 544 LOAD_VECTOR_UNALIGNEDh(31) 545 546Lnovec: 547 lwz %r0, 136(%r3) // __cr 548 mtcr %r0 549 lwz %r0, 148(%r3) // __ctr 550 mtctr %r0 551 lwz %r0, 0(%r3) // __ssr0 552 mtctr %r0 553 lwz %r0, 8(%r3) // do r0 now 554 lwz %r5, 28(%r3) // do r5 now 555 lwz %r4, 24(%r3) // do r4 now 556 lwz %r1, 12(%r3) // do sp now 557 lwz %r3, 20(%r3) // do r3 last 558 bctr 559 560#elif defined(__arm64__) || defined(__aarch64__) 561 562// 563// void libunwind::Registers_arm64::jumpto() 564// 565// On entry: 566// thread_state pointer is in x0 567// 568 .p2align 2 569DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_arm646jumptoEv) 570 // skip restore of x0,x1 for now 571 ldp x2, x3, [x0, #0x010] 572 ldp x4, x5, [x0, #0x020] 573 ldp x6, x7, [x0, #0x030] 574 ldp x8, x9, [x0, #0x040] 575 ldp x10,x11, [x0, #0x050] 576 ldp x12,x13, [x0, #0x060] 577 ldp x14,x15, [x0, #0x070] 578 // x16 and x17 were clobbered by the call into the unwinder, so no point in 579 // restoring them. 580 ldp x18,x19, [x0, #0x090] 581 ldp x20,x21, [x0, #0x0A0] 582 ldp x22,x23, [x0, #0x0B0] 583 ldp x24,x25, [x0, #0x0C0] 584 ldp x26,x27, [x0, #0x0D0] 585 ldp x28,x29, [x0, #0x0E0] 586 ldr x30, [x0, #0x100] // restore pc into lr 587 588 ldp d0, d1, [x0, #0x110] 589 ldp d2, d3, [x0, #0x120] 590 ldp d4, d5, [x0, #0x130] 591 ldp d6, d7, [x0, #0x140] 592 ldp d8, d9, [x0, #0x150] 593 ldp d10,d11, [x0, #0x160] 594 ldp d12,d13, [x0, #0x170] 595 ldp d14,d15, [x0, #0x180] 596 ldp d16,d17, [x0, #0x190] 597 ldp d18,d19, [x0, #0x1A0] 598 ldp d20,d21, [x0, #0x1B0] 599 ldp d22,d23, [x0, #0x1C0] 600 ldp d24,d25, [x0, #0x1D0] 601 ldp d26,d27, [x0, #0x1E0] 602 ldp d28,d29, [x0, #0x1F0] 603 ldr d30, [x0, #0x200] 604 ldr d31, [x0, #0x208] 605 606 // Finally, restore sp. This must be done after the the last read from the 607 // context struct, because it is allocated on the stack, and an exception 608 // could clobber the de-allocated portion of the stack after sp has been 609 // restored. 610 ldr x16, [x0, #0x0F8] 611 ldp x0, x1, [x0, #0x000] // restore x0,x1 612 mov sp,x16 // restore sp 613 ret x30 // jump to pc 614 615#elif defined(__arm__) && !defined(__APPLE__) 616 617#if !defined(__ARM_ARCH_ISA_ARM) 618#if (__ARM_ARCH_ISA_THUMB == 2) 619 .syntax unified 620#endif 621 .thumb 622#endif 623 624@ 625@ void libunwind::Registers_arm::restoreCoreAndJumpTo() 626@ 627@ On entry: 628@ thread_state pointer is in r0 629@ 630 .p2align 2 631DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm20restoreCoreAndJumpToEv) 632#if !defined(__ARM_ARCH_ISA_ARM) && __ARM_ARCH_ISA_THUMB == 1 633 @ r8-r11: ldm into r1-r4, then mov to r8-r11 634 adds r0, #0x20 635 ldm r0!, {r1-r4} 636 subs r0, #0x30 637 mov r8, r1 638 mov r9, r2 639 mov r10, r3 640 mov r11, r4 641 @ r12 does not need loading, it it the intra-procedure-call scratch register 642 ldr r2, [r0, #0x34] 643 ldr r3, [r0, #0x3c] 644 mov sp, r2 645 mov lr, r3 @ restore pc into lr 646 ldm r0, {r0-r7} 647#else 648 @ Use lr as base so that r0 can be restored. 649 mov lr, r0 650 @ 32bit thumb-2 restrictions for ldm: 651 @ . the sp (r13) cannot be in the list 652 @ . the pc (r15) and lr (r14) cannot both be in the list in an LDM instruction 653 ldm lr, {r0-r12} 654 ldr sp, [lr, #52] 655 ldr lr, [lr, #60] @ restore pc into lr 656#endif 657 JMP(lr) 658 659@ 660@ static void libunwind::Registers_arm::restoreVFPWithFLDMD(unw_fpreg_t* values) 661@ 662@ On entry: 663@ values pointer is in r0 664@ 665 .p2align 2 666#if defined(__ELF__) 667 .fpu vfpv3-d16 668#endif 669DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFLDMDEPv) 670 @ VFP and iwMMX instructions are only available when compiling with the flags 671 @ that enable them. We do not want to do that in the library (because we do not 672 @ want the compiler to generate instructions that access those) but this is 673 @ only accessed if the personality routine needs these registers. Use of 674 @ these registers implies they are, actually, available on the target, so 675 @ it's ok to execute. 676 @ So, generate the instruction using the corresponding coprocessor mnemonic. 677 vldmia r0, {d0-d15} 678 JMP(lr) 679 680@ 681@ static void libunwind::Registers_arm::restoreVFPWithFLDMX(unw_fpreg_t* values) 682@ 683@ On entry: 684@ values pointer is in r0 685@ 686 .p2align 2 687#if defined(__ELF__) 688 .fpu vfpv3-d16 689#endif 690DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFLDMXEPv) 691 vldmia r0, {d0-d15} @ fldmiax is deprecated in ARMv7+ and now behaves like vldmia 692 JMP(lr) 693 694@ 695@ static void libunwind::Registers_arm::restoreVFPv3(unw_fpreg_t* values) 696@ 697@ On entry: 698@ values pointer is in r0 699@ 700 .p2align 2 701#if defined(__ELF__) 702 .fpu vfpv3 703#endif 704DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm12restoreVFPv3EPv) 705 vldmia r0, {d16-d31} 706 JMP(lr) 707 708#if defined(__ARM_WMMX) 709 710@ 711@ static void libunwind::Registers_arm::restoreiWMMX(unw_fpreg_t* values) 712@ 713@ On entry: 714@ values pointer is in r0 715@ 716 .p2align 2 717#if defined(__ELF__) 718 .arch armv5te 719#endif 720DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm12restoreiWMMXEPv) 721 ldcl p1, cr0, [r0], #8 @ wldrd wR0, [r0], #8 722 ldcl p1, cr1, [r0], #8 @ wldrd wR1, [r0], #8 723 ldcl p1, cr2, [r0], #8 @ wldrd wR2, [r0], #8 724 ldcl p1, cr3, [r0], #8 @ wldrd wR3, [r0], #8 725 ldcl p1, cr4, [r0], #8 @ wldrd wR4, [r0], #8 726 ldcl p1, cr5, [r0], #8 @ wldrd wR5, [r0], #8 727 ldcl p1, cr6, [r0], #8 @ wldrd wR6, [r0], #8 728 ldcl p1, cr7, [r0], #8 @ wldrd wR7, [r0], #8 729 ldcl p1, cr8, [r0], #8 @ wldrd wR8, [r0], #8 730 ldcl p1, cr9, [r0], #8 @ wldrd wR9, [r0], #8 731 ldcl p1, cr10, [r0], #8 @ wldrd wR10, [r0], #8 732 ldcl p1, cr11, [r0], #8 @ wldrd wR11, [r0], #8 733 ldcl p1, cr12, [r0], #8 @ wldrd wR12, [r0], #8 734 ldcl p1, cr13, [r0], #8 @ wldrd wR13, [r0], #8 735 ldcl p1, cr14, [r0], #8 @ wldrd wR14, [r0], #8 736 ldcl p1, cr15, [r0], #8 @ wldrd wR15, [r0], #8 737 JMP(lr) 738 739@ 740@ static void libunwind::Registers_arm::restoreiWMMXControl(unw_uint32_t* values) 741@ 742@ On entry: 743@ values pointer is in r0 744@ 745 .p2align 2 746#if defined(__ELF__) 747 .arch armv5te 748#endif 749DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm19restoreiWMMXControlEPj) 750 ldc2 p1, cr8, [r0], #4 @ wldrw wCGR0, [r0], #4 751 ldc2 p1, cr9, [r0], #4 @ wldrw wCGR1, [r0], #4 752 ldc2 p1, cr10, [r0], #4 @ wldrw wCGR2, [r0], #4 753 ldc2 p1, cr11, [r0], #4 @ wldrw wCGR3, [r0], #4 754 JMP(lr) 755 756#endif 757 758#elif defined(__or1k__) 759 760DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind14Registers_or1k6jumptoEv) 761# 762# void libunwind::Registers_or1k::jumpto() 763# 764# On entry: 765# thread_state pointer is in r3 766# 767 768 # restore integral registers 769 l.lwz r0, 0(r3) 770 l.lwz r1, 4(r3) 771 l.lwz r2, 8(r3) 772 # skip r3 for now 773 l.lwz r4, 16(r3) 774 l.lwz r5, 20(r3) 775 l.lwz r6, 24(r3) 776 l.lwz r7, 28(r3) 777 l.lwz r8, 32(r3) 778 # skip r9 779 l.lwz r10, 40(r3) 780 l.lwz r11, 44(r3) 781 l.lwz r12, 48(r3) 782 l.lwz r13, 52(r3) 783 l.lwz r14, 56(r3) 784 l.lwz r15, 60(r3) 785 l.lwz r16, 64(r3) 786 l.lwz r17, 68(r3) 787 l.lwz r18, 72(r3) 788 l.lwz r19, 76(r3) 789 l.lwz r20, 80(r3) 790 l.lwz r21, 84(r3) 791 l.lwz r22, 88(r3) 792 l.lwz r23, 92(r3) 793 l.lwz r24, 96(r3) 794 l.lwz r25,100(r3) 795 l.lwz r26,104(r3) 796 l.lwz r27,108(r3) 797 l.lwz r28,112(r3) 798 l.lwz r29,116(r3) 799 l.lwz r30,120(r3) 800 l.lwz r31,124(r3) 801 802 # at last, restore r3 803 l.lwz r3, 12(r3) 804 805 # load new pc into ra 806 l.lwz r9, 128(r3) 807 # jump to pc 808 l.jr r9 809 l.nop 810 811#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 812 813// 814// void libunwind::Registers_mips_o32::jumpto() 815// 816// On entry: 817// thread state pointer is in a0 ($4) 818// 819DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind18Registers_mips_o326jumptoEv) 820 .set push 821 .set noat 822 .set noreorder 823 .set nomacro 824#ifdef __mips_hard_float 825#if __mips_fpr != 64 826 ldc1 $f0, (4 * 36 + 8 * 0)($4) 827 ldc1 $f2, (4 * 36 + 8 * 2)($4) 828 ldc1 $f4, (4 * 36 + 8 * 4)($4) 829 ldc1 $f6, (4 * 36 + 8 * 6)($4) 830 ldc1 $f8, (4 * 36 + 8 * 8)($4) 831 ldc1 $f10, (4 * 36 + 8 * 10)($4) 832 ldc1 $f12, (4 * 36 + 8 * 12)($4) 833 ldc1 $f14, (4 * 36 + 8 * 14)($4) 834 ldc1 $f16, (4 * 36 + 8 * 16)($4) 835 ldc1 $f18, (4 * 36 + 8 * 18)($4) 836 ldc1 $f20, (4 * 36 + 8 * 20)($4) 837 ldc1 $f22, (4 * 36 + 8 * 22)($4) 838 ldc1 $f24, (4 * 36 + 8 * 24)($4) 839 ldc1 $f26, (4 * 36 + 8 * 26)($4) 840 ldc1 $f28, (4 * 36 + 8 * 28)($4) 841 ldc1 $f30, (4 * 36 + 8 * 30)($4) 842#else 843 ldc1 $f0, (4 * 36 + 8 * 0)($4) 844 ldc1 $f1, (4 * 36 + 8 * 1)($4) 845 ldc1 $f2, (4 * 36 + 8 * 2)($4) 846 ldc1 $f3, (4 * 36 + 8 * 3)($4) 847 ldc1 $f4, (4 * 36 + 8 * 4)($4) 848 ldc1 $f5, (4 * 36 + 8 * 5)($4) 849 ldc1 $f6, (4 * 36 + 8 * 6)($4) 850 ldc1 $f7, (4 * 36 + 8 * 7)($4) 851 ldc1 $f8, (4 * 36 + 8 * 8)($4) 852 ldc1 $f9, (4 * 36 + 8 * 9)($4) 853 ldc1 $f10, (4 * 36 + 8 * 10)($4) 854 ldc1 $f11, (4 * 36 + 8 * 11)($4) 855 ldc1 $f12, (4 * 36 + 8 * 12)($4) 856 ldc1 $f13, (4 * 36 + 8 * 13)($4) 857 ldc1 $f14, (4 * 36 + 8 * 14)($4) 858 ldc1 $f15, (4 * 36 + 8 * 15)($4) 859 ldc1 $f16, (4 * 36 + 8 * 16)($4) 860 ldc1 $f17, (4 * 36 + 8 * 17)($4) 861 ldc1 $f18, (4 * 36 + 8 * 18)($4) 862 ldc1 $f19, (4 * 36 + 8 * 19)($4) 863 ldc1 $f20, (4 * 36 + 8 * 20)($4) 864 ldc1 $f21, (4 * 36 + 8 * 21)($4) 865 ldc1 $f22, (4 * 36 + 8 * 22)($4) 866 ldc1 $f23, (4 * 36 + 8 * 23)($4) 867 ldc1 $f24, (4 * 36 + 8 * 24)($4) 868 ldc1 $f25, (4 * 36 + 8 * 25)($4) 869 ldc1 $f26, (4 * 36 + 8 * 26)($4) 870 ldc1 $f27, (4 * 36 + 8 * 27)($4) 871 ldc1 $f28, (4 * 36 + 8 * 28)($4) 872 ldc1 $f29, (4 * 36 + 8 * 29)($4) 873 ldc1 $f30, (4 * 36 + 8 * 30)($4) 874 ldc1 $f31, (4 * 36 + 8 * 31)($4) 875#endif 876#endif 877 // restore hi and lo 878 lw $8, (4 * 33)($4) 879 mthi $8 880 lw $8, (4 * 34)($4) 881 mtlo $8 882 // r0 is zero 883 lw $1, (4 * 1)($4) 884 lw $2, (4 * 2)($4) 885 lw $3, (4 * 3)($4) 886 // skip a0 for now 887 lw $5, (4 * 5)($4) 888 lw $6, (4 * 6)($4) 889 lw $7, (4 * 7)($4) 890 lw $8, (4 * 8)($4) 891 lw $9, (4 * 9)($4) 892 lw $10, (4 * 10)($4) 893 lw $11, (4 * 11)($4) 894 lw $12, (4 * 12)($4) 895 lw $13, (4 * 13)($4) 896 lw $14, (4 * 14)($4) 897 lw $15, (4 * 15)($4) 898 lw $16, (4 * 16)($4) 899 lw $17, (4 * 17)($4) 900 lw $18, (4 * 18)($4) 901 lw $19, (4 * 19)($4) 902 lw $20, (4 * 20)($4) 903 lw $21, (4 * 21)($4) 904 lw $22, (4 * 22)($4) 905 lw $23, (4 * 23)($4) 906 lw $24, (4 * 24)($4) 907 lw $25, (4 * 25)($4) 908 lw $26, (4 * 26)($4) 909 lw $27, (4 * 27)($4) 910 lw $28, (4 * 28)($4) 911 lw $29, (4 * 29)($4) 912 lw $30, (4 * 30)($4) 913 // load new pc into ra 914 lw $31, (4 * 32)($4) 915 // jump to ra, load a0 in the delay slot 916 jr $31 917 lw $4, (4 * 4)($4) 918 .set pop 919 920#elif defined(__mips64) 921 922// 923// void libunwind::Registers_mips_newabi::jumpto() 924// 925// On entry: 926// thread state pointer is in a0 ($4) 927// 928DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind21Registers_mips_newabi6jumptoEv) 929 .set push 930 .set noat 931 .set noreorder 932 .set nomacro 933#ifdef __mips_hard_float 934 ldc1 $f0, (8 * 35)($4) 935 ldc1 $f1, (8 * 36)($4) 936 ldc1 $f2, (8 * 37)($4) 937 ldc1 $f3, (8 * 38)($4) 938 ldc1 $f4, (8 * 39)($4) 939 ldc1 $f5, (8 * 40)($4) 940 ldc1 $f6, (8 * 41)($4) 941 ldc1 $f7, (8 * 42)($4) 942 ldc1 $f8, (8 * 43)($4) 943 ldc1 $f9, (8 * 44)($4) 944 ldc1 $f10, (8 * 45)($4) 945 ldc1 $f11, (8 * 46)($4) 946 ldc1 $f12, (8 * 47)($4) 947 ldc1 $f13, (8 * 48)($4) 948 ldc1 $f14, (8 * 49)($4) 949 ldc1 $f15, (8 * 50)($4) 950 ldc1 $f16, (8 * 51)($4) 951 ldc1 $f17, (8 * 52)($4) 952 ldc1 $f18, (8 * 53)($4) 953 ldc1 $f19, (8 * 54)($4) 954 ldc1 $f20, (8 * 55)($4) 955 ldc1 $f21, (8 * 56)($4) 956 ldc1 $f22, (8 * 57)($4) 957 ldc1 $f23, (8 * 58)($4) 958 ldc1 $f24, (8 * 59)($4) 959 ldc1 $f25, (8 * 60)($4) 960 ldc1 $f26, (8 * 61)($4) 961 ldc1 $f27, (8 * 62)($4) 962 ldc1 $f28, (8 * 63)($4) 963 ldc1 $f29, (8 * 64)($4) 964 ldc1 $f30, (8 * 65)($4) 965 ldc1 $f31, (8 * 66)($4) 966#endif 967 // restore hi and lo 968 ld $8, (8 * 33)($4) 969 mthi $8 970 ld $8, (8 * 34)($4) 971 mtlo $8 972 // r0 is zero 973 ld $1, (8 * 1)($4) 974 ld $2, (8 * 2)($4) 975 ld $3, (8 * 3)($4) 976 // skip a0 for now 977 ld $5, (8 * 5)($4) 978 ld $6, (8 * 6)($4) 979 ld $7, (8 * 7)($4) 980 ld $8, (8 * 8)($4) 981 ld $9, (8 * 9)($4) 982 ld $10, (8 * 10)($4) 983 ld $11, (8 * 11)($4) 984 ld $12, (8 * 12)($4) 985 ld $13, (8 * 13)($4) 986 ld $14, (8 * 14)($4) 987 ld $15, (8 * 15)($4) 988 ld $16, (8 * 16)($4) 989 ld $17, (8 * 17)($4) 990 ld $18, (8 * 18)($4) 991 ld $19, (8 * 19)($4) 992 ld $20, (8 * 20)($4) 993 ld $21, (8 * 21)($4) 994 ld $22, (8 * 22)($4) 995 ld $23, (8 * 23)($4) 996 ld $24, (8 * 24)($4) 997 ld $25, (8 * 25)($4) 998 ld $26, (8 * 26)($4) 999 ld $27, (8 * 27)($4) 1000 ld $28, (8 * 28)($4) 1001 ld $29, (8 * 29)($4) 1002 ld $30, (8 * 30)($4) 1003 // load new pc into ra 1004 ld $31, (8 * 32)($4) 1005 // jump to ra, load a0 in the delay slot 1006 jr $31 1007 ld $4, (8 * 4)($4) 1008 .set pop 1009 1010#elif defined(__sparc__) 1011 1012// 1013// void libunwind::Registers_sparc_o32::jumpto() 1014// 1015// On entry: 1016// thread_state pointer is in o0 1017// 1018DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_sparc6jumptoEv) 1019 ta 3 1020 ldd [%o0 + 64], %l0 1021 ldd [%o0 + 72], %l2 1022 ldd [%o0 + 80], %l4 1023 ldd [%o0 + 88], %l6 1024 ldd [%o0 + 96], %i0 1025 ldd [%o0 + 104], %i2 1026 ldd [%o0 + 112], %i4 1027 ldd [%o0 + 120], %i6 1028 ld [%o0 + 60], %o7 1029 jmp %o7 1030 nop 1031 1032#elif defined(__riscv) && __riscv_xlen == 64 1033 1034// 1035// void libunwind::Registers_riscv::jumpto() 1036// 1037// On entry: 1038// thread_state pointer is in a0 1039// 1040 .p2align 2 1041DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_riscv6jumptoEv) 1042#if defined(__riscv_flen) && __riscv_flen == 64 1043 fld f0, (8 * 32 + 8 * 0)(a0) 1044 fld f1, (8 * 32 + 8 * 1)(a0) 1045 fld f2, (8 * 32 + 8 * 2)(a0) 1046 fld f3, (8 * 32 + 8 * 3)(a0) 1047 fld f4, (8 * 32 + 8 * 4)(a0) 1048 fld f5, (8 * 32 + 8 * 5)(a0) 1049 fld f6, (8 * 32 + 8 * 6)(a0) 1050 fld f7, (8 * 32 + 8 * 7)(a0) 1051 fld f8, (8 * 32 + 8 * 8)(a0) 1052 fld f9, (8 * 32 + 8 * 9)(a0) 1053 fld f10, (8 * 32 + 8 * 10)(a0) 1054 fld f11, (8 * 32 + 8 * 11)(a0) 1055 fld f12, (8 * 32 + 8 * 12)(a0) 1056 fld f13, (8 * 32 + 8 * 13)(a0) 1057 fld f14, (8 * 32 + 8 * 14)(a0) 1058 fld f15, (8 * 32 + 8 * 15)(a0) 1059 fld f16, (8 * 32 + 8 * 16)(a0) 1060 fld f17, (8 * 32 + 8 * 17)(a0) 1061 fld f18, (8 * 32 + 8 * 18)(a0) 1062 fld f19, (8 * 32 + 8 * 19)(a0) 1063 fld f20, (8 * 32 + 8 * 20)(a0) 1064 fld f21, (8 * 32 + 8 * 21)(a0) 1065 fld f22, (8 * 32 + 8 * 22)(a0) 1066 fld f23, (8 * 32 + 8 * 23)(a0) 1067 fld f24, (8 * 32 + 8 * 24)(a0) 1068 fld f25, (8 * 32 + 8 * 25)(a0) 1069 fld f26, (8 * 32 + 8 * 26)(a0) 1070 fld f27, (8 * 32 + 8 * 27)(a0) 1071 fld f28, (8 * 32 + 8 * 28)(a0) 1072 fld f29, (8 * 32 + 8 * 29)(a0) 1073 fld f30, (8 * 32 + 8 * 30)(a0) 1074 fld f31, (8 * 32 + 8 * 31)(a0) 1075#endif 1076 1077 // x0 is zero 1078 ld x1, (8 * 1)(a0) 1079 ld x2, (8 * 2)(a0) 1080 ld x3, (8 * 3)(a0) 1081 ld x4, (8 * 4)(a0) 1082 ld x5, (8 * 5)(a0) 1083 ld x6, (8 * 6)(a0) 1084 ld x7, (8 * 7)(a0) 1085 ld x8, (8 * 8)(a0) 1086 ld x9, (8 * 9)(a0) 1087 // skip a0 for now 1088 ld x11, (8 * 11)(a0) 1089 ld x12, (8 * 12)(a0) 1090 ld x13, (8 * 13)(a0) 1091 ld x14, (8 * 14)(a0) 1092 ld x15, (8 * 15)(a0) 1093 ld x16, (8 * 16)(a0) 1094 ld x17, (8 * 17)(a0) 1095 ld x18, (8 * 18)(a0) 1096 ld x19, (8 * 19)(a0) 1097 ld x20, (8 * 20)(a0) 1098 ld x21, (8 * 21)(a0) 1099 ld x22, (8 * 22)(a0) 1100 ld x23, (8 * 23)(a0) 1101 ld x24, (8 * 24)(a0) 1102 ld x25, (8 * 25)(a0) 1103 ld x26, (8 * 26)(a0) 1104 ld x27, (8 * 27)(a0) 1105 ld x28, (8 * 28)(a0) 1106 ld x29, (8 * 29)(a0) 1107 ld x30, (8 * 30)(a0) 1108 ld x31, (8 * 31)(a0) 1109 ld x10, (8 * 10)(a0) // restore a0 1110 1111 ret // jump to ra 1112 1113#endif 1114 1115#endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */ 1116 1117NO_EXEC_STACK_DIRECTIVE 1118 1119