Unified · Split
| @@ -1409,37 +1409,60 @@ void gjmp_addr(int a) · 1408 unmodified lines | |||
| 1409 | /* generate a test. set 'inv' to invert test. Stack entry is popped */ | 1409 | /* generate a test. set 'inv' to invert test. Stack entry is popped */ |
| 1410 | int gtst(int inv, int t) | 1410 | int gtst(int inv, int t) |
| 1411 | { | 1411 | { |
| 1412 | int v, r; | 1412 | int v, r; |
| 1413 | uint32_t op; | 1413 | uint32_t op; |
| 1414 | v = vtop->r & VT_VALMASK; | 1414 | v = vtop->r & VT_VALMASK; |
| 1415 | r=ind; | 1415 | r=ind; |
| 1416 | if (v == VT_CMP) { | 1416 | if (v == VT_CMP) { |
| 1417 | op=mapcc(inv?negcc(vtop->c.i):vtop->c.i); | 1417 | op=mapcc(inv?negcc(vtop->c.i):vtop->c.i); |
| 1418 | op|=encbranch(r,t,1); | 1418 | op|=encbranch(r,t,1); |
| 1419 | o(op); | 1419 | o(op); |
| 1420 | t=r; | 1420 | t=r; |
| 1421 | } else { /* VT_JMP || VT_JMPI */ | 1421 | } else if (v == VT_JMP || v == VT_JMPI) { |
| 1422 | if ((v & 1) == inv) { | 1422 | if ((v & 1) == inv) { |
| 1423 | if(!vtop->c.i) | 1423 | if(!vtop->c.i) |
| 1424 | vtop->c.i=t; | 1424 | vtop->c.i=t; |
| 1425 | else { | 1425 | else { |
| 1426 | uint32_t *x; | 1426 | uint32_t *x; |
| 1427 | int p,lp; | 1427 | int p,lp; |
| 1428 | if(t) { | 1428 | if(t) { |
| 1429 | p = vtop->c.i; | 1429 | p = vtop->c.i; |
| 1430 | do { | 1430 | do { |
| 1431 | p = decbranch(lp=p); | 1431 | p = decbranch(lp=p); |
| 1432 | } while(p); | 1432 | } while(p); |
| 1433 | x = (uint32_t *)(cur_text_section->data + lp); | 1433 | x = (uint32_t *)(cur_text_section->data + lp); |
| 1434 | *x &= 0xff000000; | 1434 | *x &= 0xff000000; |
| 1435 | *x |= encbranch(lp,t,1); | 1435 | *x |= encbranch(lp,t,1); |
| 1436 | } | 1436 | } |
| 1437 | t = vtop->c.i; | 1437 | t = vtop->c.i; |
| 1438 | } | 1438 | } |
| 1439 | } else { | 1439 | } else { |
| 1440 | t = gjmp(t); | 1440 | t = gjmp(t); |
| 1441 | gsym(vtop->c.i); | 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 | vtop--; | 1467 | vtop--; |
| 1445 | return t; | 1468 | return t; |
| @@ -2102,7 +2102,7 @@ int gtst(int inv, int t) · 2101 unmodified lines | |||
| 2102 | C67_NOP(5); | 2102 | C67_NOP(5); |
| 2103 | t = ind1; //return where we need to patch | 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 | /* && or || optimization */ | 2106 | /* && or || optimization */ |
| 2107 | if ((v & 1) == inv) { | 2107 | if ((v & 1) == inv) { |
| 2108 | /* insert vtop->c jump list in t */ | 2108 | /* insert vtop->c jump list in t */ |
| @@ -2128,6 +2128,37 @@ int gtst(int inv, int t) · 19 unmodified lines | |||
| 2128 | t = gjmp(t); | 2128 | t = gjmp(t); |
| 2129 | gsym(vtop->c.i); | 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 | vtop--; | 2163 | vtop--; |
| 2133 | return t; | 2164 | return t; |
| @@ -677,7 +677,7 @@ ST_FUNC int gtst(int inv, int t) · 676 unmodified lines | |||
| 677 | /* fast case : can jump directly since flags are set */ | 677 | /* fast case : can jump directly since flags are set */ |
| 678 | g(0x0f); | 678 | g(0x0f); |
| 679 | t = psym((vtop->c.i - 16) ^ inv, t); | 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 | /* && or || optimization */ | 681 | /* && or || optimization */ |
| 682 | if ((v & 1) == inv) { | 682 | if ((v & 1) == inv) { |
| 683 | /* insert vtop->c jump list in t */ | 683 | /* insert vtop->c jump list in t */ |
| @@ -690,6 +690,23 @@ ST_FUNC int gtst(int inv, int t) · 6 unmodified lines | |||
| 690 | t = gjmp(t); | 690 | t = gjmp(t); |
| 691 | gsym(vtop->c.i); | 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 | vtop--; | 711 | vtop--; |
| 695 | return t; | 712 | return t; |
| @@ -516,7 +516,7 @@ int gtst(int inv, int t) · 515 unmodified lines | |||
| 516 | break; | 516 | break; |
| 517 | } | 517 | } |
| 518 | t = out_opj(c, t); | 518 | t = out_opj(c, t); |
| 519 | } else { /* VT_JMP || VT_JMPI */ | 519 | } else if (v == VT_JMP || v == VT_JMPI) { |
| 520 | /* && or || optimization */ | 520 | /* && or || optimization */ |
| 521 | if ((v & 1) == inv) { | 521 | if ((v & 1) == inv) { |
| 522 | /* insert vtop->c jump list in t */ | 522 | /* insert vtop->c jump list in t */ |
| @@ -529,6 +529,19 @@ int gtst(int inv, int t) · 6 unmodified lines | |||
| 529 | t = gjmp(t); | 529 | t = gjmp(t); |
| 530 | gsym(vtop->c.i); | 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 | vtop--; | 546 | vtop--; |
| 534 | return t; | 547 | return t; |
| @@ -92,7 +92,7 @@ static int is_compatible_parameter_types(CType *type1, CType *type2); · 91 unmodified lines | |||
| 92 | static void expr_type(CType *type); | 92 | static void expr_type(CType *type); |
| 93 | ST_FUNC void vpush64(int ty, unsigned long long v); | 93 | ST_FUNC void vpush64(int ty, unsigned long long v); |
| 94 | ST_FUNC void vpush(CType *type); | 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 | ST_FUNC int is_btype_size(int bt); | 96 | ST_FUNC int is_btype_size(int bt); |
| 97 | 97 | ||
| 98 | ST_INLN int is_float(int t) | 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 | #ifndef TCC_TARGET_X86_64 | 1131 | #ifndef TCC_TARGET_X86_64 |
| 1152 | /* generate CPU independent (unsigned) long long operations */ | 1132 | /* generate CPU independent (unsigned) long long operations */ |
| 1153 | static void gen_opl(int op) | 1133 | static void gen_opl(int op) |
| @@ -1346,13 +1326,13 @@ static void gen_opl(int op) · 192 unmodified lines | |||
| 1346 | b = 0; | 1326 | b = 0; |
| 1347 | gen_op(op1); | 1327 | gen_op(op1); |
| 1348 | if (op1 != TOK_NE) { | 1328 | if (op1 != TOK_NE) { |
| 1349 | a = gvtst(1, 0); | 1329 | a = gtst(1, 0); |
| 1350 | } | 1330 | } |
| 1351 | if (op != TOK_EQ) { | 1331 | if (op != TOK_EQ) { |
| 1352 | /* generate non equal test */ | 1332 | /* generate non equal test */ |
| 1353 | /* XXX: NOT PORTABLE yet */ | 1333 | /* XXX: NOT PORTABLE yet */ |
| 1354 | if (a == 0) { | 1334 | if (a == 0) { |
| 1355 | b = gvtst(0, 0); | 1335 | b = gtst(0, 0); |
| 1356 | } else { | 1336 | } else { |
| 1357 | #if defined(TCC_TARGET_I386) | 1337 | #if defined(TCC_TARGET_I386) |
| 1358 | b = psym(0x850f, 0); | 1338 | b = psym(0x850f, 0); |
| @@ -1377,7 +1357,7 @@ static void gen_opl(int op) · 18 unmodified lines | |||
| 1377 | else if (op1 == TOK_GE) | 1357 | else if (op1 == TOK_GE) |
| 1378 | op1 = TOK_UGE; | 1358 | op1 = TOK_UGE; |
| 1379 | gen_op(op1); | 1359 | gen_op(op1); |
| 1380 | a = gvtst(1, a); | 1360 | a = gtst(1, a); |
| 1381 | gsym(b); | 1361 | gsym(b); |
| 1382 | vseti(VT_JMPI, a); | 1362 | vseti(VT_JMPI, a); |
| 1383 | break; | 1363 | break; |
| @@ -3760,7 +3740,7 @@ ST_FUNC void unary(void) · 2376 unmodified lines | |||
| 3760 | vtop->c.i = vtop->c.i ^ 1; | 3740 | vtop->c.i = vtop->c.i ^ 1; |
| 3761 | else { | 3741 | else { |
| 3762 | save_regs(1); | 3742 | save_regs(1); |
| 3763 | vseti(VT_JMP, gvtst(1, 0)); | 3743 | vseti(VT_JMP, gtst(1, 0)); |
| 3764 | } | 3744 | } |
| 3765 | break; | 3745 | break; |
| 3766 | case '~': | 3746 | case '~': |
| @@ -4288,7 +4268,7 @@ static void expr_land(void) · 521 unmodified lines | |||
| 4288 | t = 0; | 4268 | t = 0; |
| 4289 | save_regs(1); | 4269 | save_regs(1); |
| 4290 | for(;;) { | 4270 | for(;;) { |
| 4291 | t = gvtst(1, t); | 4271 | t = gtst(1, t); |
| 4292 | if (tok != TOK_LAND) { | 4272 | if (tok != TOK_LAND) { |
| 4293 | vseti(VT_JMPI, t); | 4273 | vseti(VT_JMPI, t); |
| 4294 | break; | 4274 | break; |
| @@ -4308,7 +4288,7 @@ static void expr_lor(void) · 13 unmodified lines | |||
| 4308 | t = 0; | 4288 | t = 0; |
| 4309 | save_regs(1); | 4289 | save_regs(1); |
| 4310 | for(;;) { | 4290 | for(;;) { |
| 4311 | t = gvtst(0, t); | 4291 | t = gtst(0, t); |
| 4312 | if (tok != TOK_LOR) { | 4292 | if (tok != TOK_LOR) { |
| 4313 | vseti(VT_JMP, t); | 4293 | vseti(VT_JMP, t); |
| 4314 | break; | 4294 | break; |
| @@ -4370,9 +4350,9 @@ static void expr_cond(void) · 55 unmodified lines | |||
| 4370 | } | 4350 | } |
| 4371 | if (tok == ':' && gnu_ext) { | 4351 | if (tok == ':' && gnu_ext) { |
| 4372 | gv_dup(); | 4352 | gv_dup(); |
| 4373 | tt = gvtst(1, 0); | 4353 | tt = gtst(1, 0); |
| 4374 | } else { | 4354 | } else { |
| 4375 | tt = gvtst(1, 0); | 4355 | tt = gtst(1, 0); |
| 4376 | gexpr(); | 4356 | gexpr(); |
| 4377 | } | 4357 | } |
| 4378 | type1 = vtop->type; | 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 | skip('('); | 4598 | skip('('); |
| 4619 | gexpr(); | 4599 | gexpr(); |
| 4620 | skip(')'); | 4600 | skip(')'); |
| 4621 | a = gvtst(1, 0); | 4601 | a = gtst(1, 0); |
| 4622 | block(bsym, csym, case_sym, def_sym, case_reg, 0); | 4602 | block(bsym, csym, case_sym, def_sym, case_reg, 0); |
| 4623 | c = tok; | 4603 | c = tok; |
| 4624 | if (c == TOK_ELSE) { | 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 | skip('('); | 4615 | skip('('); |
| 4636 | gexpr(); | 4616 | gexpr(); |
| 4637 | skip(')'); | 4617 | skip(')'); |
| 4638 | a = gvtst(1, 0); | 4618 | a = gtst(1, 0); |
| 4639 | b = 0; | 4619 | b = 0; |
| 4640 | block(&a, &b, case_sym, def_sym, case_reg, 0); | 4620 | block(&a, &b, case_sym, def_sym, case_reg, 0); |
| 4641 | gjmp_addr(d); | 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 | b = 0; | 4794 | b = 0; |
| 4815 | if (tok != ';') { | 4795 | if (tok != ';') { |
| 4816 | gexpr(); | 4796 | gexpr(); |
| 4817 | a = gvtst(1, 0); | 4797 | a = gtst(1, 0); |
| 4818 | } | 4798 | } |
| 4819 | skip(';'); | 4799 | skip(';'); |
| 4820 | if (tok != ')') { | 4800 | if (tok != ')') { |
| @@ -4843,7 +4823,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 22 unmodified lines | |||
| 4843 | skip('('); | 4823 | skip('('); |
| 4844 | gsym(b); | 4824 | gsym(b); |
| 4845 | gexpr(); | 4825 | gexpr(); |
| 4846 | c = gvtst(0, 0); | 4826 | c = gtst(0, 0); |
| 4847 | gsym_addr(c, d); | 4827 | gsym_addr(c, d); |
| 4848 | skip(')'); | 4828 | skip(')'); |
| 4849 | gsym(a); | 4829 | gsym(a); |
| @@ -1593,7 +1593,7 @@ int gtst(int inv, int t) · 1592 unmodified lines | |||
| 1593 | } | 1593 | } |
| 1594 | g(0x0f); | 1594 | g(0x0f); |
| 1595 | t = psym((vtop->c.i - 16) ^ inv, t); | 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 | /* && or || optimization */ | 1597 | /* && or || optimization */ |
| 1598 | if ((v & 1) == inv) { | 1598 | if ((v & 1) == inv) { |
| 1599 | /* insert vtop->c jump list in t */ | 1599 | /* insert vtop->c jump list in t */ |
| @@ -1606,6 +1606,23 @@ int gtst(int inv, int t) · 6 unmodified lines | |||
| 1606 | t = gjmp(t); | 1606 | t = gjmp(t); |
| 1607 | gsym(vtop->c.i); | 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 | vtop--; | 1627 | vtop--; |
| 1611 | return t; | 1628 | return t; |