| @@ -552,6 +552,23 @@ ST_FUNC void load(int r, SValue *sv) · 551 unmodified lines |
| 552 | 552 | } |
| 553 | 553 | |
| 554 | 554 | if (svr == (VT_CONST | VT_LVAL | VT_SYM)) { |
| 555 | + if (sv->sym->type.t & VT_TLS) { |
| 556 | + o(0xd53bd05e); /* mrs x30, tpidr_el0 */ |
| 557 | + greloca(cur_text_section, sv->sym, ind, |
| 558 | + R_AARCH64_TLSLE_ADD_TPREL_HI12, 0); |
| 559 | + o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_SH(1) | |
| 560 | + ARM64_RN(30) | ARM64_RD(30)); /* add x30, x30, #0, lsl #12 */ |
| 561 | + greloca(cur_text_section, sv->sym, ind, |
| 562 | + R_AARCH64_TLSLE_ADD_TPREL_LO12, 0); |
| 563 | + o(ARM64_ADD_IMM | ARM64_SF(1) | |
| 564 | + ARM64_RN(30) | ARM64_RD(30)); /* add x30, x30, #0 */ |
| 565 | + if (IS_FREG(r)) |
| 566 | + arm64_ldrv(arm64_type_size(svtt), fltr(r), 30, svcoff); |
| 567 | + else |
| 568 | + arm64_ldrx(!(svtt&VT_UNSIGNED), arm64_type_size(svtt), |
| 569 | + intr(r), 30, svcoff); |
| 570 | + return; |
| 571 | + } |
| 555 | 572 | arm64_sym(30, sv->sym, // use x30 for address |
| 556 | 573 | arm64_check_offset(0, arm64_type_size(svtt), svcoff)); |
| 557 | 574 | if (IS_FREG(r)) |
| @@ -645,6 +662,22 @@ ST_FUNC void store(int r, SValue *sv) · 87 unmodified lines |
| 645 | 662 | if (svr == (VT_CONST | VT_LVAL)) { |
| 646 | 663 | uint64_t i = sv->c.i; |
| 647 | 664 | |
| 665 | + if (sv->sym && (sv->sym->type.t & VT_TLS)) { |
| 666 | + o(0xd53bd05e); |
| 667 | + greloca(cur_text_section, sv->sym, ind, |
| 668 | + R_AARCH64_TLSLE_ADD_TPREL_HI12, 0); |
| 669 | + o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_SH(1) | |
| 670 | + ARM64_RN(30) | ARM64_RD(30)); |
| 671 | + greloca(cur_text_section, sv->sym, ind, |
| 672 | + R_AARCH64_TLSLE_ADD_TPREL_LO12, 0); |
| 673 | + o(ARM64_ADD_IMM | ARM64_SF(1) | |
| 674 | + ARM64_RN(30) | ARM64_RD(30)); |
| 675 | + if (IS_FREG(r)) |
| 676 | + arm64_strv(arm64_type_size(svtt), fltr(r), 30, i); |
| 677 | + else |
| 678 | + arm64_strx(arm64_type_size(svtt), intr(r), 30, i); |
| 679 | + return; |
| 680 | + } |
| 648 | 681 | if (sv->sym) |
| 649 | 682 | arm64_sym(30, sv->sym, // use x30 for address |
| 650 | 683 | arm64_check_offset(0, arm64_type_size(svtt), i)); |
| @@ -668,6 +701,22 @@ ST_FUNC void store(int r, SValue *sv) · 17 unmodified lines |
| 668 | 701 | } |
| 669 | 702 | |
| 670 | 703 | if (svr == (VT_CONST | VT_LVAL | VT_SYM)) { |
| 704 | + if (sv->sym->type.t & VT_TLS) { |
| 705 | + o(0xd53bd05e); /* mrs x30, tpidr_el0 */ |
| 706 | + greloca(cur_text_section, sv->sym, ind, |
| 707 | + R_AARCH64_TLSLE_ADD_TPREL_HI12, 0); |
| 708 | + o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_SH(1) | |
| 709 | + ARM64_RN(30) | ARM64_RD(30)); /* add x30, x30, #0, lsl #12 */ |
| 710 | + greloca(cur_text_section, sv->sym, ind, |
| 711 | + R_AARCH64_TLSLE_ADD_TPREL_LO12, 0); |
| 712 | + o(ARM64_ADD_IMM | ARM64_SF(1) | |
| 713 | + ARM64_RN(30) | ARM64_RD(30)); /* add x30, x30, #0 */ |
| 714 | + if (IS_FREG(r)) |
| 715 | + arm64_strv(arm64_type_size(svtt), fltr(r), 30, svcoff); |
| 716 | + else |
| 717 | + arm64_strx(arm64_type_size(svtt), intr(r), 30, svcoff); |
| 718 | + return; |
| 719 | + } |
| 671 | 720 | arm64_sym(30, sv->sym, // use x30 for address |
| 672 | 721 | arm64_check_offset(0, arm64_type_size(svtt), svcoff)); |
| 673 | 722 | if (IS_FREG(r)) |