Mercurial > hg > CbC > old > device
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