changeset 779:a0f84a0a990a

float value sharing
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Fri, 19 Nov 2010 14:09:56 +0900
parents a177c65f3e37
children c5315f472912
files mc-code-i64.c mc-code-ia32.c mc-code-powerpc.c mc-parse.c mc-parse.h
diffstat 5 files changed, 186 insertions(+), 61 deletions(-) [+]
line wrap: on
line diff
--- a/mc-code-i64.c	Fri Nov 19 04:39:47 2010 +0900
+++ b/mc-code-i64.c	Fri Nov 19 14:09:56 2010 +0900
@@ -3640,19 +3640,50 @@
     return (i[1] == 0x3ff00000)?j[1]:j[0];
 }
 
+static void emit_dconst0(ValuePtr value, int lb, void *arg)
+{
+    long d_mode = (long) arg;
+#ifdef __APPLE__
+    printf(" \t.literal8\n\t.align 3\n");
+#else
+    printf(" \t.section\t.rodata\n\t.align 8\n");
+#endif
+    printf("_%d:\n",lb);
+#if ENDIAN_D==0
+    if (d_mode)
+	printf("\t.long\t0x%x,0x%x\n",code_d1(value->d),code_d2(value->d));
+    else {
+	printf("\t.long\t0x%x\n",value->i);
+    }
+#endif
+    if (output_mode==TEXT_EMIT_MODE) {
+	printf(".text\n");
+    } else {
+	text_mode(0);
+    }
+} 
+
 /* load double / float const
    we should keep what constant we have create
  */
 void code_dconst(int e2,int freg,int d)
 { 
-    int lb;
-    double value = dcadr(e2);
+    int sz;
+    Value value;
+    value.d = dcadr(e2);
+    if (d) {
+       sz = sizeof(double);
+    } else {
+       value.f = (float) value.d;
+       sz = sizeof(float);
+    }
+
     use_float(d,freg);
-    if (value==1.0) {
+    if (value.d==1.0) {
         code_dload_1(d,freg);
         return;
     }
-    if (value==0.0) {
+    if (value.d==0.0) {
         char *f = fregister_name(freg);
         if (d) {
             printf("\txorpd %s,%s\n",f,f);
@@ -3661,27 +3692,8 @@
         }
         return ;
     }
-
-#ifdef __APPLE__
-    printf(" \t.literal8\n\t.align 3\n");
-#else
-    printf(" \t.section\t.rodata\n\t.align 8\n");
-#endif
-    lb=fwdlabel();
-    printf("_%d:\n",lb);
-#if ENDIAN_D==0
-    if (d)
-	printf("\t.long\t0x%x,0x%x\n",code_d1(value),code_d2(value));
-    else {
-	float f = (float) value;
-	printf("\t.long\t0x%x\n",*(unsigned *)(&f));
-    }
-#endif
-    if (output_mode==TEXT_EMIT_MODE) {
-	printf(".text\n");
-    } else {
-	text_mode(0);
-    }
+    long d_mode = d;
+    int lb = get_data_label(&value,sz,emit_dconst0, (void*) d_mode);
 #ifdef __APPLE__
     printf("\tmovs%s _%d(%%rip),%s\n",d?"d":"s",lb,fregister_name(freg));
 #else
--- a/mc-code-ia32.c	Fri Nov 19 04:39:47 2010 +0900
+++ b/mc-code-ia32.c	Fri Nov 19 14:09:56 2010 +0900
@@ -3130,32 +3130,53 @@
     return (i[1] == 0x3ff00000)?j[1]:j[0];
 }
 
-void code_dconst(int e2,int freg,int d)
-{ 
-    int lb;
-    double value = dcadr(e2);
-
-    if (value==0.0) {
-	printf("\tfldz\n"); return;
-    }
-    if (value==1.0) {
-	printf("\tfld1\n"); return;
-    }
+static void emit_dconst0(ValuePtr value, int lb, void *arg)
+{
+    long d_mode = (long) arg;
 #ifdef __APPLE__
     printf(" \t.literal8\n\t.align 3\n");
 #else
     printf(" \t.section\t.rodata\n\t.align 8\n");
 #endif
-    lb=fwdlabel();
     printf("_%d:\n",lb);
 #if ENDIAN_D==0
-    printf("\t.long\t0x%x,0x%x\n",code_d1(value),code_d2(value));
+    if (d_mode)
+        printf("\t.long\t0x%x,0x%x\n",code_d1(value->d),code_d2(value->d));
+    else {
+        printf("\t.long\t0x%x\n",value->i);
+    }
 #endif
     if (output_mode==TEXT_EMIT_MODE) {
-	printf(".text\n");
+        printf(".text\n");
     } else {
-	text_mode(0);
+        text_mode(0);
     }
+}
+
+/* load double / float const
+   we should keep what constant we have create
+ */
+void code_dconst(int e2,int freg,int d)
+{
+    int sz;
+    Value value;
+    value.d = dcadr(e2);
+    use_float(d,freg);
+    if (value.d==0.0) {
+	printf("\tfldz\n"); return;
+    }
+    if (value.d==1.0) {
+	printf("\tfld1\n"); return;
+    }
+    if (d) {
+       sz = sizeof(double);
+    } else {
+       value.f = (float) value.d;
+       sz = sizeof(float);
+    }
+
+    long d_mode = d;
+    int lb = get_data_label(&value,sz,emit_dconst0, (void*) d_mode);
 #ifdef __APPLE__
     printf("\tfldl _%d-_%d(%%ebx)\n",lb,goffset_label);
 #else
@@ -3163,6 +3184,7 @@
 #endif
 }
 
+
 void
 code_builtin_fabsf(int e)
 {
--- a/mc-code-powerpc.c	Fri Nov 19 04:39:47 2010 +0900
+++ b/mc-code-powerpc.c	Fri Nov 19 14:09:56 2010 +0900
@@ -4242,49 +4242,68 @@
     return *j;
 }
 
+static void emit_dconst0(ValuePtr value, int lb, void *arg)
+{
+    long d = (long) arg;
+    printf(" \t.data\n\t.align 3\n");
+    lb=fwdlabel();
+    printf("%s%d:\n",lpfx,lb);
+    if (d) {
+#if ENDIAN_D==0
+	printf("\t.long\t0x%x,0x%x\n",code_d1(value->d),code_d2(value->d));
+#else
+	printf("\t.long\t0x%x,0x%x\n",code_d2(value->d),code_d1(value->d));
+#endif
+    } else {
+	printf("\t.long\t0x%x\n",code_f(value->i));
+    }
+    if (output_mode==TEXT_EMIT_MODE) {
+	printf(".text\n");
+    } else {
+	text_mode(0);
+    }
+}
+
+/* load double / float const
+   we should keep what constant we have create
+ */
+
 void
 code_dconst(int e2,int freg,int d)
 { 
     int lb;
-    double value = dcadr(e2);
+    Value value;
+    value.d = dcadr(e2);
     int r;
     char *rrn,*frn;
-
     use_float(d,freg);
     frn = fregister_name(freg);
-    if (value==0.0) {
+    if (value.d==0.0) {
 	float_zero_lib_used=1;
 	r = get_ptr_cache(&float_zero);
 	rrn = register_name(r);
 	printf("\tlfs %s,0(%s)\n",frn,rrn);
 	return;
     }
-    if (value==1.0) {
+    if (value.d==1.0) {
 	float_one_lib_used=1;
 	r = get_ptr_cache(&float_one);
 	rrn = register_name(r);
 	printf("\tlfs %s,0(%s)\n",frn,rrn);
 	return;
     }
+    if (d) {
+       sz = sizeof(double);
+    } else {
+       sz = sizeof(float);
+       value.f = (float) value.d;
+    }
+
+    long d_mode = d;
+    int lb = get_data_label(&value,sz,emit_dconst0, (void*) d_mode);
+
     rrn = register_name((r=get_register()));
     use_reg(r); // to clear ptr cache
-    printf(" \t.data\n\t.align 3\n");
-    lb=fwdlabel();
-    printf("%s%d:\n",lpfx,lb);
-    if (d) {
-#if ENDIAN_D==0
-	printf("\t.long\t0x%x,0x%x\n",code_d1(value),code_d2(value));
-#else
-	printf("\t.long\t0x%x,0x%x\n",code_d2(value),code_d1(value));
-#endif
-    } else {
-	printf("\t.long\t0x%x\n",code_f(value));
-    }
-    if (output_mode==TEXT_EMIT_MODE) {
-	printf(".text\n");
-    } else {
-	text_mode(0);
-    }
     code_label_value(lb,r);
     if (d) {
 	printf("\tlfd %s,0(%s)\n",frn,rrn);
--- a/mc-parse.c	Fri Nov 19 04:39:47 2010 +0900
+++ b/mc-parse.c	Fri Nov 19 14:09:56 2010 +0900
@@ -4662,6 +4662,16 @@
     return len!=-1;
 }
 
+
+/**
+    hash table search
+       *char name   
+       cheap        heap
+       len          length
+       hash         hash value
+       mode         NONDEF search only, DEF define
+    return NMTBL in hash entry
+ */
 static NMTBL *
 hash_search(char *name,struct cheap *scheap,int len,unsigned int hash,int mode)
 {
@@ -4675,6 +4685,7 @@
 	    iptr=&htable[0];
 	if (eptr==iptr) error(GSERR);
     }
+    // we cannot extend hash now
     if (HEAP_REPORT && i>3) {
 	for(j=0,eptr=htable;eptr<htable+GSYMS;eptr++) {
 	    if (*eptr) j++;
@@ -4683,19 +4694,70 @@
 		i, hash%GSYMS,GSYMS,j*100/GSYMS,name);
     }
     if (!hptr) {
+	// not found
 	if (mode==NONDEF) return 0;
 	hptr = get_nptr();
 	hptr->nm = name; /* name should be in the safe place (cheap) */
 	*iptr = hptr;
     }
     if (hptr->sc == 0) {
+	// newly created entry
 	hptr->sc=EMPTY;
     } else {
+	// already defined
 	cheap = reset_cheap(scheap);
     }
     return hptr;
 }
 
+/**
+    register general data in hash
+      for long long or double
+    data is copied into cheap when it is created
+	typedef union {
+	       double d;
+	       float f;
+	       int i;
+	       long l;
+	       long long ll;
+	} Value, *ValuePtr;
+
+ */
+extern NMTBL *
+get_data(ValuePtr name,int len,int mode)
+{
+    /* no name copy */
+    unsigned int c;
+    unsigned int hash0 = 0;
+    int i = len;
+    char *n = (char*)name;
+    struct cheap scheap;
+    save_cheap(&scheap,cheap);
+    char *top = cheap->ptr;
+
+    while(len-->0) {
+	c = *n++;
+	hash_value(hash0,*cheap->ptr = c);
+	cheap = increment_cheap(cheap,&top);
+    }
+    return name_space_search(hash_search(top,&scheap,i,hash0,DEF),STRING);
+}
+
+extern int
+get_data_label(ValuePtr name,int len, void emit(ValuePtr, int, void * ), void *arg)
+{
+    int lb;
+    NMTBL * n = get_data(name,len,DEF);
+    if ((lb=attr_value(n,LABEL))) return lb;
+    lb=fwdlabel();
+    set_attr(n,LABEL,lb);
+    emit(name, lb, arg);
+    return lb;
+}
+
+/**
+   get name from already stored in cheap
+ */
 extern NMTBL *
 get_name(char *name,int *len,int mode)
 {
@@ -4715,6 +4777,9 @@
     return hash_search(name,&scheap,i,hash0,mode);
 }
 
+/**
+   get name from input
+ */
 extern NMTBL *
 get_name_from_chptr()
 {
--- a/mc-parse.h	Fri Nov 19 04:39:47 2010 +0900
+++ b/mc-parse.h	Fri Nov 19 14:09:56 2010 +0900
@@ -171,10 +171,17 @@
 
 /* used in mc-macro.c */
 
+typedef union {
+       double d; float f; int i; long l; long long ll; char c;
+} Value, *ValuePtr;
+
 extern struct cheap *cheap;
 extern struct cheap *st_cheap, *cheap1;  // for ST_COMMENT
 
 extern NMTBL *get_name(char *name,int *i,int mode);
+extern NMTBL * get_data(ValuePtr name,int len, int mode);
+extern int get_data_label(ValuePtr name,int len, void emit(ValuePtr, int , void *), void *arg);
+
 #define DEF 1
 #define NONDEF 2