changeset 527:6b0fd56848e6 inline-asm

inline continue.... asm, lvar free
author kono
date Wed, 28 Dec 2005 21:21:57 +0900
parents 9ff5cd7afe2f
children d6fff671793a
files Changes mc-code-arm.c mc-code-ia32.c mc-code-mips.c mc-code-powerpc.c mc-codegen.c mc-inline.c mc-macro.c mc-macro.h mc-parse.c
diffstat 10 files changed, 191 insertions(+), 111 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Wed Dec 28 15:45:39 2005 +0900
+++ b/Changes	Wed Dec 28 21:21:57 2005 +0900
@@ -7644,3 +7644,21 @@
 attribute も必要なわけだ。
 
 ま、それはあとで。
+
+Wed Dec 28 17:29:59 JST 2005
+
+skipspc() で、inmode の時に、cheap に書かれてしまうので、
+cheap 上の string  をterminate しないうちに、skipspc()
+してはいけないわけね。
+
+なんだが、"hoge" "ahoge" のcaseに、inmode の ST_COMMENT
+が干渉してしまうわけね。それは、まずいか。
+
+やっぱり、STRING は、"" で一つにして、複数つながる
+っていう構文にした方が良いね。
+
+    list(STRINNG,value,continue)
+
+みたいな感じ。
+
+
--- a/mc-code-arm.c	Wed Dec 28 15:45:39 2005 +0900
+++ b/mc-code-arm.c	Wed Dec 28 21:21:57 2005 +0900
@@ -401,25 +401,25 @@
 
 
 #if 0
-printf("# vars= %d, regs= %d/%d, args= %d, extra= %d\n",
+printf("## vars= %d, regs= %d/%d, args= %d, extra= %d\n",
 	round16(-disp),
 	max_reg_var+2,
 	max_freg_var,
 	round16(max_func_args*SIZE_OF_INT),
 	0
 );
-   printf("# callee arg top=\t%d\n",CALLEE_ARG(0));
-   printf("# reg_save_top=\t\t%d\n",r1_offsetv);
-   printf("# reg_save_end=\t\t%d\n",
+   printf("## callee arg top=\t%d\n",CALLEE_ARG(0));
+   printf("## reg_save_top=\t\t%d\n",r1_offsetv);
+   printf("## reg_save_end=\t\t%d\n",
 	-max_reg_var*SIZE_OF_INT-max_freg_var*SIZE_OF_FLOAT-2*SIZE_OF_INT+
 	r1_offsetv);
-   printf("# lvar_offset=\t\t%d %d\n",lvar_offsetv,lvar_offsetv%16);
-   printf("# min local var=\t%d\n",FUNC_LVAR(0)+lvar_offsetv);
-   printf("# max local var=\t%d\n",FUNC_LVAR(disp)+lvar_offsetv);
-   printf("# min caller arg var=\t%d\n",
+   printf("## lvar_offset=\t\t%d %d\n",lvar_offsetv,lvar_offsetv%16);
+   printf("## min local var=\t%d\n",FUNC_LVAR(0)+lvar_offsetv);
+   printf("## max local var=\t%d\n",FUNC_LVAR(disp)+lvar_offsetv);
+   printf("## min caller arg var=\t%d\n",
 	CALLER_ARG(round16(max_func_args*SIZE_OF_INT)));
-   printf("# max caller arg var=\t%d\n",CALLER_ARG(0));
-   printf("#\n");
+   printf("## max caller arg var=\t%d\n",CALLER_ARG(0));
+   printf("##\n");
 #endif
 
     return 0;
@@ -721,7 +721,7 @@
 get_register(void)
 {
     int i = get_register0();
-    printf("# get_register %d\n",i);
+    printf("## get_register %d\n",i);
     return i;
 }
 #endif
@@ -774,7 +774,7 @@
 get_dregister(int d)
 {
     int i = get_dregister0(d);
-printf("# get_dregister %d\n",i);
+printf("## get_dregister %d\n",i);
     return i;
 }
 #endif
@@ -793,7 +793,7 @@
     int i;
     for(i=LREG_OFFSET;i<REAL_MAX_LREGISTER+LREG_OFFSET;i++) {
 	if (regs[i]==0) {
-// printf("# get_lregister %d (%d)\n",i,lreg_count++);
+// printf("## get_lregister %d (%d)\n",i,lreg_count++);
 	    return i;
 	}
     }
@@ -863,10 +863,10 @@
 void
 
 free_register(int i) {    /* いらなくなったレジスタを開放 */
-// printf("# free_register %d\n",i);
+// printf("## free_register %d\n",i);
     regs[i]=0;
     if (is_longlong_reg(i)) {
-// printf("# free lregister %d (%d)\n",i,lreg_count++);
+// printf("## free lregister %d (%d)\n",i,lreg_count++);
 	regs[regv_l(i)]=0;
 	regs[regv_h(i)]=0;
 	//regv_l(i)=0;
@@ -957,7 +957,7 @@
     for(i=0;i<MAX_FREGISTER;i++) {
         if (! regs[i+FREG_OFFSET]) fcount++;
     }
-    printf("# free reg %d freg %d\n",count,fcount);
+    printf("## free reg %d freg %d\n",count,fcount);
     return d?fcount:count;
 }
 
@@ -979,7 +979,7 @@
 free_all_register(void)
 {
     int i;
-// printf("# free_all register\n");
+// printf("## free_all register\n");
 #if LONGLONG_CODE||FLOAT_CODE
     for(i=0;i<REAL_MAX_LREGISTER;i++) {
 	regs[i+LREG_OFFSET]=0; 
@@ -1052,7 +1052,7 @@
 #endif
 #define USAGE_MAX 4
     if (!lsrc) return;
-    printf("# %d: %s:",lineno,s);
+    printf("## %d: %s:",lineno,s);
     if (ireg) printf(" creg=%s",register_name(ireg));
     if (freg) printf(" freg=%s",fregister_name(freg));
     if (lreg) printf(" lreg=%s,%s",lregister_name_high(lreg),
@@ -1351,7 +1351,7 @@
 static void
 inc_inst(int count)
 {
-// printf("# inst %d\n",inst_count);
+// printf("## inst %d\n",inst_count);
     if ((inst_count+=count)>CONST_TBL_COUNT) {
 	inst_count = 0;
 	const_list_table();
@@ -2170,7 +2170,7 @@
 void
 use_reg(int arg)
 {
-// printf("# use reg %d\n",arg);
+// printf("## use reg %d\n",arg);
     if (arg<0||arg> REGS_MAX)
 	error(-1);
     clear_ptr_cache_reg(arg);
@@ -4513,7 +4513,7 @@
 	if (regv_l(lreg)==edx || regv_h(lreg)==edx) {
 	    edx0 = get_register(); if(!edx0) error(-1);
 	    inc_inst(1);
-	    printf("# dassop\n\tmov\t%s, %s\n",
+	    printf("## dassop\n\tmov\t%s, %s\n",
 		register_name(edx0),register_name(edx));
 	    edx = edx0;
 	}
@@ -5704,7 +5704,7 @@
     if (regv_l(lreg)==edx || regv_h(lreg)==edx) {
 	edx0 = get_register(); if(!edx0) error(-1);
 	inc_inst(1);
-	printf("# lassop\n\tmov\t%s, %s\n",register_name(edx0),
+	printf("## lassop\n\tmov\t%s, %s\n",register_name(edx0),
 	       register_name(edx));
 	edx = edx0;
     }
@@ -5894,7 +5894,7 @@
     int val;
     int clobber = 0;
 
-    printf("# constraint %s\n",p);
+    printf("## constraint %s\n",p);
     if (*p=='=') {
 	// output register
 	p++;
@@ -6115,7 +6115,7 @@
 		*bfd = (i==bitsz)?0:i;
 	        *sz = (i+7)/8;
 #ifdef BITPOS_DEBUG
-    printf("# %d: bitpos=%d bitsize=%d bitsz=%d offset=%d\n",lineno,bitpos,bitsize,bitsz,*poffset);
+    printf("## %d: bitpos=%d bitsize=%d bitsz=%d offset=%d\n",lineno,bitpos,bitsize,bitsz,*poffset);
 #endif
 		return l;
 	    } 
@@ -6131,7 +6131,7 @@
     *bfd = (bitsize==bitsz)?0:bitsize;
     *sz = (bitsize+7)/8;
 #ifdef BITPOS_DEBUG
-    printf("# %d: bitpos=%d bitsize=%d bitsz=%d offset=%d\n",lineno,bitpos,bitsize,bitsz,*poffset);
+    printf("## %d: bitpos=%d bitsize=%d bitsz=%d offset=%d\n",lineno,bitpos,bitsize,bitsz,*poffset);
 #endif
     return bitpos;
 }
@@ -6147,7 +6147,7 @@
     int i,size;
     set_bitsz(type,&bitpos,&bitsize,&sign,&bitsz,&align,&l);
     size = bitsz/8;
-// printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz);
+// printf("## %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz);
     /* this implementation returns -1 for int i:1; */
     if (l==1) {
 #if LONGLONG_CODE
@@ -6221,7 +6221,7 @@
 static void
 make_mask_and_or(int mask,int tmp,char *trn,char *crn,char *lrn)
 {
-// printf("# mask 0x%08x ~0x%08x\n",mask,~mask);
+// printf("## mask 0x%08x ~0x%08x\n",mask,~mask);
 	inc_inst(4);
 	code_const(~mask,tmp);
 	printf("\torr\t%s, %s, %s\n",trn,crn,trn);
@@ -6244,7 +6244,7 @@
     char *crn,*lrn,*trn;
     set_bitsz(type,&bitpos,&bitsize,&sign,&bitsz,&align,&l);
     size = bitsz/8;
-// printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz);
+// printf("## %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz);
     if (l==1) {
 #if LONGLONG_CODE
 	int tmp2;
@@ -6356,7 +6356,7 @@
     char *trn;
     int tmp = -1;
     int m;
-// printf("# mask 0x%08x ~0x%08x\n",mask,~mask);
+// printf("## mask 0x%08x ~0x%08x\n",mask,~mask);
     if ((m=(~mask|c))!=-1) {
 	inc_inst(1);
 	if (is_stage1_const(m,0)>0) {
@@ -6400,7 +6400,7 @@
     char *crn;
     set_bitsz(type,&bitpos,&bitsize,&sign,&bitsz,&align,&l);
     size = bitsz/8;
-// printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz);
+// printf("## %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz);
     if (l==1) {
 #if LONGLONG_CODE
         use_int(adr);
--- a/mc-code-ia32.c	Wed Dec 28 15:45:39 2005 +0900
+++ b/mc-code-ia32.c	Wed Dec 28 21:21:57 2005 +0900
@@ -495,7 +495,7 @@
 	    printf(" %s",register_name(reg_stack[i],0));
     }
 #endif
-    printf("# f:%d",freg_sp);
+    printf("## f:%d",freg_sp);
     printf("\n");
 }
 
@@ -514,7 +514,7 @@
         /* process in reverse order */
         n = (NMTBL*)caddr(args);
         type = n->ty;
-// printf("##  %s %d %d\n",n->nm,n->dsp,n->ty);
+// printf("###  %s %d %d\n",n->nm,n->dsp,n->ty);
         if (scalar(type)) {
             if ((reg = get_input_register_var(reg_var,n,is_code0))) {
                 n->sc = REGISTER;
@@ -695,7 +695,7 @@
 	else if (type==DATA_REG)
 	    use_data_reg(dreg,0);
 if (regv[dreg]) {
-    printf("## emit_pop dreg conflict\n");
+    printf("### emit_pop dreg conflict\n");
     error(-1);
 }
 	printf("\tpopl %s\n",register_name(dreg,0));
--- a/mc-code-mips.c	Wed Dec 28 15:45:39 2005 +0900
+++ b/mc-code-mips.c	Wed Dec 28 21:21:57 2005 +0900
@@ -382,25 +382,25 @@
 );
 #endif
 #if 0
-    printf("# mask_label $L_%d=0x%x\n",mask_label,code_mask());
-    printf("# mask_offset$L_%d=%d\n",mask_offset_label,code_mask_offset());
-    printf("# fmask_label $L_%d=0x%x\n",fmask_label,code_fmask());
-    printf("# fmask_offset$L_%d=%d\n",fmask_offset_label,code_fmask_offset());
-    printf("# cprestore  $L_%d=%d\n",cprestore_label ,round16(max_func_args*SIZE_OF_INT));
-   printf("#\n");
-   printf("# callee arg top=\t%d\n",CALLEE_ARG(0)+r1_offsetv);
-   printf("# r1_offset=\t\t%d %d\n",r1_offsetv,r1_offsetv%16);
-   printf("# reg_save_top=\t\t%d\n",r1_offsetv);
-   printf("# reg_save_end=\t\t%d\n",
+    printf("## mask_label $L_%d=0x%x\n",mask_label,code_mask());
+    printf("## mask_offset$L_%d=%d\n",mask_offset_label,code_mask_offset());
+    printf("## fmask_label $L_%d=0x%x\n",fmask_label,code_fmask());
+    printf("## fmask_offset$L_%d=%d\n",fmask_offset_label,code_fmask_offset());
+    printf("## cprestore  $L_%d=%d\n",cprestore_label ,round16(max_func_args*SIZE_OF_INT));
+   printf("##\n");
+   printf("## callee arg top=\t%d\n",CALLEE_ARG(0)+r1_offsetv);
+   printf("## r1_offset=\t\t%d %d\n",r1_offsetv,r1_offsetv%16);
+   printf("## reg_save_top=\t\t%d\n",r1_offsetv);
+   printf("## reg_save_end=\t\t%d\n",
 	-max_reg_var*SIZE_OF_INT-max_freg_var*SIZE_OF_FLOAT-2*SIZE_OF_INT+
 	r1_offsetv);
-   printf("# lvar_offset=\t\t%d %d\n",lvar_offsetv,lvar_offsetv%16);
-   printf("# min local var=\t%d\n",FUNC_LVAR(0)+lvar_offsetv);
-   printf("# max local var=\t%d\n",FUNC_LVAR(disp)+lvar_offsetv);
-   printf("# min caller arg var=\t%d\n",
+   printf("## lvar_offset=\t\t%d %d\n",lvar_offsetv,lvar_offsetv%16);
+   printf("## min local var=\t%d\n",FUNC_LVAR(0)+lvar_offsetv);
+   printf("## max local var=\t%d\n",FUNC_LVAR(disp)+lvar_offsetv);
+   printf("## min caller arg var=\t%d\n",
 	CALLER_ARG(round16(max_func_args*SIZE_OF_INT)));
-   printf("# max caller arg var=\t%d\n",CALLER_ARG(0));
-   printf("#\n");
+   printf("## max caller arg var=\t%d\n",CALLER_ARG(0));
+   printf("##\n");
 #endif
     fprintf(asi,"$L_%d=0x%x\n",mask_label,code_mask());
     fprintf(asi,"$L_%d=%d\n",mask_offset_label,code_mask_offset());
@@ -651,7 +651,7 @@
 get_register(void)
 {
     int i = get_register0();
-    printf("# get_register %d\n",i);
+    printf("## get_register %d\n",i);
     return i;
 }
 #endif
@@ -703,7 +703,7 @@
 get_dregister(int d)
 {
     int i = get_dregister0(d);
-printf("# get_dregister %d\n",i);
+printf("## get_dregister %d\n",i);
     return i;
 }
 #endif
@@ -721,7 +721,7 @@
     int i;
     for(i=LREG_OFFSET;i<REAL_MAX_LREGISTER+LREG_OFFSET;i++) {
 	if (regs[i]==0) {
-// printf("# get_lregister %d\n",i);
+// printf("## get_lregister %d\n",i);
 	    return i;
 	}
     }
@@ -791,7 +791,7 @@
 void
 
 free_register(int i) {    /* いらなくなったレジスタを開放 */
-// printf("# free_register %d\n",i);
+// printf("## free_register %d\n",i);
     regs[i]=0;
     if (is_longlong_reg(i)) {
 	regs[regv_l(i)]=0;
@@ -908,7 +908,7 @@
     for(i=0;i<MAX_FREGISTER;i++) {
         if (! regs[i+FREG_OFFSET]) fcount++;
     }
-    printf("# free reg %d freg %d\n",count,fcount);
+    printf("## free reg %d freg %d\n",count,fcount);
     return d?fcount:count;
 }
 
@@ -930,7 +930,7 @@
 free_all_register(void)
 {
     int i;
-// printf("# free_all register\n");
+// printf("## free_all register\n");
 #if LONGLONG_CODE||FLOAT_CODE
     for(i=0;i<REAL_MAX_LREGISTER;i++) {
 	regs[i+LREG_OFFSET]=0; 
@@ -1003,7 +1003,7 @@
 #endif
 #define USAGE_MAX 4
     if (!lsrc) return;
-    printf("# %d: %s:",lineno,s);
+    printf("## %d: %s:",lineno,s);
     if (ireg) printf(" creg=%s",register_name(ireg));
     if (freg) printf(" freg=%s",fregister_name(freg));
     if (lreg) printf(" lreg=%s,%s",lregister_name_high(lreg),
@@ -1758,7 +1758,7 @@
 void
 use_reg(int arg)
 {
-// printf("# use reg %d\n",arg);
+// printf("## use reg %d\n",arg);
     if (arg<0||arg> REGS_MAX)
 	error(-1);
     clear_ptr_cache_reg(arg);
@@ -2494,7 +2494,7 @@
     free_register(edx);
     emit_pop_free(xreg);
 #else
-    printf("# assop\n\tmove %s,%s\n",register_name(edx),register_name(creg));
+    printf("## assop\n\tmove %s,%s\n",register_name(edx),register_name(creg));
     ld_indexx(byte,0,edx,creg,sign);
     tosop(op,creg,xreg);
     crn = register_name(creg);
@@ -2761,7 +2761,7 @@
     char *rn1;
     char *rn0;
 
-// printf("# pcond %d cond %d\n",op,cond);
+// printf("## pcond %d cond %d\n",op,cond);
     switch(op+(!cond)*BNOT) {
     case GT:  case LE+BNOT:
 		    t=r1;r1=r0;r0=t;
@@ -4026,7 +4026,7 @@
       use_float(d,reg);
       if (regv_l(lreg)==edx || regv_h(lreg)==edx) {
 	edx0 = get_register(); if(!edx0) error(-1);
-	printf("# dassop\n\tmove %s,%s\n",register_name(edx0),register_name(edx));
+	printf("## dassop\n\tmove %s,%s\n",register_name(edx0),register_name(edx));
 	edx = edx0;
       }
       lload(edx,reg,0);
@@ -5221,7 +5221,7 @@
     use_longlong(reg);
     if (regv_l(lreg)==edx || regv_h(lreg)==edx) {
 	edx0 = get_register(); if(!edx0) error(-1);
-	printf("# lassop\n\tmove %s,%s\n",register_name(edx0),
+	printf("## lassop\n\tmove %s,%s\n",register_name(edx0),
 	       register_name(edx));
 	edx = edx0;
     }
@@ -5412,7 +5412,7 @@
     int val;
     int clobber = 0;
 
-    printf("# constraint %s\n",p);
+    printf("## constraint %s\n",p);
     if (*p=='=') {
 	// output register
 	p++;
@@ -5572,7 +5572,7 @@
 		i = l+bitsize;
                 *bfd = (i==bitsz)?0:i;
 		*sz = (i+7)/8;
-// printf("# bitpos=%d bitsize=%d bitsz=%d offset=%d\n",l,bitsize,bitsz,*poffset);
+// printf("## bitpos=%d bitsize=%d bitsz=%d offset=%d\n",l,bitsize,bitsz,*poffset);
 		return l;
 	    } 
 	}
@@ -5587,7 +5587,7 @@
     *bfd = (bitsize==bitsz)?0:bitsize;
     *sz = (bitsize+7)/8;
 
-// printf("# bitpos=%d bitsize=%d bitsz=%d offset=%d\n",bitpos,bitsize,bitsz,*poffset);
+// printf("## bitpos=%d bitsize=%d bitsz=%d offset=%d\n",bitpos,bitsize,bitsz,*poffset);
     return bitpos;
 }
 
@@ -5601,7 +5601,7 @@
     int i,size;
     set_bitsz(type,&bitpos,&bitsize,&sign,&bitsz,&align,&l);
     size = bitsz/8;
-// printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz);
+// printf("## %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz);
     /* this implementation returns -1 for int i:1; */
     if (l==1) {
 #if LONGLONG_CODE
@@ -5633,7 +5633,7 @@
 static void
 make_mask_and_or(int mask,int tmp,char *trn,char *crn,char *lrn)
 {
-// printf("# mask 0x%08x ~0x%08x\n",mask,~mask);
+// printf("## mask 0x%08x ~0x%08x\n",mask,~mask);
 	code_const(~mask,tmp);
 	printf("\tor %s,%s,%s\n",trn,crn,trn);
 	/* do conjunction  */
@@ -5655,7 +5655,7 @@
     char *crn,*lrn,*trn;
     set_bitsz(type,&bitpos,&bitsize,&sign,&bitsz,&align,&l);
     size = bitsz/8;
-// printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz);
+// printf("## %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz);
     if (l) {
 #if LONGLONG_CODE
 	use_int(adr);
@@ -5711,7 +5711,7 @@
 {
     char *trn;
     int tmp = -1;
-// printf("# mask 0x%08x ~0x%08x\n",mask,~mask);
+// printf("## mask 0x%08x ~0x%08x\n",mask,~mask);
     if ((~mask|c)!=-1) {
 	trn = register_name(tmp=get_register());
 	code_const((~mask|c),tmp);
@@ -5748,7 +5748,7 @@
     char *crn;
     set_bitsz(type,&bitpos,&bitsize,&sign,&bitsz,&align,&l);
     size = bitsz/8;
-// printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz);
+// printf("## %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz);
     if (l) {
 #if LONGLONG_CODE
         use_int(adr);
--- a/mc-code-powerpc.c	Wed Dec 28 15:45:39 2005 +0900
+++ b/mc-code-powerpc.c	Wed Dec 28 21:21:57 2005 +0900
@@ -1242,7 +1242,7 @@
     char *crn;
     use_int(reg);
     crn = register_name(reg);
-    // printf("# 0x%08x\n",e2);
+    // printf("## 0x%08x\n",e2);
     if (-32768<e2&&e2<32768)
 	printf("\tli %s,%d\n",crn,e2);
     else {
@@ -5164,18 +5164,26 @@
     int val;
     int clobber = 0;
 
-    printf("# constraint %s\n",p);
-    if (*p=='=') {
+    printf("## constraint %s\n",p);
+retry:
+    switch((c=*p)) {
+    case '?':
+    case '!':
+    case '+':
+    case '%':
+    case '#':
+    case '*':
+    case '=':
 	// output register
 	p++;
-    }
-    if (*p=='&') {
+	goto retry;
+    case '&':
 	// earlyclobber
 	p++;
 	clobber = 1;
-    }
-    c = *p;
-    if (c=='r') {
+	goto retry;
+    case 'b':  // address base register (what?)
+    case 'r':
 	if (mode==ASM_INPUT) {
 	    for(;repl0;repl0 = cadr(repl0)) {
 		if (car(car(repl0))==REGISTER && caddr(repl0)==0) {
@@ -5189,9 +5197,11 @@
 	    r = get_register();
 	}
 	repl = list3(list2(REGISTER,r),repl,clobber);
-    } else if (c=='m') {
+	break;
+    case 'm':
 	repl = list3(list2(0,0),repl,clobber);
-    } else if (c=='i') {
+	break;
+    case 'i':
 	if (car(e1)==GVAR) {
 	    e1=list3(FNAME,(int)(((NMTBL *)caddr(e1))->nm),0);
 	} else if (car(e1)==FNAME) {
@@ -5203,13 +5213,18 @@
 	} else if (car(e1)==CONST) {
 	} else error(-1);
 	repl = list3(e1,repl,clobber);
-    } else if (digit(c)) {
+	break;
+    case '0': case '1': case '2': case '3': case '4':
+    case '5': case '6': case '7': case '8': case '9':
 	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);
+	break;
+    default:
+	printf("### unknown asm constraint %c\n",c);
+    }
     return repl;
 }
 
@@ -5325,7 +5340,7 @@
 		i = l+bitsize;
                 *bfd = (i==bitsz)?0:i;
 		*sz = (i+7)/8;
-// printf("# bitpos=%d bitsize=%d bitsz=%d offset=%d\n",l,bitsize,bitsz,*poffset);
+// printf("## bitpos=%d bitsize=%d bitsz=%d offset=%d\n",l,bitsize,bitsz,*poffset);
 		return l;
 	    } 
 	}
@@ -5340,7 +5355,7 @@
     *bfd = (bitsize==bitsz)?0:bitsize;
     *sz = (bitsize+7)/8;
 
-// printf("# bitpos=%d bitsize=%d bitsz=%d offset=%d\n",bitpos,bitsize,bitsz,*poffset);
+// printf("## bitpos=%d bitsize=%d bitsz=%d offset=%d\n",bitpos,bitsize,bitsz,*poffset);
     return bitpos;
 }
 
@@ -5354,7 +5369,7 @@
     int i,size;
     set_bitsz(type,&bitpos,&bitsize,&sign,&bitsz,&align,&l);
     size = bitsz/8;
-// printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz);
+// printf("## %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz);
     /* this implementation returns -1 for int i:1; */
     if (l==1) {
 #if LONGLONG_CODE
@@ -5388,7 +5403,7 @@
 static void
 make_mask_and_or(int mask,int tmp,char *trn,char *crn,char *lrn)
 {
-// printf("# mask 0x%08x ~0x%08x\n",mask,~mask);
+// printf("## mask 0x%08x ~0x%08x\n",mask,~mask);
 	code_const(~mask,tmp);
 	printf("\tor %s,%s,%s\n",trn,crn,trn);
 	/* do conjunction  */
@@ -5472,7 +5487,7 @@
 {
     char *trn;
     int tmp = -1;
-// printf("# mask 0x%08x ~0x%08x\n",mask,~mask);
+// printf("## mask 0x%08x ~0x%08x\n",mask,~mask);
     if ((~mask|c)!=-1) {
 	trn = register_name(tmp=get_register());
 	code_const((~mask|c),tmp);
--- a/mc-codegen.c	Wed Dec 28 15:45:39 2005 +0900
+++ b/mc-codegen.c	Wed Dec 28 21:21:57 2005 +0900
@@ -2653,8 +2653,6 @@
     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));
--- a/mc-inline.c	Wed Dec 28 15:45:39 2005 +0900
+++ b/mc-inline.c	Wed Dec 28 21:21:57 2005 +0900
@@ -14,6 +14,8 @@
 
 static int ret_register,ret_reg_mode;
 
+static int inline_lvars;
+
 /*
     Basic code generator from parse tree
  */
@@ -421,9 +423,11 @@
 {
     int sz = is_memory(e1);
     int d = cadr(e1);
-    int d1;
+    int d1,e;
     if ((d1=(heap[pdisp+d]))) return d1;
-    return (heap[pdisp+d]=list3(LVAR,new_lvar(sz),0));
+    e =  heap[pdisp+d]=list3(LVAR,new_lvar(sz),0);
+    inline_lvars = glist2(e,inline_lvars);
+    return e;
 }
 
 static int
@@ -458,6 +462,15 @@
 }
 
 static int
+pindirect(int e)
+{
+    int lvar;
+    if (car(lvar=cadr(e))==IVAR)
+	lvar=p_lvar(cadr(e)); // can be anything....
+    return list3(car(e),pexpr(cadr(e)),caddr(e));
+}
+
+static int
 paddress(int e)
 {
     return list2(car(e),pexpr(cadr(e)));
@@ -466,7 +479,7 @@
 static int
 p_conv(int e1,int e2)
 {
-    return list3(CONV,pexpr(e1),e2);
+    return list3(CONV,pexpr(e2),e1);
 }
 
 static int
@@ -595,6 +608,7 @@
     default:
 	v = list3(LVAR,new_lvar(size(n->ty)),(int)n);
     }
+    inline_lvars = glist2(v,inline_lvars);
     if (heap[pdisp+dsp]) error(-1);
     heap[pdisp+dsp]=v;
     return pexpr(cadr(e));
@@ -807,7 +821,7 @@
     case INLINE:
 	return p_inline(e1);
     case INDIRECT:
-	return prindirect(e1);
+	return pindirect(e1);
     case RINDIRECT:  case URINDIRECT:  
     case CRINDIRECT: case CURINDIRECT:
     case SRINDIRECT: case SURINDIRECT:
@@ -1016,6 +1030,7 @@
     int sdisp = pdisp;
     int sret_register = ret_register;
     int sret_reg_mode = ret_reg_mode;
+    int sinline_lvars = inline_lvars;
 
     int narg,arg;
     NMTBL *n = (NMTBL*)cadr(cadr(e));
@@ -1036,6 +1051,7 @@
     retpending = 0;
     ret_reg_mode = 0;
     ret_register = 5555;
+    inline_lvars = 0;
     retlabel = fwdlabel();
 
     enter_scope(); // to make label scope happy
@@ -1056,6 +1072,7 @@
 	    heap[pdisp+narg]=e4;
 	} else {
 	    arg = heap[pdisp+narg]=list3(LVAR,new_lvar(size(t)),0);
+	    inline_lvars = glist2(arg,inline_lvars);
 	    //  should contain correct argument variable name
 	    if (anptr)
 		printf("## var %s\n",anptr->nm);
@@ -1082,12 +1099,26 @@
     if (retcont) error(STERR); // inline can't handle return/environment
 
     leave_scope();
+    while(inline_lvars) {
+	int e;
+	int l = car(inline_lvars);
+	switch(car(l)) {
+	case LVAR: free_lvar(cadr(l)); break;
+	case REGISTER: case DREGISTER: 
+	case FREGISTER: case LREGISTER: 
+	    free_register(cadr(l));
+	}
+	e = cadr(inline_lvars); 
+	free_glist2(inline_lvars);
+	inline_lvars = e; 
+    }
     fnptr = sfnptr;
     retlabel = sretlabel;
     retcont = sretcont;
     cslabel = scslabel;
     ret_register = sret_register;
     ret_reg_mode = sret_reg_mode;
+    inline_lvars = sinline_lvars;
 
     return ret_type;
 }
--- a/mc-macro.c	Wed Dec 28 15:45:39 2005 +0900
+++ b/mc-macro.c	Wed Dec 28 21:21:57 2005 +0900
@@ -19,7 +19,7 @@
 static int macro_function(int macrop,char **pchptr,NMTBL *nptr,int history);
 static void local_define(char *macro,char *value);
 static int macro_eval(int macrop,char *body0,int history);
-static char * mappend(int lists,char **result);
+extern char * mappend(int lists,char **result);
 static int macro_processing();
 
 static void
@@ -788,7 +788,7 @@
     result overwrited by next cheap allocation
  */
 
-static char *
+extern char *
 mappend(int lists,char **result)
 {
     char *p;
--- a/mc-macro.h	Wed Dec 28 15:45:39 2005 +0900
+++ b/mc-macro.h	Wed Dec 28 21:21:57 2005 +0900
@@ -6,5 +6,6 @@
 extern void getline(void);
 extern void macro_define(char *macro);
 extern char *chinput;
+extern char *mappend(int lists,char **result);
 
 extern int in_macro_if;
--- a/mc-parse.c	Wed Dec 28 15:45:39 2005 +0900
+++ b/mc-parse.c	Wed Dec 28 21:21:57 2005 +0900
@@ -773,7 +773,7 @@
     } else {
 	conv->return_type_(type,n,sd);
 	n = def(n,ctmode);
-	if (inmode) {
+	if (inmode && mode==LDECL) {
 	    parse = list4(ST_DECL,parse,(int)n,stmode);
 	}
 	if (sym==ASS && n!=&null_nptr) { 
@@ -2649,6 +2649,8 @@
 	} while(sym==COMMA);
     }
     checksym(RPAR);
+    input = reverse0(input);
+    out = reverse0(out);
     if (inmode) {
 	parse = list4(ST_ASM,parse,list4(asm0,input,out,opt),e1);
     } else {
@@ -3787,28 +3789,43 @@
 {
     char *name = cheap->ptr;
     int i= 0;
+    int str=0;
     unsigned int hash = 0;
     struct cheap scheap;
 
-    save_cheap(&scheap,cheap);
-    while (ch == '"') {
-	in_quote = 1;
-	getch();
-	while (ch != '"') {
-	    if (i>STRSIZE) error(STRERR);
-	    hash_value(hash, *cheap->ptr = escape());
-	    cheap = increment_cheap(cheap,&name);
-	    i++;
+    do {
+	save_cheap(&scheap,cheap);
+	while (ch == '"') {
+	    in_quote = 1;
+	    getch();
+	    while (ch != '"') {
+		if (i>STRSIZE) error(STRERR);
+		hash_value(hash, *cheap->ptr = escape());
+		cheap = increment_cheap(cheap,&name);
+		i++;
+	    }
+	    in_quote = 0;
+	    getch();
+	    //   skipspc is not allowed, becase it interfered with ST_COMMENT
+	    //   skipspc();  // "aaa" "bbb" case
 	}
 	in_quote = 0;
-	getch();
-	skipspc();  // "aaa" "bbb" case
+	*cheap->ptr = 0;
+	cheap = increment_cheap(cheap,&name);
+	i++;
+	nptr = name_space_search(hash_search(name,&scheap,i,hash,DEF),STRING);
+	// if we can reclaim space if we already have this
+	skipspc();
+	if (ch=='"') {
+	    str = list2((int)nptr->nm,str);
+	}
+    } while (ch=='"'); 
+    if (str) {
+	save_cheap(&scheap,cheap);
+	mappend(str,&name);
+	for(i=0;name[i];i++);
+	nptr = name_space_search(hash_search(name,&scheap,i,hash,DEF),STRING);
     }
-    in_quote = 0;
-    *cheap->ptr = 0;
-    cheap = increment_cheap(cheap,&name);
-    i++;
-    nptr = name_space_search(hash_search(name,&scheap,i,hash,DEF),STRING);
     symval = i;
 }