History

Fix va_arg bug, Fix type conversion bug, an increase of loc_stack () function is used to manage loc

jiang committed 12 years ago

Commit 5af0ea71 parent 9ff28865 files · +245 −163Browse files

Unified · Split

5 files
  1. lib/libtcc1.c +66 −62
  2. tcc.h +1 −0
  3. tccgen.c +127 −72
  4. tests/tcctest.c +17 −6
  5. x86_64-gen.c +34 −23
lib/libtcc1.c+66−62
@@ -530,74 +530,77 @@ long double __floatundixf(unsigned long long a) · 529 unmodified lines
530 530
531unsigned long long __fixunssfdi (float a1)531unsigned long long __fixunssfdi (float a1)
532{532{
533 register union float_long fl1;533 register union float_long fl1;
534 register int exp;534 register int exp;
535 register unsigned long l;535 register unsigned long l;
536 536 int s;
537 fl1.f = a1;537 fl1.f = a1;
538 538
539 if (fl1.l == 0)539 if (fl1.l == 0)
540 return (0);540 return 0;
541 541
542 exp = EXP (fl1.l) - EXCESS - 24;542 exp = EXP (fl1.l) - EXCESS - 24;
543 543
544 l = MANT(fl1.l);544 l = MANT(fl1.l);
545 if (exp >= 41)545 s = SIGN(fl1.l)? -1: 1;
546 return (unsigned long long)-1;546 if (exp >= 64)
547 else if (exp >= 0)547 return (unsigned long long)-1;
548 return (unsigned long long)l << exp;548 else if (exp >= 0)
549 else if (exp >= -23)549 return ((unsigned long long)l << exp)*s;
550 return l >> -exp;550 else if (exp >= -23)
551 else551 return (l >> -exp)*s;
552 return 0;552 else
553 return 0;
553}554}
554 555
555unsigned long long __fixunsdfdi (double a1)556unsigned long long __fixunsdfdi (double a1)
556{557{
557 register union double_long dl1;558 register union double_long dl1;
558 register int exp;559 register int exp;
559 register unsigned long long l;560 register unsigned long long l;
560 561 int s;
561 dl1.d = a1;562 dl1.d = a1;
562 563
563 if (dl1.ll == 0)564 if (dl1.ll == 0)
564 return (0);565 return (0);
565 566
566 exp = EXPD (dl1) - EXCESSD - 53;567 exp = EXPD (dl1) - EXCESSD - 53;
567 568
568 l = MANTD_LL(dl1);569 l = MANTD_LL(dl1);
569 570 s = SIGND(dl1)? -1: 1;
570 if (exp >= 12)571 if (exp >= 64)
571 return (unsigned long long)-1;572 return (unsigned long long)-1;
572 else if (exp >= 0)573 else if (exp >= 0)
573 return l << exp;574 return (l << exp)*s;
574 else if (exp >= -52)575 else if (exp >= -52)
575 return l >> -exp;576 return (l >> -exp)*s;
576 else577 else
577 return 0;578 return 0;
578}579}
579 580
580unsigned long long __fixunsxfdi (long double a1)581unsigned long long __fixunsxfdi (long double a1)
581{582{
582 register union ldouble_long dl1;583 register union ldouble_long dl1;
583 register int exp;584 register int exp;
584 register unsigned long long l;585 register unsigned long long l;
585 586 int s;
586 dl1.ld = a1;587 dl1.ld = a1;
587 588
588 if (dl1.l.lower == 0 && dl1.l.upper == 0)589 if (dl1.l.lower == 0 && dl1.l.upper == 0)
589 return (0);590 return (0);
590 591
591 exp = EXPLD (dl1) - EXCESSLD - 64;592 exp = EXPLD (dl1) - EXCESSLD - 64;
592 593 s = SIGNLD(dl1)? -1: 1;
593 l = dl1.l.lower;594 l = dl1.l.lower;
594 595
595 if (exp > 0)596 if (exp >= 64)
596 return (unsigned long long)-1;597 return (unsigned long long)-1;
597 else if (exp >= -63) 598 else if (exp >= 0)
598 return l >> -exp;599 return ((unsigned long long)l << exp)*s;
599 else600 else if (exp >= -64)
600 return 0;601 return (l >> -exp)*s;
602 else
603 return 0;
601}604}
602 605
603long long __fixsfdi (float a1)606long long __fixsfdi (float a1)
@@ -637,7 +640,7 @@ extern void abort(void); · 33 unmodified lines
637#endif640#endif
638 641
639enum __va_arg_type {642enum __va_arg_type {
640 __va_gen_reg, __va_float_reg, __va_stack643 __va_gen_reg, __va_float_reg, __va_ld_reg, __va_stack
641};644};
642 645
643//This should be in sync with the declaration on our include/stdarg.h646//This should be in sync with the declaration on our include/stdarg.h
@@ -688,10 +691,11 @@ void *__va_arg(__va_list_struct *ap, · 44 unmodified lines
688 size = 8;691 size = 8;
689 goto use_overflow_area;692 goto use_overflow_area;
690 693
694 case __va_ld_reg:
695 ap->overflow_arg_area = (char*)((intptr_t)(ap->overflow_arg_area + align - 1) & -(intptr_t)align);
691 case __va_stack:696 case __va_stack:
692 use_overflow_area:697 use_overflow_area:
693 ap->overflow_arg_area += size;698 ap->overflow_arg_area += size;
694 ap->overflow_arg_area = (char*)((intptr_t)(ap->overflow_arg_area + align - 1) & -(intptr_t)align);
695 return ap->overflow_arg_area - size;699 return ap->overflow_arg_area - size;
696 700
697 default:701 default:
tcc.h+1−0
@@ -1194,6 +1194,7 @@ ST_DATA int func_var; /* true if current function is variadic */ · 1193 unmodified lines
1194ST_DATA int func_vc;1194ST_DATA int func_vc;
1195ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */1195ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
1196ST_DATA char *funcname;1196ST_DATA char *funcname;
1197ST_DATA int pop_stack;
1197 1198
1198ST_INLN int is_float(int t);1199ST_INLN int is_float(int t);
1199ST_FUNC int ieee_finite(double d);1200ST_FUNC int ieee_finite(double d);
tccgen.c+127−72
@@ -70,6 +70,7 @@ ST_DATA int func_var; /* true if current function is variadic (used by return in · 69 unmodified lines
70ST_DATA int func_vc;70ST_DATA int func_vc;
71ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */71ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
72ST_DATA char *funcname;72ST_DATA char *funcname;
73ST_DATA int pop_stack;
73 74
74ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;75ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
75 76
@@ -524,6 +525,41 @@ static void vdup(void) · 448 unmodified lines
524 vpushv(vtop);525 vpushv(vtop);
525}526}
526 527
528static int align_size(int size)
529{
530#ifdef TCC_TARGET_X86_64
531 if(size > 4)
532 return 8;
533 else
534#endif
535 if(size > 2)
536 return 4;
537 else if(size > 1)
538 return 2;
539 else
540 return 1;
541}
542
543int loc_stack(int size, int is_sub){
544 int l, align;
545 align = align_size(size);
546 size = (size + align - 1) & - align;
547 if(is_sub){
548 pop_stack -= size;
549 if(pop_stack >= 0)
550 l = loc + pop_stack;
551 else{
552 loc += pop_stack;
553 l = loc &= -align;
554 pop_stack = 0;
555 }
556 }else{
557 pop_stack += size;
558 l = loc + pop_stack;
559 }
560 return l;
561}
562
527/* save r to the memory stack, and mark it as being free */563/* save r to the memory stack, and mark it as being free */
528ST_FUNC void save_reg(int r)564ST_FUNC void save_reg(int r)
529{565{
@@ -924,13 +960,10 @@ ST_FUNC int gv(int rc) · 394 unmodified lines
924/* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */960/* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
925ST_FUNC void gv2(int rc1, int rc2)961ST_FUNC void gv2(int rc1, int rc2)
926{962{
927 int v;
928
929 /* generate more generic register first. But VT_JMP or VT_CMP963 /* generate more generic register first. But VT_JMP or VT_CMP
930 values must be generated first in all cases to avoid possible964 values must be generated first in all cases to avoid possible
931 reload errors */965 reload errors */
932 v = vtop[0].r & VT_VALMASK;966 if (rc1 <= rc2) {
933 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
934 vswap();967 vswap();
935 gv(rc1);968 gv(rc1);
936 vswap();969 vswap();
@@ -1018,6 +1051,7 @@ ST_FUNC void lexpand_nr(void) · 81 unmodified lines
1018}1051}
1019#endif1052#endif
1020 1053
1054#ifndef TCC_TARGET_X86_64
1021/* build a long long from two ints */1055/* build a long long from two ints */
1022static void lbuild(int t)1056static void lbuild(int t)
1023{1057{
@@ -1026,6 +1060,7 @@ static void lbuild(int t) · 2 unmodified lines
1026 vtop[-1].type.t = t;1060 vtop[-1].type.t = t;
1027 vpop();1061 vpop();
1028}1062}
1063#endif
1029 1064
1030/* rotate n first stack elements to the bottom 1065/* rotate n first stack elements to the bottom
1031 I1 ... In -> I2 ... In I1 [top is right]1066 I1 ... In -> I2 ... In I1 [top is right]
@@ -1087,8 +1122,8 @@ static void gv_dup(void) · 55 unmodified lines
1087{1122{
1088 int rc, t, r, r1;1123 int rc, t, r, r1;
1089 SValue sv;1124 SValue sv;
1090
1091 t = vtop->type.t;1125 t = vtop->type.t;
1126#ifndef TCC_TARGET_X86_64
1092 if ((t & VT_BTYPE) == VT_LLONG) {1127 if ((t & VT_BTYPE) == VT_LLONG) {
1093 lexpand();1128 lexpand();
1094 gv_dup();1129 gv_dup();
@@ -1098,15 +1133,14 @@ static void gv_dup(void) · 3 unmodified lines
1098 vrotb(4);1133 vrotb(4);
1099 /* stack: H L L1 H1 */1134 /* stack: H L L1 H1 */
1100 lbuild(t);1135 lbuild(t);
1101 vrotb(3);1136 vrott(3);
1102 vrotb(3);
1103 vswap();1137 vswap();
1104 lbuild(t);1138 lbuild(t);
1105 vswap();1139 vswap();
1106 } else {1140 } else
1141#endif
1142 {
1107 /* duplicate value */1143 /* duplicate value */
1108 rc = RC_INT;
1109 sv.type.t = VT_INT;
1110 if (is_float(t)) {1144 if (is_float(t)) {
1111 rc = RC_FLOAT;1145 rc = RC_FLOAT;
1112#ifdef TCC_TARGET_X86_641146#ifdef TCC_TARGET_X86_64
@@ -1114,8 +1148,9 @@ static void gv_dup(void) · 1 unmodified line
1114 rc = RC_ST0;1148 rc = RC_ST0;
1115 }1149 }
1116#endif1150#endif
1117 sv.type.t = t;1151 }else
1118 }1152 rc = RC_INT;
1153 sv.type.t = t;
1119 r = gv(rc);1154 r = gv(rc);
1120 r1 = get_reg(rc);1155 r1 = get_reg(rc);
1121 sv.r = r;1156 sv.r = r;
@@ -1127,7 +1162,6 @@ static void gv_dup(void) · 5 unmodified lines
1127 vtop->r = r1;1162 vtop->r = r1;
1128 }1163 }
1129}1164}
1130
1131#ifndef TCC_TARGET_X86_641165#ifndef TCC_TARGET_X86_64
1132/* generate CPU independent (unsigned) long long operations */1166/* generate CPU independent (unsigned) long long operations */
1133static void gen_opl(int op)1167static void gen_opl(int op)
@@ -2441,17 +2475,78 @@ static void gen_assign_cast(CType *dt) · 1307 unmodified lines
2441 gen_cast(dt);2475 gen_cast(dt);
2442}2476}
2443 2477
2478static void vstore_im(){
2479 int rc, ft, sbt, dbt, t, r;
2480 ft = vtop[-1].type.t;
2481 sbt = vtop->type.t & VT_BTYPE;
2482 dbt = ft & VT_BTYPE;
2483 if (is_float(ft)) {
2484 rc = RC_FLOAT;
2485#ifdef TCC_TARGET_X86_64
2486 if (dbt == VT_LDOUBLE) {
2487 rc = RC_ST0;
2488 }
2489#endif
2490 }else
2491 rc = RC_INT;
2492 r = gv(rc); /* generate value */
2493 /* if lvalue was saved on stack, must read it */
2494 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2495 SValue sv;
2496 t = get_reg(RC_INT);
2497#ifdef TCC_TARGET_X86_64
2498 sv.type.t = VT_PTR;
2499#else
2500 sv.type.t = VT_INT;
2501#endif
2502 sv.r = VT_LOCAL | VT_LVAL;
2503 sv.c.ul = vtop[-1].c.ul;
2504 load(t, &sv);
2505 vtop[-1].r = t | VT_LVAL;
2506 vtop[-1].c.ul = 0;
2507 }
2508 /* two word case handling : store second register at word + 4 */
2509#ifdef TCC_TARGET_X86_64
2510 if ((dbt == VT_QLONG) || (dbt == VT_QFLOAT))
2511#else
2512 if (dbt == VT_LLONG)
2513#endif
2514 {
2515#ifdef TCC_TARGET_X86_64
2516 int load_size = 8, load_type = (sbt == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
2517#else
2518 int load_size = 4, load_type = VT_INT;
2519#endif
2520 vtop[-1].type.t = load_type;
2521 store(r, vtop - 1);
2522 vswap();
2523 /* convert to int to increment easily */
2524 vtop->type = char_pointer_type;
2525 gaddrof();
2526 vpushi(load_size);
2527 gen_op('+');
2528 vtop->r |= VT_LVAL;
2529 vswap();
2530 vtop[-1].type.t = load_type;
2531 /* XXX: it works because r2 is spilled last ! */
2532 store(vtop->r2, vtop - 1);
2533 vtop->type.t = ft;
2534 vtop[-1].type.t = ft;
2535 } else {
2536 store(r, vtop - 1);
2537 }
2538}
2539
2444/* store vtop in lvalue pushed on stack */2540/* store vtop in lvalue pushed on stack */
2445ST_FUNC void vstore(void)2541ST_FUNC void vstore(void)
2446{2542{
2447 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;2543 int sbt, dbt, ft, size, align, bit_size, bit_pos, delayed_cast;
2448 2544
2449 ft = vtop[-1].type.t;2545 ft = vtop[-1].type.t;
2450 sbt = vtop->type.t & VT_BTYPE;2546 sbt = vtop->type.t & VT_BTYPE;
2451 dbt = ft & VT_BTYPE;2547 dbt = ft & VT_BTYPE;
2452 if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||2548 if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2453 (sbt == VT_INT && dbt == VT_SHORT))2549 (sbt == VT_INT && dbt == VT_SHORT)) && !(vtop->type.t & VT_BITFIELD)) {
2454 && !(vtop->type.t & VT_BITFIELD)) {
2455 /* optimize char/short casts */2550 /* optimize char/short casts */
2456 delayed_cast = VT_MUSTCAST;2551 delayed_cast = VT_MUSTCAST;
2457 vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));2552 vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
@@ -2507,15 +2602,15 @@ ST_FUNC void vstore(void) · 49 unmodified lines
2507 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));2602 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2508 2603
2509 /* duplicate source into other register */2604 /* duplicate source into other register */
2510 gv_dup();
2511 vswap();
2512 vrott(3);
2513
2514 if((ft & VT_BTYPE) == VT_BOOL) {2605 if((ft & VT_BTYPE) == VT_BOOL) {
2515 gen_cast(&vtop[-1].type);2606 gen_cast(&vtop[-1].type);
2516 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);2607 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2517 }2608 }
2518 2609
2610 /* duplicate destination */
2611 vdup();
2612 vtop[-1] = vtop[-2];
2613
2519 /* duplicate destination */2614 /* duplicate destination */
2520 vdup();2615 vdup();
2521 vtop[-1] = vtop[-2];2616 vtop[-1] = vtop[-2];
@@ -2556,56 +2651,7 @@ ST_FUNC void vstore(void) · 34 unmodified lines
2556 }2651 }
2557#endif2652#endif
2558 if (!nocode_wanted) {2653 if (!nocode_wanted) {
2559 rc = RC_INT;2654 vstore_im();
2560 if (is_float(ft)) {
2561 rc = RC_FLOAT;
2562#ifdef TCC_TARGET_X86_64
2563 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2564 rc = RC_ST0;
2565 } else if ((ft & VT_BTYPE) == VT_QFLOAT) {
2566 rc = RC_FRET;
2567 }
2568#endif
2569 }
2570 r = gv(rc); /* generate value */
2571 /* if lvalue was saved on stack, must read it */
2572 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2573 SValue sv;
2574 t = get_reg(RC_INT);
2575#ifdef TCC_TARGET_X86_64
2576 sv.type.t = VT_PTR;
2577#else
2578 sv.type.t = VT_INT;
2579#endif
2580 sv.r = VT_LOCAL | VT_LVAL;
2581 sv.c.ul = vtop[-1].c.ul;
2582 load(t, &sv);
2583 vtop[-1].r = t | VT_LVAL;
2584 }
2585 /* two word case handling : store second register at word + 4 (or +8 for x86-64) */
2586#ifdef TCC_TARGET_X86_64
2587 if (((ft & VT_BTYPE) == VT_QLONG) || ((ft & VT_BTYPE) == VT_QFLOAT)) {
2588 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
2589#else
2590 if ((ft & VT_BTYPE) == VT_LLONG) {
2591 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
2592#endif
2593 vtop[-1].type.t = load_type;
2594 store(r, vtop - 1);
2595 vswap();
2596 /* convert to int to increment easily */
2597 vtop->type.t = addr_type;
2598 gaddrof();
2599 vpushi(load_size);
2600 gen_op('+');
2601 vtop->r |= VT_LVAL;
2602 vswap();
2603 vtop[-1].type.t = load_type;
2604 /* XXX: it works because r2 is spilled last ! */
2605 store(vtop->r2, vtop - 1);
2606 } else {
2607 store(r, vtop - 1);
2608 }
2609 }2655 }
2610 vswap();2656 vswap();
2611 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */2657 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
@@ -4623,6 +4669,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 2011 unmodified lines
4623 gsym_addr(b, d);4669 gsym_addr(b, d);
4624 } else if (tok == '{') {4670 } else if (tok == '{') {
4625 Sym *llabel;4671 Sym *llabel;
4672 int saved_loc, saved_pop_stack, size;
4626 int block_vla_sp_loc, *saved_vla_sp_loc, saved_vla_flags;4673 int block_vla_sp_loc, *saved_vla_sp_loc, saved_vla_flags;
4627 4674
4628 next();4675 next();
@@ -4632,7 +4679,10 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 3 unmodified lines
4632 frame_bottom->next = scope_stack_bottom;4679 frame_bottom->next = scope_stack_bottom;
4633 scope_stack_bottom = frame_bottom;4680 scope_stack_bottom = frame_bottom;
4634 llabel = local_label_stack;4681 llabel = local_label_stack;
4635 4682
4683 saved_loc = loc;
4684 saved_pop_stack = pop_stack;
4685
4636 /* save VLA state */4686 /* save VLA state */
4637 block_vla_sp_loc = *(saved_vla_sp_loc = vla_sp_loc);4687 block_vla_sp_loc = *(saved_vla_sp_loc = vla_sp_loc);
4638 if (saved_vla_sp_loc != &vla_sp_root_loc)4688 if (saved_vla_sp_loc != &vla_sp_root_loc)
@@ -4684,7 +4734,12 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 45 unmodified lines
4684 /* pop locally defined symbols */4734 /* pop locally defined symbols */
4685 scope_stack_bottom = scope_stack_bottom->next;4735 scope_stack_bottom = scope_stack_bottom->next;
4686 sym_pop(&local_stack, s);4736 sym_pop(&local_stack, s);
4687 4737
4738 size = -(loc - saved_loc);
4739 pop_stack = saved_pop_stack;
4740 if(size)
4741 pop_stack += size;
4742
4688 /* Pop VLA frames and restore stack pointer if required */4743 /* Pop VLA frames and restore stack pointer if required */
4689 if (saved_vla_sp_loc != &vla_sp_root_loc)4744 if (saved_vla_sp_loc != &vla_sp_root_loc)
4690 *saved_vla_sp_loc = block_vla_sp_loc;4745 *saved_vla_sp_loc = block_vla_sp_loc;
tests/tcctest.c+17−6
@@ -1680,7 +1680,6 @@ void prefix ## fcast(type a)\ · 1679 unmodified lines
1680 printf("ftof: %f %f %Lf\n", fa, da, la);\1680 printf("ftof: %f %f %Lf\n", fa, da, la);\
1681 ia = (int)a;\1681 ia = (int)a;\
1682 llia = (long long)a;\1682 llia = (long long)a;\
1683 a = (a >= 0) ? a : -a;\
1684 ua = (unsigned int)a;\1683 ua = (unsigned int)a;\
1685 llua = (unsigned long long)a;\1684 llua = (unsigned long long)a;\
1686 printf("ftoi: %d %u %lld %llu\n", ia, ua, llia, llua);\1685 printf("ftoi: %d %u %lld %llu\n", ia, ua, llia, llua);\
@@ -1710,6 +1709,18 @@ void prefix ## call(void)\ · 23 unmodified lines
1710 printf("strto%s: %f\n", #prefix, (double)strto ## prefix("1.2", NULL));\1709 printf("strto%s: %f\n", #prefix, (double)strto ## prefix("1.2", NULL));\
1711}\1710}\
1712\1711\
1712void prefix ## calc(type x, type y)\
1713{\
1714 x=x*x;y=y*y;\
1715 printf("%d, %d\n", (int)x, (int)y);\
1716 x=x-y;y=y-x;\
1717 printf("%d, %d\n", (int)x, (int)y);\
1718 x=x/y;y=y/x;\
1719 printf("%d, %d\n", (int)x, (int)y);\
1720 x=x+x;y=y+y;\
1721 printf("%d, %d\n", (int)x, (int)y);\
1722}\
1723\
1713void prefix ## signed_zeros(void) \1724void prefix ## signed_zeros(void) \
1714{\1725{\
1715 type x = 0.0, y = -0.0, n, p;\1726 type x = 0.0, y = -0.0, n, p;\
@@ -1732,7 +1743,7 @@ void prefix ## signed_zeros(void) \ · 16 unmodified lines
1732 1.0 / x != 1.0 / p);\1743 1.0 / x != 1.0 / p);\
1733 else\1744 else\
1734 printf ("x != +y; this is wrong!\n");\1745 printf ("x != +y; this is wrong!\n");\
1735 p = -y;\1746 p = -y;\
1736 if (x == p)\1747 if (x == p)\
1737 printf ("Test 1.0 / x != 1.0 / -y returns %d (should be 0).\n",\1748 printf ("Test 1.0 / x != 1.0 / -y returns %d (should be 0).\n",\
1738 1.0 / x != 1.0 / p);\1749 1.0 / x != 1.0 / p);\
@@ -1748,7 +1759,8 @@ void prefix ## test(void)\ · 9 unmodified lines
1748 prefix ## fcast(234.6);\1759 prefix ## fcast(234.6);\
1749 prefix ## fcast(-2334.6);\1760 prefix ## fcast(-2334.6);\
1750 prefix ## call();\1761 prefix ## call();\
1751 prefix ## signed_zeros();\1762 prefix ## calc(1, 1.0000000000000001);\
1763 prefix ## signed_zeros();\
1752}1764}
1753 1765
1754FTEST(f, float, float, "%f")1766FTEST(f, float, float, "%f")
@@ -2572,7 +2584,6 @@ int constant_p_var; · 817 unmodified lines
2572 2584
2573void builtin_test(void)2585void builtin_test(void)
2574{2586{
2575#if GCC_MAJOR >= 3
2576 COMPAT_TYPE(int, int);2587 COMPAT_TYPE(int, int);
2577 COMPAT_TYPE(int, unsigned int);2588 COMPAT_TYPE(int, unsigned int);
2578 COMPAT_TYPE(int, char);2589 COMPAT_TYPE(int, char);
@@ -2582,9 +2593,9 @@ void builtin_test(void) · 3 unmodified lines
2582 COMPAT_TYPE(int *, void *);2593 COMPAT_TYPE(int *, void *);
2583 COMPAT_TYPE(int *, const int *);2594 COMPAT_TYPE(int *, const int *);
2584 COMPAT_TYPE(char *, unsigned char *);2595 COMPAT_TYPE(char *, unsigned char *);
2596 COMPAT_TYPE(char, unsigned char);
2585/* space is needed because tcc preprocessor introduces a space between each token */2597/* space is needed because tcc preprocessor introduces a space between each token */
2586 COMPAT_TYPE(char * *, void *); 2598 COMPAT_TYPE(char **, void *);
2587#endif
2588 printf("res = %d\n", __builtin_constant_p(1));2599 printf("res = %d\n", __builtin_constant_p(1));
2589 printf("res = %d\n", __builtin_constant_p(1 + 2));2600 printf("res = %d\n", __builtin_constant_p(1 + 2));
2590 printf("res = %d\n", __builtin_constant_p(&constant_p_var));2601 printf("res = %d\n", __builtin_constant_p(&constant_p_var));
x86_64-gen.c+34−23
@@ -826,7 +826,7 @@ void gfunc_prolog(CType *func_type) · 825 unmodified lines
826 826
827 func_ret_sub = 0;827 func_ret_sub = 0;
828 func_scratch = 0;828 func_scratch = 0;
829 loc = 0;829 pop_stack = loc = 0;
830 830
831 addr = PTR_SIZE * 2;831 addr = PTR_SIZE * 2;
832 ind += FUNC_PROLOG_SIZE;832 ind += FUNC_PROLOG_SIZE;
@@ -968,12 +968,14 @@ static X86_64_Mode classify_x86_64_inner(CType *ty) · 135 unmodified lines
968 case VT_BYTE:968 case VT_BYTE:
969 case VT_SHORT:969 case VT_SHORT:
970 case VT_LLONG:970 case VT_LLONG:
971 case VT_QLONG:
971 case VT_BOOL:972 case VT_BOOL:
972 case VT_PTR:973 case VT_PTR:
973 case VT_FUNC:974 case VT_FUNC:
974 case VT_ENUM: return x86_64_mode_integer;975 case VT_ENUM: return x86_64_mode_integer;
975 976
976 case VT_FLOAT:977 case VT_FLOAT:
978 case VT_QFLOAT:
977 case VT_DOUBLE: return x86_64_mode_sse;979 case VT_DOUBLE: return x86_64_mode_sse;
978 980
979 case VT_LDOUBLE: return x86_64_mode_x87;981 case VT_LDOUBLE: return x86_64_mode_x87;
@@ -984,7 +986,7 @@ static X86_64_Mode classify_x86_64_inner(CType *ty) · 4 unmodified lines
984 // Detect union986 // Detect union
985 if (f->next && (f->c == f->next->c))987 if (f->next && (f->c == f->next->c))
986 return x86_64_mode_memory;988 return x86_64_mode_memory;
987 989
988 mode = x86_64_mode_none;990 mode = x86_64_mode_none;
989 for (f = f->next; f; f = f->next)991 for (f = f->next; f; f = f->next)
990 mode = classify_x86_64_merge(mode, classify_x86_64_inner(&f->type));992 mode = classify_x86_64_merge(mode, classify_x86_64_inner(&f->type));
@@ -995,14 +997,14 @@ static X86_64_Mode classify_x86_64_inner(CType *ty) · 4 unmodified lines
995 assert(0);997 assert(0);
996}998}
997 999
998static X86_64_Mode classify_x86_64_arg(CType *ty, CType *ret, int *psize, int *palign, int *reg_count)1000static int classify_x86_64_arg(CType *ty, CType *ret, int *psize, int *palign, int *reg_count)
999{1001{
1000 X86_64_Mode mode;1002 X86_64_Mode mode;
1001 int size, align, ret_t = 0;1003 int size, align, ret_t = 0;
1002 1004
1003 if (ty->t & (VT_BITFIELD|VT_ARRAY)) {1005 if (ty->t & (VT_BITFIELD|VT_ARRAY)) {
1004 *psize = 8;1006 *psize = 8;
1005 *palign = 8;1007 *palign = 8;
1006 *reg_count = 1;1008 *reg_count = 1;
1007 ret_t = ty->t;1009 ret_t = ty->t;
1008 mode = x86_64_mode_integer;1010 mode = x86_64_mode_integer;
@@ -1013,6 +1015,7 @@ static X86_64_Mode classify_x86_64_arg(CType *ty, CType *ret, int *psize, int *p · 4 unmodified lines
1013 1015
1014 if (size > 16) {1016 if (size > 16) {
1015 mode = x86_64_mode_memory;1017 mode = x86_64_mode_memory;
1018 ret_t = ty->t;
1016 } else {1019 } else {
1017 mode = classify_x86_64_inner(ty);1020 mode = classify_x86_64_inner(ty);
1018 switch (mode) {1021 switch (mode) {
@@ -1021,16 +1024,22 @@ static X86_64_Mode classify_x86_64_arg(CType *ty, CType *ret, int *psize, int *p · 2 unmodified lines
1021 *reg_count = 2;1024 *reg_count = 2;
1022 ret_t = VT_QLONG;1025 ret_t = VT_QLONG;
1023 } else {1026 } else {
1024 *reg_count = 1;1027 *reg_count = 1;
1025 ret_t = (size > 4) ? VT_LLONG : VT_INT;1028 if(size > 4)
1026 }1029 ret_t = VT_LLONG;
1030 else if(size > 2){
1031 ret_t = VT_INT;
1032 }else if(size > 1)
1033 ret_t = VT_SHORT;
1034 else
1035 ret_t = VT_BYTE;
1036 }
1037 ret_t |= (ty->t & VT_UNSIGNED);
1027 break;1038 break;
1028
1029 case x86_64_mode_x87:1039 case x86_64_mode_x87:
1030 *reg_count = 1;1040 *reg_count = 1;
1031 ret_t = VT_LDOUBLE;1041 ret_t = VT_LDOUBLE;
1032 break;1042 break;
1033
1034 case x86_64_mode_sse:1043 case x86_64_mode_sse:
1035 if (size > 8) {1044 if (size > 8) {
1036 *reg_count = 2;1045 *reg_count = 2;
@@ -1040,13 +1049,15 @@ static X86_64_Mode classify_x86_64_arg(CType *ty, CType *ret, int *psize, int *p · 3 unmodified lines
1040 ret_t = (size > 4) ? VT_DOUBLE : VT_FLOAT;1049 ret_t = (size > 4) ? VT_DOUBLE : VT_FLOAT;
1041 }1050 }
1042 break;1051 break;
1043 default: break; /* nothing to be done for x86_64_mode_memory and x86_64_mode_none*/1052 default:
1053 ret_t = ty->t;
1054 break; /* nothing to be done for x86_64_mode_memory and x86_64_mode_none*/
1044 }1055 }
1045 }1056 }
1046 }1057 }
1047 1058
1048 if (ret) {1059 if (ret) {
1049 ret->ref = NULL;1060 ret->ref = ty->ref;
1050 ret->t = ret_t;1061 ret->t = ret_t;
1051 }1062 }
1052 1063
@@ -1057,12 +1068,13 @@ ST_FUNC int classify_x86_64_va_arg(CType *ty) · 4 unmodified lines
1057{1068{
1058 /* This definition must be synced with stdarg.h */1069 /* This definition must be synced with stdarg.h */
1059 enum __va_arg_type {1070 enum __va_arg_type {
1060 __va_gen_reg, __va_float_reg, __va_stack1071 __va_gen_reg, __va_float_reg, __va_ld_reg, __va_stack
1061 };1072 };
1062 int size, align, reg_count;1073 int size, align, reg_count;
1063 X86_64_Mode mode = classify_x86_64_arg(ty, NULL, &size, &align, &reg_count);1074 X86_64_Mode mode = classify_x86_64_arg(ty, NULL, &size, &align, &reg_count);
1064 switch (mode) {1075 switch (mode) {
1065 default: return __va_stack;1076 default: return __va_stack;
1077 case x86_64_mode_x87: return __va_ld_reg;
1066 case x86_64_mode_integer: return __va_gen_reg;1078 case x86_64_mode_integer: return __va_gen_reg;
1067 case x86_64_mode_sse: return __va_float_reg;1079 case x86_64_mode_sse: return __va_float_reg;
1068 }1080 }
@@ -1387,7 +1399,7 @@ void gfunc_prolog(CType *func_type) · 318 unmodified lines
1387 1399
1388 sym = func_type->ref;1400 sym = func_type->ref;
1389 addr = PTR_SIZE * 2;1401 addr = PTR_SIZE * 2;
1390 loc = 0;1402 pop_stack = loc = 0;
1391 ind += FUNC_PROLOG_SIZE;1403 ind += FUNC_PROLOG_SIZE;
1392 func_sub_sp_offset = ind;1404 func_sub_sp_offset = ind;
1393 func_ret_sub = 0;1405 func_ret_sub = 0;
@@ -1398,7 +1410,6 @@ void gfunc_prolog(CType *func_type) · 4 unmodified lines
1398 /* frame pointer and return address */1410 /* frame pointer and return address */
1399 seen_stack_size = PTR_SIZE * 2;1411 seen_stack_size = PTR_SIZE * 2;
1400 /* count the number of seen parameters */1412 /* count the number of seen parameters */
1401 sym = func_type->ref;
1402 while ((sym = sym->next) != NULL) {1413 while ((sym = sym->next) != NULL) {
1403 type = &sym->type;1414 type = &sym->type;
1404 mode = classify_x86_64_arg(type, NULL, &size, &align, &reg_count);1415 mode = classify_x86_64_arg(type, NULL, &size, &align, &reg_count);
@@ -1439,19 +1450,19 @@ void gfunc_prolog(CType *func_type) · 34 unmodified lines
1439 o(0xf845c7);1450 o(0xf845c7);
1440 gen_le32(seen_stack_size);1451 gen_le32(seen_stack_size);
1441 1452
1453 o(0xc084);/* test %al,%al */
1454 o(0x74);/* je */
1455 g(4*(8 - seen_sse_num) + 3);
1456
1442 /* save all register passing arguments */1457 /* save all register passing arguments */
1443 for (i = 0; i < 8; i++) {1458 for (i = 0; i < 8; i++) {
1444 loc -= 16;1459 loc -= 16;
1445 o(0xd60f66); /* movq */1460 o(0x290f);/* movaps %xmm1-7,-XXX(%rbp) */
1446 gen_modrm(7 - i, VT_LOCAL, NULL, loc);1461 gen_modrm(7 - i, VT_LOCAL, NULL, loc);
1447 /* movq $0, loc+8(%rbp) */
1448 o(0x85c748);
1449 gen_le32(loc + 8);
1450 gen_le32(0);
1451 }
1452 for (i = 0; i < REGN; i++) {
1453 push_arg_reg(REGN-1-i);
1454 }1462 }
1463 for (i = 0; i < (REGN - seen_reg_num); i++) {
1464 push_arg_reg(REGN-1 - i);
1465 }
1455 }1466 }
1456 1467
1457 sym = func_type->ref;1468 sym = func_type->ref;

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