在 2014年08月10日 19:55, Thomas Preud'homme
写道:
Le samedi 09 août 2014, 11:49:50 jiang a écrit :
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
I didn't look at the patch yet but I still see the control structure with lots
of enumerator unused. What happen to my comments about this?
Best regards,
Thomas
+/* gen_ctrl */
+enum {
+ CTRL_NONE,
+ CTRL_CALL,
+ CTRL_FOCE,
+ CTRL_ARGS,
+ CTRL_RETS,
+ CTRL_INIT,
+ CTRL_USED,
+};
+ST_DATA int gen_ctrl;
This is one of my local branch code, want to join the mob after
CTRL_CALL:
int get_reg(int rc)
{
int r;
SValue *p;
/* find a free register */
r = for_reg(rc);
if (r != -1)
return r;
/* no register left : free the first one on the stack (VERY
IMPORTANT to start from the bottom to ensure that we don't
spill registers used in gen_opi()) */
for(p = vstack; p <= vtop; p++) {
/* look at second register (if long long) */
if(p->r & VT_TMP)
continue;
r = p->r2 & VT_VALMASK;
if (r < VT_CONST && (reg_classes[r] & rc))
goto save_found;
r = p->r & VT_VALMASK;
if (r < VT_CONST && (reg_classes[r] & rc)) {
int r1, rc_mask;
save_found:
if(gen_ctrl == CTRL_CALL)
rc_mask = (RC_INT2|RC_FLOAT);
else
rc_mask = RC_MASK;
r1 = for_reg(reg_classes[r] & rc_mask);
if(r1 != -1){
mov_reg(r1, r, p);
}else{
save_reg(r);
}
return r;
}
}
/* Should never comes here */
assert(0);
return -1;
}
CTRL_ARGS,
static void gen_assign_cast(CType *dt, void *v)
[...]
if (((type1->t & VT_BTYPE) == (type2->t & VT_BTYPE)) &&
((type1->t & VT_UNSIGNED) != (type2->t & VT_UNSIGNED))){
if(tcc_state->warn_pointer_sign){
if(gen_ctrl == CTRL_ARGS){
struct {
int t;
int n;
} *pwarn_arg = v;
tcc_warning("pointer targets in passing argument %d of '%s' differ in signedness",
pwarn_arg->n, get_tok_str(pwarn_arg->t, NULL));
}else
tcc_warning("pointer targets in assignment differ in signedness");
}
}
[....]
After tcc built-in functions to use
CTRL_RETS
"tcctok.h"
#ifdef TCC_TARGET_X86_64
# ifndef TCC_TARGET_PE
DEF(TOK_builtin_va_arg_types, "__builtin_va_arg_types")
DEF(TOK_builtin_va_start, "__builtin_va_start")
DEF(TOK_builtin_va_copy, "__builtin_va_copy")
DEF(TOK_builtin_va_arg, "__builtin_va_arg")
# endif
#endif
"tccgen.c"
void unary(void)
[...]
.case '*':
next();
save_ctrl = gen_ctrl;
gen_ctrl = CTRL_RETS;
unary();
gen_ctrl = save_ctrl;
indir();
break;
[...]
CTRL_USED
Add to tcc used to initialize a warning, but in my local branch of the warning is not very good, there are some bug.
The idea is not very mature.
Before officially pushed mob I will delete these ID
ft = vtop[-1].type.t;
sbt = vtop->type.t & VT_BTYPE;
dbt = ft & VT_BTYPE;
+ ret = delayed_cast = 0;
+ cc = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
- (sbt == VT_INT && dbt == VT_SHORT))
- && !(vtop->type.t & VT_BITFIELD)) {
+ (sbt == VT_INT && dbt == VT_SHORT)) && !(vtop->type.t & VT_BITFIELD)
&& !cc) {
/* optimize char/short casts */
delayed_cast = VT_MUSTCAST;
vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 <<
VT_STRUCT_SHIFT)));
/* XXX: factorize */
if (ft & VT_CONSTANT)
tcc_warning("assignment of read-only location");
+ }else if(ft & VT_BITFIELD){
+ ret = (vtop > (vstack + 1) || gen_ctrl == CTRL_INIT);
Why this vtop > (vstack + 1)? What's so special about a stack with 3 entries
or more? It looks fishy.
For example the following _expression_:
a = b = c; -> (a = (b = c));
Requires three SValue, will be greater than vstack + 1, ret equal to 1.
Return right value
a = b
Less than or equal vstack + 1, ret equal to 0.
Does not return the right value
Generate less machine code
Say tomorrow
Best regards,
Jiang