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;
 }
 
 /*