Unified · Split
| @@ -632,9 +632,24 @@ void load(int r, SValue *sv) · 631 unmodified lines | |||
| 632 | if (fr & VT_SYM || !op) { | 632 | if (fr & VT_SYM || !op) { |
| 633 | o(0xE59F0000|(intr(r)<<12)); | 633 | o(0xE59F0000|(intr(r)<<12)); |
| 634 | o(0xEA000000); | 634 | o(0xEA000000); |
| 635 | if(fr & VT_SYM) | 635 | if(fr & VT_SYM) { |
| 636 | greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32); | 636 | if (sv->sym->type.t & VT_STATIC) { |
| 637 | o(sv->c.i); | 637 | greloc(cur_text_section, sv->sym, ind, R_ARM_REL32); |
| 638 | o(sv->c.i - 12); | ||
| 639 | o(0xe080000f | (intr(r)<<12) | (intr(r)<<16)); // add rx,rx,pc | ||
| 640 | } | ||
| 641 | else { | ||
| 642 | greloc(cur_text_section, sv->sym, ind, R_ARM_GOT_PREL); | ||
| 643 | o(-12); | ||
| 644 | o(0xe080000f | (intr(r)<<12) | (intr(r)<<16)); // add rx,rx,pc | ||
| 645 | o(0xe5900000 | (intr(r)<<12) | (intr(r)<<16)); // ldr rx,[rx] | ||
| 646 | if (sv->c.i) | ||
| 647 | stuff_const_harder(0xe2800000 | (intr(r)<<12) | (intr(r)<<16), | ||
| 648 | sv->c.i); | ||
| 649 | } | ||
| 650 | } | ||
| 651 | else | ||
| 652 | o(sv->c.i); | ||
| 638 | } else | 653 | } else |
| 639 | o(op); | 654 | o(op); |
| 640 | return; | 655 | return; |
| @@ -643,9 +658,24 @@ void load(int r, SValue *sv) · 2 unmodified lines | |||
| 643 | if (fr & VT_SYM || !op) { | 658 | if (fr & VT_SYM || !op) { |
| 644 | o(0xE59F0000|(intr(r)<<12)); | 659 | o(0xE59F0000|(intr(r)<<12)); |
| 645 | o(0xEA000000); | 660 | o(0xEA000000); |
| 646 | if(fr & VT_SYM) // needed ? | 661 | if(fr & VT_SYM) { |
| 647 | greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32); | 662 | if (sv->sym->type.t & VT_STATIC) { |
| 648 | o(sv->c.i); | 663 | greloc(cur_text_section, sv->sym, ind, R_ARM_REL32); |
| 664 | o(sv->c.i - 12); | ||
| 665 | o(0xe080000f | (intr(r)<<12) | (intr(r)<<16)); // add rx,rx,pc | ||
| 666 | } | ||
| 667 | else { | ||
| 668 | greloc(cur_text_section, sv->sym, ind, R_ARM_GOT_PREL); | ||
| 669 | o(-12); | ||
| 670 | o(0xe080000f | (intr(r)<<12) | (intr(r)<<16)); // add rx,rx,pc | ||
| 671 | o(0xe5900000 | (intr(r)<<12) | (intr(r)<<16)); // ldr rx,[rx] | ||
| 672 | if (sv->c.i) | ||
| 673 | stuff_const_harder(0xe2800000 | (intr(r)<<12) | (intr(r)<<16), | ||
| 674 | sv->c.i); | ||
| 675 | } | ||
| 676 | } | ||
| 677 | else | ||
| 678 | o(sv->c.i); | ||
| 649 | o(0xE08B0000|(intr(r)<<12)|intr(r)); | 679 | o(0xE08B0000|(intr(r)<<12)|intr(r)); |
| 650 | } else | 680 | } else |
| 651 | o(op); | 681 | o(op); |
| @@ -771,25 +801,41 @@ static void gcall_or_jmp(int is_jmp) · 119 unmodified lines | |||
| 771 | uint32_t x; | 801 | uint32_t x; |
| 772 | if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { | 802 | if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { |
| 773 | /* constant case */ | 803 | /* constant case */ |
| 774 | if(vtop->r & VT_SYM){ | 804 | if(vtop->r & VT_SYM){ |
| 775 | x=encbranch(ind,ind+vtop->c.i,0); | 805 | x=encbranch(ind,ind+vtop->c.i,0); |
| 776 | if(x) { | 806 | if(x) { |
| 777 | /* relocation case */ | 807 | /* relocation case */ |
| 778 | greloc(cur_text_section, vtop->sym, ind, R_ARM_PC24); | 808 | greloc(cur_text_section, vtop->sym, ind, R_ARM_PC24); |
| 779 | o(x|(is_jmp?0xE0000000:0xE1000000)); | 809 | o(x|(is_jmp?0xE0000000:0xE1000000)); |
| 780 | } else { | 810 | } else { |
| 781 | if(!is_jmp) | 811 | r = TREG_LR; |
| 782 | o(0xE28FE004); // add lr,pc,#4 | 812 | o(0xE59F0000|(intr(r)<<12)); // ldr r,[pc] |
| 783 | o(0xE51FF004); // ldr pc,[pc,#-4] | 813 | o(0xEA000000); // b $+4 |
| 784 | greloc(cur_text_section, vtop->sym, ind, R_ARM_ABS32); | 814 | if (vtop->sym->type.t & VT_STATIC) { |
| 785 | o(vtop->c.i); | 815 | greloc(cur_text_section, vtop->sym, ind, R_ARM_REL32); |
| 786 | } | 816 | o(vtop->c.i - 12); |
| 787 | }else{ | 817 | o(0xe080000f | (intr(r)<<12) | (intr(r)<<16)); // add rx,rx,pc |
| 788 | if(!is_jmp) | 818 | } |
| 789 | o(0xE28FE004); // add lr,pc,#4 | 819 | else { |
| 790 | o(0xE51FF004); // ldr pc,[pc,#-4] | 820 | greloc(cur_text_section, vtop->sym, ind, R_ARM_GOT_PREL); |
| 791 | o(vtop->c.i); | 821 | o(-12); |
| 822 | o(0xe080000f | (intr(r)<<12) | (intr(r)<<16)); // add r,r,pc | ||
| 823 | o(0xe5900000 | (intr(r)<<12) | (intr(r)<<16)); // ldr r,[r] | ||
| 824 | if (vtop->c.i) | ||
| 825 | stuff_const_harder(0xe2800000 | (intr(r)<<12) | (intr(r)<<16), | ||
| 826 | vtop->c.i); | ||
| 827 | } | ||
| 828 | if(is_jmp) | ||
| 829 | o(0xE1A0F000 | intr(r)); // mov pc, r | ||
| 830 | else | ||
| 831 | o(0xe12fff30 | intr(r)); // blx r | ||
| 792 | } | 832 | } |
| 833 | }else{ | ||
| 834 | if(!is_jmp) | ||
| 835 | o(0xE28FE004); // add lr,pc,#4 | ||
| 836 | o(0xE51FF004); // ldr pc,[pc,#-4] | ||
| 837 | o(vtop->c.i); | ||
| 838 | } | ||
| 793 | } else { | 839 | } else { |
| 794 | /* otherwise, indirect call */ | 840 | /* otherwise, indirect call */ |
| 795 | #ifdef CONFIG_TCC_BCHECK | 841 | #ifdef CONFIG_TCC_BCHECK |
| @@ -821,6 +867,7 @@ static void gen_bounds_prolog(void) · 25 unmodified lines | |||
| 821 | o(0xe1a00000); /* ld r0,lbounds_section->data_offset */ | 867 | o(0xe1a00000); /* ld r0,lbounds_section->data_offset */ |
| 822 | o(0xe1a00000); | 868 | o(0xe1a00000); |
| 823 | o(0xe1a00000); | 869 | o(0xe1a00000); |
| 870 | o(0xe1a00000); | ||
| 824 | o(0xe1a00000); /* call __bound_local_new */ | 871 | o(0xe1a00000); /* call __bound_local_new */ |
| 825 | } | 872 | } |
| 826 | 873 | ||
| @@ -847,8 +894,9 @@ static void gen_bounds_epilog(void) · 20 unmodified lines | |||
| 847 | ind = func_bound_ind; | 894 | ind = func_bound_ind; |
| 848 | o(0xe59f0000); /* ldr r0, [pc] */ | 895 | o(0xe59f0000); /* ldr r0, [pc] */ |
| 849 | o(0xea000000); /* b $+4 */ | 896 | o(0xea000000); /* b $+4 */ |
| 850 | greloc(cur_text_section, sym_data, ind, R_ARM_ABS32); | 897 | greloc(cur_text_section, sym_data, ind, R_ARM_REL32); |
| 851 | o(0x00000000); /* lbounds_section->data_offset */ | 898 | o(-12); /* lbounds_section->data_offset */ |
| 899 | o(0xe080000f); /* add r0,r0,pc */ | ||
| 852 | gen_bounds_call(TOK___bound_local_new); | 900 | gen_bounds_call(TOK___bound_local_new); |
| 853 | ind = saved_ind; | 901 | ind = saved_ind; |
| 854 | } | 902 | } |
| @@ -858,8 +906,9 @@ static void gen_bounds_epilog(void) · 3 unmodified lines | |||
| 858 | o(0xed2d0b02); /* vpush {d0} */ | 906 | o(0xed2d0b02); /* vpush {d0} */ |
| 859 | o(0xe59f0000); /* ldr r0, [pc] */ | 907 | o(0xe59f0000); /* ldr r0, [pc] */ |
| 860 | o(0xea000000); /* b $+4 */ | 908 | o(0xea000000); /* b $+4 */ |
| 861 | greloc(cur_text_section, sym_data, ind, R_ARM_ABS32); | 909 | greloc(cur_text_section, sym_data, ind, R_ARM_REL32); |
| 862 | o(0x00000000); /* lbounds_section->data_offset */ | 910 | o(-12); /* lbounds_section->data_offset */ |
| 911 | o(0xe080000f); /* add r0,r0,pc */ | ||
| 863 | gen_bounds_call(TOK___bound_local_delete); | 912 | gen_bounds_call(TOK___bound_local_delete); |
| 864 | o(0xecbd0b02); /* vpop {d0} */ | 913 | o(0xecbd0b02); /* vpop {d0} */ |
| 865 | o(0xe8bd0003); /* pop {r0,r1} */ | 914 | o(0xe8bd0003); /* pop {r0,r1} */ |