Mercurial > hg > CbC > old > device
changeset 300:86255dd7f148
table done. (?)
author | kono |
---|---|
date | Mon, 07 Jun 2004 02:32:07 +0900 |
parents | 3d260008c449 |
children | 60dba3ef1f69 |
files | mc-code-powerpc.c mc-code.h mc-switch.c |
diffstat | 3 files changed, 126 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/mc-code-powerpc.c Mon Jun 07 00:20:46 2004 +0900 +++ b/mc-code-powerpc.c Mon Jun 07 02:32:07 2004 +0900 @@ -4777,5 +4777,80 @@ /* printf("\t.ident \"Micro-C compiled\"\n"); */ } +#if CASE_CODE + +int +code_table_jump_p() { return 1; } + +void +code_table_jump(int l,int csvalue,int delta,int max,int min) +{ + int t,s,c0; + char *crn = register_name(csvalue); + char *trn = register_name(t=get_register()); + char *srn = register_name(s=get_register()); + + inc_cmpflag(); + if (min>32767||min<-32765) { + code_const(min,t); + printf("\tsub\t%s,%s,%s\n",trn,crn,trn); + } else { + printf("\taddi\t%s,%s,lo16(%d)\n",trn,crn,-min); + } + printf("\tcmpwi cr%d,%s,0\n",c0=cmpflag,trn); + inc_cmpflag(); + printf("\tcmpwi cr%d,%s,%d\n",cmpflag,trn,max-min); + printf("\tblt\tcr%d,1f\n",c0); + printf("\tbgt\tcr%d,1f\n",cmpflag); + switch(delta) { + case 1: printf("\tslwi %s,%s,2\n",trn,trn); break; + case 2: printf("\tslwi %s,%s,1\n",trn,trn); + case 4: break; + default: + srn = register_name(s=get_register()); + if (delta%4==0) { + printf("\tli %s,%d\n",srn,delta/4); + printf("\tdivwu %s,%s,%s\n",trn,trn,srn); + } else { + printf("\tli %s,%d\n",srn,delta); + printf("\tdivwu %s,%s,%s\n",trn,trn,srn); + printf("\tslwi %s,%s,2\n",trn,trn); + } + } + printf("\taddis %s,r31,ha16(L_%d-L_%d)\n", + srn,l,code_base); + printf("\tla %s,lo16(L_%d-L_%d)(%s)\n", + srn,l,code_base,srn); + printf("\tadd %s,%s,%s\n",trn,srn,trn); + printf("\tlwz r0,0(%s)\n",trn); + printf("\tadd r0,r0,%s\n",srn); + printf("\tmtctr r0\n"); + printf("\tbctr\n"); + + free_register(s); + free_register(t); +} + +void +code_table_open(int l) +{ + printf("\t.p2align 2\n"); + fwddef(l); +} + +void +code_table_value(int label,int table_top) +{ + printf("\t.long L_%d-L_%d\n",label,table_top); +} + +void +code_table_close() +{ + printf("1:\n"); +} + +#endif + /* end */
--- a/mc-code.h Mon Jun 07 00:20:46 2004 +0900 +++ b/mc-code.h Mon Jun 07 02:32:07 2004 +0900 @@ -211,4 +211,12 @@ // extern int use_double(int); // extern int use_longlong(int); +#if CASE_CODE +extern int code_table_jump_p(); +extern void code_table_jump(int table,int csvalue,int delta,int max,int min); +extern void code_table_open(int table); +extern void code_table_value(int label,int table); +extern void code_table_close(); +#endif + /* */
--- a/mc-switch.c Mon Jun 07 00:20:46 2004 +0900 +++ b/mc-switch.c Mon Jun 07 02:32:07 2004 +0900 @@ -27,8 +27,8 @@ #define index_min(index) cadddr(index) #define index_label(index) car(index) -#define CASE_TABLE_COUNT 3 -#define CASE_INDEX_COUNT 3 +#define CASE_TABLE_COUNT 10 +#define CASE_INDEX_COUNT 10 /* @@ -141,24 +141,6 @@ } static int -table_jump(int count,int delta,int cslist) -{ - int list; - for(;count-->0;cslist=cadr(cslist)) { - list = car(cslist); - printf("# table cases delta=%d count=%d min=%d max=%d\n", - caddr(cslist),car(cadddr(cslist)), - cadr(cadddr(cslist)),caddr(cadddr(cslist)) - ); - for(;list; list=cadr(list)) { - if (caddr(list)) - cmpdimm(car(list),csvalue1,caddr(list),0); - } - } - return cslist; -} - -static int cascade_compare(int count,int cslist) { int list; @@ -177,6 +159,43 @@ return cslist; } +static int +table_jump(int count,int delta,int chunks) +{ + int list,i; + int l,max,min; + if (!code_table_jump_p()) + return cascade_compare(count,chunks); + + min=cadr(cadddr(chunks)); + // find max + for(i=0,list=chunks;i<count;list=cadr(list),i++) { + max=caddr(cadddr(list)); + } + + printf("# table count %d delta %d max %d min %d\n", + count,delta,max,min); + + l = fwdlabel(); + code_table_jump(l,csvalue1,delta,max,min); + code_table_open(l); + i = min; + for(;count-->0;chunks=cadr(chunks)) { + list = car(chunks); + for(;list; list=cadr(list)) { + if (caddr(list)) { + for(;i<car(list);i+=delta) { + code_table_value(dlabel,l); + } + code_table_value(caddr(list),l); + i+=delta; + } + } + } + code_table_close(); + return chunks; +} + /* generate index jmp @@ -251,19 +270,19 @@ */ static int -switch_leaf(int count,int merge,int cslist) +switch_leaf(int count,int merge,int chunks) { control=1; for(;count-- !=0 && merge;merge=cadr(merge)) { printf("# merge count %d delta %d c_count %d\n", car(merge),caddr(merge),cadddr(merge)); if (cadddr(merge)>CASE_TABLE_COUNT) - cslist = table_jump(car(merge),caddr(merge),cslist); + chunks = table_jump(car(merge),caddr(merge),chunks); else - cslist = cascade_compare(car(merge),cslist); + chunks = cascade_compare(car(merge),chunks); } if (control&&dlabel) jmp(dlabel); - return cslist; + return chunks; } /*