| @@ -552,6 +552,23 @@ ST_FUNC void load(int r, SValue *sv) · 551 unmodified lines |
| 552 | } | 552 | } |
| 553 | | 553 | |
| 554 | if (svr == (VT_CONST | VT_LVAL | VT_SYM)) { | 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 | arm64_sym(30, sv->sym, // use x30 for address | 572 | arm64_sym(30, sv->sym, // use x30 for address |
| 556 | arm64_check_offset(0, arm64_type_size(svtt), svcoff)); | 573 | arm64_check_offset(0, arm64_type_size(svtt), svcoff)); |
| 557 | if (IS_FREG(r)) | 574 | if (IS_FREG(r)) |
| @@ -645,6 +662,22 @@ ST_FUNC void store(int r, SValue *sv) · 87 unmodified lines |
| 645 | if (svr == (VT_CONST | VT_LVAL)) { | 662 | if (svr == (VT_CONST | VT_LVAL)) { |
| 646 | uint64_t i = sv->c.i; | 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 | if (sv->sym) | 681 | if (sv->sym) |
| 649 | arm64_sym(30, sv->sym, // use x30 for address | 682 | arm64_sym(30, sv->sym, // use x30 for address |
| 650 | arm64_check_offset(0, arm64_type_size(svtt), i)); | 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 | if (svr == (VT_CONST | VT_LVAL | VT_SYM)) { | 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 | arm64_sym(30, sv->sym, // use x30 for address | 720 | arm64_sym(30, sv->sym, // use x30 for address |
| 672 | arm64_check_offset(0, arm64_type_size(svtt), svcoff)); | 721 | arm64_check_offset(0, arm64_type_size(svtt), svcoff)); |
| 673 | if (IS_FREG(r)) | 722 | if (IS_FREG(r)) |