RISC-V supports small immediates for some operations, let's use them.
Unified · Split
| @@ -794,8 +794,70 @@ static void gen_opil(int op, int ll) · 793 unmodified lines | |||
| 794 | { | 794 | { |
| 795 | int a, b, d; | 795 | int a, b, d; |
| 796 | int inv = 0; | 796 | int inv = 0; |
| 797 | int func3 = 0, func7 = 0; | 797 | int func3 = 0; |
| 798 | /* XXX We could special-case some constant args. */ | 798 | ll = ll ? 0 : 8; |
| 799 | if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { | ||
| 800 | int fc = vtop->c.i; | ||
| 801 | if (fc == vtop->c.i && !(((unsigned)fc + (1 << 11)) >> 12)) { | ||
| 802 | int cll = 0; | ||
| 803 | vswap(); | ||
| 804 | gv(RC_INT); | ||
| 805 | a = ireg(vtop[0].r); | ||
| 806 | --vtop; | ||
| 807 | d = get_reg(RC_INT); | ||
| 808 | ++vtop; | ||
| 809 | vswap(); | ||
| 810 | switch (op) { | ||
| 811 | case '-': | ||
| 812 | if (fc <= -(1 << 11)) | ||
| 813 | break; | ||
| 814 | fc = -fc; | ||
| 815 | case '+': | ||
| 816 | func3 = 0; // addi d, a, fc | ||
| 817 | do_cop: | ||
| 818 | EI(0x13 | cll, func3, ireg(d), a, fc); | ||
| 819 | --vtop; | ||
| 820 | vtop[0].r = d; | ||
| 821 | return; | ||
| 822 | case TOK_LE: | ||
| 823 | if (fc >= (1 << 11) - 1) | ||
| 824 | break; | ||
| 825 | ++fc; | ||
| 826 | case TOK_LT: func3 = 2; goto do_cop; // slti d, a, fc | ||
| 827 | case TOK_ULE: | ||
| 828 | if (fc >= (1 << 11) - 1) | ||
| 829 | break; | ||
| 830 | ++fc; | ||
| 831 | case TOK_ULT: func3 = 3; goto do_cop; // sltiu d, a, fc | ||
| 832 | case '^': func3 = 4; goto do_cop; // xori d, a, fc | ||
| 833 | case '|': func3 = 6; goto do_cop; // ori d, a, fc | ||
| 834 | case '&': func3 = 7; goto do_cop; // andi d, a, fc | ||
| 835 | case TOK_SHL: func3 = 1; fc &= 63; goto do_cop; // slli d, a, fc | ||
| 836 | case TOK_SHR: func3 = 5; cll = ll; fc &= 63; goto do_cop; // srli d, a, fc | ||
| 837 | case TOK_SAR: func3 = 5; cll = ll; fc = 1024 | (fc & 63); goto do_cop; | ||
| 838 | |||
| 839 | case TOK_UGE: | ||
| 840 | case TOK_UGT: | ||
| 841 | case TOK_GE: | ||
| 842 | case TOK_GT: | ||
| 843 | gen_opil(op - 1, ll); | ||
| 844 | EI(0x13, 4, ireg(vtop->r), ireg(vtop->r), 1);// xori d, d, 1 | ||
| 845 | return; | ||
| 846 | |||
| 847 | case TOK_NE: | ||
| 848 | case TOK_EQ: | ||
| 849 | if (fc) | ||
| 850 | gen_opil('-', ll), a = ireg(vtop++->r); | ||
| 851 | if (op == TOK_NE) | ||
| 852 | o(0x33 | (3 << 12) | (ireg(d) << 7) | (0 << 15) | (a << 20)); // sltu d, x0, a == snez d,a | ||
| 853 | else | ||
| 854 | EI(0x13, 3, ireg(d), a, 1); // sltiu d, a, 1 == seqz d,a | ||
| 855 | --vtop; | ||
| 856 | vtop[0].r = d; | ||
| 857 | return; | ||
| 858 | } | ||
| 859 | } | ||
| 860 | } | ||
| 799 | gv2(RC_INT, RC_INT); | 861 | gv2(RC_INT, RC_INT); |
| 800 | a = ireg(vtop[-1].r); | 862 | a = ireg(vtop[-1].r); |
| 801 | b = ireg(vtop[0].r); | 863 | b = ireg(vtop[0].r); |
| @@ -804,7 +866,6 @@ static void gen_opil(int op, int ll) · 2 unmodified lines | |||
| 804 | vtop++; | 866 | vtop++; |
| 805 | vtop[0].r = d; | 867 | vtop[0].r = d; |
| 806 | d = ireg(d); | 868 | d = ireg(d); |
| 807 | ll = ll ? 0 : 8; | ||
| 808 | switch (op) { | 869 | switch (op) { |
| 809 | default: | 870 | default: |
| 810 | tcc_error("implement me: %s(%s)", __FUNCTION__, get_tok_str(op, NULL)); | 871 | tcc_error("implement me: %s(%s)", __FUNCTION__, get_tok_str(op, NULL)); |
| @@ -2151,7 +2151,7 @@ static void gen_opic(int op) · 2150 unmodified lines | |||
| 2151 | } else { | 2151 | } else { |
| 2152 | /* if commutative ops, put c2 as constant */ | 2152 | /* if commutative ops, put c2 as constant */ |
| 2153 | if (c1 && (op == '+' || op == '&' || op == '^' || | 2153 | if (c1 && (op == '+' || op == '&' || op == '^' || |
| 2154 | op == '|' || op == '*')) { | 2154 | op == '|' || op == '*' || op == TOK_EQ || op == TOK_NE)) { |
| 2155 | vswap(); | 2155 | vswap(); |
| 2156 | c2 = c1; //c = c1, c1 = c2, c2 = c; | 2156 | c2 = c1; //c = c1, c1 = c2, c2 = c; |
| 2157 | l2 = l1; //l = l1, l1 = l2, l2 = l; | 2157 | l2 = l1; //l = l1, l1 = l2, l2 = l; |