History

riscv: Optimize compares

don't convert to 1/0 prematurely, we can save enough info in the VT_CMP metadata to be usable for the gtst branch expansion.

Michael Matz committed 7 years ago

Commit 91e297a1 parent 48ba22c1 file · +66 −47Browse files

Unified · Split

riscv64-gen.c+66−47
@@ -285,8 +285,42 @@ ST_FUNC void load(int r, SValue *sv) · 284 unmodified lines
285285 o(0x53 | (rr << 7) | ((is_freg(v) ? freg(v) : ireg(v)) << 15)
286286 | (func7 << 25)); // fmv.{w.x, x.w, d.x, x.d} RR, VR
287287 }
288− } else if (v == VT_CMP) { // we rely on cmp_r to be the correct result
289− EI(0x13, 0, rr, vtop->cmp_r, 0); // mv RR, CMP_R
288+ } else if (v == VT_CMP) {
289+ int op = vtop->cmp_op;
290+ int a = vtop->cmp_r & 0xff;
291+ int b = (vtop->cmp_r >> 8) & 0xff;
292+ int inv = 0;
293+ switch (op) {
294+ case TOK_ULT:
295+ case TOK_UGE:
296+ case TOK_ULE:
297+ case TOK_UGT:
298+ case TOK_LT:
299+ case TOK_GE:
300+ case TOK_LE:
301+ case TOK_GT:
302+ if (op & 1) { // remove [U]GE,GT
303+ inv = 1;
304+ op--;
305+ }
306+ if ((op & 7) == 6) { // [U]LE
307+ int t = a; a = b; b = t;
308+ inv ^= 1;
309+ }
310+ ER(0x33, (op > TOK_UGT) ? 2 : 3, rr, a, b, 0); // slt[u] d, a, b
311+ if (inv)
312+ EI(0x13, 4, rr, rr, 1); // xori d, d, 1
313+ break;
314+ case TOK_NE:
315+ case TOK_EQ:
316+ if (rr != a || b)
317+ ER(0x33, 0, rr, a, b, 0x20); // sub d, a, b
318+ if (op == TOK_NE)
319+ ER(0x33, 3, rr, 0, rr, 0); // sltu d, x0, d == snez d,d
320+ else
321+ EI(0x13, 3, rr, rr, 1); // sltiu d, d, 1 == seqz d,d
322+ break;
323+ }
290324 } else if ((v & ~1) == VT_JMP) {
291325 int t = v & 1;
292326 assert(is_ireg(r));
@@ -775,10 +809,22 @@ ST_FUNC void gjmp_addr(int a) · 482 unmodified lines
775809
776810 ST_FUNC int gjmp_cond(int op, int t)
777811 {
778− int inv = op & 1;
779− assert(op == TOK_EQ || op == TOK_NE);
780− assert(vtop->cmp_r >= 10 && vtop->cmp_r < 18);
781− o(0x63 | (!inv << 12) | (vtop->cmp_r << 15) | (8 << 7)); // bne/beq x0,r,+4
812+ int tmp;
813+ int a = vtop->cmp_r & 0xff;
814+ int b = (vtop->cmp_r >> 8) & 0xff;
815+ switch (op) {
816+ case TOK_ULT: op = 6; break;
817+ case TOK_UGE: op = 7; break;
818+ case TOK_ULE: op = 7; tmp = a; a = b; b = tmp; break;
819+ case TOK_UGT: op = 6; tmp = a; a = b; b = tmp; break;
820+ case TOK_LT: op = 4; break;
821+ case TOK_GE: op = 5; break;
822+ case TOK_LE: op = 5; tmp = a; a = b; b = tmp; break;
823+ case TOK_GT: op = 4; tmp = a; a = b; b = tmp; break;
824+ case TOK_NE: op = 1; break;
825+ case TOK_EQ: op = 0; break;
826+ }
827+ o(0x63 | (op ^ 1) << 12 | a << 15 | b << 20 | 8 << 7); // bOP a,b,+4
782828 return gjmp(t);
783829 }
784830
@@ -799,7 +845,6 @@ ST_FUNC int gjmp_append(int n, int t) · 14 unmodified lines
799845 static void gen_opil(int op, int ll)
800846 {
801847 int a, b, d;
802− int inv = 0;
803848 int func3 = 0;
804849 ll = ll ? 0 : 8;
805850 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
@@ -823,7 +868,11 @@ static void gen_opil(int op, int ll) · 17 unmodified lines
823868 do_cop:
824869 EI(0x13 | cll, func3, ireg(d), a, fc);
825870 --vtop;
826− vtop[0].r = d;
871+ if (op >= TOK_ULT && op <= TOK_GT) {
872+ vset_VT_CMP(TOK_NE);
873+ vtop->cmp_r = ireg(d) | 0 << 8;
874+ } else
875+ vtop[0].r = d;
827876 return;
828877 case TOK_LE:
829878 if (fc >= (1 << 11) - 1)
@@ -847,19 +896,16 @@ static void gen_opil(int op, int ll) · 17 unmodified lines
847896 case TOK_GE:
848897 case TOK_GT:
849898 gen_opil(op - 1, ll);
850− EI(0x13, 4, ireg(vtop->r), ireg(vtop->r), 1);// xori d, d, 1
899+ vtop->cmp_op ^= 1;
851900 return;
852901
853902 case TOK_NE:
854903 case TOK_EQ:
855904 if (fc)
856905 gen_opil('-', ll), a = ireg(vtop++->r);
857− if (op == TOK_NE)
858− ER(0x33, 3, ireg(d), 0, a, 0); //sltu d, x0, a == snez d,a
859− else
860− EI(0x13, 3, ireg(d), a, 1); // sltiu d, a, 1 == seqz d,a
861906 --vtop;
862− vtop[0].r = d;
907+ vset_VT_CMP(op);
908+ vtop->cmp_r = a | 0 << 8;
863909 return;
864910 }
865911 }
@@ -874,7 +920,13 @@ static void gen_opil(int op, int ll) · 8 unmodified lines
874920 d = ireg(d);
875921 switch (op) {
876922 default:
923+ if (op >= TOK_ULT && op <= TOK_GT) {
924+ vset_VT_CMP(op);
925+ vtop->cmp_r = a | b << 8;
926+ break;
927+ }
877928 tcc_error("implement me: %s(%s)", __FUNCTION__, get_tok_str(op, NULL));
929+ break;
878930
879931 case '+':
880932 ER(0x33, 0, d, a, b, 0); // add d, a, b
@@ -916,39 +968,6 @@ static void gen_opil(int op, int ll) · 35 unmodified lines
916968 case TOK_UDIV:
917969 ER(0x33, 5, d, a, b, 1); // divu d, a, b
918970 break;
919−
920− case TOK_ULT:
921− case TOK_UGE:
922− case TOK_ULE:
923− case TOK_UGT:
924− case TOK_LT:
925− case TOK_GE:
926− case TOK_LE:
927− case TOK_GT:
928− if (op & 1) { // remove [U]GE,GT
929− inv = 1;
930− op--;
931− }
932− if ((op & 7) == 6) { // [U]LE
933− int t = a; a = b; b = t;
934− inv ^= 1;
935− }
936− ER(0x33, (op > TOK_UGT) ? 2 : 3, d, a, b, 0); // slt[u] d, a, b
937− if (inv)
938− EI(0x13, 4, d, d, 1); // xori d, d, 1
939− vset_VT_CMP(TOK_NE);
940− vtop->cmp_r = d;
941− break;
942− case TOK_NE:
943− case TOK_EQ:
944− ER(0x33, 0, d, a, b, 0x20); // sub d, a, b
945− if (op == TOK_NE)
946− ER(0x33, 3, d, 0, d, 0); // sltu d, x0, d == snez d,d
947− else
948− EI(0x13, 3, d, d, 1); // sltiu d, d, 1 == seqz d,d
949− vset_VT_CMP(TOK_NE);
950− vtop->cmp_r = d;
951− break;
952971 }
953972 }
954973

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t