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
530530
531531 unsigned long long __fixunssfdi (float a1)
532532 {
533− register union float_long fl1;
534− register int exp;
535− register unsigned long l;
536−
537− fl1.f = a1;
538−
539− if (fl1.l == 0)
540− return (0);
541−
542− exp = EXP (fl1.l) - EXCESS - 24;
543−
544− l = MANT(fl1.l);
545− if (exp >= 41)
546− return (unsigned long long)-1;
547− else if (exp >= 0)
548− return (unsigned long long)l << exp;
549− else if (exp >= -23)
550− return l >> -exp;
551− else
552− return 0;
533+ register union float_long fl1;
534+ register int exp;
535+ register unsigned long l;
536+ int s;
537+ fl1.f = a1;
538+
539+ if (fl1.l == 0)
540+ return 0;
541+
542+ exp = EXP (fl1.l) - EXCESS - 24;
543+
544+ l = MANT(fl1.l);
545+ s = SIGN(fl1.l)? -1: 1;
546+ if (exp >= 64)
547+ return (unsigned long long)-1;
548+ else if (exp >= 0)
549+ return ((unsigned long long)l << exp)*s;
550+ else if (exp >= -23)
551+ return (l >> -exp)*s;
552+ else
553+ return 0;
553554 }
554555
555556 unsigned long long __fixunsdfdi (double a1)
556557 {
557− register union double_long dl1;
558− register int exp;
559− register unsigned long long l;
560−
561− dl1.d = a1;
562−
563− if (dl1.ll == 0)
564− return (0);
565−
566− exp = EXPD (dl1) - EXCESSD - 53;
567−
568− l = MANTD_LL(dl1);
569−
570− if (exp >= 12)
571− return (unsigned long long)-1;
572− else if (exp >= 0)
573− return l << exp;
574− else if (exp >= -52)
575− return l >> -exp;
576− else
577− return 0;
558+ register union double_long dl1;
559+ register int exp;
560+ register unsigned long long l;
561+ int s;
562+ dl1.d = a1;
563+
564+ if (dl1.ll == 0)
565+ return (0);
566+
567+ exp = EXPD (dl1) - EXCESSD - 53;
568+
569+ l = MANTD_LL(dl1);
570+ s = SIGND(dl1)? -1: 1;
571+ if (exp >= 64)
572+ return (unsigned long long)-1;
573+ else if (exp >= 0)
574+ return (l << exp)*s;
575+ else if (exp >= -52)
576+ return (l >> -exp)*s;
577+ else
578+ return 0;
578579 }
579580
580581 unsigned long long __fixunsxfdi (long double a1)
581582 {
582− register union ldouble_long dl1;
583− register int exp;
584− register unsigned long long l;
585−
586− dl1.ld = a1;
587−
588− if (dl1.l.lower == 0 && dl1.l.upper == 0)
589− return (0);
590−
591− exp = EXPLD (dl1) - EXCESSLD - 64;
592−
593− l = dl1.l.lower;
594−
595− if (exp > 0)
596− return (unsigned long long)-1;
597− else if (exp >= -63)
598− return l >> -exp;
599− else
600− return 0;
583+ register union ldouble_long dl1;
584+ register int exp;
585+ register unsigned long long l;
586+ int s;
587+ dl1.ld = a1;
588+
589+ if (dl1.l.lower == 0 && dl1.l.upper == 0)
590+ return (0);
591+
592+ exp = EXPLD (dl1) - EXCESSLD - 64;
593+ s = SIGNLD(dl1)? -1: 1;
594+ l = dl1.l.lower;
595+
596+ if (exp >= 64)
597+ return (unsigned long long)-1;
598+ else if (exp >= 0)
599+ return ((unsigned long long)l << exp)*s;
600+ else if (exp >= -64)
601+ return (l >> -exp)*s;
602+ else
603+ return 0;
601604 }
602605
603606 long long __fixsfdi (float a1)
@@ -637,7 +640,7 @@ extern void abort(void); · 33 unmodified lines
637640 #endif
638641
639642 enum __va_arg_type {
640− __va_gen_reg, __va_float_reg, __va_stack
643+ __va_gen_reg, __va_float_reg, __va_ld_reg, __va_stack
641644 };
642645
643646 //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
688691 size = 8;
689692 goto use_overflow_area;
690693
694+ case __va_ld_reg:
695+ ap->overflow_arg_area = (char*)((intptr_t)(ap->overflow_arg_area + align - 1) & -(intptr_t)align);
691696 case __va_stack:
692697 use_overflow_area:
693698 ap->overflow_arg_area += size;
694− ap->overflow_arg_area = (char*)((intptr_t)(ap->overflow_arg_area + align - 1) & -(intptr_t)align);
695699 return ap->overflow_arg_area - size;
696700
697701 default:
tcc.h+1−0
@@ -1194,6 +1194,7 @@ ST_DATA int func_var; /* true if current function is variadic */ · 1193 unmodified lines
11941194 ST_DATA int func_vc;
11951195 ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
11961196 ST_DATA char *funcname;
1197+ST_DATA int pop_stack;
11971198
11981199 ST_INLN int is_float(int t);
11991200 ST_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
7070 ST_DATA int func_vc;
7171 ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
7272 ST_DATA char *funcname;
73+ST_DATA int pop_stack;
7374
7475 ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
7576
@@ -524,6 +525,41 @@ static void vdup(void) · 448 unmodified lines
524525 vpushv(vtop);
525526 }
526527
528+static 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+
543+int 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+
527563 /* save r to the memory stack, and mark it as being free */
528564 ST_FUNC void save_reg(int r)
529565 {
@@ -924,13 +960,10 @@ ST_FUNC int gv(int rc) · 394 unmodified lines
924960 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
925961 ST_FUNC void gv2(int rc1, int rc2)
926962 {
927− int v;
928−
929963 /* generate more generic register first. But VT_JMP or VT_CMP
930964 values must be generated first in all cases to avoid possible
931965 reload errors */
932− v = vtop[0].r & VT_VALMASK;
933− if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
966+ if (rc1 <= rc2) {
934967 vswap();
935968 gv(rc1);
936969 vswap();
@@ -1018,6 +1051,7 @@ ST_FUNC void lexpand_nr(void) · 81 unmodified lines
10181051 }
10191052 #endif
10201053
1054+#ifndef TCC_TARGET_X86_64
10211055 /* build a long long from two ints */
10221056 static void lbuild(int t)
10231057 {
@@ -1026,6 +1060,7 @@ static void lbuild(int t) · 2 unmodified lines
10261060 vtop[-1].type.t = t;
10271061 vpop();
10281062 }
1063+#endif
10291064
10301065 /* rotate n first stack elements to the bottom
10311066 I1 ... In -> I2 ... In I1 [top is right]
@@ -1087,8 +1122,8 @@ static void gv_dup(void) · 55 unmodified lines
10871122 {
10881123 int rc, t, r, r1;
10891124 SValue sv;
1090−
10911125 t = vtop->type.t;
1126+#ifndef TCC_TARGET_X86_64
10921127 if ((t & VT_BTYPE) == VT_LLONG) {
10931128 lexpand();
10941129 gv_dup();
@@ -1098,15 +1133,14 @@ static void gv_dup(void) · 3 unmodified lines
10981133 vrotb(4);
10991134 /* stack: H L L1 H1 */
11001135 lbuild(t);
1101− vrotb(3);
1102− vrotb(3);
1136+ vrott(3);
11031137 vswap();
11041138 lbuild(t);
11051139 vswap();
1106− } else {
1140+ } else
1141+#endif
1142+ {
11071143 /* duplicate value */
1108− rc = RC_INT;
1109− sv.type.t = VT_INT;
11101144 if (is_float(t)) {
11111145 rc = RC_FLOAT;
11121146 #ifdef TCC_TARGET_X86_64
@@ -1114,8 +1148,9 @@ static void gv_dup(void) · 1 unmodified line
11141148 rc = RC_ST0;
11151149 }
11161150 #endif
1117− sv.type.t = t;
1118− }
1151+ }else
1152+ rc = RC_INT;
1153+ sv.type.t = t;
11191154 r = gv(rc);
11201155 r1 = get_reg(rc);
11211156 sv.r = r;
@@ -1127,7 +1162,6 @@ static void gv_dup(void) · 5 unmodified lines
11271162 vtop->r = r1;
11281163 }
11291164 }
1130−
11311165 #ifndef TCC_TARGET_X86_64
11321166 /* generate CPU independent (unsigned) long long operations */
11331167 static void gen_opl(int op)
@@ -2441,17 +2475,78 @@ static void gen_assign_cast(CType *dt) · 1307 unmodified lines
24412475 gen_cast(dt);
24422476 }
24432477
2478+static 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+
24442540 /* store vtop in lvalue pushed on stack */
24452541 ST_FUNC void vstore(void)
24462542 {
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;
24482544
24492545 ft = vtop[-1].type.t;
24502546 sbt = vtop->type.t & VT_BTYPE;
24512547 dbt = ft & VT_BTYPE;
24522548 if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2453− (sbt == VT_INT && dbt == VT_SHORT))
2454− && !(vtop->type.t & VT_BITFIELD)) {
2549+ (sbt == VT_INT && dbt == VT_SHORT)) && !(vtop->type.t & VT_BITFIELD)) {
24552550 /* optimize char/short casts */
24562551 delayed_cast = VT_MUSTCAST;
24572552 vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
@@ -2507,15 +2602,15 @@ ST_FUNC void vstore(void) · 49 unmodified lines
25072602 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
25082603
25092604 /* duplicate source into other register */
2510− gv_dup();
2511− vswap();
2512− vrott(3);
2513−
25142605 if((ft & VT_BTYPE) == VT_BOOL) {
25152606 gen_cast(&vtop[-1].type);
25162607 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
25172608 }
25182609
2610+ /* duplicate destination */
2611+ vdup();
2612+ vtop[-1] = vtop[-2];
2613+
25192614 /* duplicate destination */
25202615 vdup();
25212616 vtop[-1] = vtop[-2];
@@ -2556,56 +2651,7 @@ ST_FUNC void vstore(void) · 34 unmodified lines
25562651 }
25572652 #endif
25582653 if (!nocode_wanted) {
2559− rc = RC_INT;
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− }
2654+ vstore_im();
26092655 }
26102656 vswap();
26112657 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
46234669 gsym_addr(b, d);
46244670 } else if (tok == '{') {
46254671 Sym *llabel;
4672+ int saved_loc, saved_pop_stack, size;
46264673 int block_vla_sp_loc, *saved_vla_sp_loc, saved_vla_flags;
46274674
46284675 next();
@@ -4632,7 +4679,10 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 3 unmodified lines
46324679 frame_bottom->next = scope_stack_bottom;
46334680 scope_stack_bottom = frame_bottom;
46344681 llabel = local_label_stack;
4635−
4682+
4683+ saved_loc = loc;
4684+ saved_pop_stack = pop_stack;
4685+
46364686 /* save VLA state */
46374687 block_vla_sp_loc = *(saved_vla_sp_loc = vla_sp_loc);
46384688 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
46844734 /* pop locally defined symbols */
46854735 scope_stack_bottom = scope_stack_bottom->next;
46864736 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+
46884743 /* Pop VLA frames and restore stack pointer if required */
46894744 if (saved_vla_sp_loc != &vla_sp_root_loc)
46904745 *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
16801680 printf("ftof: %f %f %Lf\n", fa, da, la);\
16811681 ia = (int)a;\
16821682 llia = (long long)a;\
1683− a = (a >= 0) ? a : -a;\
16841683 ua = (unsigned int)a;\
16851684 llua = (unsigned long long)a;\
16861685 printf("ftoi: %d %u %lld %llu\n", ia, ua, llia, llua);\
@@ -1710,6 +1709,18 @@ void prefix ## call(void)\ · 23 unmodified lines
17101709 printf("strto%s: %f\n", #prefix, (double)strto ## prefix("1.2", NULL));\
17111710 }\
17121711 \
1712+void 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+\
17131724 void prefix ## signed_zeros(void) \
17141725 {\
17151726 type x = 0.0, y = -0.0, n, p;\
@@ -1732,7 +1743,7 @@ void prefix ## signed_zeros(void) \ · 16 unmodified lines
17321743 1.0 / x != 1.0 / p);\
17331744 else\
17341745 printf ("x != +y; this is wrong!\n");\
1735− p = -y;\
1746+ p = -y;\
17361747 if (x == p)\
17371748 printf ("Test 1.0 / x != 1.0 / -y returns %d (should be 0).\n",\
17381749 1.0 / x != 1.0 / p);\
@@ -1748,7 +1759,8 @@ void prefix ## test(void)\ · 9 unmodified lines
17481759 prefix ## fcast(234.6);\
17491760 prefix ## fcast(-2334.6);\
17501761 prefix ## call();\
1751− prefix ## signed_zeros();\
1762+ prefix ## calc(1, 1.0000000000000001);\
1763+ prefix ## signed_zeros();\
17521764 }
17531765
17541766 FTEST(f, float, float, "%f")
@@ -2572,7 +2584,6 @@ int constant_p_var; · 817 unmodified lines
25722584
25732585 void builtin_test(void)
25742586 {
2575−#if GCC_MAJOR >= 3
25762587 COMPAT_TYPE(int, int);
25772588 COMPAT_TYPE(int, unsigned int);
25782589 COMPAT_TYPE(int, char);
@@ -2582,9 +2593,9 @@ void builtin_test(void) · 3 unmodified lines
25822593 COMPAT_TYPE(int *, void *);
25832594 COMPAT_TYPE(int *, const int *);
25842595 COMPAT_TYPE(char *, unsigned char *);
2596+ COMPAT_TYPE(char, unsigned char);
25852597 /* space is needed because tcc preprocessor introduces a space between each token */
2586− COMPAT_TYPE(char * *, void *);
2587−#endif
2598+ COMPAT_TYPE(char **, void *);
25882599 printf("res = %d\n", __builtin_constant_p(1));
25892600 printf("res = %d\n", __builtin_constant_p(1 + 2));
25902601 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
826826
827827 func_ret_sub = 0;
828828 func_scratch = 0;
829− loc = 0;
829+ pop_stack = loc = 0;
830830
831831 addr = PTR_SIZE * 2;
832832 ind += FUNC_PROLOG_SIZE;
@@ -968,12 +968,14 @@ static X86_64_Mode classify_x86_64_inner(CType *ty) · 135 unmodified lines
968968 case VT_BYTE:
969969 case VT_SHORT:
970970 case VT_LLONG:
971+ case VT_QLONG:
971972 case VT_BOOL:
972973 case VT_PTR:
973974 case VT_FUNC:
974975 case VT_ENUM: return x86_64_mode_integer;
975976
976977 case VT_FLOAT:
978+ case VT_QFLOAT:
977979 case VT_DOUBLE: return x86_64_mode_sse;
978980
979981 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
984986 // Detect union
985987 if (f->next && (f->c == f->next->c))
986988 return x86_64_mode_memory;
987−
989+
988990 mode = x86_64_mode_none;
989991 for (f = f->next; f; f = f->next)
990992 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
995997 assert(0);
996998 }
997999
998−static X86_64_Mode classify_x86_64_arg(CType *ty, CType *ret, int *psize, int *palign, int *reg_count)
1000+static int classify_x86_64_arg(CType *ty, CType *ret, int *psize, int *palign, int *reg_count)
9991001 {
10001002 X86_64_Mode mode;
10011003 int size, align, ret_t = 0;
10021004
10031005 if (ty->t & (VT_BITFIELD|VT_ARRAY)) {
10041006 *psize = 8;
1005− *palign = 8;
1007+ *palign = 8;
10061008 *reg_count = 1;
10071009 ret_t = ty->t;
10081010 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
10131015
10141016 if (size > 16) {
10151017 mode = x86_64_mode_memory;
1018+ ret_t = ty->t;
10161019 } else {
10171020 mode = classify_x86_64_inner(ty);
10181021 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
10211024 *reg_count = 2;
10221025 ret_t = VT_QLONG;
10231026 } else {
1024− *reg_count = 1;
1025− ret_t = (size > 4) ? VT_LLONG : VT_INT;
1026− }
1027+ *reg_count = 1;
1028+ if(size > 4)
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);
10271038 break;
1028−
10291039 case x86_64_mode_x87:
10301040 *reg_count = 1;
10311041 ret_t = VT_LDOUBLE;
10321042 break;
1033−
10341043 case x86_64_mode_sse:
10351044 if (size > 8) {
10361045 *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
10401049 ret_t = (size > 4) ? VT_DOUBLE : VT_FLOAT;
10411050 }
10421051 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*/
10441055 }
10451056 }
10461057 }
10471058
10481059 if (ret) {
1049− ret->ref = NULL;
1060+ ret->ref = ty->ref;
10501061 ret->t = ret_t;
10511062 }
10521063
@@ -1057,12 +1068,13 @@ ST_FUNC int classify_x86_64_va_arg(CType *ty) · 4 unmodified lines
10571068 {
10581069 /* This definition must be synced with stdarg.h */
10591070 enum __va_arg_type {
1060− __va_gen_reg, __va_float_reg, __va_stack
1061− };
1071+ __va_gen_reg, __va_float_reg, __va_ld_reg, __va_stack
1072+ };
10621073 int size, align, reg_count;
10631074 X86_64_Mode mode = classify_x86_64_arg(ty, NULL, &size, &align, &reg_count);
10641075 switch (mode) {
10651076 default: return __va_stack;
1077+ case x86_64_mode_x87: return __va_ld_reg;
10661078 case x86_64_mode_integer: return __va_gen_reg;
10671079 case x86_64_mode_sse: return __va_float_reg;
10681080 }
@@ -1387,7 +1399,7 @@ void gfunc_prolog(CType *func_type) · 318 unmodified lines
13871399
13881400 sym = func_type->ref;
13891401 addr = PTR_SIZE * 2;
1390− loc = 0;
1402+ pop_stack = loc = 0;
13911403 ind += FUNC_PROLOG_SIZE;
13921404 func_sub_sp_offset = ind;
13931405 func_ret_sub = 0;
@@ -1398,7 +1410,6 @@ void gfunc_prolog(CType *func_type) · 4 unmodified lines
13981410 /* frame pointer and return address */
13991411 seen_stack_size = PTR_SIZE * 2;
14001412 /* count the number of seen parameters */
1401− sym = func_type->ref;
14021413 while ((sym = sym->next) != NULL) {
14031414 type = &sym->type;
14041415 mode = classify_x86_64_arg(type, NULL, &size, &align, &reg_count);
@@ -1439,19 +1450,19 @@ void gfunc_prolog(CType *func_type) · 34 unmodified lines
14391450 o(0xf845c7);
14401451 gen_le32(seen_stack_size);
14411452
1453+ o(0xc084);/* test %al,%al */
1454+ o(0x74);/* je */
1455+ g(4*(8 - seen_sse_num) + 3);
1456+
14421457 /* save all register passing arguments */
14431458 for (i = 0; i < 8; i++) {
14441459 loc -= 16;
1445− o(0xd60f66); /* movq */
1460+ o(0x290f);/* movaps %xmm1-7,-XXX(%rbp) */
14461461 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);
14541462 }
1463+ for (i = 0; i < (REGN - seen_reg_num); i++) {
1464+ push_arg_reg(REGN-1 - i);
1465+ }
14551466 }
14561467
14571468 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