Unified · Split
| @@ -1409,37 +1409,60 @@ void gjmp_addr(int a) · 1408 unmodified lines | ||
| 1409 | 1409 | /* generate a test. set 'inv' to invert test. Stack entry is popped */ |
| 1410 | 1410 | int gtst(int inv, int t) |
| 1411 | 1411 | { |
| 1412 | − int v, r; | |
| 1413 | − uint32_t op; | |
| 1414 | − v = vtop->r & VT_VALMASK; | |
| 1415 | − r=ind; | |
| 1416 | − if (v == VT_CMP) { | |
| 1417 | − op=mapcc(inv?negcc(vtop->c.i):vtop->c.i); | |
| 1418 | − op|=encbranch(r,t,1); | |
| 1419 | − o(op); | |
| 1420 | − t=r; | |
| 1421 | − } else { /* VT_JMP || VT_JMPI */ | |
| 1422 | − if ((v & 1) == inv) { | |
| 1423 | − if(!vtop->c.i) | |
| 1424 | − vtop->c.i=t; | |
| 1425 | − else { | |
| 1426 | − uint32_t *x; | |
| 1427 | − int p,lp; | |
| 1428 | − if(t) { | |
| 1429 | − p = vtop->c.i; | |
| 1430 | − do { | |
| 1431 | − p = decbranch(lp=p); | |
| 1432 | − } while(p); | |
| 1433 | − x = (uint32_t *)(cur_text_section->data + lp); | |
| 1434 | − *x &= 0xff000000; | |
| 1435 | − *x |= encbranch(lp,t,1); | |
| 1436 | − } | |
| 1437 | − t = vtop->c.i; | |
| 1438 | − } | |
| 1439 | − } else { | |
| 1440 | − t = gjmp(t); | |
| 1441 | − gsym(vtop->c.i); | |
| 1412 | + int v, r; | |
| 1413 | + uint32_t op; | |
| 1414 | + v = vtop->r & VT_VALMASK; | |
| 1415 | + r=ind; | |
| 1416 | + if (v == VT_CMP) { | |
| 1417 | + op=mapcc(inv?negcc(vtop->c.i):vtop->c.i); | |
| 1418 | + op|=encbranch(r,t,1); | |
| 1419 | + o(op); | |
| 1420 | + t=r; | |
| 1421 | + } else if (v == VT_JMP || v == VT_JMPI) { | |
| 1422 | + if ((v & 1) == inv) { | |
| 1423 | + if(!vtop->c.i) | |
| 1424 | + vtop->c.i=t; | |
| 1425 | + else { | |
| 1426 | + uint32_t *x; | |
| 1427 | + int p,lp; | |
| 1428 | + if(t) { | |
| 1429 | + p = vtop->c.i; | |
| 1430 | + do { | |
| 1431 | + p = decbranch(lp=p); | |
| 1432 | + } while(p); | |
| 1433 | + x = (uint32_t *)(cur_text_section->data + lp); | |
| 1434 | + *x &= 0xff000000; | |
| 1435 | + *x |= encbranch(lp,t,1); | |
| 1436 | + } | |
| 1437 | + t = vtop->c.i; | |
| 1438 | + } | |
| 1439 | + } else { | |
| 1440 | + t = gjmp(t); | |
| 1441 | + gsym(vtop->c.i); | |
| 1442 | 1442 | } |
| 1443 | + } else { | |
| 1444 | + if (is_float(vtop->type.t)) { | |
| 1445 | + r=gv(RC_FLOAT); | |
| 1446 | +#ifdef TCC_ARM_VFP | |
| 1447 | + o(0xEEB50A40|(vfpr(r)<<12)|T2CPR(vtop->type.t)); /* fcmpzX */ | |
| 1448 | + o(0xEEF1FA10); /* fmstat */ | |
| 1449 | +#else | |
| 1450 | + o(0xEE90F118|(fpr(r)<<16)); | |
| 1451 | +#endif | |
| 1452 | + vtop->r = VT_CMP; | |
| 1453 | + vtop->c.i = TOK_NE; | |
| 1454 | + return gtst(inv, t); | |
| 1455 | + } else if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { | |
| 1456 | + /* constant jmp optimization */ | |
| 1457 | + if ((vtop->c.i != 0) != inv) | |
| 1458 | + t = gjmp(t); | |
| 1459 | + } else { | |
| 1460 | + v = gv(RC_INT); | |
| 1461 | + o(0xE3300000|(intr(v)<<16)); | |
| 1462 | + vtop->r = VT_CMP; | |
| 1463 | + vtop->c.i = TOK_NE; | |
| 1464 | + return gtst(inv, t); | |
| 1465 | + } | |
| 1443 | 1466 | } |
| 1444 | 1467 | vtop--; |
| 1445 | 1468 | return t; |
| @@ -2102,7 +2102,7 @@ int gtst(int inv, int t) · 2101 unmodified lines | ||
| 2102 | 2102 | C67_NOP(5); |
| 2103 | 2103 | t = ind1; //return where we need to patch |
| 2104 | 2104 | |
| 2105 | − } else { /* VT_JMP || VT_JMPI */ | |
| 2105 | + } else if (v == VT_JMP || v == VT_JMPI) { | |
| 2106 | 2106 | /* && or || optimization */ |
| 2107 | 2107 | if ((v & 1) == inv) { |
| 2108 | 2108 | /* insert vtop->c jump list in t */ |
| @@ -2128,6 +2128,37 @@ int gtst(int inv, int t) · 19 unmodified lines | ||
| 2128 | 2128 | t = gjmp(t); |
| 2129 | 2129 | gsym(vtop->c.i); |
| 2130 | 2130 | } |
| 2131 | + } else { | |
| 2132 | + if (is_float(vtop->type.t)) { | |
| 2133 | + vpushi(0); | |
| 2134 | + gen_op(TOK_NE); | |
| 2135 | + } | |
| 2136 | + if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { | |
| 2137 | + /* constant jmp optimization */ | |
| 2138 | + if ((vtop->c.i != 0) != inv) | |
| 2139 | + t = gjmp(t); | |
| 2140 | + } else { | |
| 2141 | + // I think we need to get the value on the stack | |
| 2142 | + // into a register, test it, and generate a branch | |
| 2143 | + // return the address of the branch, so it can be | |
| 2144 | + // later patched | |
| 2145 | + | |
| 2146 | + v = gv(RC_INT); // get value into a reg | |
| 2147 | + ind1 = ind; | |
| 2148 | + C67_MVKL(C67_A0, t); //r=reg to load, constant | |
| 2149 | + C67_MVKH(C67_A0, t); //r=reg to load, constant | |
| 2150 | + | |
| 2151 | + if (v != TREG_EAX && // check if not already in a conditional test reg | |
| 2152 | + v != TREG_EDX && v != TREG_ST0 && v != C67_B2) { | |
| 2153 | + C67_MV(v, C67_B2); | |
| 2154 | + v = C67_B2; | |
| 2155 | + } | |
| 2156 | + | |
| 2157 | + C67_IREG_B_REG(inv, v, C67_A0); // [!R] B.S2x A0 | |
| 2158 | + C67_NOP(5); | |
| 2159 | + t = ind1; //return where we need to patch | |
| 2160 | + ind1 = ind; | |
| 2161 | + } | |
| 2131 | 2162 | } |
| 2132 | 2163 | vtop--; |
| 2133 | 2164 | return t; |
| @@ -677,7 +677,7 @@ ST_FUNC int gtst(int inv, int t) · 676 unmodified lines | ||
| 677 | 677 | /* fast case : can jump directly since flags are set */ |
| 678 | 678 | g(0x0f); |
| 679 | 679 | t = psym((vtop->c.i - 16) ^ inv, t); |
| 680 | − } else { /* VT_JMP || VT_JMPI */ | |
| 680 | + } else if (v == VT_JMP || v == VT_JMPI) { | |
| 681 | 681 | /* && or || optimization */ |
| 682 | 682 | if ((v & 1) == inv) { |
| 683 | 683 | /* insert vtop->c jump list in t */ |
| @@ -690,6 +690,23 @@ ST_FUNC int gtst(int inv, int t) · 6 unmodified lines | ||
| 690 | 690 | t = gjmp(t); |
| 691 | 691 | gsym(vtop->c.i); |
| 692 | 692 | } |
| 693 | + } else { | |
| 694 | + if (is_float(vtop->type.t) || | |
| 695 | + (vtop->type.t & VT_BTYPE) == VT_LLONG) { | |
| 696 | + vpushi(0); | |
| 697 | + gen_op(TOK_NE); | |
| 698 | + } | |
| 699 | + if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { | |
| 700 | + /* constant jmp optimization */ | |
| 701 | + if ((vtop->c.i != 0) != inv) | |
| 702 | + t = gjmp(t); | |
| 703 | + } else { | |
| 704 | + v = gv(RC_INT); | |
| 705 | + o(0x85); | |
| 706 | + o(0xc0 + v * 9); | |
| 707 | + g(0x0f); | |
| 708 | + t = psym(0x85 ^ inv, t); | |
| 709 | + } | |
| 693 | 710 | } |
| 694 | 711 | vtop--; |
| 695 | 712 | return t; |
| @@ -516,7 +516,7 @@ int gtst(int inv, int t) · 515 unmodified lines | ||
| 516 | 516 | break; |
| 517 | 517 | } |
| 518 | 518 | t = out_opj(c, t); |
| 519 | − } else { /* VT_JMP || VT_JMPI */ | |
| 519 | + } else if (v == VT_JMP || v == VT_JMPI) { | |
| 520 | 520 | /* && or || optimization */ |
| 521 | 521 | if ((v & 1) == inv) { |
| 522 | 522 | /* insert vtop->c jump list in t */ |
| @@ -529,6 +529,19 @@ int gtst(int inv, int t) · 6 unmodified lines | ||
| 529 | 529 | t = gjmp(t); |
| 530 | 530 | gsym(vtop->c.i); |
| 531 | 531 | } |
| 532 | + } else { | |
| 533 | + if (is_float(vtop->t)) { | |
| 534 | + vpushi(0); | |
| 535 | + gen_op(TOK_NE); | |
| 536 | + } | |
| 537 | + if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_FORWARD)) == VT_CONST) { | |
| 538 | + /* constant jmp optimization */ | |
| 539 | + if ((vtop->c.i != 0) != inv) | |
| 540 | + t = gjmp(t); | |
| 541 | + } else { | |
| 542 | + v = gv(RC_INT); | |
| 543 | + t = out_opj(IL_OP_BRTRUE - inv, t); | |
| 544 | + } | |
| 532 | 545 | } |
| 533 | 546 | vtop--; |
| 534 | 547 | return t; |
| @@ -92,7 +92,7 @@ static int is_compatible_parameter_types(CType *type1, CType *type2); · 91 unmodified lines | ||
| 92 | 92 | static void expr_type(CType *type); |
| 93 | 93 | ST_FUNC void vpush64(int ty, unsigned long long v); |
| 94 | 94 | ST_FUNC void vpush(CType *type); |
| 95 | −ST_FUNC int gvtst(int inv, int t); | |
| 95 | +ST_FUNC int gtst(int inv, int t); | |
| 96 | 96 | ST_FUNC int is_btype_size(int bt); |
| 97 | 97 | |
| 98 | 98 | ST_INLN int is_float(int t) |
| @@ -1128,26 +1128,6 @@ static void gv_dup(void) · 1029 unmodified lines | ||
| 1128 | 1128 | } |
| 1129 | 1129 | } |
| 1130 | 1130 | |
| 1131 | −/* Generate value test | |
| 1132 | − * | |
| 1133 | − * Generate a test for any value (jump, comparison and integers) */ | |
| 1134 | −ST_FUNC int gvtst(int inv, int t) | |
| 1135 | −{ | |
| 1136 | − int v = vtop->r & VT_VALMASK; | |
| 1137 | − if (v != VT_CMP && v != VT_JMP && v != VT_JMPI) { | |
| 1138 | − vpushi(0); | |
| 1139 | − gen_op(TOK_NE); | |
| 1140 | − } | |
| 1141 | − if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { | |
| 1142 | − /* constant jmp optimization */ | |
| 1143 | − if ((vtop->c.i != 0) != inv) | |
| 1144 | − t = gjmp(t); | |
| 1145 | − vtop--; | |
| 1146 | − return t; | |
| 1147 | − } | |
| 1148 | − return gtst(inv, t); | |
| 1149 | −} | |
| 1150 | − | |
| 1151 | 1131 | #ifndef TCC_TARGET_X86_64 |
| 1152 | 1132 | /* generate CPU independent (unsigned) long long operations */ |
| 1153 | 1133 | static void gen_opl(int op) |
| @@ -1346,13 +1326,13 @@ static void gen_opl(int op) · 192 unmodified lines | ||
| 1346 | 1326 | b = 0; |
| 1347 | 1327 | gen_op(op1); |
| 1348 | 1328 | if (op1 != TOK_NE) { |
| 1349 | − a = gvtst(1, 0); | |
| 1329 | + a = gtst(1, 0); | |
| 1350 | 1330 | } |
| 1351 | 1331 | if (op != TOK_EQ) { |
| 1352 | 1332 | /* generate non equal test */ |
| 1353 | 1333 | /* XXX: NOT PORTABLE yet */ |
| 1354 | 1334 | if (a == 0) { |
| 1355 | − b = gvtst(0, 0); | |
| 1335 | + b = gtst(0, 0); | |
| 1356 | 1336 | } else { |
| 1357 | 1337 | #if defined(TCC_TARGET_I386) |
| 1358 | 1338 | b = psym(0x850f, 0); |
| @@ -1377,7 +1357,7 @@ static void gen_opl(int op) · 18 unmodified lines | ||
| 1377 | 1357 | else if (op1 == TOK_GE) |
| 1378 | 1358 | op1 = TOK_UGE; |
| 1379 | 1359 | gen_op(op1); |
| 1380 | − a = gvtst(1, a); | |
| 1360 | + a = gtst(1, a); | |
| 1381 | 1361 | gsym(b); |
| 1382 | 1362 | vseti(VT_JMPI, a); |
| 1383 | 1363 | break; |
| @@ -3760,7 +3740,7 @@ ST_FUNC void unary(void) · 2376 unmodified lines | ||
| 3760 | 3740 | vtop->c.i = vtop->c.i ^ 1; |
| 3761 | 3741 | else { |
| 3762 | 3742 | save_regs(1); |
| 3763 | − vseti(VT_JMP, gvtst(1, 0)); | |
| 3743 | + vseti(VT_JMP, gtst(1, 0)); | |
| 3764 | 3744 | } |
| 3765 | 3745 | break; |
| 3766 | 3746 | case '~': |
| @@ -4288,7 +4268,7 @@ static void expr_land(void) · 521 unmodified lines | ||
| 4288 | 4268 | t = 0; |
| 4289 | 4269 | save_regs(1); |
| 4290 | 4270 | for(;;) { |
| 4291 | − t = gvtst(1, t); | |
| 4271 | + t = gtst(1, t); | |
| 4292 | 4272 | if (tok != TOK_LAND) { |
| 4293 | 4273 | vseti(VT_JMPI, t); |
| 4294 | 4274 | break; |
| @@ -4308,7 +4288,7 @@ static void expr_lor(void) · 13 unmodified lines | ||
| 4308 | 4288 | t = 0; |
| 4309 | 4289 | save_regs(1); |
| 4310 | 4290 | for(;;) { |
| 4311 | − t = gvtst(0, t); | |
| 4291 | + t = gtst(0, t); | |
| 4312 | 4292 | if (tok != TOK_LOR) { |
| 4313 | 4293 | vseti(VT_JMP, t); |
| 4314 | 4294 | break; |
| @@ -4370,9 +4350,9 @@ static void expr_cond(void) · 55 unmodified lines | ||
| 4370 | 4350 | } |
| 4371 | 4351 | if (tok == ':' && gnu_ext) { |
| 4372 | 4352 | gv_dup(); |
| 4373 | − tt = gvtst(1, 0); | |
| 4353 | + tt = gtst(1, 0); | |
| 4374 | 4354 | } else { |
| 4375 | − tt = gvtst(1, 0); | |
| 4355 | + tt = gtst(1, 0); | |
| 4376 | 4356 | gexpr(); |
| 4377 | 4357 | } |
| 4378 | 4358 | type1 = vtop->type; |
| @@ -4618,7 +4598,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 239 unmodified lines | ||
| 4618 | 4598 | skip('('); |
| 4619 | 4599 | gexpr(); |
| 4620 | 4600 | skip(')'); |
| 4621 | − a = gvtst(1, 0); | |
| 4601 | + a = gtst(1, 0); | |
| 4622 | 4602 | block(bsym, csym, case_sym, def_sym, case_reg, 0); |
| 4623 | 4603 | c = tok; |
| 4624 | 4604 | if (c == TOK_ELSE) { |
| @@ -4635,7 +4615,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 10 unmodified lines | ||
| 4635 | 4615 | skip('('); |
| 4636 | 4616 | gexpr(); |
| 4637 | 4617 | skip(')'); |
| 4638 | − a = gvtst(1, 0); | |
| 4618 | + a = gtst(1, 0); | |
| 4639 | 4619 | b = 0; |
| 4640 | 4620 | block(&a, &b, case_sym, def_sym, case_reg, 0); |
| 4641 | 4621 | gjmp_addr(d); |
| @@ -4814,7 +4794,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 172 unmodified lines | ||
| 4814 | 4794 | b = 0; |
| 4815 | 4795 | if (tok != ';') { |
| 4816 | 4796 | gexpr(); |
| 4817 | − a = gvtst(1, 0); | |
| 4797 | + a = gtst(1, 0); | |
| 4818 | 4798 | } |
| 4819 | 4799 | skip(';'); |
| 4820 | 4800 | if (tok != ')') { |
| @@ -4843,7 +4823,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 22 unmodified lines | ||
| 4843 | 4823 | skip('('); |
| 4844 | 4824 | gsym(b); |
| 4845 | 4825 | gexpr(); |
| 4846 | − c = gvtst(0, 0); | |
| 4826 | + c = gtst(0, 0); | |
| 4847 | 4827 | gsym_addr(c, d); |
| 4848 | 4828 | skip(')'); |
| 4849 | 4829 | gsym(a); |
| @@ -1593,7 +1593,7 @@ int gtst(int inv, int t) · 1592 unmodified lines | ||
| 1593 | 1593 | } |
| 1594 | 1594 | g(0x0f); |
| 1595 | 1595 | t = psym((vtop->c.i - 16) ^ inv, t); |
| 1596 | − } else { /* VT_JMP || VT_JMPI */ | |
| 1596 | + } else if (v == VT_JMP || v == VT_JMPI) { | |
| 1597 | 1597 | /* && or || optimization */ |
| 1598 | 1598 | if ((v & 1) == inv) { |
| 1599 | 1599 | /* insert vtop->c jump list in t */ |
| @@ -1606,6 +1606,23 @@ int gtst(int inv, int t) · 6 unmodified lines | ||
| 1606 | 1606 | t = gjmp(t); |
| 1607 | 1607 | gsym(vtop->c.i); |
| 1608 | 1608 | } |
| 1609 | + } else { | |
| 1610 | + if (is_float(vtop->type.t) || | |
| 1611 | + (vtop->type.t & VT_BTYPE) == VT_LLONG) { | |
| 1612 | + vpushi(0); | |
| 1613 | + gen_op(TOK_NE); | |
| 1614 | + } | |
| 1615 | + if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { | |
| 1616 | + /* constant jmp optimization */ | |
| 1617 | + if ((vtop->c.i != 0) != inv) | |
| 1618 | + t = gjmp(t); | |
| 1619 | + } else { | |
| 1620 | + v = gv(RC_INT); | |
| 1621 | + orex(0,v,v,0x85); | |
| 1622 | + o(0xc0 + REG_VALUE(v) * 9); | |
| 1623 | + g(0x0f); | |
| 1624 | + t = psym(0x85 ^ inv, t); | |
| 1625 | + } | |
| 1609 | 1626 | } |
| 1610 | 1627 | vtop--; |
| 1611 | 1628 | return t; |