Просмотр исходного кода

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

ceriel 37 лет назад
Родитель
Сommit
6445b23318
5 измененных файлов с 82 добавлено и 42 удалено
  1. 1 0
      lang/cem/cemcom/LLlex.c
  2. 21 7
      lang/cem/cemcom/conversion.c
  3. 29 19
      lang/cem/cemcom/eval.c
  4. 11 5
      lang/cem/cemcom/field.c
  5. 20 11
      lang/cem/cemcom/ival.c

+ 1 - 0
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);

+ 21 - 7
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();

+ 29 - 19
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;
 		}

+ 11 - 5
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);

+ 20 - 11
lang/cem/cemcom/ival.c

@@ -4,6 +4,7 @@
 #include	"nofloat.h"
 #include	<em.h>
 #include	"debug.h"
+#include	<alloc.h>
 #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