From ca1655c25ec5a21ee94393bf253d6a10d5b7f943 Mon Sep 17 00:00:00 2001 From: ceriel Date: Mon, 23 Feb 1987 13:08:54 +0000 Subject: [PATCH] bug fixes: - assignment operators for bit fields were wrong - some conversions for characters were wrong - result of assignment operator sometimes had wrong size - character constant \377 was 255, not -1 - string constant generation was clumsy --- lang/cem/cemcom/LLlex.c | 1 + lang/cem/cemcom/conversion.c | 28 +++++++++++++++------ lang/cem/cemcom/eval.c | 48 ++++++++++++++++++++++-------------- lang/cem/cemcom/field.c | 16 ++++++++---- lang/cem/cemcom/ival.c | 31 ++++++++++++++--------- 5 files changed, 82 insertions(+), 42 deletions(-) diff --git a/lang/cem/cemcom/LLlex.c b/lang/cem/cemcom/LLlex.c index f3a5771e3..08032df1d 100644 --- a/lang/cem/cemcom/LLlex.c +++ b/lang/cem/cemcom/LLlex.c @@ -309,6 +309,7 @@ firstline: LineNumber++; ch = quoted(ch); } + if (ch >= 128) ch -= 256; val = val*256 + ch; size++; LoadChar(ch); diff --git a/lang/cem/cemcom/conversion.c b/lang/cem/cemcom/conversion.c index 6e55474cb..decd7ab6d 100644 --- a/lang/cem/cemcom/conversion.c +++ b/lang/cem/cemcom/conversion.c @@ -32,22 +32,35 @@ conversion(from_type, to_type) if (from_type == to_type) /* a little optimisation */ return; + if (to_size < word_size) to_size = word_size; switch (fundamental(from_type)) { case T_SIGNED: switch (fundamental(to_type)) { case T_SIGNED: C_loc(from_size); - C_loc(to_size < word_size ? word_size : to_size); + C_loc(to_size); C_cii(); break; case T_UNSIGNED: - C_loc(from_size < word_size ? word_size : from_size); - C_loc(to_size < word_size ? word_size : to_size); + if (from_size < word_size) { + C_loc(from_size); + C_loc(word_size); + C_cii(); + from_size = word_size; + } + C_loc(from_size); + C_loc(to_size); C_ciu(); break; #ifndef NOFLOAT case T_FLOATING: - C_loc(from_size < word_size ? word_size : from_size); + if (from_size < word_size) { + C_loc(from_size); + C_loc(word_size); + C_cii(); + from_size = word_size; + } + C_loc(from_size); C_loc(to_size); C_cif(); break; @@ -55,8 +68,9 @@ conversion(from_type, to_type) } break; case T_UNSIGNED: - C_loc(from_size < word_size ? word_size : from_size); - C_loc(to_size < word_size ? word_size : to_size); + if (from_size < word_size) from_size = word_size; + C_loc(from_size); + C_loc(to_size); switch (fundamental(to_type)) { case T_SIGNED: C_cui(); @@ -74,7 +88,7 @@ conversion(from_type, to_type) #ifndef NOFLOAT case T_FLOATING: C_loc(from_size); - C_loc(to_size < word_size ? word_size : to_size); + C_loc(to_size); switch (fundamental(to_type)) { case T_SIGNED: C_cfi(); diff --git a/lang/cem/cemcom/eval.c b/lang/cem/cemcom/eval.c index 61a6ea7a3..8b7d9d7f9 100644 --- a/lang/cem/cemcom/eval.c +++ b/lang/cem/cemcom/eval.c @@ -395,32 +395,42 @@ EVAL(expr, val, code, true_label, false_label) } } if (newcode) { - conversion(left->ex_type, tp); if (gencode && (oper == POSTINCR || oper == POSTDECR)) - C_dup(tp->tp_size); + C_dup(ATW(left->ex_type->tp_size)); + conversion(left->ex_type, tp); } EVAL(right, RVAL, newcode, NO_LABEL, NO_LABEL); if (newcode) { + int dupval = gencode && oper != POSTINCR && + oper != POSTDECR; assop(tp, oper); - if (gencode && oper != POSTINCR && - oper != POSTDECR) - C_dup(tp->tp_size); conversion(tp, left->ex_type); - } - if (newcode && compl == 0) - store_val(&(left->ex_object.ex_value), - left->ex_type); - else - if (compl == 1) { - EVAL(left, LVAL, newcode, NO_LABEL, NO_LABEL); - if (newcode) C_sti(left->ex_type->tp_size); - } - else if (newcode) { - C_lal(tmp); /* always init'd */ - C_loi(pointer_size); - C_sti(left->ex_type->tp_size); - free_tmp_var(old_offset); + if (compl == 0) { + store_val(&(left->ex_object.ex_value), + left->ex_type); + if (dupval) load_val(left, RVAL); + } + else if (compl == 1) { + EVAL(left, LVAL,1, NO_LABEL, NO_LABEL); + C_sti(left->ex_type->tp_size); + if (dupval) { + EVAL(left, LVAL, 1, NO_LABEL, + NO_LABEL); + C_loi(left->ex_type->tp_size); + } + } + else { + C_lal(tmp); /* always init'd */ + C_loi(pointer_size); + C_sti(left->ex_type->tp_size); + if (dupval) { + C_lal(tmp); + C_loi(pointer_size); + C_loi(left->ex_type->tp_size); + } + free_tmp_var(old_offset); + } } break; } diff --git a/lang/cem/cemcom/field.c b/lang/cem/cemcom/field.c index 63c1b61bd..0a34db008 100644 --- a/lang/cem/cemcom/field.c +++ b/lang/cem/cemcom/field.c @@ -99,13 +99,19 @@ eval_field(expr, code) C_sti(pointer_size); C_loi(asize); } - C_loc((arith)fd->fd_shift); - if (atype->tp_unsigned) + if (atype->tp_unsigned) { + C_loc((arith)fd->fd_shift); C_sru(asize); - else + C_loc(fd->fd_mask); + C_and(asize); + } + else { + arith bits_in_type = asize * 8; + C_loc(bits_in_type - (fd->fd_width + fd->fd_shift)); + C_sli(asize); + C_loc(bits_in_type - fd->fd_width); C_sri(asize); - C_loc(fd->fd_mask); - C_and(asize); + } if (code == TRUE && (op == POSTINCR || op == POSTDECR)) C_dup(asize); conversion(atype, rightop->ex_type); diff --git a/lang/cem/cemcom/ival.c b/lang/cem/cemcom/ival.c index b64577d9b..87a4a71c5 100644 --- a/lang/cem/cemcom/ival.c +++ b/lang/cem/cemcom/ival.c @@ -4,6 +4,7 @@ #include "nofloat.h" #include #include "debug.h" +#include #include "nobitfield.h" #include "arith.h" #include "align.h" @@ -469,12 +470,11 @@ ch_array(tpp, ex) struct expr *ex; { register struct type *tp = *tpp; - register arith length; - register char *s = ex->SG_VALUE; - register arith ntopad; + register arith length = ex->SG_LEN; + char *s; + arith ntopad; ASSERT(ex->ex_class == String); - length = ex->SG_LEN; if (tp->tp_size == (arith)-1) { /* set the dimension */ tp = *tpp = construct_type(ARRAY, tp->tp_up, length); @@ -497,19 +497,28 @@ ch_array(tpp, ex) ntopad = align(dim, word_align) - length; } /* throw out the characters of the already prepared string */ - while (length-- > 0) - C_con_ucon(long2str((long)*s++ & 0xFF, 10), (arith)1); - /* pad the allocated memory (the alignment has been calculated) */ - while (ntopad-- > 0) - con_nullbyte(); + s = Malloc((int) (length + ntopad)); + clear(s, (int) (length + ntopad)); + strncpy(s, ex->SG_VALUE, (int) length); + str_cst(s, (int) (length + ntopad)); + free(s); } +/* As long as some parts of the pipeline cannot handle very long string + constants, string constants are written out in chunks +*/ str_cst(str, len) register char *str; register int len; { - while (len-- > 0) - C_con_ucon(long2str((long)*str++ & 0xFF, 10), (arith)1); + arith chunksize = ((127 + word_size) / word_size) * word_size; + + while (len > chunksize) { + C_con_scon(str, chunksize); + len -= chunksize; + str += chunksize; + } + C_con_scon(str, (arith) len); } #ifndef NOBITFIELD -- 2.34.1