diff --git a/lang/cem/cemcom.ansi/ch3mon.c b/lang/cem/cemcom.ansi/ch3mon.c index b047671f0..6a810df6b 100644 --- a/lang/cem/cemcom.ansi/ch3mon.c +++ b/lang/cem/cemcom.ansi/ch3mon.c @@ -123,7 +123,7 @@ ch3mon(oper, expp) (*expp)->VL_VALUE = (oper == '-') ? -o1 : ((*expp)->ex_type->tp_unsigned ? - (~o1) & full_mask[(*expp)->ex_type->tp_size] : + (~o1) & full_mask[(int)(*expp)->ex_type->tp_size] : ~o1 ); } diff --git a/lang/cem/cemcom.ansi/field.c b/lang/cem/cemcom.ansi/field.c index 7cff3ff3b..4720f347e 100644 --- a/lang/cem/cemcom.ansi/field.c +++ b/lang/cem/cemcom.ansi/field.c @@ -28,7 +28,6 @@ #include "field.h" arith NewLocal(); /* util.c */ -char *symbol2str(); /* symbol2str.c */ extern arith full_mask[]; /* cstoper.c */ /* Eval_field() evaluates expressions involving bit fields. @@ -64,35 +63,7 @@ eval_field(expr, code) ASSERT(tp == rightop->ex_type); EVAL(rightop, RVAL, TRUE, NO_LABEL, NO_LABEL); conversion(tp, atype); - C_loc(fd->fd_mask); - C_and(word_size); - if (code == TRUE) - C_dup(word_size); - C_loc((arith)fd->fd_shift); - if (atype->tp_unsigned) - C_slu(word_size); - else - C_sli(word_size); - C_loc(~((fd->fd_mask << fd->fd_shift) | ~full_mask[(int)word_size])); - if (leftop->ex_depth == 0) { /* simple case */ - load_val(leftop, RVAL); - C_and(word_size); - C_ior(word_size); - store_val(&(leftop->EX_VALUE), atype); - } - else { /* complex case */ - tmpvar = NewLocal(pointer_size, pointer_align, - reg_pointer, 0); - EVAL(leftop, LVAL, TRUE, NO_LABEL, NO_LABEL); - C_dup(pointer_size); - StoreLocal(tmpvar, pointer_size); - C_loi(word_size); - C_and(word_size); - C_ior(word_size); - LoadLocal(tmpvar, pointer_size); - C_sti(word_size); - FreeLocal(tmpvar); - } + store_field(fd, tp->tp_unsigned, code, leftop, (arith) 0); } else { /* treat ++F as F += 1 and --F as F -= 1 */ /* F op= e: f = (((((f>>shift)&mask) op e)&mask)<fd_width + fd->fd_shift)); + arith sft = word_size * 8 - fd->fd_width; + C_loc(sft - fd->fd_shift); C_sli(word_size); - C_loc(bits_in_type - fd->fd_width); + C_loc(sft); C_sri(word_size); } if (code == TRUE && (op == POSTINCR || op == POSTDECR)) @@ -134,31 +105,9 @@ eval_field(expr, code) else assop(rightop->ex_type, op); conversion(rightop->ex_type, atype); - C_loc(fd->fd_mask); - C_and(word_size); - if (code == TRUE && op != POSTINCR && op != POSTDECR) - C_dup(word_size); - C_loc((arith)fd->fd_shift); - if (atype->tp_unsigned) - C_slu(word_size); - else - C_sli(word_size); - C_loc(~((fd->fd_mask << fd->fd_shift) | ~full_mask[(int)word_size])); - if (leftop->ex_depth == 0) { - load_val(leftop, RVAL); - C_and(word_size); - C_ior(word_size); - store_val(&(leftop->EX_VALUE), atype); - } - else { - LoadLocal(tmpvar, pointer_size); - C_loi(word_size); - C_and(word_size); - C_ior(word_size); - LoadLocal(tmpvar, pointer_size); - C_sti(word_size); - FreeLocal(tmpvar); - } + store_field(fd, atype->tp_unsigned, + code == TRUE && op != POSTINCR && op != POSTDECR, + leftop, tmpvar); } if (code == TRUE) { /* Take care that the effective value stored in @@ -176,6 +125,46 @@ eval_field(expr, code) conversion(atype, expr->ex_type); } } + +store_field(fd, uns, code, leftop, tmpvar) + register struct field *fd; + int uns; + int code; + register struct expr *leftop; + arith tmpvar; +{ + C_loc(fd->fd_mask); + C_and(word_size); + if (code == TRUE) + C_dup(word_size); + C_loc((arith)fd->fd_shift); + if (uns) + C_slu(word_size); + else + C_sli(word_size); + C_loc(~((fd->fd_mask << fd->fd_shift) | ~full_mask[(int)word_size])); + if (leftop->ex_depth == 0) { /* simple case */ + load_val(leftop, RVAL); + C_and(word_size); + C_ior(word_size); + store_val(&(leftop->EX_VALUE), uns ? uword_type : word_type); + } + else { /* complex case */ + if (! tmpvar) { + tmpvar = NewLocal(pointer_size, pointer_align, + reg_pointer, 0); + EVAL(leftop, LVAL, TRUE, NO_LABEL, NO_LABEL); + StoreLocal(tmpvar, pointer_size); + } + LoadLocal(tmpvar, pointer_size); + C_loi(word_size); + C_and(word_size); + C_ior(word_size); + LoadLocal(tmpvar, pointer_size); + C_sti(word_size); + FreeLocal(tmpvar); + } +} #endif NOBITFIELD #endif LINT diff --git a/lang/cem/cemcom.ansi/util.c b/lang/cem/cemcom.ansi/util.c index b51cf68d6..b8724409e 100644 --- a/lang/cem/cemcom.ansi/util.c +++ b/lang/cem/cemcom.ansi/util.c @@ -64,7 +64,7 @@ NewLocal(sz, al, regtype, sc) { register struct localvar *tmp = FreeTmps; struct localvar *prev = 0; - register int index; + int index; while (tmp) { if (tmp->t_align >= al && @@ -149,10 +149,12 @@ LocalFinish() } regs[i] = 0; } +#ifdef PEEPHOLE if (! options['n']) { C_mes_begin(ms_reg); C_mes_end(); } +#endif #ifdef USE_TMP C_endpart(loc_id); #endif