changeset 329:4c8f8ef8c0cf

bit field continue...
author kono
date Wed, 23 Jun 2004 16:10:03 +0900
parents 7ecb023d29b8
children fa4c7b15d7ed
files Changes mc-code-powerpc.c mc-code.h mc-codegen.c mc-parse.c mc-parse.h mc.h
diffstat 7 files changed, 392 insertions(+), 90 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Tue Jun 22 01:24:00 2004 +0900
+++ b/Changes	Wed Jun 23 16:10:03 2004 +0900
@@ -5070,3 +5070,67 @@
 
 ようやっとリカバリできたよ。
 
+local scope { int hoge; ... { int hoge;... }} for(int i=0; hoge...)
+は、やらざるを得ないだろうね。
+
+Tue Jun 22 06:49:55 JST 2004
+
+bit-field の alignment は、アーキテクチャによって任意って
+感じだな。
+
+MIPS
+
+01:ffffffffffffffff
+02:fffffff0 0000001f 00000000 00000000 00000000 00000000 00000000 00000000
+02:00000000 00000000 ffffffff 00000001 00000000 00000000 00000000 00000000
+02:00000000 00000000 00000000 00000000 ffffffff 00000001 00000000 00000000
+01:ffffffffffffffff
+02:fffffff0 000fffff 00000000 00000000 00000000 00000000 00000000 00000000
+02:00000000 00000000 ffffffff 0000ffff 00000000 00000000 00000000 00000000
+02:00000000 00000000 00000000 00000000 ffffffff 0000ffff 00000000 00000000
+1:ffffffffffffffff
+2:fffffff0 0fffffff 00000000 00000000 00000000 00000000 00000000 00000000
+2:00000000 00000000 ffffffff 00ffffff 00000000 00000000 00000000 00000000
+2:00000000 00000000 00000000 00000000 ffffffff 00ffffff 00000000 00000000
+
+PowerPC
+
+01:ffffffffffffffff
+02:0fffffff f8000000 00000000 00000000 00000000 00000000 00000000 00000000
+02:00000000 07ffffff fc000000 00000000 00000000 00000000 00000000 00000000
+02:00000000 00000000 03ffffff fe000000 00000000 00000000 00000000 00000000
+01:ffffffffffffffff
+02:0fffffff fffff000 00000000 00000000 00000000 00000000 00000000 00000000
+02:00000000 00000000 ffffffff ffff0000 00000000 00000000 00000000 00000000
+02:00000000 00000000 00000000 0000ffff ffffffff 00000000 00000000 00000000
+1:ffffffffffffffff
+2:0fffffff fffffff0 00000000 00000000 00000000 00000000 00000000 00000000
+2:00000000 00000000 ffffffff ffffff00 00000000 00000000 00000000 00000000
+2:00000000 00000000 00000000 00000000 ffffffff ffffff00 00000000 00000000
+
+実装は、mc-parse.c では決められないのか。
+
+まず、
+        boundary を含めて読み込み (必ず指定された型のサイズに収まる)
+次に、
+        読み込んだ部分の指定されたbitを置き換え
+           まず 0 にして、置き換えと or を取る(?)
+そして、
+        書込
+って感じですかね。64bit はめんどくさいな〜
+
+ってことは、
+       and mask をつくって、or mask をつくって、
+       逐次実行
+って感じですか。はぁ〜。
+       
+BIT_FIELD のsizeをやらないと、初期化ができない。
+
+Wed Jun 23 14:06:10 JST 2004
+
+(昨日は飲みすぎ...)
+
+emit_data は、mc-codegen にあるべきだよね。
+
+bit_field の大域変数の初期化ができない。いったん、どっかに
+貯めないとだめ。assign_data level?
--- a/mc-code-powerpc.c	Tue Jun 22 01:24:00 2004 +0900
+++ b/mc-code-powerpc.c	Wed Jun 23 16:10:03 2004 +0900
@@ -5072,4 +5072,137 @@
 #endif
 
 
+#if BIT_FIELD_CODE
+
+/* bit field alignment calcuration */
+
+static void
+set_bitsz(int type,int *psign,int *pbitsz,int *palign,int *pl)
+{ 
+    int sign=0,bitsz; 
+    switch(cadr(type)) { 
+    case INT:		sign=1; bitsz=32; align=4;break; 
+    case UNSIGNED:		bitsz=32; align=4;break; 
+    case CHAR:          sign=1; bitsz=24; align=1;break; 
+    case UCHAR: 		bitsz=24; align=1;break; 
+    case SHORT:         sign=1; bitsz=16; align=2;break; 
+    case USHORT:        sign=1; bitsz=16; align=2;break; 
+    case LONGLONG:      sign=1; bitsz=64; align=4;l=1; break; 
+    case ULONGLONG:            	bitsz=64; align=4;l=1; break; 
+    default: error(-1);
+    }
+    *psign = sign;
+    *pbitsz = bitsz;
+    *palign = align;
+    *pl = l;
+}
+
+/*
+      bit field alignment calcuration
+        this is architecture depenedent
+ */
+
+extern int
+code_bit_field_disp(int type,int *poffset,int *bfd,int *sz)
+{
+    int sign,bitsz;
+    int i;
+    int bitpos = *bfd;
+    int offset = *poffset;
+    int l;
+    int bitsize = cadddr(type);
+    set_bitsz(type,&sign,&bitsz,&l);
+
+    if (bitsize>bitsz) { error(BTERR); bitsize = i; }
+
+    /* bfd means previous bit field bit offset */
+    if (bitpos) {
+	/* previous field is bit field and spaces may remain */
+	/* calc previsous offset */
+
+	i= offset-(bitpos+7)/8;
+
+	if ((i & (align-1)) && bitpos+bitsize < bitsz) {
+
+	    /* alignment is correct and space remains */
+
+	    *poffset=offset=i;
+	    i = bitpos+bitsize;
+	    *bfd = i;
+	    *sz = (i+7)/8;
+	    return bitpos;
+	} 
+    }
+
+    /* first bit-field */
+
+    if ((i=(offset & (align-1)))) {
+	*poffset = (offset += i);
+    }
+    bitpos = 0;
+    *bfd = bitsize;
+    *sz = (bitsize+7)/8;
+
+    return bitpos;
+}
+
+/* bit field value */
+
+/* reg contains container value, result should be in reg */
+extern void
+code_bit_field(int type,int bit_offset,int bit_size,int reg)
+{
+    int sign,bitsz,l;
+    int bitsize = cadddr(type);
+    int i;
+    set_bitsz(type,&sign,&bitsz,&l);
+    /* this implementation returns -1 for int i:1; */
+    if (l==1) {
+	use_longlong(reg);
+	/* shift left */
+	if (bit_offset) 
+	    loprtc(LLSHIFT,reg,bit_offset);
+	/* shift right */
+	if ((i=bitsz-bitsize)) 
+	    loprtc(sign?LRSHIFT:LRUSHIFT,reg,i);
+    } else {
+	use_int(reg);
+	/* shift left */
+	if (bit_offset) 
+	    oprtc(LSHIFT,reg,bit_offset);
+	/* shift right */
+	if ((i=bitsz-bitsize)) 
+	    oprtc(sign?RSHIFT:RUSHIFT,reg,i);
+    }
+}
+
+/* bit field replacement */
+
+extern void
+code_bit_replace(int value,int lvalue,int type,int bit_offset)
+{
+    int sign,bitsz,l;
+    int bitsize = cadddr(type);
+    set_bitsz(type,&sign,&bitsz,&l);
+    if (l) {
+	use_longlong(reg);
+	/* make and-mask lower */
+	/* make and-mask upper */
+	/* make or-mask  lower */
+	/* make or-mask  upper */
+	/* shift left */
+	/* do conjunction  */
+	/* do disjunction  */
+    } else {
+	use_int(reg);
+	/* make and-mask */
+	/* make or-mask  */
+	/* shift left */
+	/* do conjunction  */
+	/* do disjunction  */
+    }
+}
+
+#endif
+
 /* end */
--- a/mc-code.h	Tue Jun 22 01:24:00 2004 +0900
+++ b/mc-code.h	Wed Jun 23 16:10:03 2004 +0900
@@ -246,4 +246,22 @@
 
 extern void gen_comment(char *s);
 
+#if BIT_FIELD_CODE
+
+/* bit field alignment calcuration */
+
+extern int code_bit_field_disp(int type,int *offset,int *bfd,int *sz,int mode);
+
+/* bit field value */
+
+/* reg contains address of bit_field, result should goto reg */
+extern void code_bit_field(int type,int bit_offset,int reg);
+
+/* bit field replacement */
+
+extern void code_bit_replace(int value,int lvalue,int type,int bit_offset);
+                          /*  register,   register */
+
+#endif
+
 /* end */
--- a/mc-codegen.c	Tue Jun 22 01:24:00 2004 +0900
+++ b/mc-codegen.c	Wed Jun 23 16:10:03 2004 +0900
@@ -46,6 +46,12 @@
 static void lassign(int e1);
 #endif
 
+#if BIT_FIELD_CODE
+static int bit_field(int e1,int t);
+static int bassign(int e1,int e2,int t);
+static int bassop(int e1,int e2,int op,int t);
+#endif
+
 
 extern void
 codegen_init()
@@ -457,6 +463,17 @@
     case ENVIRONMENT:
 	code_environment(USE_CREG);
 	return ADDRESS;
+#if BIT_FIELD_CODE
+    case RBIT_FIELD:
+	return bit_field(e2,caddr(e1) /* type */);
+    case BASS:
+	return bassign(e2,caddr(e1),cadr(cadddr(e1))/* type */);
+    case BASSOP:
+	return bassop(e2,caddr(e1),car(cadddr(e1)),/* op */
+				    cadr(cadddr(e1))/* type */);
+    case BFD_REPL:
+	return bit_field_repl(e2,caddr(e1),cadddr(e1) /* type */);
+#endif
 #if ASM_CODE
     case ASM:
 	gen_asm(car(e2),cadr(e2),caddr(e2),cadddr(e2),caddr(e1));
@@ -1269,21 +1286,21 @@
     case CURGVAR:  code_crgvar(e4,reg,e5==CRGVAR,1); return;
     case SRGVAR:  
     case SURGVAR:  code_crgvar(e4,reg,e5==SRGVAR,size_of_short); return;
-    case RGVAR:   code_rgvar(e4,reg);  return;
+    case RGVAR:    code_rgvar(e4,reg);  return;
     case CRLVAR:  
     case CURLVAR:  code_crlvar(cadr(e4),reg,e5==CRLVAR,1); return;
     case SRLVAR:  
     case SURLVAR:  code_crlvar(cadr(e4),reg,e5==SRLVAR,size_of_short); return;
-    case RLVAR:   code_rlvar(cadr(e4),reg);  return;
-    case GVAR:    code_gvar(e4,reg);   return;
-    case LVAR:    code_lvar(cadr(e4),reg);   return;
-    case CONST:   code_const(cadr(e4),reg); return;
+    case RLVAR:    code_rlvar(cadr(e4),reg);  return;
+    case GVAR:     code_gvar(e4,reg);   return;
+    case LVAR:     code_lvar(cadr(e4),reg);   return;
+    case CONST:    code_const(cadr(e4),reg); return;
     case ADDRESS: 
 	if (car(cadr(e4))==STRING) code_string(cadr(e4),reg);
 	else code_gvar(cadr(e4),reg);   
 	return;
-    case FNAME:   code_fname((NMTBL*)cadr(e4),reg); return;
-    case STRING:  code_string(e4,reg); return;
+    case FNAME:    code_fname((NMTBL*)cadr(e4),reg); return;
+    case STRING:   code_string(e4,reg); return;
     default: error(-1);
     }
 }
@@ -1681,7 +1698,7 @@
         return(list3(ASS,e1,e2));
     } else if (car(t)==BIT_FIELD) {
 	e2 = correct_type(e2,cadr(t));
-        return(list3(BASS,e1,e2));
+        return(list4(BASS,e1,e2,list2(BASS,t)));
     } else if((car(t)==STRUCT||car(t)==UNION)) {
         if (size(t)!=size(type)) error(TYERR);
         type=t;
@@ -1790,8 +1807,6 @@
     type=t;
     if(integral(t)) return(list4(ASSOP,e1,e2,op));
     /* pointer += ... */
-    if(integral(t)) return(list4(ASSOP,e1,e2,op));
-    /* pointer += ... */
     if((op!=ADD&&op!=SUB)||car(t)!=POINTER) error(TYERR);
     e2=binop(MUL,e2,list2(CONST,size(cadr(t))),INT,UNSIGNED);
     type=t;
@@ -2221,10 +2236,9 @@
 	if (car(n->ty)==BIT_FIELD) {
 	    bit_field_disp=sbit_f;   // default is 0, recover only here.
             // n->ty = list4(BIT_FIELD,type,bit_offset,bit_width);
-	    caddr(n->ty) = bit_field_disp;  // bitwise offset
-	    bit_field_disp += cadddr(n->ty);
-	    sz = bit_field_disp/bit_of_byte;
-	    bit_field_disp %= bit_of_byte;
+	    caddr(n->ty) = code_bit_field_disp(
+		cadr(n->ty),cadddr(n->ty),&disp,&bit_field_disp,&sz);
+	    /* bit_field_disp is next bit posision */
 	}  else {
 	    sz = size(type);
 	}
@@ -2361,14 +2375,17 @@
 extern int
 assign_data(int e, int t, NMTBL *n,int offset)
 {
-    int ass;
+    int ass,sz,bfd;
 
     if(mode==GDECL) {
  	emit_data(e,t,n);
     } else if(mode==STADECL) {
  	emit_data(e,t,n);
     } else if(mode==LDECL) {
-	if (t==EMPTY) return offset+cadr(e);
+	if (t==EMPTY) {
+	    /* empty space in partial initialization */
+	    return offset+cadr(e);
+	}
 	ass = assign_expr0(
     (n->sc==REGISTER||n->sc==DREGISTER||n->sc==FREGISTER||n->sc==LREGISTER)?
 	    list3(n->sc,n->dsp,(int)n):
@@ -2382,6 +2399,12 @@
 	error(DCERR);
 	return offset;
     }
+    if (t>0&&car(t)==BIT_FIELD) {
+	sz = 0; 
+	bfd = caddr(t); /* bit_field_disp */
+	code_bit_field_disp(cadr(t),cadddr(t),&offset,&bfd,&sz);
+	return offset+sz;
+    }
     return offset+((t==EMPTY)?cadr(e):size(t));
 }
 
@@ -2607,8 +2630,8 @@
 	case POINTER:
 	    break;
 	case BIT_FIELD:
-	    return list4(BIT_FIELD,caddr(type),cadddr(type),rvalue(cadddr(e)));
-            /*                      bit offset,   bit size,  rvalue */
+	    return list3(RBIT_FIELD,rvalue(cadddr(e)),type);
+            /*                         byte rvalue,   type */
 	    type = cadr(e);
 	    break;
 	default:
@@ -2727,7 +2750,7 @@
     }
     if (type>0&&car(type)==BIT_FIELD) {
 	// n->ty = list4(BIT_FIELD,type,bit_offset, bit_size);
-	e=list4(BIT_FIELD,     caddr(type),cadddr(type), e);
+	e=list3(BIT_FIELD,e,type);
     }
     return e;
 }
@@ -3134,6 +3157,64 @@
     return (cadr(e));
 }
 
+#define is_long_type(type)  (type==LONGLONG||type==ULONGLONG)
+
+#if BIT_FIELD_CODE
+static int
+bit_field(int e1,int t)
+{
+    g_expr(e1);
+    code_bit_field(cadr(t)   /* type */,
+                   caddr(t)  /* bit offset */, 
+                   USE_CREG);
+    return cadr(t);
+}
+
+static int
+bit_field_repl(int e1,int e2,int t)
+{
+    /* e1 = e2 */
+    int lo = is_long_type(cadr(t));
+    g_expr(e2);
+    if (lo) emit_lpush(); else emit_push();
+    g_expr(e1);
+    code_bit_replace(USE_CREG,(e2=lo?emit_lpop():pop_register()),
+	t /* type */,caddr(t) /* bit offset */);
+    if (lo) emit_lpop_free(e2) else emit_pop_free(e2);
+    return cadr(t);
+}
+
+static int
+bassop(int e2,int e3,int op,int t)
+{
+    int type  = cadr(t);
+    /* if op==NULL  e2 = e3 */
+    /*  e2 = e2 op e3; */
+    if (car(e2)==LREGISTER||car(e2)==REGISTER||car(e2)==LVAR||car(e2)==GVAR) {
+	g_expr(assign_expr0(e2,
+	    list4(BFD_REPL,e2,op?list3(op,rvalue_t(e2,t),e3):e3,t),
+	    type,type));
+	return type;
+    }
+    /*  new = &e2 */
+    /*  *new = *new op e3 */
+    n = list2(LVAR,new_lvar(size_of_int));
+    g_expr_u(assign_expr0(n,list2(ADDRESS,e2),INT,INT));
+    g_expr(assign_expr0(list2(INDIRECT,n),
+	list4(BFD_REPL,n,op?list3(op,n,e3):e3,t),
+	type,type));
+    free_lvar(cadr(n));
+    return type;
+}
+
+static int
+bassign(int e2,int e3,int t)
+{
+    return bassop(e2,e3,0,t);
+}
+
+#endif
+
 /* temporal local variable free list */
 
 static int lvar_list,lvar_free_list;
--- a/mc-parse.c	Tue Jun 22 01:24:00 2004 +0900
+++ b/mc-parse.c	Wed Jun 23 16:10:03 2004 +0900
@@ -1116,7 +1116,11 @@
 	    return offset; /* not reached */
 	}
     } else if (t1==BIT_FIELD) {
-	error(DCERR); // not supported now
+ 	e=expr1();
+	mode = mode_save;
+ 	offset = assign_data(e,t,n,offset);
+ 	type=t;
+	return offset;
     } else if (t1==STRUCT) {
         if (sym==LC) {
             conv->lc_(); conv->decl_data_begin_();
--- a/mc-parse.h	Tue Jun 22 01:24:00 2004 +0900
+++ b/mc-parse.h	Wed Jun 23 16:10:03 2004 +0900
@@ -9,7 +9,7 @@
 extern int gtypedefed;
 extern int retlabel,retpending,retcont;
 extern int chk;
-#if BITFIELD_CODE
+#if BIT_FIELD_CODE
 extern int bit_field_disp;
 #endif
 extern int fields;
--- a/mc.h	Tue Jun 22 01:24:00 2004 +0900
+++ b/mc.h	Wed Jun 23 16:10:03 2004 +0900
@@ -4,7 +4,7 @@
 #define LONGLONG_CODE 1
 #define CASE_CODE 1
 #define ASM_CODE 1
-#define BITFIELD_CODE 1
+#define BIT_FIELD_CODE 1
 
 /* reserved word start */
 
@@ -69,7 +69,6 @@
 #define VOLATILE        (-57)
 #define TYPEOF  (-58)
 #define ASM     (-59)
-#define BIT_FIELD       (-60)
 
 /* reserved word end */
 
@@ -199,52 +198,54 @@
 #define LURINDIRECT     (LOP+URINDIRECT)
 #define RSTRUCT	27
 #define ALLOCA 	28
-#define CONV   	29
+#define BIT_FIELD 	29
+#define RBIT_FIELD 	30
+#define CONV   	31
 
 #define UNARY_ARGS(i) (ADDRESS<=(i%SOP)&&(i%SOP)<=CONV)
 
 /* binary  argments */
 
-#define MUL    	30
-#define UMUL   	31
-#define DIV    	32
-#define UDIV   	33
-#define MOD    	34
-#define UMOD   	35
-#define ADD    	36
-#define SUB    	37
-#define CMP    	38      
-#define RSHIFT 	39
-#define URSHIFT	40
-#define LSHIFT 	41
-#define ULSHIFT	42
-#define GT     	43
-#define UGT    	44
-#define GE     	45
-#define UGE    	46
-#define LT     	47
-#define ULT    	48
-#define LE     	49
-#define ULE    	50
-#define EQ     	51
-#define NEQ    	52
-#define BAND   	53
-#define EOR    	54
-#define BOR    	55
-#define LAND   	56
-#define LOR    	57
-#define ASS    	58
-#define UCMP   	59
-#define UCMPGE 	60
-#define CMPGE  	61
-#define CMPEQ  	62
-#define CMPNEQ 	63
-#define ASSOP  	64
-#define COMMA  	65
+#define MUL    	32
+#define UMUL   	33
+#define DIV    	34
+#define UDIV   	35
+#define MOD    	36
+#define UMOD   	37
+#define ADD    	38
+#define SUB    	39
+#define CMP    	40      
+#define RSHIFT 	41
+#define URSHIFT	42
+#define LSHIFT 	43
+#define ULSHIFT	44
+#define GT     	45
+#define UGT    	46
+#define GE     	47
+#define UGE    	48
+#define LT     	49
+#define ULT    	50
+#define LE     	51
+#define ULE    	52
+#define EQ     	53
+#define NEQ    	54
+#define BAND   	55
+#define EOR    	56
+#define BOR    	57
+#define LAND   	58
+#define LOR    	59
+#define ASS    	60
+#define UCMP   	61
+#define UCMPGE 	62
+#define CMPGE  	63
+#define CMPEQ  	64
+#define CMPNEQ 	65
+#define ASSOP  	66
+#define COMMA  	67
 
-#define CASS   	66
-#define CASSOP 	67
-#define CUASSOP	68
+#define CASS   	68
+#define CASSOP 	69
+#define CUASSOP	70
 
 #define SASS    (SOP+CASS)
 #define SASSOP (SOP+CASSOP)
@@ -300,17 +301,18 @@
 #define LEOR    (LOP+EOR)
 #define LBOR    (LOP+BOR)
 
-#define BASS   	69
-#define BASSOP 	70
+#define BASS   	71
+#define BASSOP 	72
+#define BFD_REPL 	73
 
-#define STASS  	71
+#define STASS  	74
 
 
 #define BINARY_ARGS(i) (MUL<=(i%SOP)&&(i%SOP)<=STASS)
 
 /* tarnary  argments */
 
-#define COND   	72
+#define COND   	75
 #define SCOND   (SOP+COND)
 #define DCOND   (DOP+COND)
 #define FCOND   (FOP+COND)
@@ -320,19 +322,19 @@
 
 /* not appeared as tags */
 
-#define I2I    	73
-#define I2U    	74
-#define I2D    	75
-#define I2F    	76
-#define I2LL   	77
-#define I2ULL  	78
+#define I2I    	76
+#define I2U    	77
+#define I2D    	78
+#define I2F    	79
+#define I2LL   	80
+#define I2ULL  	81
 
-#define U2I    	79
-#define U2U    	80
-#define U2D    	81
-#define U2F    	82
-#define U2LL   	83
-#define U2ULL  	84
+#define U2I    	82
+#define U2U    	83
+#define U2D    	84
+#define U2F    	85
+#define U2LL   	86
+#define U2ULL  	87
 
 #define D2I     (DOP+I2I)
 #define D2U     (DOP+I2U)
@@ -362,17 +364,17 @@
 #define ULL2LL  (LOP+U2LL)
 #define ULL2ULL (LOP+U2ULL)
 
-#define LPAR   	85
-#define RPAR   	86
-#define LBRA   	87
-#define RBRA   	88
-#define LC     	89
-#define RC     	90
-#define COLON  	91
-#define SM     	92
-#define PERIOD 	93
-#define ARROW  	94
-#define CNAME  	95
+#define LPAR   	88
+#define RPAR   	89
+#define LBRA   	90
+#define RBRA   	91
+#define LC     	92
+#define RC     	93
+#define COLON  	94
+#define SM     	95
+#define PERIOD 	96
+#define ARROW  	97
+#define CNAME  	98
 
 /* tree node tags end */