changeset 320:183726ccd83d

asm minor fix. ia32 table jmp fix.
author kono
date Sat, 19 Jun 2004 00:13:36 +0900
parents 88cf6512fa1b
children 80beb03e5b73
files mc-code-ia32.c mc-code-mips.c mc-code-powerpc.c mc-code.h mc-codegen.c mc-codegen.h test/asm-powerpc.c
diffstat 7 files changed, 882 insertions(+), 150 deletions(-) [+]
line wrap: on
line diff
--- a/mc-code-ia32.c	Fri Jun 18 19:18:44 2004 +0900
+++ b/mc-code-ia32.c	Sat Jun 19 00:13:36 2004 +0900
@@ -940,35 +940,33 @@
     printf("%c\n",34);
 }
 
+static int
+emit_string_label()
+{
+    int lb;
+    printf(".section\t.rodata\n");
+    lb=fwdlabel();
+    printf("_%d:\n",lb);
+    output_mode = RODATA_EMIT_MODE;
+    return lb;
+}
+
 void
 code_string(int e1,int creg)
 {
     char *s;
-    int i,lb;
+    int lb;
 
     use_int(creg);
-    if (0) {
-	s=(char *)cadr(e1);
-	lb=fwdlabel();
-	printf("\tjmp _%d\n",lb);
-	i=backdef();
-	ascii(s);
-	printf("\t.align 2\n");
-	fwddef(lb);
-	printf("\tlea _%d,%s\n",i,register_name(creg,0));
+    s=(char *)cadr(e1);
+    lb = emit_string_label();
+    ascii(s);
+    if (output_mode==TEXT_EMIT_MODE) {
+	printf(".text\n");
     } else {
-	s=(char *)cadr(e1);
-	printf(".section\t.rodata\n");
-	lb=fwdlabel();
-	printf("_%d:\n",lb);
-	ascii(s);
-	if (output_mode==TEXT_EMIT_MODE) {
-	    printf(".text\n");
-	} else {
-	    text_mode();
-	}
-	printf("\tlea _%d,%s\n",lb,register_name(creg,0));
+	text_mode();
     }
+    printf("\tlea _%d,%s\n",lb,register_name(creg,0));
 }
 
 #define MAX_COPY_LEN 20
@@ -1971,14 +1969,13 @@
 	} else if(car(e)==FNAME) {
 	    printf("\t.long %s\n",((NMTBL *)cadr(e))->nm);
 	} else if(car(e)==STRING) {       
-	    if (car(n->ty)!=ARRAY || cadr(n->ty)!=CHAR) {
-		l = fwdlabel();
-		printf("\t.long _%d\n",l);
-		printf(".section\t.rodata\n");
-		printf("_%d:\n",l);
-		output_mode = RODATA_EMIT_MODE;
-	    }
-	    ascii((char *)cadr(e));
+            if (car(n->ty)!=ARRAY || cadr(n->ty)!=CHAR) {
+                l = emit_string_label();
+                ascii((char *)cadr(e));
+                data_mode(0);
+                printf("\t.long _%d\n",l);
+            } else
+                ascii((char *)cadr(e));
 	} else error(TYERR);
     } else error(TYERR);
 }
@@ -3018,12 +3015,12 @@
     switch(delta) {
     case 2:
 	printf("\tmovl\t$1,%%edx\n");
-	printf("\tandl\t%%edx,%%eax\n");
+	printf("\tandl\t%%eax,%%edx\n");
 	printf("\tjne\t_%d\n",dlabel);
 	printf("\tjmp\t*_%d(,%%eax,2)\n",l); break;
     case 4:
 	printf("\tmovl\t$3,%%edx\n");
-	printf("\tandl\t%%edx,%%eax\n");
+	printf("\tandl\t%%eax,%%edx\n");
 	printf("\tjne\t_%d\n",dlabel);
 	printf("\tjmp\t*_%d(%%eax)\n",l); break;
     default:
@@ -3059,5 +3056,148 @@
 #endif
 
 
+#if ASM_CODE
+
+/*
+    print an operand  
+ */
+
+static void
+emit_asm_operand(int rstr)
+{
+    if (car(rstr)==REGISTER) {
+	printf("%s",register_name(cadr(rstr),0));
+    } else if (car(rstr)==CONST) {
+	printf("%d",cadr(rstr));
+    } else if (car(rstr)==FNAME) {
+	printf("%s",(char*)cadr(rstr));
+    } else if (car(rstr)==STRING) {
+	printf("_%d",cadr(rstr));
+    } else {
+	error(-1);
+    }
+}
+
+/*
+     prepare asm operands
+
+     char *constraints sgtring
+     int  oeprand expre
+     int  mode          (ASM_INPUT,ASM_OUTPUT)
+     int  replacement list
+     int  output operands count
+     int  output operands replacement list
+
+     retrun replacement list
+        list3( operands, next, clobber )
+                               0    can be shared in input/output
+                               1    can't be used in input
+ */
+
+int
+asm_operand(char *p,int e1,int mode,int repl,int n,int repl0)
+{
+    int r;
+    int c;
+    int val;
+    int clobber = 0;
+
+    printf("# constraint %s\n",p);
+    if (*p=='=') {
+	// output register
+	p++;
+    }
+    if (*p=='&') {
+	// earlyclobber
+	p++;
+	clobber = 1;
+    }
+    c = *p;
+    if (c=='r') {
+	if (mode==ASM_INPUT) {
+	    for(;repl0;repl0 = cadr(repl0)) {
+		if (car(car(repl0))==REGISTER && caddr(repl0)==0) {
+		    r = cadr(car(repl0));
+		    caddr(repl0) = ASM_USED;
+		    break;
+		}
+            }  
+	    r = get_register();
+	} else {
+	    r = get_register();
+	}
+	repl = list3(list2(REGISTER,r),repl,clobber);
+    } else if (c=='m') {
+	repl = list3(list2(0,0),repl,clobber);
+    } else if (c=='i') {
+	if (car(e1)==GVAR||car(e1)==FNAME) {
+	    e1=list3(FNAME,(int)(((NMTBL *)cadr(e1))->nm),0);
+	} else if (car(e1)==STRING) {
+	    val = emit_string_label();
+	    ascii((char*)cadr(e1));
+	    e1=list3(STRING,val,0);
+	} else if (car(e1)==CONST) {
+	} else error(-1);
+	repl = list3(e1,repl,clobber);
+    } else if (digit(c)) {
+	val = 0;
+	do { val = val*10 + c-'0'; } while (digit(c=*p++));
+	if (val>MAX_ASM_REG) error(-1); // too large register
+	if (n-val<0) error(-1);
+	repl = list3(car(nth(n-val-1,repl0)),repl,clobber);
+    } else error(-1);
+    return repl;
+}
+
+void
+free_asm_operand(int repl)
+{
+    for(;repl;repl=cadr(repl)) {
+	if (car(car(repl))==REGISTER)
+	    free_register(cadr(car(repl)));
+    }
+}
+
+
+extern void
+replace_asm_string(char *asm_str,int repl)
+{
+    int c,i,rstr,val;
+    char *p;
+    int reg[MAX_ASM_REG];
+
+    text_mode();
+    c = *asm_str;
+    if (c!='\t'&&c!=' ') printf("\t");
+    for(i=0;repl && i<MAX_ASM_REG;i++) {
+	reg[i] = car(repl);
+	repl = cadr(repl);
+    }
+    p = asm_str;
+    while((c = *p++)) {
+	if (c=='%') {
+	    c = *p++;
+	    if (!c) { break;
+	    } else if (c=='%') {
+		printf("%%"); continue;
+	    } else if (!digit(c)) {
+		printf("%%%c",c); continue;
+	    }
+	    val = 0;
+	    do { val = val*10 + c-'0'; } while (digit(c=*p++)) ;
+	    p--;
+	    if (val>MAX_ASM_REG) error(-1); // too large register
+	    rstr = reg[val];
+	    emit_asm_operand(rstr);
+	} else {
+	    printf("%c",c);
+	}
+    }
+    printf("\n");
+}
+
+#endif
+
+
 /* end */
 
--- a/mc-code-mips.c	Fri Jun 18 19:18:44 2004 +0900
+++ b/mc-code-mips.c	Sat Jun 19 00:13:36 2004 +0900
@@ -1473,6 +1473,18 @@
     printf("\\0%c\n\t.align 2\n",34);
 }
 
+static int
+emit_string_label() {
+    int lb;
+
+    lb=fwdlabel();
+    // should put on diffirent segement
+    printf("\t.rdata\n\t.align 2\n");
+    printf("$L_%d:\n",lb);
+    output_mode = RODATA_EMIT_MODE;
+    return lb;
+}
+
 void
 code_string(int e1,int creg)
 {
@@ -1483,15 +1495,9 @@
     crn = register_name(creg);
 
     s=(char *)cadr(e1);
-    printf("\t.rdata\n\t.align 2\n");
-    lb=fwdlabel();
-    printf("$L_%d:\n",lb);
+    lb = emit_string_label();
     ascii(s);
-    if (output_mode==TEXT_EMIT_MODE) {
-	printf(".text\n");
-    } else {
-	text_mode(2);
-    }
+    text_mode(2);
     printf("\tla %s,$L_%d\n",crn,lb);
 }
 
@@ -3307,14 +3313,12 @@
 	    printf("\t.long %s\n",((NMTBL *)cadr(e))->nm);
 	} else if(car(e)==STRING) {       
 	    if (car(n->ty)!=ARRAY || cadr(n->ty)!=CHAR) {
-		l = fwdlabel();
+		l = emit_string_label();
+		ascii((char *)cadr(e));
+		data_mode(0);
 		printf("\t.long $L_%d\n",l);
-		// should put on diffirent segement
-		printf("\t.rdata\n\t.align 2\n");
-		printf("$L_%d:\n",l);
-		output_mode = RODATA_EMIT_MODE;
-	    }
-	    ascii((char *)cadr(e));
+	    } else
+		ascii((char *)cadr(e));
 	} else error(TYERR);
     } else error(TYERR);
 }
@@ -5254,5 +5258,148 @@
 
 #endif
 
+
+#if ASM_CODE
+
+/*
+    print an operand  
+ */
+
+static void
+emit_asm_operand(int rstr)
+{
+    if (car(rstr)==REGISTER) {
+	printf("%s",register_name(cadr(rstr)));
+    } else if (car(rstr)==CONST) {
+	printf("%d",cadr(rstr));
+    } else if (car(rstr)==FNAME) {
+	printf("%s",(char*)cadr(rstr));
+    } else if (car(rstr)==STRING) {
+	printf("$L_%d",cadr(rstr));
+    } else {
+	error(-1);
+    }
+}
+
+/*
+     prepare asm operands
+
+     char *constraints sgtring
+     int  oeprand expre
+     int  mode          (ASM_INPUT,ASM_OUTPUT)
+     int  replacement list
+     int  output operands count
+     int  output operands replacement list
+
+     retrun replacement list
+        list3( operands, next, clobber )
+                               0    can be shared in input/output
+                               1    can't be used in input
+ */
+
+int
+asm_operand(char *p,int e1,int mode,int repl,int n,int repl0)
+{
+    int r;
+    int c;
+    int val;
+    int clobber = 0;
+
+    printf("# constraint %s\n",p);
+    if (*p=='=') {
+	// output register
+	p++;
+    }
+    if (*p=='&') {
+	// earlyclobber
+	p++;
+	clobber = 1;
+    }
+    c = *p;
+    if (c=='r') {
+	if (mode==ASM_INPUT) {
+	    for(;repl0;repl0 = cadr(repl0)) {
+		if (car(car(repl0))==REGISTER && caddr(repl0)==0) {
+		    r = cadr(car(repl0));
+		    caddr(repl0) = ASM_USED;
+		    break;
+		}
+            }  
+	    r = get_register();
+	} else {
+	    r = get_register();
+	}
+	repl = list3(list2(REGISTER,r),repl,clobber);
+    } else if (c=='m') {
+	repl = list3(list2(0,0),repl,clobber);
+    } else if (c=='i') {
+	if (car(e1)==GVAR||car(e1)==FNAME) {
+	    e1=list3(FNAME,(int)(((NMTBL *)cadr(e1))->nm),0);
+	} else if (car(e1)==STRING) {
+	    val = emit_string_label();
+	    ascii((char*)cadr(e1));
+	    e1=list3(STRING,val,0);
+	} else if (car(e1)==CONST) {
+	} else error(-1);
+	repl = list3(e1,repl,clobber);
+    } else if (digit(c)) {
+	val = 0;
+	do { val = val*10 + c-'0'; } while (digit(c=*p++));
+	if (val>MAX_ASM_REG) error(-1); // too large register
+	if (n-val<0) error(-1);
+	repl = list3(car(nth(n-val-1,repl0)),repl,clobber);
+    } else error(-1);
+    return repl;
+}
+
+void
+free_asm_operand(int repl)
+{
+    for(;repl;repl=cadr(repl)) {
+	if (car(car(repl))==REGISTER)
+	    free_register(cadr(car(repl)));
+    }
+}
+
+
+extern void
+replace_asm_string(char *asm_str,int repl)
+{
+    int c,i,rstr,val;
+    char *p;
+    int reg[MAX_ASM_REG];
+
+    text_mode(2);
+    c = *asm_str;
+    if (c!='\t'&&c!=' ') printf("\t");
+    for(i=0;repl && i<MAX_ASM_REG;i++) {
+	reg[i] = car(repl);
+	repl = cadr(repl);
+    }
+    p = asm_str;
+    while((c = *p++)) {
+	if (c=='%') {
+	    c = *p++;
+	    if (!c) { break;
+	    } else if (c=='%') {
+		printf("%%"); continue;
+	    } else if (!digit(c)) {
+		printf("%%%c",c); continue;
+	    }
+	    val = 0;
+	    do { val = val*10 + c-'0'; } while (digit(c=*p++)) ;
+	    p--;
+	    if (val>MAX_ASM_REG) error(-1); // too large register
+	    rstr = reg[val];
+	    emit_asm_operand(rstr);
+	} else {
+	    printf("%c",c);
+	}
+    }
+    printf("\n");
+}
+
+#endif
+
 /* end */
 
--- a/mc-code-powerpc.c	Fri Jun 18 19:18:44 2004 +0900
+++ b/mc-code-powerpc.c	Sat Jun 19 00:13:36 2004 +0900
@@ -2999,10 +2999,13 @@
 	} else if(car(e)==GVAR) {
 	    printf("\t.long _%s\n",((NMTBL *)cadr(e))->nm);
 	} else if(car(e)==STRING) {       
-	    if (car(n->ty)!=ARRAY || cadr(n->ty)!=CHAR) {
-		l = emit_string_label();
-	    }
-	    ascii((char *)cadr(e));
+            if (car(n->ty)!=ARRAY || cadr(n->ty)!=CHAR) {
+                l = emit_string_label();
+                ascii((char *)cadr(e));
+                data_mode(0);
+                printf("\t.long L_%d\n",l);
+            } else
+                ascii((char *)cadr(e));
 	} else error(TYERR);
     } else error(TYERR);
 }
@@ -4938,31 +4941,11 @@
 #if ASM_CODE
 
 /*
-        __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (a
-ddr));
-   asm string : output constraint parameter : input constraint parameter : opt
-
-     1: asm string     %1,%2 will be replaced by register or value
-     2: constraint     gcc constraint sting
-        prefix
-           =    overwrite by this asm for output
-           &    overwrite by this asm and can't be used as input register
-           ignored in this compiler
-        constraints
-           m    value expression is modified (no coresponding register)
-                        information for compiler
-           r    register for input or output 
-			input register, output register can be shared
-           0-9  same operands as outout register in input constraints
-      3: opt     "cc", "memory"
-           ignored in this compiler
+    print an operand  
  */
 
-
-#define MAX_ASM_REG 30
-
 static void
-print_asm_reg(int rstr)
+emit_asm_operand(int rstr)
 {
     if (car(rstr)==REGISTER) {
 	printf("%s",register_name(cadr(rstr)));
@@ -4977,48 +4960,23 @@
     }
 }
 
-static void
-replace_asm_string(char *asm_str,int repl)
-{
-    int c,i,rstr,val;
-    char *p;
-    int reg[MAX_ASM_REG];
-
-    text_mode();
-    c = *asm_str;
-    if (c!='\t'&&c!=' ') printf("\t");
-    for(i=0;repl && i<MAX_ASM_REG;i++) {
-	reg[i] = car(repl);
-	repl = cadr(repl);
-    }
-    p = asm_str;
-    while((c = *p++)) {
-	if (c=='%') {
-	    c = *p++;
-	    if (!c) { break;
-	    } else if (c=='%') {
-		printf("%%"); continue;
-	    } else if (!digit(c)) {
-		printf("%%%c",c); continue;
-	    }
-	    val = 0;
-	    do { val = val*10 + c-'0'; } while (digit(c=*p++)) ;
-	    p--;
-	    if (val>MAX_ASM_REG) error(-1); // too large register
-	    rstr = reg[val];
-	    print_asm_reg(rstr);
-	} else {
-	    printf("%c",c);
-	}
-    }
-    printf("\n");
-}
-
-#define ASM_INPUT  1
-#define ASM_OUTPUT 2
-#define ASM_USED   3
-
-static int
+/*
+     prepare asm operands
+
+     char *constraints sgtring
+     int  oeprand expre
+     int  mode          (ASM_INPUT,ASM_OUTPUT)
+     int  replacement list
+     int  output operands count
+     int  output operands replacement list
+
+     retrun replacement list
+        list3( operands, next, clobber )
+                               0    can be shared in input/output
+                               1    can't be used in input
+ */
+
+int
 asm_operand(char *p,int e1,int mode,int repl,int n,int repl0)
 {
     int r;
@@ -5073,7 +5031,7 @@
     return repl;
 }
 
-static void
+void
 free_asm_operand(int repl)
 {
     for(;repl;repl=cadr(repl)) {
@@ -5082,44 +5040,42 @@
     }
 }
 
-void
-code_asm(int asm0,int in,int out,int opt,int e)
+
+extern void
+replace_asm_string(char *asm_str,int repl)
 {
-    int i,e1,n;
-    int repl = 0;
-    int repl0;
-    int assign = 0;
+    int c,i,rstr,val;
     char *p;
-
-    printf("# asm\n");
-    in = reverse0(in);
-    out = reverse0(out);
-    e = reverse0(e);
-    for(i=out;i;i=cadr(i)) {
-	p = (char*)cadr(car(i));
-	e1 = car(e); e = cadr(e);
-	repl = asm_operand(p,e1,ASM_OUTPUT,repl,0,0);
-	if (car(car(repl))==REGISTER) {
-	    assign = list2(assign_expr0(e1,car(repl),INT,INT),assign);
+    int reg[MAX_ASM_REG];
+
+    text_mode();
+    c = *asm_str;
+    if (c!='\t'&&c!=' ') printf("\t");
+    for(i=0;repl && i<MAX_ASM_REG;i++) {
+	reg[i] = car(repl);
+	repl = cadr(repl);
+    }
+    p = asm_str;
+    while((c = *p++)) {
+	if (c=='%') {
+	    c = *p++;
+	    if (!c) { break;
+	    } else if (c=='%') {
+		printf("%%"); continue;
+	    } else if (!digit(c)) {
+		printf("%%%c",c); continue;
+	    }
+	    val = 0;
+	    do { val = val*10 + c-'0'; } while (digit(c=*p++)) ;
+	    p--;
+	    if (val>MAX_ASM_REG) error(-1); // too large register
+	    rstr = reg[val];
+	    emit_asm_operand(rstr);
+	} else {
+	    printf("%c",c);
 	}
     }
-    repl0 = repl;
-    n = length(repl0);
-    for(i=in;i;i=cadr(i)) {
-	p = (char*)cadr(car(i));
-	e1 = car(e); e = cadr(e);
-	repl = asm_operand(p,e1,ASM_INPUT,repl,n,repl0);
-	if (car(car(repl))==REGISTER) {
-	    g_expr_u(assign_expr0(car(repl),e1,INT,INT));
-	}
-    }
-    repl = reverse0(repl);
-    replace_asm_string((char*)cadr(asm0),repl);
-    for(i=assign;i;i=cadr(i)) {
-	g_expr_u(car(i));
-    }
-    free_asm_operand(repl);
-    // no check for opt 
+    printf("\n");
 }
 
 #endif
--- a/mc-code.h	Fri Jun 18 19:18:44 2004 +0900
+++ b/mc-code.h	Sat Jun 19 00:13:36 2004 +0900
@@ -225,7 +225,11 @@
 #endif
 
 #if ASM_CODE
-extern void code_asm(int asm0,int in,int out,int opt,int e);
+
+extern void replace_asm_string(char *asm_str,int repl);
+extern int asm_operand(char *p,int e1,int mode,int repl,int n,int repl0);
+extern void free_asm_operand(int repl);
+
 #endif
 
 /* */
--- a/mc-codegen.c	Fri Jun 18 19:18:44 2004 +0900
+++ b/mc-codegen.c	Sat Jun 19 00:13:36 2004 +0900
@@ -19,6 +19,7 @@
 static int g_expr0(int e1);
 static int register_to_lvar(int e);
 static void bexpr_u(int e1, char cond, int l1);
+static void code_asm(int asm0,int in,int out,int opt,int e);
 
 #if FLOAT_CODE
 
@@ -1798,4 +1799,72 @@
     return 0;
 }
 
+#if ASM_CODE
+
+
+/*
+        __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (a
+ddr));
+   asm string : output constraint parameter : input constraint parameter : opt
+
+     1: asm string     %1,%2 will be replaced by register or value
+     2: constraint     gcc constraint sting
+        prefix
+           =    overwrite by this asm for output
+           &    overwrite by this asm and can't be used as input register
+           ignored in this compiler
+        constraints
+           m    value expression is modified (no coresponding register)
+                        information for compiler
+           r    register for input or output 
+			input register, output register can be shared
+           0-9  same operands as outout register in input constraints
+      3: opt     "cc", "memory"
+           ignored in this compiler
+ */
+
+static void
+code_asm(int asm0,int in,int out,int opt,int e)
+{
+    int i,e1,n;
+    int repl = 0;
+    int repl0;
+    int assign = 0;
+    char *p;
+
+    printf("# asm\n");
+    in = reverse0(in);
+    out = reverse0(out);
+    e = reverse0(e);
+    for(i=out;i;i=cadr(i)) {
+	p = (char*)cadr(car(i));
+	e1 = car(e); e = cadr(e);
+	repl = asm_operand(p,e1,ASM_OUTPUT,repl,0,0);
+	if (car(car(repl))==REGISTER) {
+	    assign = list2(assign_expr0(e1,car(repl),INT,INT),assign);
+	}
+    }
+    repl0 = repl;
+    n = length(repl0);
+    for(i=in;i;i=cadr(i)) {
+	p = (char*)cadr(car(i));
+	e1 = car(e); e = cadr(e);
+	repl = asm_operand(p,e1,ASM_INPUT,repl,n,repl0);
+	if (car(car(repl))==REGISTER) {
+	    g_expr_u(assign_expr0(car(repl),e1,INT,INT));
+	}
+    }
+    repl = reverse0(repl);
+    replace_asm_string((char*)cadr(asm0),repl);
+    for(i=assign;i;i=cadr(i)) {
+	g_expr_u(car(i));
+    }
+    free_asm_operand(repl);
+    // no check for opt 
+}
+
+
+
+#endif
+
 /* end */
--- a/mc-codegen.h	Fri Jun 18 19:18:44 2004 +0900
+++ b/mc-codegen.h	Sat Jun 19 00:13:36 2004 +0900
@@ -3,6 +3,10 @@
 extern int use;         /* generated value will be used in gexpr */
 
 #define USE_CREG (-1)
+#define ASM_INPUT	1
+#define ASM_OUTPUT	2
+#define ASM_USED	3
+#define MAX_ASM_REG	30
 
 /* function provided by mc-code-*.c */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/asm-powerpc.c	Sat Jun 19 00:13:36 2004 +0900
@@ -0,0 +1,412 @@
+#define const
+
+typedef unsigned short __u16;
+typedef unsigned int __u32;
+
+struct task_struct {
+        volatile long state;
+        int usage;
+        unsigned long flags;
+        unsigned long ptrace;
+} c0;
+
+// register struct task_struct *current asm ("r2");
+typedef struct { volatile int counter; } atomic_t;
+
+struct thread_info {
+        struct task_struct *task;
+/*
+        struct exec_domain *exec_domain;
+        unsigned long flags;
+        unsigned long local_flags;
+        int cpu;
+        int preempt_count;
+        struct restart_block restart_block;
+ */
+};
+
+struct page {
+        int flags;
+        atomic_t count;
+};
+
+struct dentry {
+        atomic_t *d_count;
+        unsigned long d_vfs_flags;
+        int d_lock;
+};
+
+int t;
+__u16 result;
+__u32 result32;
+unsigned long old;
+unsigned long mask;
+unsigned long *p ;
+const unsigned long *b;
+unsigned long msr;
+unsigned val;
+unsigned short *addr;
+__u16 value;
+ atomic_t *v;
+int a;
+int lz;
+int owner;
+unsigned long x;
+struct thread_info *ti;
+unsigned long prev;
+int old1; int new;
+unsigned long ret;
+unsigned long size;
+struct dentry *dentry;
+unsigned long flags;
+unsigned long tmp;
+unsigned long clr;
+unsigned long set;
+unsigned int sum;
+struct page *page;
+ unsigned int offset;
+int *sk_owner ;
+unsigned long saddr;
+unsigned long daddr;
+unsigned short len;
+unsigned short proto;
+unsigned int rval;
+
+
+
+
+
+
+main()
+{
+
+
+
+        __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
+
+        __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
+
+
+        __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
+
+        __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
+
+
+        __asm__("rlwimi %0,%2,8,16,23" : "=&r" (result) : "0" (value >> 8), "r" (value));
+
+
+        __asm__("rlwimi %0,%2,24,16,23" : "=&r" (result) : "0" (value>>24), "r" (value));
+        __asm__("rlwimi %0,%2,8,8,15" : "=&r" (result) : "0" (result), "r" (value));
+        __asm__("rlwimi %0,%2,24,0,7" : "=&r" (result) : "0" (result), "r" (value));
+
+
+        __asm__ __volatile__(
+"1:	lwarx	%0,0,%3		\n	add	%0,%2,%0\n"
+
+       
+"	stwcx.	%0,0,%3 \n	bne-	1b"
+
+        : "=&r" (t), "=m" (v->counter)
+        : "r" (a), "r" (&v->counter), "m" (v->counter)
+        : "cc");
+
+
+        __asm__ __volatile__(
+"1:	lwarx	%0,0,%2		\n	add	%0,%1,%0\n"
+
+       
+"	stwcx.	%0,0,%2 \n	bne-	1b"
+
+       
+        : "=&r" (t)
+        : "r" (a), "r" (&v->counter)
+        : "cc", "memory");
+
+
+
+
+        __asm__ __volatile__(
+"1:	lwarx	%0,0,%3		\n	subf	%0,%2,%0\n"
+
+       
+"	stwcx.	%0,0,%3 \n	bne-	1b"
+
+        : "=&r" (t), "=m" (v->counter)
+        : "r" (a), "r" (&v->counter), "m" (v->counter)
+        : "cc");
+
+
+        __asm__ __volatile__(
+"1:	lwarx	%0,0,%2		\n	subf	%0,%1,%0\n"
+
+       
+"	stwcx.	%0,0,%2 \n	bne-	1b"
+
+       
+        : "=&r" (t)
+        : "r" (a), "r" (&v->counter)
+        : "cc", "memory");
+
+
+
+        __asm__ __volatile__(
+"1:	lwarx	%0,0,%2		\n	addic	%0,%0,1\n"
+
+       
+"	stwcx.	%0,0,%2 \n	bne-	1b"
+
+        : "=&r" (t), "=m" (v->counter)
+        : "r" (&v->counter), "m" (v->counter)
+        : "cc");
+
+
+        __asm__ __volatile__(
+"1:	lwarx	%0,0,%1		\n	addic	%0,%0,1\n"
+
+       
+"	stwcx.	%0,0,%1 \n	bne-	1b"
+
+       
+        : "=&r" (t)
+        : "r" (&v->counter)
+        : "cc", "memory");
+
+
+
+        __asm__ __volatile__(
+"1:	lwarx	%0,0,%2		\n	addic	%0,%0,-1\n"
+
+        "	stwcx.	%0,0,%2\n	bne-	1b"
+
+
+        : "=&r" (t), "=m" (v->counter)
+        : "r" (&v->counter), "m" (v->counter)
+        : "cc");
+
+
+        __asm__ __volatile__(
+"1:	lwarx	%0,0,%1		\n	addic	%0,%0,-1\n"
+
+       
+"	stwcx.	%0,0,%1\n	bne-	1b"
+
+       
+        : "=&r" (t)
+        : "r" (&v->counter)
+        : "cc", "memory");
+
+
+        __asm__ __volatile__(
+"1:	lwarx	%0,0,%1		\n	addic.	%0,%0,-1\n	blt-	2f\n"
+
+
+       
+"	stwcx.	%0,0,%1\n	bne-	1b"
+
+       
+        "\n2:" : "=&r" (t)
+
+        : "r" (&v->counter)
+        : "cc", "memory");
+
+
+        __asm__ __volatile__("\n1:	lwarx	%0,0,%3 \n	or	%0,%0,%2 \n"
+
+
+       
+"	stwcx.	%0,0,%3 \n	bne-	1b"
+
+        : "=&r" (old), "=m" (*p)
+        : "r" (mask), "r" (p), "m" (*p)
+        : "cc" );
+
+
+        __asm__ __volatile__("\n1:	lwarx	%0,0,%3 \n	andc	%0,%0,%2 \n"
+
+
+       
+"	stwcx.	%0,0,%3 \n	bne-	1b"
+
+        : "=&r" (old), "=m" (*p)
+        : "r" (mask), "r" (p), "m" (*p)
+        : "cc");
+
+
+
+        __asm__ __volatile__("\n1:	lwarx	%0,0,%3 \n	xor	%0,%0,%2 \n"
+
+
+       
+"	stwcx.	%0,0,%3 \n	bne-	1b"
+
+        : "=&r" (old), "=m" (*p)
+        : "r" (mask), "r" (p), "m" (*p)
+        : "cc");
+
+
+
+
+        __asm__ __volatile__( "\n1:	lwarx	%0,0,%4 \n	or	%1,%0,%3 \n"
+
+
+       
+"	stwcx.	%1,0,%4 \n	bne	1b"
+
+       
+        : "=&r" (old), "=&r" (t), "=m" (*p)
+        : "r" (mask), "r" (p), "m" (*p)
+        : "cc", "memory");
+
+
+
+
+        __asm__ __volatile__( "\n1:	lwarx	%0,0,%4 \n	andc	%1,%0,%3 \n"
+
+
+       
+"	stwcx.	%1,0,%4 \n	bne	1b"
+
+       
+        : "=&r" (old), "=&r" (t), "=m" (*p)
+        : "r" (mask), "r" (p), "m" (*p)
+        : "cc", "memory");
+
+
+        __asm__ __volatile__( "\n1:	lwarx	%0,0,%4 \n	xor	%1,%0,%3 \n"
+
+
+       
+"	stwcx.	%1,0,%4 \n	bne	1b"
+
+       
+        : "=&r" (old), "=&r" (t), "=m" (*p)
+        : "r" (mask), "r" (p), "m" (*p)
+        : "cc", "memory");
+
+        asm ("cntlzw %0,%1" : "=r" (lz) : "r" (x));
+        asm ("cntlzw %0,%1" : "=r" (lz) : "r" (x));
+#if 0
+        if (__builtin_expect(!!(b[0]), 0))
+                return 0;
+#endif
+
+        // __asm__("rlwinm %0,1,0,0,18" : "=r"(ti));
+
+
+
+
+         __asm__ __volatile__ ("dcbt 0,%0" : : "r" (x));
+         __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (x));
+        msr = ({ asm volatile("mfmsr %0" : "=r" (rval)); rval;});
+        asm volatile("mtmsr %0" : : "r" (msr & ~(1<<15)));
+        __asm__ __volatile__("": : :"memory");
+
+        __asm__ __volatile__("": : :"memory");
+        msr = ({ asm volatile("mfmsr %0" : "=r" (rval)); rval;});
+        asm volatile("mtmsr %0" : : "r" (msr | (1<<15)));
+
+        msr = ({ asm volatile("mfmsr %0" : "=r" (rval)); rval;});
+        asm volatile("mtmsr %0" : : "r" (msr & ~(1<<15)));
+        __asm__ __volatile__("": : :"memory");
+
+        __asm__ __volatile__ ("\n1:	lwarx	%0,0,%2 \n"
+
+       
+"	stwcx.	%3,0,%2 \n	bne-	1b"
+
+        : "=&r" (prev), "=m" (*(volatile unsigned long *)p)
+        : "r" (p), "r" (val), "m" (*(volatile unsigned long *)p)
+        : "cc", "memory");
+
+        __asm__ __volatile__ ("\n1:	lwarx	%0,0,%2 \n	cmpw	0,%0,%3 \n	bne	2f \n"
+
+
+
+       
+"	stwcx.	%4,0,%2 \n	bne-	1b\n"
+
+
+
+
+"2:"
+        : "=&r" (prev), "=m" (*p)
+        : "r" (p), "r" (old1), "r" (new), "m" (*p)
+        : "cc", "memory");
+
+
+        __asm__ __volatile__(
+                "2:	mftb %0\n"
+                "3:\n"
+                ".section __ftr_fixup,\"a\"\n"
+                "	.long %1\n"
+                "	.long 0\n"
+                "	.long 2b\n"
+                "	.long 3b\n"
+                ".text"
+                : "=r" (ret) : "i" (0x00000100));
+        __asm__ __volatile__("": : :"memory");
+        asm ("cntlzw %0,%1" : "=r" (lz) : "r" (size));
+
+
+
+  do { asm volatile("mtmsr %0" : : "r" (flags)); do { } while (0); } while (0);
+
+                do { __asm__ __volatile__( 
+	"1:	twnei %0,0\n" 
+	".section __bug_table,\"a\"\n\t" 
+	"	.long 1b,%1,%2,%3\n" ".text" : : 
+	"r" (!((dentry->d_count)
+		->counter)), 
+	"i" (273), 
+	"i" ("../../include/linux/dcache.h"), 
+	"i" ((__func__))); } while (0);
+        __asm__ __volatile__("1:	lwarx	%0,0,%3\n	andc	%1,%0,%4\n	or	%1,%1,%5\n"
+
+
+
+       
+"	stwcx.	%1,0,%3\n	bne-	1b"
+
+        : "=&r" (old1), "=&r" (tmp), "=m" (*p)
+        : "r" ((unsigned long)(p+1) - 4), "r" (clr), "r" (set), "m" (*p)
+        : "cc" );
+
+        if (({ do { __asm__ __volatile__( "1:	twnei %0,0\n" ".section __bug_table,\"a\"\n\t" "	.long 1b,%1,%2,%3\n" ".text" : : "r" (((&(page)->count)->counter) == 0), "i" (284), "i" ("../../include/linux/mm.h"), "i" ((__func__))); } while (0); (atomic_dec_return((&(page)->count)) == 0); }))
+        return 0;
+
+        do { __asm__ __volatile__( "1:	twnei %0,0\n" ".section __bug_table,\"a\"\n\t" "	.long 1b,%1,%2,%3\n" ".text" : : "r" (offset + size > (1UL << 12)), "i" (59), "i" ("../../include/linux/highmem.h"), "i" ((__func__))); } while (0);
+
+	asm volatile("mtmsr %0" : : "r" (flags)); 
+
+                asm volatile("mtmsr %0" : : "r" (flags));
+
+        if (((({ asm volatile("mfmsr %0" : "=r" (rval)); rval;}) & (1<<15)) == 0))
+	    return 0;
+
+        __asm__ __volatile__("": : :"memory");
+
+
+                do { __asm__ __volatile__( "1:	twnei %0,0\n" ".section __bug_table,\"a\"\n\t" "	.long 1b,%1,%2,%3\n" ".text" : : "r" ((v->counter) == 1), "i" (333 + 0x1000000), "i" ("../../include/net/sock.h"), "i" ((__func__))); } while (0);
+
+        do { __asm__ __volatile__( "1:	twnei %0,0\n" ".section __bug_table,\"a\"\n\t" "	.long 1b,%1,%2,%3\n" ".text" : : "r" (sk_owner != ((void *)0)), "i" (476), "i" ("../../include/net/sock.h"), "i" ((__func__))); } while (0);
+
+        do { __asm__ __volatile__( "1:	twnei %0,0\n" ".section __bug_table,\"a\"\n\t" "	.long 1b,%1,%2,%3\n" ".text" : : "r" (sizeof(struct page) > (24 * sizeof(long))), "i" (523), "i" ("../../include/net/sock.h"), "i" ((__func__))); } while (0);
+
+
+
+        __asm__("rlwinm %0,%1,16,0,31" : "=r" (tmp) : "r" (sum));
+
+    __asm__("\n	addc %0,%0,%1 \n	adde %0,%0,%2 \n	adde %0,%0,%3 \n	addze %0,%0 \n	"
+
+
+
+
+
+        : "=r" (sum)
+        : "r" (daddr), "r"(saddr), "r"((proto<<16)+len), "0"(sum));
+
+
+        do { __asm__ __volatile__( "1:	twnei %0,0\n" ".section __bug_table,\"a\"\n\t" "	.long 1b,%1,%2,%3\n" ".text" : : "r" ((tmp) != 0x00000001), "i" (231), "i" ("../../include/linux/crypto.h"), "i" ((__func__))); } while (0);
+
+
+}