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 | 795 | int a, b, d; |
| 796 | 796 | int inv = 0; |
| 797 | − int func3 = 0, func7 = 0; | |
| 798 | − /* XXX We could special-case some constant args. */ | |
| 797 | + int func3 = 0; | |
| 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 | 861 | gv2(RC_INT, RC_INT); |
| 800 | 862 | a = ireg(vtop[-1].r); |
| 801 | 863 | b = ireg(vtop[0].r); |
| @@ -804,7 +866,6 @@ static void gen_opil(int op, int ll) · 2 unmodified lines | ||
| 804 | 866 | vtop++; |
| 805 | 867 | vtop[0].r = d; |
| 806 | 868 | d = ireg(d); |
| 807 | − ll = ll ? 0 : 8; | |
| 808 | 869 | switch (op) { |
| 809 | 870 | default: |
| 810 | 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 | 2151 | } else { |
| 2152 | 2152 | /* if commutative ops, put c2 as constant */ |
| 2153 | 2153 | if (c1 && (op == '+' || op == '&' || op == '^' || |
| 2154 | − op == '|' || op == '*')) { | |
| 2154 | + op == '|' || op == '*' || op == TOK_EQ || op == TOK_NE)) { | |
| 2155 | 2155 | vswap(); |
| 2156 | 2156 | c2 = c1; //c = c1, c1 = c2, c2 = c; |
| 2157 | 2157 | l2 = l1; //l = l1, l1 = l2, l2 = l; |