Re: [Tinycc-devel] tcc grammar problems
These days I'm going to worship. Few days and then a detailed reply to you. This is my latest Review: Please see the attachment. fixbitfields.patch By testing the software: tcc gnumake binutils-2.24 Best regards, Jiang commit 3c15eb7f912016738fc9c604d81d5f7a8a4fb200 Author: Jiang <30155...@qq.com> Date: Sat Aug 9 11:13:51 2014 +0800 fix bitfields see: http://lists.nongnu.org/archive/html/tinycc-devel/2014-07/msg00023.html diff --git a/tcc.h b/tcc.h index c93cedf..a8cabb6 100644 --- a/tcc.h +++ b/tcc.h @@ -1192,6 +1192,17 @@ ST_DATA int func_var; /* true if current function is variadic */ ST_DATA int func_vc; ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */ ST_DATA char *funcname; +/* gen_ctrl */ +enum { +CTRL_NONE, +CTRL_CALL, +CTRL_FOCE, +CTRL_ARGS, +CTRL_RETS, +CTRL_INIT, +CTRL_USED, +}; +ST_DATA int gen_ctrl; ST_INLN int is_float(int t); ST_FUNC int ieee_finite(double d); diff --git a/tccgen.c b/tccgen.c index 5fd127f..dcf7253 100644 --- a/tccgen.c +++ b/tccgen.c @@ -70,6 +70,7 @@ ST_DATA int func_var; /* true if current function is variadic (used by return in ST_DATA int func_vc; ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */ ST_DATA char *funcname; +ST_DATA int gen_ctrl; ST_DATA CType char_pointer_type, func_old_type, int_type, size_type; @@ -1017,6 +1018,7 @@ ST_FUNC void lexpand_nr(void) } #endif +#ifndef TCC_TARGET_X86_64 /* build a long long from two ints */ static void lbuild(int t) { @@ -1025,6 +1027,7 @@ static void lbuild(int t) vtop[-1].type.t = t; vpop(); } +#endif /* rotate n first stack elements to the bottom I1 ... In -> I2 ... In I1 [top is right] @@ -1087,7 +1090,8 @@ static void gv_dup(void) int rc, t, r, r1; SValue sv; -t = vtop->type.t; +#ifndef TCC_TARGET_X86_64 +t = VT_INT; if ((t & VT_BTYPE) == VT_LLONG) { lexpand(); gv_dup(); @@ -1097,15 +1101,16 @@ static void gv_dup(void) vrotb(4); /* stack: H L L1 H1 */ lbuild(t); -vrotb(3); -vrotb(3); +vrott(3); vswap(); lbuild(t); vswap(); -} else { +} else +#else +t = vtop->type.t; +#endif +{ /* duplicate value */ -rc = RC_INT; -sv.type.t = VT_INT; if (is_float(t)) { rc = RC_FLOAT; #ifdef TCC_TARGET_X86_64 @@ -1113,8 +1118,9 @@ static void gv_dup(void) rc = RC_ST0; } #endif -sv.type.t = t; -} +}else +rc = RC_INT; +sv.type.t = t; r = gv(rc); r1 = get_reg(rc); sv.r = r; @@ -1909,8 +1915,11 @@ static void force_charshort_cast(int t) /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */ static void gen_cast(CType *type) { -int sbt, dbt, sf, df, c, p; +int sbt, dbt, dt, sf, df, c, p, bitfield; +CType dtype; +dtype = *type; +bitfield = dtype.t & VT_BITFIELD; /* special delayed cast for char/short */ /* XXX: in some cases (multiple cascaded casts), it may still be incorrect */ @@ -1924,10 +1933,11 @@ static void gen_cast(CType *type) gv(RC_INT); } -dbt = type->t & (VT_BTYPE | VT_UNSIGNED); +dbt = dtype.t & (VT_BTYPE | VT_UNSIGNED); +dt = dbt & VT_BTYPE; sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED); -if (sbt != dbt) { +if (sbt != dbt || bitfield) { sf = is_float(sbt); df = is_float(dbt); c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; @@ -1959,6 +1969,8 @@ static void gen_cast(CType *type) vtop->c.d = (double)vtop->c.ld; } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) { vtop->c.ull = (unsigned long long)vtop->c.ld; +if(bitfield) +goto cast_bitfield; } else if (sf && dbt == VT_BOOL) { vtop->c.i = (vtop->c.ld != 0); } else { @@ -1975,24 +1987,53 @@ static void gen_cast(CType *type) else if (sbt != VT_LLONG) vtop->c.ll = vtop->c.i; -if (dbt == (VT_LLONG|VT_UNSIGNED)) +if (dbt == (VT_LLONG|VT_UNSIGNED)){ vtop->c.ull = vtop->c.ll; -else if (dbt == VT_BOOL) +if(bitfield) +goto cast_bitfield; +}else if (dbt == VT_BOOL) vtop->c.i = (vtop->c.ll != 0); #ifdef TCC_TARGET_X86_64 else if (dbt == VT_PTR) ; #endif else if (dbt != VT_LLONG) { -int s = 0; -if ((dbt & VT_BTYPE) == VT_BYTE) -s = 24; -else if ((dbt & VT_BTYPE) == VT_SHORT) -s = 16; -if(dbt & VT_UNSIGNED) -
[Tinycc-devel] 回复: tcc grammar problems
I recently some busy. may have to over a day or two to use the computer. I will give you reply. Best regards, jiang Thomas Preud'homme 编写: >Le mercredi 06 août 2014, 22:41:18 Thomas Preud'homme a écrit : > >[SNIP review part 2] > >And here is the final part (part 3) > >@@ -3605,7 +3643,7 @@ static void vpush_tokc(int t) > >ST_FUNC void unary(void) >{ >- int n, t, align, size, r, sizeof_caller; >+ int n, t, align, size, r, sizeof_caller, save_ctrl; > CType type; > Sym *s; > AttributeDef ad; >@@ -3714,7 +3752,10 @@ ST_FUNC void unary(void) > return; > } > unary(); >+ save_ctrl = gen_ctrl; >+ gen_ctrl = CTRL_FOCE; > gen_cast(&type); >+ gen_ctrl = save_ctrl; > > >I think it would be better to add a parameter "explicit" of type bool to >gen_cast(). CTRL_INIT looks weird and you only need to know if it's an >implicit cast or not. > > > } > } else if (tok == '{') { > /* save all registers */ >@@ -5127,7 +5168,7 @@ static void decl_designator(CType *type, Section *sec, >unsigned long c, >static void init_putv(CType *type, Section *sec, unsigned long c, > int v, int expr_type) >{ >- int saved_global_expr, bt, bit_pos, bit_size; >+ int saved_global_expr, bt, bit_pos, bit_size, save_ctrl; > void *ptr; > unsigned long long bit_mask; > CType dtype; >@@ -5147,7 +5188,10 @@ static void init_putv(CType *type, Section *sec, >unsigned long c, > tcc_error("initializer element is not constant"); > break; > case EXPR_ANY: >+ save_ctrl = gen_ctrl; >+ gen_ctrl = CTRL_INIT; > expr_eq(); >+ gen_ctrl = save_ctrl; > break; > } > > >I don't see why this is needed. The code you moved in vstore() didn't need it >before. > > >diff --git a/tests/tests2/03_struct.c b/tests/tests2/03_struct.c >index c5d48c5..e06d20d 100644 >--- a/tests/tests2/03_struct.c >+++ b/tests/tests2/03_struct.c >@@ -27,5 +27,36 @@ int main() > printf("%d\n", jones[1].boris); > printf("%d\n", jones[1].natasha); > >+ struct sbf1 { >+ int f1 : 3; >+ int : 2; >+ int f2 : 1; >+ int : 0; >+ int f3 : 5; >+ int f4 : 7; >+ unsigned int f5 : 7; >+ } st1; >+ st1.f1 = st1.f2 = st1.f3 = st1.f4 = st1.f5 = 3; >+ printf("%d %d %d %d %d\n", >+ st1.f1, st1.f2, st1.f3, st1.f4, st1.f5); >+ >+ struct { unsigned a:9, b:7, c:5; } s1; >+ s1.a = s1.b = s1.c = 3; >+ printf("%d / %d / %d\n", s1.a, s1.b, s1.c); >+ >+ struct { >+ unsigned a:9, b:5, c:7; >+ } s2, *ps = &s2; >+ int n = 250; >+ >+ int ii = ps->a = ps->b = ps->c = n + 4; >+ printf("%d / %d / %d\n", ps->a, ps->b, ps->c); >+ printf("%d\n", ii); >+ >+ ps->a = n + 4; >+ ps->b = n + 4; >+ ps->c = n + 4; >+ printf("%d / %d / %d\n", ps->a, ps->b, ps->c); >+ > return 0; >} >diff --git a/tests/tests2/03_struct.expect b/tests/tests2/03_struct.expect >index ecbf589..6b90186 100644 >--- a/tests/tests2/03_struct.expect >+++ b/tests/tests2/03_struct.expect >@@ -1,6 +1,12 @@ >+03_struct.c:39: warning: overflow in implicit constant conversion >12 >34 >12 >34 >56 >78 >+-1 -1 3 3 3 >+3 / 3 / 3 >+30 / 30 / 126 >+30 >+254 / 30 / 126 > > >The added code in 03_struct.c don't exercise the explicit cast. Is it exercise >somewhere else? If not you should add something for this. > >Best regards, > >Thomas ___ Tinycc-devel mailing list Tinycc-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/tinycc-devel
Re: [Tinycc-devel] tcc grammar problems
Le mercredi 06 août 2014, 22:41:18 Thomas Preud'homme a écrit : [SNIP review part 2] And here is the final part (part 3) @@ -3605,7 +3643,7 @@ static void vpush_tokc(int t) ST_FUNC void unary(void) { -int n, t, align, size, r, sizeof_caller; +int n, t, align, size, r, sizeof_caller, save_ctrl; CType type; Sym *s; AttributeDef ad; @@ -3714,7 +3752,10 @@ ST_FUNC void unary(void) return; } unary(); +save_ctrl = gen_ctrl; +gen_ctrl = CTRL_FOCE; gen_cast(&type); +gen_ctrl = save_ctrl; I think it would be better to add a parameter "explicit" of type bool to gen_cast(). CTRL_INIT looks weird and you only need to know if it's an implicit cast or not. } } else if (tok == '{') { /* save all registers */ @@ -5127,7 +5168,7 @@ static void decl_designator(CType *type, Section *sec, unsigned long c, static void init_putv(CType *type, Section *sec, unsigned long c, int v, int expr_type) { -int saved_global_expr, bt, bit_pos, bit_size; +int saved_global_expr, bt, bit_pos, bit_size, save_ctrl; void *ptr; unsigned long long bit_mask; CType dtype; @@ -5147,7 +5188,10 @@ static void init_putv(CType *type, Section *sec, unsigned long c, tcc_error("initializer element is not constant"); break; case EXPR_ANY: +save_ctrl = gen_ctrl; +gen_ctrl = CTRL_INIT; expr_eq(); +gen_ctrl = save_ctrl; break; } I don't see why this is needed. The code you moved in vstore() didn't need it before. diff --git a/tests/tests2/03_struct.c b/tests/tests2/03_struct.c index c5d48c5..e06d20d 100644 --- a/tests/tests2/03_struct.c +++ b/tests/tests2/03_struct.c @@ -27,5 +27,36 @@ int main() printf("%d\n", jones[1].boris); printf("%d\n", jones[1].natasha); + struct sbf1 { +int f1 : 3; +int : 2; +int f2 : 1; +int : 0; +int f3 : 5; +int f4 : 7; +unsigned int f5 : 7; + } st1; + st1.f1 = st1.f2 = st1.f3 = st1.f4 = st1.f5 = 3; + printf("%d %d %d %d %d\n", + st1.f1, st1.f2, st1.f3, st1.f4, st1.f5); + + struct { unsigned a:9, b:7, c:5; } s1; +s1.a = s1.b = s1.c = 3; + printf("%d / %d / %d\n", s1.a, s1.b, s1.c); + + struct { +unsigned a:9, b:5, c:7; + } s2, *ps = &s2; + int n = 250; + + int ii = ps->a = ps->b = ps->c = n + 4; + printf("%d / %d / %d\n", ps->a, ps->b, ps->c); + printf("%d\n", ii); + + ps->a = n + 4; + ps->b = n + 4; + ps->c = n + 4; + printf("%d / %d / %d\n", ps->a, ps->b, ps->c); + return 0; } diff --git a/tests/tests2/03_struct.expect b/tests/tests2/03_struct.expect index ecbf589..6b90186 100644 --- a/tests/tests2/03_struct.expect +++ b/tests/tests2/03_struct.expect @@ -1,6 +1,12 @@ +03_struct.c:39: warning: overflow in implicit constant conversion 12 34 12 34 56 78 +-1 -1 3 3 3 +3 / 3 / 3 +30 / 30 / 126 +30 +254 / 30 / 126 The added code in 03_struct.c don't exercise the explicit cast. Is it exercise somewhere else? If not you should add something for this. Best regards, Thomas signature.asc Description: This is a digitally signed message part. ___ Tinycc-devel mailing list Tinycc-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/tinycc-devel