Mercurial > hg > CbC > old > device
changeset 318:9fe0b32a7d57
asm continue...
author | kono |
---|---|
date | Fri, 18 Jun 2004 18:34:42 +0900 |
parents | 3dfac70ef7e1 |
children | 88cf6512fa1b |
files | Changes mc-code-powerpc.c mc-parse.c mc.h |
diffstat | 4 files changed, 238 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Wed Jun 16 21:13:56 2004 +0900 +++ b/Changes Fri Jun 18 18:34:42 2004 +0900 @@ -4968,3 +4968,28 @@ association list を使って、unwind すれば良いんだけどね。 それは、全体的に手直しした方が良い。後回し。 + +cheap の扱いで boundary を見てないのがいつくあるね。 + +Thu Jun 17 17:10:21 JST 2004 + +えーと、 + "m" とかは、メモリの変更なので見なくてよろしい + "r" はレジスタを割り当てる + "=" は出力のマークなので無視して良い + "+", "&" は出力のマークなので無視して良い +で、 + "0" 0番目のoperand +とかなんだけど... こいつは input (先にコンパイルする方) +に現れる。だから、output operand を先に処理する。out +put operand は単純な代入文だから、それでOk。 + +Fri Jun 18 13:33:19 JST 2004 + +なんか、%0,%1 とかって、同じレジスタに割り振られることも +あるみたいね。さらに、連続してでて来るとも限らないみたい。 + +ってことは? + +なんか、間違えた。%0...%8 は、パラメターの順序を +さしているのね。そうだよな。
--- a/mc-code-powerpc.c Wed Jun 16 21:13:56 2004 +0900 +++ b/mc-code-powerpc.c Fri Jun 18 18:34:42 2004 +0900 @@ -4934,13 +4934,198 @@ #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 + */ + + +#define MAX_ASM_REG 30 + +static void +print_asm_reg(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)==STRING) { + printf("%s",(char*)cadr(rstr)); + } else { + error(-1); + } +} + +static void +replase_asm_string(char *asm_str,int repl) +{ + int c,i,rstr,val,path; + char *p; + int reg[MAX_ASM_REG]; + + c = *asm_str; + if (c!='\t'&&c!=' ') printf("\t"); + for(i=0;i<MAX_ASM_REG;i++) { + reg[i] = 0; + } + // asm parameters %0,%1 may be not contiguous nor starting from 0. + // two path execution is necessary. + for(path=1;path<=2;path++) { + p = asm_str; + if (path==2) { + for(i=0;repl && i<MAX_ASM_REG;i++) { + if (reg[i]) { + reg[i] = car(repl); + repl = cadr(repl); + } + } + } + while((c = *p++)) { + if (c=='%') { + c = *p++; + if (!c) { break; + } else if (c=='%') { + if (path==2) printf("%%"); continue; + } else if (!digit(c)) { + if (path==2) printf("%%%c",c); continue; + } + val = 0; + do { val = val*10 + c-'0'; } while (digit(c=*asm_str++)) ; + asm_str--; + if (val>MAX_ASM_REG) error(-1); // too large register + if (path==1) { + reg[val] = 1; + } else { + rstr = reg[val]; + print_asm_reg(rstr); + } + } else { + if (path==2) printf("%c",c); + } + } + if (path==2) printf("\n"); + } +} + +#define ASM_INPUT 1 +#define ASM_OUTPUT 2 +#define ASM_USED 3 + +static 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') { + } else if (c=='i') { + if (car(e1)==GVAR||car(e1)==FNAME) { + e1=list3(STRING,(int)(((NMTBL *)cadr(e1))->nm),0); + } + if (car(e1)!=CONST && car(e1)!=STRING) 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; +} + +static void +free_asm_operand(int repl) +{ + for(;repl;repl=cadr(repl)) { + if (car(car(repl))==REGISTER) + free_register(cadr(car(repl))); + } +} + 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)); + } + } + replase_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-parse.c Wed Jun 16 21:13:56 2004 +0900 +++ b/mc-parse.c Fri Jun 18 18:34:42 2004 +0900 @@ -12,12 +12,10 @@ static NMTBL *msearch(char *name); static NMTBL *msearch0(char *name); static char * mappend(int lists); -static int alpha(char c); static int append3(int p,int a1,int a2); static int binop(int op, int e1, int e2, int t1, int t2); static int cexpr(int e); static int decl_data(int t, NMTBL *n,int offset,int skip); -static int digit(char c); static int expr(int); static int expr0(void); static int expr1(void); @@ -4261,14 +4259,14 @@ return sym=s1; } -static int -alpha(char c) +int +alpha(int c) { return(('a'<=c&&c<='z')||('A'<=c&&c<='Z')||c=='_'); } -static int -digit(char c) +int +digit(int c) { return('0'<=c&&c<='9'); } @@ -5271,6 +5269,25 @@ } int +length(int list) +{ + int n=0; + for(;list;n++) { + list = cadr(list); + } + return n; +} + +int +nth(int n, int list) +{ + while(n-->0) { + list = cadr(list); + } + return list; +} + +int insert_ascend(int p,int e,int eq()) { int p1,p2,dup;
--- a/mc.h Wed Jun 16 21:13:56 2004 +0900 +++ b/mc.h Fri Jun 18 18:34:42 2004 +0900 @@ -480,6 +480,8 @@ extern int list2(int e1, int e2); extern int list3(int e1, int e2, int e3); extern int list4(int e1, int e2, int e3,int e4); +extern int length(int e1); +extern int nth(int n,int e1); extern int reverse0(int t1); extern int assign_data(int e, int t, NMTBL *n,int offset); extern int assign_expr0(int e1,int e2,int t,int type) ; @@ -531,6 +533,8 @@ EXTERN int list3(int e1, int e2, int e3); EXTERN int list4(int e1, int e2, int e3, int e4); EXTERN int reverse0(int t1); +EXTERN int digit(int c); +EXTERN int alpha(int c); /* EXTERN int rplacad(int e, int n); EXTERN int rplacadd(int e, int n);