Mercurial > hg > CbC > old > device
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); + + +}