Move the logic to do a test of an integer value (ex if (0)) out of arch-specific code to tccgen.c to avoid code duplication. This also fixes test of long long value which was only testing the bottom half of such values on 32 bits architectures.
Unified · Split
| @@ -1390,7 +1390,7 @@ int gtst(int inv, int t) · 1389 unmodified lines | ||
| 1390 | 1390 | op|=encbranch(r,t,1); |
| 1391 | 1391 | o(op); |
| 1392 | 1392 | t=r; |
| 1393 | − } else if (v == VT_JMP || v == VT_JMPI) { | |
| 1393 | + } else { /* VT_JMP || VT_JMPI */ | |
| 1394 | 1394 | if ((v & 1) == inv) { |
| 1395 | 1395 | if(!vtop->c.i) |
| 1396 | 1396 | vtop->c.i=t; |
| @@ -1412,29 +1412,6 @@ int gtst(int inv, int t) · 15 unmodified lines | ||
| 1412 | 1412 | t = gjmp(t); |
| 1413 | 1413 | gsym(vtop->c.i); |
| 1414 | 1414 | } |
| 1415 | − } else { | |
| 1416 | − if (is_float(vtop->type.t)) { | |
| 1417 | − r=gv(RC_FLOAT); | |
| 1418 | −#ifdef TCC_ARM_VFP | |
| 1419 | − o(0xEEB50A40|(vfpr(r)<<12)|T2CPR(vtop->type.t)); /* fcmpzX */ | |
| 1420 | − o(0xEEF1FA10); /* fmstat */ | |
| 1421 | −#else | |
| 1422 | − o(0xEE90F118|(fpr(r)<<16)); | |
| 1423 | −#endif | |
| 1424 | − vtop->r = VT_CMP; | |
| 1425 | − vtop->c.i = TOK_NE; | |
| 1426 | − return gtst(inv, t); | |
| 1427 | − } else if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { | |
| 1428 | − /* constant jmp optimization */ | |
| 1429 | − if ((vtop->c.i != 0) != inv) | |
| 1430 | − t = gjmp(t); | |
| 1431 | − } else { | |
| 1432 | − v = gv(RC_INT); | |
| 1433 | − o(0xE3300000|(intr(v)<<16)); | |
| 1434 | − vtop->r = VT_CMP; | |
| 1435 | − vtop->c.i = TOK_NE; | |
| 1436 | − return gtst(inv, t); | |
| 1437 | − } | |
| 1438 | 1415 | } |
| 1439 | 1416 | vtop--; |
| 1440 | 1417 | return t; |
| @@ -2103,7 +2103,7 @@ int gtst(int inv, int t) · 2102 unmodified lines | ||
| 2103 | 2103 | C67_NOP(5); |
| 2104 | 2104 | t = ind1; //return where we need to patch |
| 2105 | 2105 | |
| 2106 | − } else if (v == VT_JMP || v == VT_JMPI) { | |
| 2106 | + } else { /* VT_JMP || VT_JMPI */ | |
| 2107 | 2107 | /* && or || optimization */ |
| 2108 | 2108 | if ((v & 1) == inv) { |
| 2109 | 2109 | /* insert vtop->c jump list in t */ |
| @@ -2129,37 +2129,6 @@ int gtst(int inv, int t) · 19 unmodified lines | ||
| 2129 | 2129 | t = gjmp(t); |
| 2130 | 2130 | gsym(vtop->c.i); |
| 2131 | 2131 | } |
| 2132 | − } else { | |
| 2133 | − if (is_float(vtop->type.t)) { | |
| 2134 | − vpushi(0); | |
| 2135 | − gen_op(TOK_NE); | |
| 2136 | − } | |
| 2137 | − if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { | |
| 2138 | − /* constant jmp optimization */ | |
| 2139 | − if ((vtop->c.i != 0) != inv) | |
| 2140 | − t = gjmp(t); | |
| 2141 | − } else { | |
| 2142 | − // I think we need to get the value on the stack | |
| 2143 | − // into a register, test it, and generate a branch | |
| 2144 | − // return the address of the branch, so it can be | |
| 2145 | − // later patched | |
| 2146 | − | |
| 2147 | − v = gv(RC_INT); // get value into a reg | |
| 2148 | − ind1 = ind; | |
| 2149 | − C67_MVKL(C67_A0, t); //r=reg to load, constant | |
| 2150 | − C67_MVKH(C67_A0, t); //r=reg to load, constant | |
| 2151 | − | |
| 2152 | − if (v != TREG_EAX && // check if not already in a conditional test reg | |
| 2153 | − v != TREG_EDX && v != TREG_ST0 && v != C67_B2) { | |
| 2154 | − C67_MV(v, C67_B2); | |
| 2155 | − v = C67_B2; | |
| 2156 | − } | |
| 2157 | − | |
| 2158 | − C67_IREG_B_REG(inv, v, C67_A0); // [!R] B.S2x A0 | |
| 2159 | − C67_NOP(5); | |
| 2160 | − t = ind1; //return where we need to patch | |
| 2161 | − ind1 = ind; | |
| 2162 | − } | |
| 2163 | 2132 | } |
| 2164 | 2133 | vtop--; |
| 2165 | 2134 | return t; |
| @@ -682,7 +682,7 @@ ST_FUNC int gtst(int inv, int t) · 681 unmodified lines | ||
| 682 | 682 | /* fast case : can jump directly since flags are set */ |
| 683 | 683 | g(0x0f); |
| 684 | 684 | t = psym((vtop->c.i - 16) ^ inv, t); |
| 685 | − } else if (v == VT_JMP || v == VT_JMPI) { | |
| 685 | + } else { /* VT_JMP || VT_JMPI */ | |
| 686 | 686 | /* && or || optimization */ |
| 687 | 687 | if ((v & 1) == inv) { |
| 688 | 688 | /* insert vtop->c jump list in t */ |
| @@ -695,23 +695,6 @@ ST_FUNC int gtst(int inv, int t) · 6 unmodified lines | ||
| 695 | 695 | t = gjmp(t); |
| 696 | 696 | gsym(vtop->c.i); |
| 697 | 697 | } |
| 698 | − } else { | |
| 699 | − if (is_float(vtop->type.t) || | |
| 700 | − (vtop->type.t & VT_BTYPE) == VT_LLONG) { | |
| 701 | − vpushi(0); | |
| 702 | − gen_op(TOK_NE); | |
| 703 | − } | |
| 704 | − if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { | |
| 705 | − /* constant jmp optimization */ | |
| 706 | − if ((vtop->c.i != 0) != inv) | |
| 707 | − t = gjmp(t); | |
| 708 | − } else { | |
| 709 | − v = gv(RC_INT); | |
| 710 | − o(0x85); | |
| 711 | − o(0xc0 + v * 9); | |
| 712 | − g(0x0f); | |
| 713 | − t = psym(0x85 ^ inv, t); | |
| 714 | − } | |
| 715 | 698 | } |
| 716 | 699 | vtop--; |
| 717 | 700 | return t; |
| @@ -515,7 +515,7 @@ int gtst(int inv, int t) · 514 unmodified lines | ||
| 515 | 515 | break; |
| 516 | 516 | } |
| 517 | 517 | t = out_opj(c, t); |
| 518 | − } else if (v == VT_JMP || v == VT_JMPI) { | |
| 518 | + } else { /* VT_JMP || VT_JMPI */ | |
| 519 | 519 | /* && or || optimization */ |
| 520 | 520 | if ((v & 1) == inv) { |
| 521 | 521 | /* insert vtop->c jump list in t */ |
| @@ -528,19 +528,6 @@ int gtst(int inv, int t) · 6 unmodified lines | ||
| 528 | 528 | t = gjmp(t); |
| 529 | 529 | gsym(vtop->c.i); |
| 530 | 530 | } |
| 531 | − } else { | |
| 532 | − if (is_float(vtop->t)) { | |
| 533 | − vpushi(0); | |
| 534 | − gen_op(TOK_NE); | |
| 535 | − } | |
| 536 | − if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_FORWARD)) == VT_CONST) { | |
| 537 | − /* constant jmp optimization */ | |
| 538 | − if ((vtop->c.i != 0) != inv) | |
| 539 | − t = gjmp(t); | |
| 540 | − } else { | |
| 541 | − v = gv(RC_INT); | |
| 542 | − t = out_opj(IL_OP_BRTRUE - inv, t); | |
| 543 | − } | |
| 544 | 531 | } |
| 545 | 532 | vtop--; |
| 546 | 533 | return t; |
| @@ -1095,6 +1095,26 @@ static void gv_dup(void) · 1094 unmodified lines | ||
| 1095 | 1095 | } |
| 1096 | 1096 | } |
| 1097 | 1097 | |
| 1098 | +/* Generate value test | |
| 1099 | + * | |
| 1100 | + * Generate a test for any value (jump, comparison and integers) */ | |
| 1101 | +int gvtst(int inv, int t) | |
| 1102 | +{ | |
| 1103 | + int v = vtop->r & VT_VALMASK; | |
| 1104 | + if (v != VT_CMP && v != VT_JMP && v != VT_JMPI) { | |
| 1105 | + vpushi(0); | |
| 1106 | + gen_op(TOK_NE); | |
| 1107 | + } | |
| 1108 | + if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { | |
| 1109 | + /* constant jmp optimization */ | |
| 1110 | + if ((vtop->c.i != 0) != inv) | |
| 1111 | + t = gjmp(t); | |
| 1112 | + vtop--; | |
| 1113 | + return t; | |
| 1114 | + } | |
| 1115 | + return gtst(inv, t); | |
| 1116 | +} | |
| 1117 | + | |
| 1098 | 1118 | #ifndef TCC_TARGET_X86_64 |
| 1099 | 1119 | /* generate CPU independent (unsigned) long long operations */ |
| 1100 | 1120 | static void gen_opl(int op) |
| @@ -1293,13 +1313,13 @@ static void gen_opl(int op) · 192 unmodified lines | ||
| 1293 | 1313 | b = 0; |
| 1294 | 1314 | gen_op(op1); |
| 1295 | 1315 | if (op1 != TOK_NE) { |
| 1296 | − a = gtst(1, 0); | |
| 1316 | + a = gvtst(1, 0); | |
| 1297 | 1317 | } |
| 1298 | 1318 | if (op != TOK_EQ) { |
| 1299 | 1319 | /* generate non equal test */ |
| 1300 | 1320 | /* XXX: NOT PORTABLE yet */ |
| 1301 | 1321 | if (a == 0) { |
| 1302 | − b = gtst(0, 0); | |
| 1322 | + b = gvtst(0, 0); | |
| 1303 | 1323 | } else { |
| 1304 | 1324 | #if defined(TCC_TARGET_I386) |
| 1305 | 1325 | b = psym(0x850f, 0); |
| @@ -1324,7 +1344,7 @@ static void gen_opl(int op) · 18 unmodified lines | ||
| 1324 | 1344 | else if (op1 == TOK_GE) |
| 1325 | 1345 | op1 = TOK_UGE; |
| 1326 | 1346 | gen_op(op1); |
| 1327 | − a = gtst(1, a); | |
| 1347 | + a = gvtst(1, a); | |
| 1328 | 1348 | gsym(b); |
| 1329 | 1349 | vseti(VT_JMPI, a); |
| 1330 | 1350 | break; |
| @@ -3665,7 +3685,7 @@ ST_FUNC void unary(void) · 2334 unmodified lines | ||
| 3665 | 3685 | vtop->c.i = vtop->c.i ^ 1; |
| 3666 | 3686 | else { |
| 3667 | 3687 | save_regs(1); |
| 3668 | − vseti(VT_JMP, gtst(1, 0)); | |
| 3688 | + vseti(VT_JMP, gvtst(1, 0)); | |
| 3669 | 3689 | } |
| 3670 | 3690 | break; |
| 3671 | 3691 | case '~': |
| @@ -4182,7 +4202,7 @@ static void expr_land(void) · 510 unmodified lines | ||
| 4182 | 4202 | t = 0; |
| 4183 | 4203 | save_regs(1); |
| 4184 | 4204 | for(;;) { |
| 4185 | − t = gtst(1, t); | |
| 4205 | + t = gvtst(1, t); | |
| 4186 | 4206 | if (tok != TOK_LAND) { |
| 4187 | 4207 | vseti(VT_JMPI, t); |
| 4188 | 4208 | break; |
| @@ -4202,7 +4222,7 @@ static void expr_lor(void) · 13 unmodified lines | ||
| 4202 | 4222 | t = 0; |
| 4203 | 4223 | save_regs(1); |
| 4204 | 4224 | for(;;) { |
| 4205 | − t = gtst(0, t); | |
| 4225 | + t = gvtst(0, t); | |
| 4206 | 4226 | if (tok != TOK_LOR) { |
| 4207 | 4227 | vseti(VT_JMP, t); |
| 4208 | 4228 | break; |
| @@ -4264,9 +4284,9 @@ static void expr_cond(void) · 55 unmodified lines | ||
| 4264 | 4284 | } |
| 4265 | 4285 | if (tok == ':' && gnu_ext) { |
| 4266 | 4286 | gv_dup(); |
| 4267 | − tt = gtst(1, 0); | |
| 4287 | + tt = gvtst(1, 0); | |
| 4268 | 4288 | } else { |
| 4269 | − tt = gtst(1, 0); | |
| 4289 | + tt = gvtst(1, 0); | |
| 4270 | 4290 | gexpr(); |
| 4271 | 4291 | } |
| 4272 | 4292 | type1 = vtop->type; |
| @@ -4512,7 +4532,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 239 unmodified lines | ||
| 4512 | 4532 | skip('('); |
| 4513 | 4533 | gexpr(); |
| 4514 | 4534 | skip(')'); |
| 4515 | − a = gtst(1, 0); | |
| 4535 | + a = gvtst(1, 0); | |
| 4516 | 4536 | block(bsym, csym, case_sym, def_sym, case_reg, 0); |
| 4517 | 4537 | c = tok; |
| 4518 | 4538 | if (c == TOK_ELSE) { |
| @@ -4529,7 +4549,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 10 unmodified lines | ||
| 4529 | 4549 | skip('('); |
| 4530 | 4550 | gexpr(); |
| 4531 | 4551 | skip(')'); |
| 4532 | − a = gtst(1, 0); | |
| 4552 | + a = gvtst(1, 0); | |
| 4533 | 4553 | b = 0; |
| 4534 | 4554 | block(&a, &b, case_sym, def_sym, case_reg, 0); |
| 4535 | 4555 | gjmp_addr(d); |
| @@ -4707,7 +4727,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 171 unmodified lines | ||
| 4707 | 4727 | b = 0; |
| 4708 | 4728 | if (tok != ';') { |
| 4709 | 4729 | gexpr(); |
| 4710 | − a = gtst(1, 0); | |
| 4730 | + a = gvtst(1, 0); | |
| 4711 | 4731 | } |
| 4712 | 4732 | skip(';'); |
| 4713 | 4733 | if (tok != ')') { |
| @@ -4736,7 +4756,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 22 unmodified lines | ||
| 4736 | 4756 | skip('('); |
| 4737 | 4757 | gsym(b); |
| 4738 | 4758 | gexpr(); |
| 4739 | − c = gtst(0, 0); | |
| 4759 | + c = gvtst(0, 0); | |
| 4740 | 4760 | gsym_addr(c, d); |
| 4741 | 4761 | skip(')'); |
| 4742 | 4762 | gsym(a); |
| @@ -1582,7 +1582,7 @@ int gtst(int inv, int t) · 1581 unmodified lines | ||
| 1582 | 1582 | } |
| 1583 | 1583 | g(0x0f); |
| 1584 | 1584 | t = psym((vtop->c.i - 16) ^ inv, t); |
| 1585 | − } else if (v == VT_JMP || v == VT_JMPI) { | |
| 1585 | + } else { /* VT_JMP || VT_JMPI */ | |
| 1586 | 1586 | /* && or || optimization */ |
| 1587 | 1587 | if ((v & 1) == inv) { |
| 1588 | 1588 | /* insert vtop->c jump list in t */ |
| @@ -1595,23 +1595,6 @@ int gtst(int inv, int t) · 6 unmodified lines | ||
| 1595 | 1595 | t = gjmp(t); |
| 1596 | 1596 | gsym(vtop->c.i); |
| 1597 | 1597 | } |
| 1598 | − } else { | |
| 1599 | − if (is_float(vtop->type.t) || | |
| 1600 | − (vtop->type.t & VT_BTYPE) == VT_LLONG) { | |
| 1601 | − vpushi(0); | |
| 1602 | − gen_op(TOK_NE); | |
| 1603 | − } | |
| 1604 | − if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { | |
| 1605 | − /* constant jmp optimization */ | |
| 1606 | − if ((vtop->c.i != 0) != inv) | |
| 1607 | − t = gjmp(t); | |
| 1608 | − } else { | |
| 1609 | − v = gv(RC_INT); | |
| 1610 | − orex(0,v,v,0x85); | |
| 1611 | − o(0xc0 + REG_VALUE(v) * 9); | |
| 1612 | − g(0x0f); | |
| 1613 | − t = psym(0x85 ^ inv, t); | |
| 1614 | − } | |
| 1615 | 1598 | } |
| 1616 | 1599 | vtop--; |
| 1617 | 1600 | return t; |