diff mc-code-powerpc.c @ 302:bea7ab2fb218 switch-table

switch table jump finished.
author kono
date Mon, 07 Jun 2004 17:55:37 +0900
parents 86255dd7f148
children 9df8aa0497ea
line wrap: on
line diff
--- a/mc-code-powerpc.c	Mon Jun 07 03:33:01 2004 +0900
+++ b/mc-code-powerpc.c	Mon Jun 07 17:55:37 2004 +0900
@@ -4783,39 +4783,53 @@
 code_table_jump_p() { return 1; }
 
 void
-code_table_jump(int l,int csvalue,int delta,int max,int min)
+code_table_jump(int l,int csvalue,int delta,int max,int min,int dlabel)
 {
-    int t,s,c0;
-    char *crn = register_name(csvalue);
+    int t,s,u=-1;
+    char *crn = register_name(csvalue); // can be t,s,u
     char *trn = register_name(t=get_register());
     char *srn = register_name(s=get_register());
+    char *urn;
 
     inc_cmpflag();
     if (min>32767||min<-32765) {
-	code_const(min,t);
-	printf("\tsub\t%s,%s,%s\n",trn,crn,trn);
+	if (t==csvalue) {
+	    code_const(min,s);
+	    printf("\tsub\t%s,%s,%s\n",trn,crn,srn);
+	} else {
+	    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);
+    printf("\tcmplwi   cr%d,%s,%d\n",cmpflag,trn,max-min);
+    printf("\tbgt-\tcr%d,L_%d\n",cmpflag,dlabel);
     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;
+    case 2: 
+	printf("\tli %s,1\n",srn);
+	printf("\tand %s,%s,%s\n",srn,srn,trn);
+	printf("\tcmplwi   cr%d,%s,0\n",cmpflag,srn);
+	printf("\tbne\tcr%d,L_%d\n",cmpflag,dlabel);
+	printf("\tslwi %s,%s,1\n",trn,trn);
+	break;
+    case 4: 
+	printf("\tli %s,3\n",srn);
+	printf("\tand %s,%s,%s\n",srn,srn,trn);
+	printf("\tcmplwi   cr%d,%s,0\n",cmpflag,srn);
+	printf("\tbne\tcr%d,L_%d\n",cmpflag,dlabel);
+	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);
-	}
+	urn = register_name(u=get_register());
+	printf("\tli %s,%d\n",srn,delta);
+	printf("\tdivwu %s,%s,%s\n",urn,trn,srn);
+	printf("\tmullw %s,%s,%s\n",srn,urn,srn);
+	printf("\tsubf %s,%s,%s\n",srn,trn,srn);
+	printf("\tcmplwi   cr%d,%s,0\n",cmpflag,srn);
+	printf("\tbne\tcr%d,L_%d\n",cmpflag,dlabel);
+	printf("\tslwi %s,%s,2\n",trn,urn);
     }
     printf("\taddis %s,r31,ha16(L_%d-L_%d)\n",
 	     srn,l,code_base);
@@ -4829,6 +4843,7 @@
 
     free_register(s);
     free_register(t);
+    if (u!=-1) free_register(u);
 }
 
 void
@@ -4847,7 +4862,6 @@
 void
 code_table_close()
 {
-    printf("1:\n");
 }
 
 #endif