changeset 737:d8b207cfbafe

all written
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 08 Nov 2010 02:12:03 +0900
parents d7a976af188a
children 1ba0d5c4d277
files mc-code-i64.c
diffstat 1 files changed, 82 insertions(+), 86 deletions(-) [+]
line wrap: on
line diff
--- a/mc-code-i64.c	Sun Nov 07 22:52:33 2010 +0900
+++ b/mc-code-i64.c	Mon Nov 08 02:12:03 2010 +0900
@@ -258,7 +258,7 @@
 
 extern int lp64;
 
-int code_lassop_p = 0;
+int code_lassop_p = 1;
 
 #define MAX_REGISTER 14                /* intel386のレジスタを6つまで使う*/
 #define REAL_MAX_REGISTER (1+16+16)    /* intel386のレジスタが8つということ*/
@@ -3905,8 +3905,9 @@
 
 void code_u2ll(int reg)
 {
-    printf("\tshlq $32,%s",regisnter_name(reg,0));
-    printf("\tshrq $32,%s",regisnter_name(reg,0));
+    printf("\tmovslq %s,%s",register_name(reg,SIZE_OF_INT),regisnter_name(reg,0));
+    //printf("\tshlq $32,%s",regisnter_name(reg,0));
+    //printf("\tshrq $32,%s",regisnter_name(reg,0));
 }
 
 void code_u2ull(int reg)
@@ -4027,12 +4028,26 @@
 
 void code_lassop(int op,int reg)
 {
-    error(-1);
+    int xreg;
+    //  (*pop()) op = creg
+    //     creg should be ecx
+
+    use_longlong(creg);
+    xreg = emit_pop(0);       /* pop e3 value */
+    emit_push();
+    ld_indexx(byte,0,creg,ireg,0);
+    tosop(op,ireg,xreg);
+    emit_pop_free(xreg);
+    xreg = emit_pop(0);       /* pop e3 value */
+    printf("\t%s %s,(%s)\n",move(SIZE_OF_LONGLONG),register_name(ireg,0),register_name(xreg,0))
+;
+    emit_pop_free(xreg);
 }
 
 void
 code_register_lassop(int reg,int op) {
-    error(-1);
+    use_longlong(reg);
+    ltosop(op,e2,reg);
 }
 
 
@@ -4059,8 +4074,8 @@
     printf("\tja\t_%d\n",dlabel);
     if (delta==1)  {
 #ifdef __APPLE__
-	printf("\tmovl\t_%d-_%d(%%ebx,%s,4),%s\n",l,goffset_label,crn,crn);
-	printf("\taddl\t%%ebx,%s\n",crn);
+	printf("\tmovq\t_%d-(%%rip,%s,8),%s\n",l,crn,crn);
+	printf("\taddq\t%%rbx,%s\n",crn);
 	printf("\tjmp\t*%s\n",crn);
 #else
 	printf("\tjmp\t*_%d(,%s,4)\n",l,crn);
@@ -4080,8 +4095,8 @@
 	printf("\tandl\t%%eax,%%edx\n");
 	printf("\tjne\t_%d\n",dlabel);
 #ifdef __APPLE__
-	printf("\tmovl\t_%d-_%d(%%ebx,%s,2),%s\n",l,goffset_label,crn,crn);
-	printf("\taddl\t%%ebx,%s\n",crn);
+	printf("\tmovq\t_%d-(%%rip,%s,6),%s\n",l,crn,crn);
+	printf("\taddq\t%%rbx,%s\n",crn);
 	printf("\tjmp\t*%s\n",crn);
 #else
 	printf("\tjmp\t*_%d(,%%eax,2)\n",l); 
@@ -4092,8 +4107,8 @@
 	printf("\tandl\t%%eax,%%edx\n");
 	printf("\tjne\t_%d\n",dlabel);
 #ifdef __APPLE__
-	printf("\tmovl\t_%d-_%d(%%ebx,%s),%s\n",l,goffset_label,crn,crn);
-	printf("\taddl\t%%ebx,%s\n",crn);
+	printf("\tmovq\t_%d-(%%ebx,%s,4),%s\n",l,crn,crn);
+	printf("\taddq\t%%rbx,%s\n",crn);
 	printf("\tjmp\t*%s\n",crn);
 #else
 	printf("\tjmp\t*_%d(%%eax)\n",l); 
@@ -4105,7 +4120,7 @@
 	printf("\tandl\t%%edx,%%edx\n");
 	printf("\tjne\t_%d\n",dlabel);
 #ifdef __APPLE__
-	printf("\tmovl\t_%d-_%d(%%ebx,%s,4),%s\n",l,goffset_label,crn,crn);
+	printf("\tmovl\t_%d-(%%rbx,%s,8),%s\n",l,crn,crn);
 	printf("\taddl\t%%ebx,%s\n",crn);
 	printf("\tjmp\t*%s\n",crn);
 #else
@@ -4132,7 +4147,7 @@
 code_table_value(int label,int table_top)
 {
 #ifdef __APPLE__
-    printf("\t.long _%d-_%d\n",label,goffset_label);
+    printf("\t.long _%d-_%d\n",label,table_top);
 #else
     printf("\t.long _%d\n",label);
 #endif
@@ -4162,13 +4177,13 @@
 	printf("%d",cadr(rstr));
     } else if (car(rstr)==FNAME) {
 #ifdef __APPLE__
-	printf("_%s-_%d",ncaddr(rstr)->nm,goffset_label);
+	printf("_%s(%%rip)",ncaddr(rstr)->nm);
 #else
 	printf("%s",ncaddr(rstr)->nm);
 #endif
     } else if (car(rstr)==LABEL) {
 #ifdef __APPLE__
-	printf("_%d-_%d",cadr(rstr),goffset_label);
+	printf("_%d(%%rip)",cadr(rstr));
 #else
 	printf("_%d",cadr(rstr));
 #endif
@@ -4426,32 +4441,37 @@
 /* bit field replacement */
 
 static void
-make_mask_and_or(int mask,int reg,int lreg)
+make_mask_and_or(int mask,int reg)
 {
 printf("## mask 0x%08x ~0x%08x\n",mask,~mask);
-	printf("\tpushl %s\n",register_name(reg,0));
+	printf("\tpushl %s\n",register_name(reg,SIZE_OF_INT));
 	/* make and-mask  */
 	oprtc(BOR,reg,list2(CONST,~mask));
 	/* do conjunction  */
-	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));
-	}
+	printf("\tandl %s,%s\n",register_name(reg,SIZE_OF_INT),register_name(lreg,SIZE_OF_INT));
 	/* make or-mask  */
-	printf("\tpopl %s\n",register_name(reg,0));
+	printf("\tpopl %s\n",register_name(reg,SIZE_OF_INT));
 	oprtc(BAND,reg,list2(CONST,mask));
 	/* do disjunction  */
-	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));
-	}
+	printf("\torl %s,%s\n",register_name(reg,SIZE_OF_INT),register_name(lreg,SIZE_OF_INT));
+	printf("\txchg %s,%s\n",register_name(reg,SIZE_OF_INT),register_name(lreg,SIZE_OF_INT));
+}
+
+static void
+make_mask_and_or_l(long mask,int reg)
+{
+printf("## mask 0x%08x ~0x%08x\n",mask,~mask);
+	printf("\tpushq %s\n",register_name(reg,0));
+	/* make and-mask  */
+	loprtc(BOR,reg,llist2(CONST,~mask));
+	/* do conjunction  */
+	printf("\tandq %s,%s\n",register_name(reg,0),register_name(lreg,0));
+	/* make or-mask  */
+	printf("\tpopq %s\n",register_name(reg,0));
+	oprtc(BAND,reg,list2(CONST,mask));
+	/* do disjunction  */
+	printf("\torq %s,%s\n",register_name(reg,0),register_name(lreg,0));
+	printf("\txchgq %s,%s\n",register_name(reg,0),register_name(lreg,0));
 }
 
 extern void
@@ -4459,7 +4479,7 @@
 {
     int sign,bitsz,l,align;
     int bitsize,bitpos;
-    int mask = 0;
+    long mask = 0;
     int size;
     set_bitsz(type,&bitpos,&bitsize,&sign,&bitsz,&align,&l);
     size = bitsz/8;
@@ -4472,43 +4492,30 @@
 	/* shift left */
 	if (bitpos) 
 	    loprtc(LLSHIFT,value,list2(CONST,bitpos));
-	if (bitpos+bitsize>=32) {
-	    /* make and-mask upper */
-	    printf("\tpushl %s\n",register_name(adr,0)); push=1;
-	    printf("\t%s %d(%s),%s\n",cload(sign,size),4,register_name(adr,0),
-			register_name(adr,0));
-	    mask = make_mask(64-bitpos-bitsize,bitpos>=32?63-bitpos:31);
-	    make_mask_and_or(mask,regv_h(value),adr);
-	    printf("\tmovl 0(%%esp),%s\n",register_name(adr,0));
-	    printf("\t%s %s,4(%s)\n",move(0),
-		    l_edx(value), register_name(adr,0));
-	}
-	if (bitpos<32) {
-	    if (!push) { printf("\tpushl %s\n",register_name(adr,0)); push=1;}
-	    /* make and-mask lower */
-	    printf("\t%s %d(%s),%s\n",cload(sign,size),0,register_name(adr,0),
-			register_name(adr,0));
-	    mask = make_mask(bitpos+bitsize>=32?0:32-bitpos-bitsize,31-bitpos);
-	    make_mask_and_or(mask,regv_l(value),adr);
-	    printf("\tpopl %s\n",register_name(adr,0)); push=0;
-	    printf("\t%s %s,(%s)\n",move(0),
-		    l_eax(value), register_name(adr,0));
-	}
-	if (push) printf("\taddl %%sp,$4\n");
+	/* make and-mask */
+	printf("\tpushq %s\n",register_name(adr,0)); 
+	printf("\t%s %d(%s),%s\n",cload(sign,size),4,register_name(adr,0),
+		    register_name(adr,0));
+	mask = make_mask(64-bitpos-bitsize,63-bitpos);
+	make_mask_and_or_l(mask,value,adr);
+	printf("\tmovq 0(%%rsp),%s\n",register_name(adr,0));
+	printf("\t%s %s,(%s)\n",move(0),
+		value, register_name(adr,0));
+	printf("\taddq %%rsp,$8\n");
 #endif
     } else {
 	use_int(adr);
 	use_int(value);
-	printf("\tpushl %s\n",register_name(adr,0));
-	printf("\t%s %d(%s),%s\n",cload(sign,size),0,register_name(adr,0),
-		    register_name(adr,0));
+	printf("\tpushl %s\n",register_name(adr,SIZE_OF_INT));
+	printf("\t%s %d(%s),%s\n",cload(sign,size),0,register_name(adr,SIZE_OF_INT),
+		    register_name(adr,SIZE_OF_INT));
 	/* shift left */
 	if (bitpos) 
 	    oprtc(LSHIFT,value,list2(CONST,bitpos));
 	/* make and-mask */
 	mask = make_mask(32-bitpos-bitsize,31-bitpos);
 	make_mask_and_or(mask,value,adr);
-	printf("\tpopl %s\n",register_name(adr,0));
+	printf("\tpopl %s\n",register_name(adr,SIZE_OF_INT));
         code_assign(adr,size==4?0:size,value);
     }
     if (use) {
@@ -4518,9 +4525,9 @@
 
 
 static void
-make_mask_and_or_const(int mask,int reg,int c)
+make_mask_and_or_const(long mask,int reg,long c)
 {
-    int a;
+    long a;
 // printf("## mask 0x%08x ~0x%08x\n",mask,~mask);
     a = ~mask|c;
     if (a!=-1) {
@@ -4531,7 +4538,7 @@
 	    else
 		printf("\tandw $%d,%s\n",a&0xffff,register_name(reg,2));
 	} else
-	    printf("\tandl $%d,%s\n",a,register_name(reg,0));
+	    printf("\tandq $%d,%s\n",a,register_name(reg,0));
     }
     /* make or-mask  */
     c = mask&c;
@@ -4543,7 +4550,7 @@
 	    else
 		printf("\torw $%d,%s\n",c&0xffff,register_name(reg,2));
 	} else
-	    printf("\torl $%d,%s\n",c,register_name(reg,0));
+	    printf("\torq $%d,%s\n",c,register_name(reg,0));
     }
 }
 
@@ -4552,8 +4559,8 @@
 {
     int sign,bitsz,l,align;
     int bitpos,bitsize,size;
-    int mask = 0;
-    int c,lvalue;
+    long mask = 0;
+    long c,lvalue;
 #if LONGLONG_CODE
     long long lc;
 #endif
@@ -4568,24 +4575,13 @@
 	lc = lcadr(value);
 	lc <<= bitpos;
 	
-	if (bitpos+bitsize>=32) {
-	    printf("\t%s %d(%s),%s\n",cload(sign,size),4,register_name(adr,0),
-			register_name(lvalue,0));
-	    /* make and-mask upper */
-	    mask = make_mask(64-bitpos-bitsize,bitpos>=32?63-bitpos:31);
-	    make_mask_and_or_const(mask,lvalue,(int)(lc>>32));
-	    printf("\t%s %s,4(%s)\n",move(0),register_name(lvalue,0),
-			register_name(adr,0));
-	}
-	if (bitpos<32) {
-	    printf("\t%s %d(%s),%s\n",cload(sign,size),0,register_name(adr,0),
-			register_name(lvalue,0));
-	    /* make and-mask lower */
-	    mask = make_mask(bitpos+bitsize>=32?0:32-bitpos-bitsize,31-bitpos);
-	    make_mask_and_or_const(mask,lvalue,(int)(lc));
-	    printf("\t%s %s,(%s)\n",move(0),
-		    register_name(lvalue,0),register_name(adr,0));
-	}
+	printf("\t%s %d(%s),%s\n",cload(sign,size),4,register_name(adr,0),
+		    register_name(lvalue,0));
+	/* make and-mask upper */
+	mask = make_mask(64-bitpos-bitsize,63-bitpos);
+	make_mask_and_or_const(mask,lvalue,lc);
+	printf("\t%s %s,(%s)\n",move(0),register_name(lvalue,0),
+		    register_name(adr,0));
 	free_register(lvalue);
 #endif
     } else {
@@ -4598,7 +4594,7 @@
 	/* make and-mask */
 	mask = make_mask(32-bitpos-bitsize,31-bitpos);
 	make_mask_and_or_const(mask,lvalue,c);
-        code_assign(adr,size==4?0:size,lvalue);
+        code_assign(adr,size,lvalue);
 	free_register(lvalue);
     }
     if (use)