History

riscv: Add special cases for const operands

RISC-V supports small immediates for some operations, let's use them.

Michael Matz committed 7 years ago

Commit d5bb4071 parent f8d80462 files · +65 −4Browse files

Unified · Split

2 files
  1. riscv64-gen.c +64 −3
  2. tccgen.c +1 −1
riscv64-gen.c+64−3
@@ -794,8 +794,70 @@ static void gen_opil(int op, int ll) · 793 unmodified lines
794794 {
795795 int a, b, d;
796796 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+ }
799861 gv2(RC_INT, RC_INT);
800862 a = ireg(vtop[-1].r);
801863 b = ireg(vtop[0].r);
@@ -804,7 +866,6 @@ static void gen_opil(int op, int ll) · 2 unmodified lines
804866 vtop++;
805867 vtop[0].r = d;
806868 d = ireg(d);
807− ll = ll ? 0 : 8;
808869 switch (op) {
809870 default:
810871 tcc_error("implement me: %s(%s)", __FUNCTION__, get_tok_str(op, NULL));
tccgen.c+1−1
@@ -2151,7 +2151,7 @@ static void gen_opic(int op) · 2150 unmodified lines
21512151 } else {
21522152 /* if commutative ops, put c2 as constant */
21532153 if (c1 && (op == '+' || op == '&' || op == '^' ||
2154− op == '|' || op == '*')) {
2154+ op == '|' || op == '*' || op == TOK_EQ || op == TOK_NE)) {
21552155 vswap();
21562156 c2 = c1; //c = c1, c1 = c2, c2 = c;
21572157 l2 = l1; //l = l1, l1 = l2, l2 = l;