changeset 338:7fe7ce0a791f bit-field-done

bit-field done for IA32, PowerPC, MIPS. bit-field assop. No bit-field global init.
author kono
date Fri, 25 Jun 2004 14:30:43 +0900
parents 694cdf15c5bd
children 375d21a2b845
files Changes Makefile mc-code-ia32.c mc-code-mips.c mc-code-powerpc.c mc-codegen.c mc-parse.c test/bitfield.c
diffstat 8 files changed, 408 insertions(+), 102 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Fri Jun 25 05:37:09 2004 +0900
+++ b/Changes	Fri Jun 25 14:30:43 2004 +0900
@@ -5146,3 +5146,46 @@
 bit field はできました。
 
 なんか MIPS のgccは、bit field にバグあるみたいだね。
+
+Fri Jun 25 11:30:30 JST 2004
+
+3249,3252c3249,3251
+<     //  n = get_register_var(0);
+<     g_expr_u(assign_expr0(n,list2(ADDRESS,cadr(e2)),INT,INT));
+<     e4 = rvalue_t(list2(INDIRECT,rvalue_t(n,INT)),type);
+<     g_expr(assign_expr0(list2(INDIRECT,rvalue_t(n,INT)),
+---
+>     g_expr_u(assign_expr0(n,list2(ADDRESS,e2),INT,INT));
+>     e4 = rvalue_t(list2(INDIRECT,n),type);
+>     g_expr(assign_expr0(list2(INDIRECT,n),
+3255,3256c3254
+<     if (car(n)==LVAR) free_lvar(cadr(n));
+<     else if (car(n)==REGISTER) free_register(cadr(n));
+---
+>     free_lvar(cadr(n));
+
+なんだけど、lassop あたりでも問題ありそう。
+
+bassop を呼び出す BPOSTINC で、post の処理をさぼってます。
+
+っていうか、bassop は間違っているじゃん。
+
+bassign だったら、読み出してbit replace で良いんだが、
+op をかけるんだったら、bit_field として読み出して、
+一旦、整数値にしてから計算しないとだめ。
+
+post の処理は複雑なので専用のを書いた方が良い。
+
+    if (simple) {
+	tmp_var = bit_field
+	tmp_var op= operand
+	bit_field = new_var
+    } else {
+	address = lvalue;
+	tmp_var = address->bit_field
+	tmp_var op= operand
+	address->bit_field = new_var
+    }
+    if (post) tmp_var;
+
+ですかね。
--- a/Makefile	Fri Jun 25 05:37:09 2004 +0900
+++ b/Makefile	Fri Jun 25 14:30:43 2004 +0900
@@ -77,8 +77,8 @@
 	make check TARGET=test/switch
 	make check TARGET=test/strinit
 	make check TARGET=test/code-gen-all
-	make check TARGET=test/bitfield.c
-	make check TARGET=test/bitfield1.c
+	make check TARGET=test/bitfield
+	make check TARGET=test/bitfield1
 #MK =-make
 MK=
 check-all-code:
--- a/mc-code-ia32.c	Fri Jun 25 05:37:09 2004 +0900
+++ b/mc-code-ia32.c	Fri Jun 25 14:30:43 2004 +0900
@@ -3269,7 +3269,7 @@
 		i = l+bitsize;
 		*bfd = i;
 		*sz = (i+7)/8;
-printf("# bitpos=%d bitsize=%d bitsz=%d offset=%d\n",l,bitsize,bitsz,*poffset);
+// printf("# bitpos=%d bitsize=%d bitsz=%d offset=%d\n",l,bitsize,bitsz,*poffset);
 		return l;
 	    } 
 	}
@@ -3284,7 +3284,7 @@
     *bfd = bitsize;
     *sz = (bitsize+7)/8;
 
-printf("# bitpos=%d bitsize=%d bitsz=%d offset=%d\n",bitpos,bitsize,bitsz,*poffset);
+// printf("# bitpos=%d bitsize=%d bitsz=%d offset=%d\n",bitpos,bitsize,bitsz,*poffset);
     return bitpos;
 }
 
@@ -3298,23 +3298,23 @@
     int bitsize = cadddr(type);
     int i;
     set_bitsz(type,&sign,&bitsz,&align,&l);
-printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz);
+// printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz);
     /* this implementation returns -1 for int i:1; */
     if (l==1) {
 	use_longlong(reg);
 	/* shift left */
-	if (bitpos) 
-	    loprtc(LLSHIFT,reg,list2(CONST,bitpos));
+	if ((i=bitsz-bitsize-bitpos)) 
+	    loprtc(LLSHIFT,reg,list2(CONST,i));
 	/* shift right */
 	if ((i=bitsz-bitsize)) 
 	    loprtc(sign?LRSHIFT:LURSHIFT,reg,list2(CONST,i));
     } else {
 	use_int(reg);
 	/* shift left */
-	if ((i=bitpos+(32-bitsz))) 
+	if ((i=32-bitsize-bitpos)) 
 	    oprtc(LSHIFT,reg,list2(CONST,i));
 	/* shift right */
-	if ((i=bitsz-bitsize+(32-bitsz))) 
+	if ((i=32-bitsize)) 
 	    oprtc(sign?RSHIFT:URSHIFT,reg,list2(CONST,i));
     }
 }
@@ -3322,19 +3322,32 @@
 /* bit field replacement */
 
 static void
-make_mask_and_or(int mask,int lreg)
+make_mask_and_or(int mask,int reg,int lreg)
 {
 printf("# mask 0x%08x ~0x%08x\n",mask,~mask);
+	printf("\tpushl %s\n",register_name(reg,0));
 	/* make and-mask  */
-	printf("\tmovl %s,%s\n",register_name(creg,0),register_name(dreg,0));
-	oprtc(BOR,creg,~mask);
+	oprtc(BOR,reg,list2(CONST,~mask));
 	/* do conjunction  */
-	printf("\tandl %s,%s\n",register_name(lreg,0),register_name(creg,0));
-
+	if (lreg==-1) {
+	    printf("\tandl %s,4(%%esp)\n",register_name(reg,0));
+	} else if (lreg==-2) {
+	    printf("\tandl %s,8(%%esp)\n",register_name(reg,0));
+	} else {
+	    printf("\tandl %s,%s\n",register_name(reg,0),register_name(lreg,0));
+	}
 	/* make or-mask  */
-	oprtc(BAND,dreg,mask);
+	printf("\tpopl %s\n",register_name(reg,0));
+	oprtc(BAND,reg,list2(CONST,mask));
 	/* do disjunction  */
-	printf("\tor %s,%s\n",register_name(lreg,0),register_name(dreg,0));
+	if (lreg==-1) {
+	    printf("\torl %s,0(%%esp)\n",register_name(reg,0));
+	} else if (lreg==-2) {
+	    printf("\torl %s,4(%%esp)\n",register_name(reg,0));
+	} else {
+	    printf("\torl %s,%s\n",register_name(reg,0),register_name(lreg,0));
+	    printf("\txchg %s,%s\n",register_name(reg,0),register_name(lreg,0));
+	}
 }
 
 extern void
@@ -3343,37 +3356,34 @@
     int sign,bitsz,l,align;
     int bitsize = cadddr(type);
     int mask = 0;
-    int tmp = -1;
-    int i;
     set_bitsz(type,&sign,&bitsz,&align,&l);
 // printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz);
     if (l) {
 	use_longlong(value);
 	/* shift left */
-	if ((i=bitsz-bitsize-bitpos)) 
-	    loprtc(LLSHIFT,value,list2(CONST,i));
-	tmp = get_register();
+	if (bitpos) 
+	    loprtc(LLSHIFT,value,list2(CONST,bitpos));
 	if (bitpos+bitsize>=32) {
-	    /* make and-mask lower */
-	    mask = make_mask(bitpos>=32?bitpos-32:0,bitpos+bitsize-32-1);
-	    make_mask_and_or(mask,tmp);
+	    /* make and-mask upper */
+	    mask = make_mask(64-bitpos-bitsize,bitpos>=32?63-bitpos:31);
+	    make_mask_and_or(mask,virtual(value==REG_L?REG_EDI:REG_EDX),-2);
 	}
 	if (bitpos<32) {
-	    /* make and-mask upper */
-	    mask = make_mask(bitpos,bitpos+bitsize>=32?31:bitpos+bitsize-1);
-	    make_mask_and_or(mask,tmp);
+	    /* make and-mask lower */
+	    mask = make_mask(bitpos+bitsize>=32?0:32-bitpos-bitsize,31-bitpos);
+	    make_mask_and_or(mask,virtual(value==REG_L?REG_ESI:REG_EAX),-1);
 	}
+	printf("\tpopl %s\n",l_eax(value));
+	printf("\tpopl %s\n",l_edx(value));
     } else {
 	use_int(value);
 	/* shift left */
-	if ((i=bitsz-bitsize-bitpos)) 
-	    oprtc(LSHIFT,value,list2(CONST,i));
-	tmp = get_register();
+	if (bitpos) 
+	    oprtc(LSHIFT,value,list2(CONST,bitpos));
 	/* make and-mask */
-	mask = make_mask(bitpos+(32-bitsz),bitpos+bitsize-1+(32-bitsz));
-	make_mask_and_or(mask,tmp);
+	mask = make_mask(32-bitpos-bitsize,31-bitpos);
+	make_mask_and_or(mask,value,lvalue);
     }
-    if (tmp!=-1) free_register(tmp);
 }
 
 #endif
--- a/mc-code-mips.c	Fri Jun 25 05:37:09 2004 +0900
+++ b/mc-code-mips.c	Fri Jun 25 14:30:43 2004 +0900
@@ -180,7 +180,7 @@
 int use_int0() { 
     int i = creg;
     if (!i||!ireg||!is_int_reg(i)) {
-	if (lreg) { free_register(lreg); lreg = 0; }
+	if (lreg) { if (regs[lreg]) free_register(lreg); lreg = 0; }
 	if (!ireg) ireg = get_register();
 	// else if (ireg!=i) free_register(i);
 	i = ireg;
@@ -5548,34 +5548,11 @@
     int bitsize = cadddr(type);
     int mask = 0;
     int tmp = -1;
-#if 0
-    int i;
-#endif
     char *crn,*lrn,*trn;
     set_bitsz(type,&sign,&bitsz,&align,&l);
 // printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz);
     if (l) {
 	use_longlong(value);
-#if 0
-	crn = lregister_name_low(value);
-	lrn = lregister_name_low(lvalue);
-	/* shift left */
-	if ((i=bitsz-bitsize-bitpos)) 
-	    loprtc(LLSHIFT,value,list2(CONST,i));
-	trn = register_name(tmp = get_register());
-	if (bitpos+bitsize>=32) {
-	    /* make and-mask lower */
-	    mask = make_mask(bitpos>=32?bitpos-32:0,bitpos+bitsize-32-1);
-	    make_mask_and_or(mask,tmp,trn,crn,lrn);
-	}
-	crn = lregister_name_high(value);
-	lrn = lregister_name_high(lvalue);
-	if (bitpos<32) {
-	    /* make and-mask upper */
-	    mask = make_mask(bitpos,bitpos+bitsize>=32?31:bitpos+bitsize-1);
-	    make_mask_and_or(mask,tmp,trn,crn,lrn);
-	}
-#else
 	crn = lregister_name_high(value);
 	lrn = lregister_name_high(lvalue);
 	/* shift left */
@@ -5594,25 +5571,16 @@
 	    mask = make_mask(bitpos+bitsize>=32?0:32-bitpos-bitsize,31-bitpos);
 	    make_mask_and_or(mask,tmp,trn,crn,lrn);
 	}
-#endif
     } else {
 	use_int(value);
 	crn = register_name(value);
 	lrn = register_name(lvalue);
 	/* shift left */
-#if 0
-	if ((i=bitsz-bitsize-bitpos)) 
-	    oprtc(LSHIFT,value,list2(CONST,i));
-	trn = register_name(tmp = get_register());
-	/* make and-mask */
-	mask = make_mask(bitpos+(32-bitsz),bitpos+bitsize-1+(32-bitsz));
-#else
 	if (bitpos) 
 	    oprtc(LSHIFT,value,list2(CONST,bitpos));
 	trn = register_name(tmp = get_register());
 	/* make and-mask */
 	mask = make_mask(32-bitpos-bitsize,31-bitpos);
-#endif
 	make_mask_and_or(mask,tmp,trn,crn,lrn);
     }
     if (tmp!=-1) free_register(tmp);
--- a/mc-code-powerpc.c	Fri Jun 25 05:37:09 2004 +0900
+++ b/mc-code-powerpc.c	Fri Jun 25 14:30:43 2004 +0900
@@ -158,7 +158,7 @@
 int use_int0() { 
     int i = creg;
     if (!i||!ireg||!is_int_reg(i)) {
-	if (lreg) { free_register(lreg); lreg = 0; }
+	if (lreg) { if (regs[lreg]) free_register(lreg); lreg = 0; }
 	if (!ireg) ireg = get_register();
 	// else if (ireg!=i) free_register(i);
 	i = ireg;
@@ -2411,6 +2411,7 @@
 #if 1
     set_ireg(edx,0);
     ld_indexx(byte,0,creg,ireg,sign);
+    use_reg(creg); // to clear ptr cache
     tosop(op,ireg,xreg);
     crn = register_name(ireg);
     drn = register_name(creg);
--- a/mc-codegen.c	Fri Jun 25 05:37:09 2004 +0900
+++ b/mc-codegen.c	Fri Jun 25 14:30:43 2004 +0900
@@ -471,10 +471,10 @@
 	return bassign(e2,caddr(e1),cadr(cadddr(e1))/* type */);
     case BPREINC:
 	return bassop(e2,list2(CONST,caddr(e1)),ADD,
-				    cadr(cadddr(e1))/* type */,0);
+				    cadddr(e1)/* type */,0);
     case BPOSTINC:
 	return bassop(e2,list2(CONST,caddr(e1)),ADD,
-				    cadr(cadddr(e1))/* type */,1);
+				    cadddr(e1)/* type */,1);
     case BASSOP:
 	return bassop(e2,caddr(e1),car(cadddr(e1)),/* op */
 				    cadr(cadddr(e1))/* type */,0);
@@ -3226,37 +3226,115 @@
 }
 
 static int
-bassop(int e2,int e3,int op,int t,int post)
+bassign(int e2,int e3,int t)
 {
     int n,e4;
     int type  = cadr(t);
-    /* if op==NULL  e2 = e3 */
-    /*  e2 = e2 op e3; */
+    /*  e2 = e3 */
+if (car(e2)==BIT_FIELD) {
+    printf("# bit_field_bug\n");
+    e2 = cadr(e2);
+}
     if (car(e2)==LREGISTER||car(e2)==REGISTER||car(e2)==LVAR||car(e2)==GVAR) {
 	e4 = rvalue_t(e2,type);
-	g_expr(assign_expr0(e2,
-	    list4(BFD_REPL,e4,op?list3(op,e4,e3):e3,t),
-	    type,type));
+	g_expr(assign_expr0(e2, list4(BFD_REPL,e4,e3,t), type,type));
+	if (use)
+	    code_bit_field(t, caddr(t)  /* bit offset */, USE_CREG);
 	return type;
     }
     /*  new = &e2 */
-    /*  *new = *new op e3 */
-    // n = list2(LVAR,new_lvar(size_of_int));
-    n = get_register_var(0);
+    /*  *new = *new bit_repl e3 */
+    n = list2(LVAR,new_lvar(size_of_int));
+    //  n = get_register_var(0);
     g_expr_u(assign_expr0(n,list2(ADDRESS,cadr(e2)),INT,INT));
-    e4 = rvalue_t(list2(INDIRECT,n),type);
-    g_expr(assign_expr0(list2(INDIRECT,n),
-	list4(BFD_REPL,e4,op?list3(op,e4,e3):e3,t),
+    e4 = rvalue_t(list2(INDIRECT,rvalue_t(n,INT)),type);
+    g_expr(assign_expr0(list2(INDIRECT,rvalue_t(n,INT)),
+	list4(BFD_REPL,e4,e3,t),
 	type,type));
-    if (car(n)==LVAR) free_lvar(cadr(n));
-    else if (car(n)==REGISTER) free_register(cadr(n));
+    free_lvar(cadr(n));
+    if (use)
+	code_bit_field(t, caddr(t)  /* bit offset */, USE_CREG);
     return type;
 }
 
 static int
-bassign(int e2,int e3,int t)
+bassop(int e2,int e3,int op,int t,int post)
 {
-    return bassop(e2,e3,0,t,0);
+  /*
+    if (simple) {
+	tmp_var1 = bit_field byte
+	tmp_var2 = tmp_var  = code_bit_field
+        tmp_var op= operand
+        bit_field = tmp_var1 bit-repl tmp_var
+    } else {
+        address = lvalue;
+
+	tmp_var1 = bit_field byte (*address)
+	tmp_var2 = tmp_var  = code_bit_field
+        tmp_var op= operand
+        bit_field (*address) = tmp_var1 bit-repl tmp_var
+
+    }
+    if (post) tmp_var2;
+   */
+
+    int n=-1,n1=-1,n2=-1,adr=-1,e4;
+    int type  = cadr(t);
+    int byte;
+    byte = size(type); if (byte==4) byte = 0;
+
+    n = list2(LVAR,new_lvar(size(type)));
+    n1 = list2(LVAR,new_lvar(size(type)));
+    if (post) n2 = list2(LVAR,new_lvar(size(type)));
+    /*  e2 = e3 */
+if (car(e2)==BIT_FIELD) {
+    printf("# bit_field_bug\n");
+    e2 = cadr(e2);
+}
+    if (!(car(e2)==LREGISTER||car(e2)==REGISTER||car(e2)==LVAR||car(e2)==GVAR)) {
+	adr = list2(LVAR,new_lvar(size(type)));
+	g_expr_u(assign_expr0(adr,list2(ADDRESS,cadr(e2)),INT,INT));
+	e4 = rvalue_t(list2(INDIRECT,rvalue_t(adr,INT)),type);
+	e2 = list2(INDIRECT,rvalue_t(adr,INT));
+    } else {
+	e4 = rvalue_t(e2,type);
+    }
+    g_expr(e4);
+    if (type==ULONGLONG||type==LONGLONG) {
+	code_lassign_lvar(cadr(n1),USE_CREG);
+	code_bit_field(t, caddr(t)  /* bit offset */, USE_CREG);
+	code_lassign_lvar(cadr(n),USE_CREG);
+	if (post) code_lassign_lvar(cadr(n2),USE_CREG);
+    } else {
+	code_assign_lvar(cadr(n1),USE_CREG,byte);
+	code_bit_field(t, caddr(t)  /* bit offset */, USE_CREG);
+	code_assign_lvar(cadr(n),USE_CREG,byte);
+	if (post) code_assign_lvar(cadr(n2),USE_CREG,byte);
+    }
+
+    switch(type) {
+    case LONGLONG:	lassop(list4(LASSOP,n,longlong_value(e3),op+LOP)); break;
+    case ULONGLONG:	lassop(list4(LUASSOP,n,longlong_value(e3),op+LOP)); break;
+    case CHAR: 		iassop(list4(CASSOP,n,int_value(e3),op)); break;
+    case UCHAR: 	iassop(list4(CUASSOP,n,unsigned_value(e3),op)); break;
+    case SHORT: 	iassop(list4(SASSOP,n,int_value(e3),op)); break;
+    case USHORT: 	iassop(list4(SUASSOP,n,unsigned_value(e3),op)); break;
+    case UNSIGNED: 	iassop(list4(ASSOP,n,unsigned_value(e3),op)); break;
+    case INT: 		iassop(list4(ASSOP,n,int_value(e3),op)); break;
+    default: error(-1);
+    }
+
+    g_expr(assign_expr0(e2,
+	    list4(BFD_REPL,rvalue_t(n1,type),rvalue_t(n,type),t),type,type));
+
+    if (post) { g_expr(rvalue_t(n2,type)); free_lvar(cadr(n2)); }
+    else if (use)  { 
+	code_bit_field(t, caddr(t)  /* bit offset */, USE_CREG);
+    }
+    if (adr!=-1) free_lvar(cadr(adr));
+    free_lvar(cadr(n));
+    free_lvar(cadr(n1));
+    return type;
 }
 
 #endif
--- a/mc-parse.c	Fri Jun 25 05:37:09 2004 +0900
+++ b/mc-parse.c	Fri Jun 25 14:30:43 2004 +0900
@@ -2261,8 +2261,11 @@
 	if(type==DOUBLE)
 	    return(list3(DPREINC,e,dir));
 #endif
-	if(type>0 && car(type)==BIT_FIELD)
-	    return(list4(BPREINC,e,dir,type));
+	if(type>0 && car(type)==BIT_FIELD) {
+	    e = list4(BPREINC,e,dir,type);
+	    type = cadr(type);
+	    return e;
+	}
 	if(car(type)!=POINTER)
 	    error(TYERR);
 	return(list4(UPREINC,e,
@@ -2408,8 +2411,11 @@
 	if(type==ULONGLONG)
 	    return(list3(LUPOSTINC,e,dir));
 #endif
-	if(type>0 && car(type)==BIT_FIELD)
-	    return(list4(BPOSTINC,e,dir,type));
+	if(type>0 && car(type)==BIT_FIELD) {
+	    e = list4(BPOSTINC,e,dir,type);
+	    type = cadr(type);
+	    return e;
+	}
 	if(car(type)!=POINTER)
 	    error(TYERR);
 	return(list4(UPOSTINC,e,
--- a/test/bitfield.c	Fri Jun 25 05:37:09 2004 +0900
+++ b/test/bitfield.c	Fri Jun 25 14:30:43 2004 +0900
@@ -17,6 +17,7 @@
 	    unsigned long g:1;
 	    unsigned long :1;
 	    unsigned long pp:2;
+	    long long lpn:40;
     } pte;
     struct {
 	    unsigned char v:1;
@@ -188,6 +189,8 @@
       printf("%d %d %d\n",a.pte.pp,g.pte.pp,p->pte.pp);
      main2();
      main5();
+     main3();
+     main4();
     return 0;
 }
 
@@ -326,25 +329,150 @@
 main3( int a )
 {
      // int b:9;       // nor local variable
-     int b;
+     int b,i;
+     i = 7;
 
 
-     g.pte.rpn--;
-     g.pte.rpn++;
-     --g.pte.rpn;
-     ++g.pte.rpn;
-     g.pte.rpn += 3;
-     g.pte.rpn -= 3;
-     g.pte.rpn *= 3;
-     g.pte.rpn /= 3;
-     g.pte.rpn %= 3;
-     g.pte.rpn |= 3;
-     g.pte.rpn &= 3;
-     g.pte.rpn ^= 3;
+     b = g.pte.rpn = -333;
+     printf("main3-0: %d\n",b);
+     b = g.pte.rpn--;
+     printf("main3-1: %d\n",b);
+     b = g.pte.rpn++;
+     printf("main3-2: %d\n",b);
+     b = --g.pte.rpn;
+     printf("main3-3: %d\n",b);
+     b = ++g.pte.rpn;
+     printf("main3-4: %d\n",b);
+     b = (g.pte.rpn += 3);
+     printf("main3-5: %d\n",b);
+     b = (g.pte.rpn -= 3);
+     printf("main3-6: %d\n",b);
+     b = (g.pte.rpn *= 3);
+     printf("main3-7: %d\n",b);
+     b = (g.pte.rpn /= 3);
+     printf("main3-8: %d\n",b);
+     b = (g.pte.rpn %= 3);
+     printf("main3-9: %d\n",b);
+     b = (g.pte.rpn |= 3);
+     printf("main3-10: %d\n",b);
+     b = (g.pte.rpn &= 3);
+     printf("main3-12: %d\n",b);
+     b = (g.pte.rpn ^= 3);
+     printf("main3-13: %d\n",b);
+     b = (g.pte.rpn <<= 3);
+     printf("main3-14: %d\n",b);
+     b = (g.pte.rpn >>= 3);
+     printf("main3-15: %d\n",b);
+
+     g.pte.rpn = -333;
+     printf("main3-16: %d\n",b);
+     b = g.pte.rpn--;
+     printf("main3-17: %d\n",b);
+     b = g.pte.rpn++;
+     printf("main3-18: %d\n",b);
+     b = --g.pte.rpn;
+     printf("main3-19: %d\n",b);
+     b = ++g.pte.rpn;
+     printf("main3-20: %d\n",b);
+     b = (g.pte.rpn += i);
+     printf("main3-21: %d\n",b);
+     b = (g.pte.rpn -= i);
+     printf("main3-22: %d\n",b);
+     b = (g.pte.rpn *= i);
+     printf("main3-23: %d\n",b);
+     b = (g.pte.rpn /= i);
+     printf("main3-24: %d\n",b);
+     b = (g.pte.rpn %= i);
+     printf("main3-25: %d\n",b);
+     b = (g.pte.rpn |= i);
+     printf("main3-26: %d\n",b);
+     b = (g.pte.rpn &= i);
+     printf("main3-27: %d\n",b);
+     b = (g.pte.rpn ^= i);
+     printf("main3-28: %d\n",b);
+     b = (g.pte.rpn <<= i);
+     printf("main3-29: %d\n",b);
+     b = (g.pte.rpn >>= i);
+     printf("main3-30: %d\n",b);
 
      return --b;
 }
 
+main4( int a )
+{
+     // int b:9;       // nor local variable
+     int b,i;
+     PTE *pg = &g;
+
+     i = 7;
+
+
+     pg->pte.rpn = -333;
+     printf("main4-0: %d\n",b);
+     b = pg->pte.rpn--;
+     printf("main4-1: %d\n",b);
+     b = pg->pte.rpn++;
+     printf("main4-2: %d\n",b);
+     b = --pg->pte.rpn;
+     printf("main4-3: %d\n",b);
+     b = ++pg->pte.rpn;
+     printf("main4-4: %d\n",b);
+     b = (pg->pte.rpn += 3);
+     printf("main4-5: %d\n",b);
+     b = (pg->pte.rpn -= 3);
+     printf("main4-6: %d\n",b);
+     b = (pg->pte.rpn *= 3);
+     printf("main4-7: %d\n",b);
+     b = (pg->pte.rpn /= 3);
+     printf("main4-8: %d\n",b);
+     b = (pg->pte.rpn %= 3);
+     printf("main4-9: %d\n",b);
+     b = (pg->pte.rpn |= 3);
+     printf("main4-10: %d\n",b);
+     b = (pg->pte.rpn &= 3);
+     printf("main4-12: %d\n",b);
+     b = (pg->pte.rpn ^= 3);
+     printf("main4-13: %d\n",b);
+     b = (pg->pte.rpn <<= 3);
+     printf("main4-14: %d\n",b);
+     b = (pg->pte.rpn >>= 3);
+     printf("main4-15: %d\n",b);
+
+     pg->pte.rpn = -333;
+     printf("main4-16: %d\n",b);
+     b = pg->pte.rpn--;
+     printf("main4-17: %d\n",b);
+     b = pg->pte.rpn++;
+     printf("main4-18: %d\n",b);
+     b = --pg->pte.rpn;
+     printf("main4-19: %d\n",b);
+     b = ++pg->pte.rpn;
+     printf("main4-20: %d\n",b);
+     b = (pg->pte.rpn += i);
+     printf("main4-21: %d\n",b);
+     b = (pg->pte.rpn -= i);
+     printf("main4-22: %d\n",b);
+     b = (pg->pte.rpn *= i);
+     printf("main4-23: %d\n",b);
+     b = (pg->pte.rpn /= i);
+     printf("main4-24: %d\n",b);
+     b = (pg->pte.rpn %= i);
+     printf("main4-25: %d\n",b);
+     b = (pg->pte.rpn |= i);
+     printf("main4-26: %d\n",b);
+     b = (pg->pte.rpn &= i);
+     printf("main4-27: %d\n",b);
+     b = (pg->pte.rpn ^= i);
+     printf("main4-28: %d\n",b);
+     b = (pg->pte.rpn <<= i);
+     printf("main4-29: %d\n",b);
+     b = (pg->pte.rpn >>= i);
+     printf("main4-30: %d\n",b);
+
+     return --b;
+}
+
+
 
 
 
@@ -537,3 +665,75 @@
 }
 
 
+main3l( int a )
+{
+     // int b:9;       // nor local variable
+     long long b,i;
+     i = 7;
+
+
+     g.pte.lpn = -333;
+     printf("main3l-0: %d\n",b);
+     b = g.pte.lpn--;
+     printf("main3l-1: %d\n",b);
+     b = g.pte.lpn++;
+     printf("main3l-2: %d\n",b);
+     b = --g.pte.lpn;
+     printf("main3l-3: %d\n",b);
+     b = ++g.pte.lpn;
+     printf("main3l-4: %d\n",b);
+     b = (g.pte.lpn += 3);
+     printf("main3l-5: %d\n",b);
+     b = (g.pte.lpn -= 3);
+     printf("main3l-6: %d\n",b);
+     b = (g.pte.lpn *= 3);
+     printf("main3l-7: %d\n",b);
+     b = (g.pte.lpn /= 3);
+     printf("main3l-8: %d\n",b);
+     b = (g.pte.lpn %= 3);
+     printf("main3l-9: %d\n",b);
+     b = (g.pte.lpn |= 3);
+     printf("main3l-10: %d\n",b);
+     b = (g.pte.lpn &= 3);
+     printf("main3l-12: %d\n",b);
+     b = (g.pte.lpn ^= 3);
+     printf("main3l-13: %d\n",b);
+     b = (g.pte.lpn <<= 3);
+     printf("main3l-14: %d\n",b);
+     b = (g.pte.lpn >>= 3);
+     printf("main3l-15: %d\n",b);
+
+     g.pte.lpn = -333;
+     printf("main3l-16: %d\n",b);
+     b = g.pte.lpn--;
+     printf("main3l-17: %d\n",b);
+     b = g.pte.lpn++;
+     printf("main3l-18: %d\n",b);
+     b = --g.pte.lpn;
+     printf("main3l-19: %d\n",b);
+     b = ++g.pte.lpn;
+     printf("main3l-20: %d\n",b);
+     b = (g.pte.lpn += i);
+     printf("main3l-21: %d\n",b);
+     b = (g.pte.lpn -= i);
+     printf("main3l-22: %d\n",b);
+     b = (g.pte.lpn *= i);
+     printf("main3l-23: %d\n",b);
+     b = (g.pte.lpn /= i);
+     printf("main3l-24: %d\n",b);
+     b = (g.pte.lpn %= i);
+     printf("main3l-25: %d\n",b);
+     b = (g.pte.lpn |= i);
+     printf("main3l-26: %d\n",b);
+     b = (g.pte.lpn &= i);
+     printf("main3l-27: %d\n",b);
+     b = (g.pte.lpn ^= i);
+     printf("main3l-28: %d\n",b);
+     b = (g.pte.lpn <<= i);
+     printf("main3l-29: %d\n",b);
+     b = (g.pte.lpn >>= i);
+     printf("main3l-30: %d\n",b);
+
+     return --b;
+}
+