changeset 715:83e18db76c96

architecture depenedent argument alignment
author kono
date Wed, 14 Nov 2007 19:36:55 +0900
parents 5fad4649bed8
children 21f770a3b298
files Changes mc-code-arm.c mc-code-ia32.c mc-code-mips.c mc-code-powerpc.c mc-code-spu.c mc-code.h mc-codegen.c mc-codegen.h mc-inline.c mc-parse.c
diffstat 11 files changed, 263 insertions(+), 175 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Sun Nov 11 20:11:35 2007 +0900
+++ b/Changes	Wed Nov 14 19:36:55 2007 +0900
@@ -9655,8 +9655,45 @@
 
 switch 文が const で inline された時の処理が間違っているようだ....
 
-
-
-
-
-
+Sun Nov 11 22:24:59 JST 2007
+
+cslist がなんだか思い出せないが、直りました。
+
+Wed Nov 14 13:03:42 JST 2007
+
+で、SPU だけど.... cross compiler と binutil いれるか...
+
+128 のレジスタを三つ持つのもなんなので、そのまま。ということは、
+use_int とかは必要ない?  is_int_reg とかは、必要ないわけね。
+じゃぁ、このままいくか...
+
+SPU のほとんどの演算は vector 演算なのか。このコンパイラって、
+そういう新しいデータを構造を増やすのに向いてないんだよね。
+
+    8bit, 16bit, 32bit, 32bit x 4
+
+かぁ。vector type を足すんだろうなぁ。vector_add とかはださいが...
+
+あぁ、そうか。関数呼び出しでも16byte単位でスタックに積むわけね。
+printf は、どうしようもなく stack に積むらしい。
+
+byte を書き込むってことは出来ないらしい。ふーむ。
+
+これは、local/global memoryを使うこと自体、禁止という感じのようですね。
+
+まぁ、とりあえず動かすことを考えて、vector 型とかは、あとで導入しよう。
+
+Wed Nov 14 18:42:42 JST 2007
+
+PS3 powerpc が動かなくなってるよ。
+
+argment/local variable の alignment は、当然、system 依存か...
+
+size_of_int と size_of_pointer を区別しないと...
+
+parallel assign でレジスタをsaveしているけど、size_of_int だと
+足りない。なので、get_register_var に変えるべきでしょう。
+(もったいないけどね)
+
+target のsize_of_int と compiler の size_of_int も別にしないと。
+なるほど。
--- a/mc-code-arm.c	Sun Nov 11 20:11:35 2007 +0900
+++ b/mc-code-arm.c	Wed Nov 14 19:36:55 2007 +0900
@@ -563,6 +563,7 @@
     int reg;
     /* called only once */
 
+    size_of_pointer = SIZE_OF_INT;
     size_of_int = SIZE_OF_INT;
     size_of_short = SIZE_OF_SHORT;
     size_of_float = SIZE_OF_FLOAT;
@@ -6549,4 +6550,18 @@
 
 #endif
 
+extern int 
+code_arg_alignment(int args,NMTBL *n, int type0,int sz)
+{
+    return code_arg_alignment0(args,n, type0,sz);
+}
+
+
+extern int 
+code_lvar_alignment(int args,NMTBL *n, int type0,int sz)
+{
+    return code_lvar_alignment0(args,n, type0,sz);
+}
+
+
 /* end */
--- a/mc-code-ia32.c	Sun Nov 11 20:11:35 2007 +0900
+++ b/mc-code-ia32.c	Wed Nov 14 19:36:55 2007 +0900
@@ -666,6 +666,7 @@
 
     init_src = init_src0;
     size_of_int = SIZE_OF_INT;
+    size_of_pointer = SIZE_OF_INT;
     size_of_short = SIZE_OF_SHORT;
     size_of_float = SIZE_OF_FLOAT;
     size_of_double = SIZE_OF_DOUBLE;
@@ -4800,4 +4801,18 @@
     return 0;
 }
 
+extern int 
+code_arg_alignment(int args,NMTBL *n, int type0,int sz)
+{
+    return code_arg_alignment0(args,n, type0,sz);
+}
+
+
+extern int 
+code_lvar_alignment(int args,NMTBL *n, int type0,int sz)
+{
+    return code_lvar_alignment0(args,n, type0,sz);
+}
+
+
 /* end */
--- a/mc-code-mips.c	Sun Nov 11 20:11:35 2007 +0900
+++ b/mc-code-mips.c	Wed Nov 14 19:36:55 2007 +0900
@@ -520,6 +520,7 @@
     /* called only once */
 
     size_of_int = SIZE_OF_INT;
+    size_of_pointer = SIZE_OF_INT;
     size_of_short = SIZE_OF_SHORT;
     size_of_float = SIZE_OF_FLOAT;
     size_of_double = SIZE_OF_DOUBLE;
@@ -5870,4 +5871,18 @@
 
 #endif
 
+extern int 
+code_arg_alignment(int args,NMTBL *n, int type0,int sz)
+{
+    return code_arg_alignment0(args,n, type0,sz);
+}
+
+
+extern int 
+code_lvar_alignment(int args,NMTBL *n, int type0,int sz)
+{
+    return code_lvar_alignment0(args,n, type0,sz);
+}
+
+
 /* end */
--- a/mc-code-powerpc.c	Sun Nov 11 20:11:35 2007 +0900
+++ b/mc-code-powerpc.c	Wed Nov 14 19:36:55 2007 +0900
@@ -736,6 +736,7 @@
 
     init_src = init_src0;
     size_of_int = SIZE_OF_INT;
+    size_of_pointer = SIZE_OF_INT;
     size_of_short = SIZE_OF_SHORT;
     size_of_float = SIZE_OF_FLOAT;
     size_of_double = SIZE_OF_DOUBLE;
@@ -2261,6 +2262,12 @@
 
 #define caller_arg_offset_v(arg) (ARG_LVAR_OFFSET+(arg)*SIZE_OF_INT)
 
+/*
+     use input register as current register
+        なんで、こんなに複雑なんだ?
+	むしろ、INPUT_REG みたいな mark をいれたら?
+ */
+
 static void
 use_input_reg(int reg,int mode)
 {
@@ -2270,6 +2277,7 @@
 	    ireg = 0;
 	} 
 	if (lreg) {
+	    // free_regsiter(lreg) でいいんじゃないの?
 	    if (regv_l(lreg)==reg) {
 		regs[lreg]=0;
 		if (regv_h(lreg)>reg&&regs[regv_h(lreg)]==USING_REG) {
@@ -6724,4 +6732,18 @@
 
 #endif
 
+extern int 
+code_arg_alignment(int args,NMTBL *n, int type0,int sz)
+{
+    return code_arg_alignment0(args,n, type0,sz);
+}
+
+
+extern int 
+code_lvar_alignment(int args,NMTBL *n, int type0,int sz)
+{
+    return code_lvar_alignment0(args,n, type0,sz);
+}
+
+
 /* end */
--- a/mc-code-spu.c	Sun Nov 11 20:11:35 2007 +0900
+++ b/mc-code-spu.c	Wed Nov 14 19:36:55 2007 +0900
@@ -107,9 +107,6 @@
 static int arg_on_register = 0;
 static int max_func_arg_label = 0;
 
-
-static int freg,ireg,lreg;
-
 int code_lassop_p = 4;
 
 #define SIZE_OF_INT  4
@@ -117,6 +114,7 @@
 #define SIZE_OF_FLOAT  4
 #define SIZE_OF_DOUBLE  8
 #define SIZE_OF_LONGLONG  8
+#define SIZE_OF_VECTOR  16
 #define ENDIAN  0
 #define ENDIAN_L  0
 #define ENDIAN_D  1
@@ -172,30 +170,16 @@
 #define RET_LREGISTER 3
 #define LREGISTER_OPERAND 3 
 #define LREGISTER_OPERAND_1 4 
-#define RET_LREGISTER_L 1    /* low word */
-#define RET_LREGISTER_H 2    /* high word */
-#define LREGISTER_OPERAND_L  1    /* low word */
-#define LREGISTER_OPERAND_H  2    /* high word */
-#define LREGISTER_OPERAND_1_L  3    /* low word */
-#define LREGISTER_OPERAND_1_H  4    /* high word */
 
 #define RET_DREGISTER RET_LREGISTER 
 #define DREGISTER_OPERAND LREGISTER_OPERAND
 #define DREGISTER_OPERAND_1 LREGISTER_OPERAND_1
-#define RET_DREGISTER_L RET_LREGISTER_L
-#define RET_DREGISTER_H RET_LREGISTER_H
-#define DREGISTER_OPERAND_H  LREGISTER_OPERAND_H  
 #define DREGISTER_OPERAND_L  LREGISTER_OPERAND_L  
-#define DREGISTER_OPERAND_1_L  LREGISTER_OPERAND_1_L  
-#define DREGISTER_OPERAND_1_H  LREGISTER_OPERAND_1_H  
 
 static int *regs  = spu_regs;
 
-// #define CREG_REGISTER  (MAX_TMP_REG)
 #define CREG_REGISTER  REGISTER_OPERAND
-// #define FREG_FREGISTER (MAX_TMP_FREG+FREG_OFFSET)
 #define FREG_FREGISTER FREGISTER_OPERAND
-// #define LREG_LREGISTER (MAX_TMP_REG+LREG_OFFSET)
 #define LREG_LREGISTER LREGISTER_OPERAND
 #define DREG_DREGISTER LREG_LREGISTER
 #define CMP_C1T (-1)
@@ -224,83 +208,16 @@
 };
 
 #define register_name(i)  reg_name[i]
-#define lregister_name_low(i) reg_name[i]
-#define lregister_name_high(i) reg_name[i]
 
 char *rn(int i) { return register_name(i); }
-char *lln(int i) { return lregister_name_low(i); }
-char *lhn(int i) { return lregister_name_high(i); }
-int ll(int i) { return i; }
-int lh(int i) { return i; }
-
-#define is_int_reg(i)  (0<=i&&i<REAL_MAX_REGISTER)
-#define is_float_reg(i)  (is_int_reg(i))
-#define is_longlong_reg(i) (is_int_reg(i)) 
-#define is_double_reg(i) (is_int_reg(i)) 
-
-#define  use_int(reg) if (reg==USE_CREG) reg=use_int0()
-static
-int use_int0() { 
-    int i = creg;
-    if (!i||!ireg||!is_int_reg(i)) {
-	if (lreg) { if (regs[lreg]) free_register(lreg); lreg = 0; }
-	if (!ireg) ireg = get_register();
-	// else if (ireg!=i) free_register(i);
-	i = ireg;
-    }
-    if (!regs[i]) regs[i]=USING_REG;
-    creg = i;
-    return i;
-}
-
-#if LONGLONG_CODE||FLOAT_CODE
-#define  use_longlong(reg) if (reg==USE_CREG) reg=use_int0()
-/*
-static
-int use_longlong0() {
-    int i = creg;
-    if (!is_longlong_reg(i)) {
-	if (ireg) { free_register(ireg); ireg=0; }
-	if (!lreg||!regs[lreg]) lreg = get_lregister();
-	 else if (lreg!=i) free_register(i);
-	i = lreg;
-    }
-    if (!(i)) (i) = get_register();
-    if (!(i)) (i) = get_register();
-    if (!regs[i]) regs[i]=USING_REG;
-    if (!regs[(i)]) regs[(i)]=USING_REG;
-    if (!regs[(i)]) regs[(i)]=USING_REG;
-    creg = i;
-    return i;
-}
-*/
-static void lmove(int to,int from);
-#endif
+
+// input register mark
 
 #define USING_DREG 5
 #define INPUT_DREG 6
 
-
 #if FLOAT_CODE
 
-#define dsuffix(d) (d?'d':'s')
-
-#define  use_float(d,reg) if (reg==USE_CREG) { reg=use_int0();}
-
-/*
-static
-int use_double0() { 
-    int i;
-    use_longlong0();
-    use_int0();
-	i = lreg;
-    if (!regs[i]) regs[i]=USING_DREG;
-    if (!regs[(i)]) regs[(i)]=USING_REG;
-    if (!regs[(i)]) regs[(i)]=USING_REG;
-    creg = i;
-    return i;
-}
-*/
 void code_lassign_lvar(int e2,int creg);
 int code_lrindirect(int e1, int reg, int offset, int us);
 void code_lregister(int e2,int reg);
@@ -323,22 +240,12 @@
 #endif
 
 static void code_save_input_registers(int dots);
-static void    set_ireg(int,int);
-#if FLOAT_CODE
-static void    set_dreg(int,int);
-static void    set_freg(int,int);
-#endif
-#if LONGLONG_CODE
-static void    set_lreg(int,int);
-#endif
+static void    set_creg(int,int);
 
 static int max_func_args;
 static int my_func_args;
 
 
-
-
-
 static void jcond(int l, int cond);
 
 #define ARG_LVAR_OFFSET 0x10000000
@@ -420,12 +327,6 @@
         max_func_arg_label = 0;
     }
 
-
-// printf("        @ args = %d, pretend = %d, frame = %d\n",
-// 	max_func_args,0,round16(-disp));
-// printf("        @ frame_needed = 1, current_function_anonymous_args = 0\n");
-
-
 #if 0
 printf("## vars= %d, regs= %d/%d, args= %d, extra= %d\n",
 	round16(-disp),
@@ -484,27 +385,23 @@
 lvar(int l,char *cext)
 {
     if (large_lvar) {
-	//printf("[%s, 0]%s\n##lvar0\n",register_name(large_lvar),cext);
 	printf("0(%s)\n##lvar0\n",register_name(large_lvar));
 	free_register(large_lvar);
 	return;
     }
     if (is_code(fnptr)) {
         if (l>=ARG_LVAR_OFFSET) {  /* caller's arguments */
-            //printf("[sp, %d]%s\n##lvar1\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET),cext);
             printf("%d($sp)\n##lvar1\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET));
-        //} else
-         //   printf("[fp, %d]%s\n",CODE_LVAR(l),cext);
-   			printf("%d($sp)\n",CODE_LVAR(l));
-		}
+	} else {
+	    printf("%d($sp)\n",CODE_LVAR(l));
+	}
    } else if (l<0) {  /* local variable */
-        //printf("[fp, #%d+.L%d]%s\n##lvar2\n",FUNC_LVAR(l),lvar_offset_label,cext);
         printf(".LC%d+%d($sp)\n",lvar_offset_label,FUNC_LVAR(l));
     } else if (l>=ARG_LVAR_OFFSET) {  /* caller's arguments */
         printf("%d($sp)%s\n",CALLER_ARG(l-ARG_LVAR_OFFSET),cext);
     } else { /* callee's arguments */
         printf("%d($sp)%s\n",CALLEE_ARG(l),cext);
-	}
+    }
 }
 
 static void
@@ -548,6 +445,8 @@
     /* called only once */
 
     size_of_int = SIZE_OF_INT;
+    size_of_pointer = SIZE_OF_INT;
+    size_of_vector = SIZE_OF_VECTOR
     size_of_short = SIZE_OF_SHORT;
     size_of_float = SIZE_OF_FLOAT;
     size_of_double = SIZE_OF_DOUBLE;
@@ -1247,7 +1146,6 @@
 code_ptr_cache_def(int r, NMTBL *nptr)
 {
     //int label,disp;
-    int disp;
     char *rrn = register_name(r);
     //disp = search_const(GVAR,(int)nptr,&label);
     printf("\tlqd\t%s, %d($sp)\n",rrn,(nptr->sc)*16);
@@ -1461,7 +1359,7 @@
     } else {
 	//disp = search_const(CONST,offset,&label);
 	drn = register_name(dreg = get_register());
-	printf("\tlqd\t%s, %d($sp)\n",drn,(disp*4));
+	// printf("\tlqd\t%s, %d($sp)\n",drn,(disp*4));
 	printf("\ta\t%s, %s, %s\n",crn,drn,rrn);
 	free_register(dreg);
     }
@@ -1707,13 +1605,12 @@
 void
 code_return(int creg) {
     //int label,disp;
-    int disp;
     char *crn;
     use_int(creg);
     crn = register_name(creg);
 
     //disp = search_const(LABEL,retcont,&label);
-    printf("\tlqd\t%s, %d($sp)\n",crn,(disp*4));
+    // printf("\tlqd\t%s, %d($sp)\n",crn,(disp*4));
 }
 
 void
@@ -1729,7 +1626,7 @@
 	char *trn = register_name(REG_ip);
 	use_int(creg);
 	//disp = search_const(LVAR,glist2(lvar_offset_label,FUNC_LVAR(0)),&label);
-	printf("\tlqa\t%s, %d\n",trn,disp);
+	// printf("\tlqa\t%s, %d\n",trn,disp);
 	printf("\ta\t%s, $sp, %s\n",register_name(creg),trn);
     }
 }
@@ -2661,7 +2558,7 @@
     if (is_function(fnptr) && ! env) {
 	trn = register_name(REG_ip);
 	//disp = search_const(LVAR,glist2(lvar_offset_label,FUNC_LVAR(0)),&label);
-	printf("\tlqd\t%s, %d($sp)\n",trn,disp);
+	// printf("\tlqd\t%s, %d($sp)\n",trn,disp);
 	printf("\ta\t$sp, $sp, %s\n",trn);
     }
 }
@@ -2675,7 +2572,7 @@
 
     trn = register_name(REG_ip);
     //disp = search_const(LVAR,glist2(lvar_offset_label,FUNC_LVAR(0)),&label);
-    printf("\tlqd\t%s, %d($sp)\n",trn,disp);
+    // printf("\tlqd\t%s, %d($sp)\n",trn,disp);
     printf("\tsf\tfp, fp, %s\n",trn);
 }
 
@@ -3421,6 +3318,7 @@
 	return ireg;
 #endif
     } else if (cadr(fnptr->ty)==VOID) {
+	return ireg;
     } else {
 	set_ireg(RET_REGISTER,mode);
 	return ireg;
@@ -3911,7 +3809,7 @@
 	    printf("\tlqd\t%s, .LC%d+%d($sp)\n",frn,label,disp);
 	} else {
 	    //disp = search_const(CONST,*((int*)&f),&label);
-	    printf("\tlqd\t%s, .LC%d+%d($sp)\n",frn,label,disp);
+	    //printf("\tlqd\t%s, .LC%d+%d($sp)\n",frn,label,disp);
 	}
 }
 
@@ -5295,7 +5193,7 @@
 	} else if (car(e1)==STRING) {
 	    val = emit_string_label();
 	    ascii(ncaddr(e1)->nm);
-	    e1=list3(LABEL,val);
+	    e1=list2(LABEL,val);
 	} else if (car(e1)==CONST) {
 	} else error(-1);
 	repl = list3(e1,repl,clobber);
@@ -5831,4 +5729,52 @@
 
 #endif
 
+extern int
+code_arg_alignment(int args,NMTBL *n, int type0,int sz)
+{
+    if(type0==CHAR||type0==UCHAR) {
+        if (n->dsp==0) {
+            n->dsp = args;
+            if (endian) n->dsp += size_of_int-1;
+        }
+        args += size_of_int;
+    } else if(type0==SHORT||type0==USHORT) {
+        if (n->dsp==0) {
+            n->dsp = args;
+            if (endian) n->dsp += size_of_int-size_of_short;
+        }
+        args += size_of_int;
+    } else if(type0>0&&(car(type0)==UNION||car(type0)==STRUCT)) {
+        /* alignment in struct in argument */
+        /* should be GCD of member alignment */
+        /* __attribute(alignment(16)) is ignored in argments */
+        n->dsp = args;
+        args += ((sz+(size_of_int-1))&~(size_of_int-1));
+    } else {
+        /* if (n->dsp==0) (argument list in ADECL is useless, type
+           list can be found in type ) */
+        n->dsp = args;
+        args += sz;
+    }
+    return args;
+}
+
+extern int
+code_lvar_alignment(int disp0,NMTBL *n,int type0,int sz) {
+    int align;
+
+    /* local variable alignment is done by new_lvar */
+    if ((align=attr_value(n,ALIGNED))) {
+        if (car(align)!=CONST) error(-1);
+        n->sc = LVAR;
+        n->dsp = new_lvar_align(sz,caddr(align));
+    } else {
+        n->sc = LVAR;
+        n->dsp = new_lvar(sz);
+    }
+    return disp;
+}
+
+
+
 /* end */
--- a/mc-code.h	Sun Nov 11 20:11:35 2007 +0900
+++ b/mc-code.h	Wed Nov 14 19:36:55 2007 +0900
@@ -88,6 +88,8 @@
 extern void jmp(int l);
 extern int not_simple_p(int l);
 extern void code_save_stacks();
+extern int code_arg_alignment(int disp0,NMTBL *n,int type0,int sz);
+extern int code_lvar_alignment(int disp0,NMTBL *n,int type0,int sz);
 
 extern int get_register_var(NMTBL *n);
 extern int get_dregister_var(NMTBL *n,int d);
--- a/mc-codegen.c	Sun Nov 11 20:11:35 2007 +0900
+++ b/mc-codegen.c	Wed Nov 14 19:36:55 2007 +0900
@@ -35,6 +35,7 @@
 
 int use;       /* generated value will be used */
 char *init_src;
+int size_of_pointer;
 int size_of_int;
 int size_of_short;
 int size_of_float;
@@ -969,6 +970,9 @@
 // parallel assignment of registers.
 //
 //  target = list3(target_regnum,next,source_regnum);
+//
+//  register の大きさはsize_of_int とは限らない。むしろ、
+//  get_register_var した方が安全...
 
 extern void
 parallel_rassign(int assigns)
@@ -3373,7 +3377,7 @@
 	if(type0>0) {
 	    if (!integral(type0) && (car(type0)==FUNCTION||car(type0)==CODE)) {
 		type=list2(POINTER,type); n->ty = type;
-		sz = size_of_int;
+		sz = size_of_int;  // should be size_of_pointer
 		type0=type;
 	    } else if (car(type0)==ARRAY) {
 		type=list2(POINTER,cadr(type)); n->ty = type;
@@ -3386,32 +3390,10 @@
 	if(inmode==INLINE) {
 	    n->dsp = args++;
 	    n->sc = IVAR;
-	} else if(type0==CHAR||type0==UCHAR) {
-	    if (n->dsp==0) {
-		n->dsp = args;
-		if (endian) n->dsp += size_of_int-1;
-	    }
-	    args += size_of_int;
-	} else if(type0==SHORT||type0==USHORT) {
-	    if (n->dsp==0) {
-		n->dsp = args;
-		if (endian) n->dsp += size_of_int-size_of_short;
-	    }
-	    args += size_of_int;
-#if  1
-	} else if(type0>0&&(car(type0)==UNION||car(type0)==STRUCT)) {
-	    /* alignment in struct in argument */
-	    /* should be GCD of member alignment */
-	    /* __attribute(alignment(16)) is ignored in argments */
-	    n->dsp = args;
-	    args += ((sz+(size_of_int-1))&~(size_of_int-1));
-#endif
 	} else {
-	    /* if (n->dsp==0) (argument list in ADECL is useless, type
-               list can be found in type ) */
-	    n->dsp = args;
-	    args += sz;
+	    args = code_arg_alignment(args,n,type0,sz);
 	}
+
 	caddr(fnptr->dsp)=sz;
 	if(type0==VOID) {
 	} else {
@@ -3443,15 +3425,9 @@
 	    nsc = IVAR;
 	    ndsp = --disp;
 	} else {
-	    /* local variable alignment is done by new_lvar */
-	    if ((align=attr_value(n,ALIGNED))) {
-		if (car(align)!=CONST) error(-1);
-		nsc = LVAR;
-		ndsp = new_lvar_align(sz,caddr(align));
-	    } else {
-		nsc = LVAR;
-		ndsp = new_lvar(sz);
-	    }
+	    code_lvar_alignment(disp,n,type0,sz);
+	    set_ctmode(n,ctmode);
+	    return n;
 	}
 	n->sc = nsc;
 	n->dsp = ndsp;
@@ -3469,6 +3445,59 @@
     return n;
 }
 
+extern int
+code_arg_alignment0(int args,NMTBL *n, int type0,int sz)
+{
+    if(type0==CHAR||type0==UCHAR) {
+        if (n->dsp==0) {
+            n->dsp = args;
+            if (endian) n->dsp += size_of_int-1;
+        }
+        args += size_of_int;
+    } else if(type0==SHORT||type0==USHORT) {
+        if (n->dsp==0) {
+            n->dsp = args;
+            if (endian) n->dsp += size_of_int-size_of_short;
+        }
+        args += size_of_int;
+    } else if(type0>0&&(car(type0)==UNION||car(type0)==STRUCT)) {
+        /* alignment in struct in argument */
+        /* should be GCD of member alignment */
+        /* __attribute(alignment(16)) is ignored in argments */
+        n->dsp = args;
+        args += ((sz+(size_of_int-1))&~(size_of_int-1));
+    } else {
+        /* if (n->dsp==0) (argument list in ADECL is useless, type
+           list can be found in type ) */
+        n->dsp = args;
+        args += sz; 
+    }
+    return args;
+}
+
+extern int
+code_lvar_alignment0(int disp0,NMTBL *n,int type0,int sz) {
+    int align;
+
+    /* local variable alignment is done by new_lvar */
+    if ((align=attr_value(n,ALIGNED))) {
+	if (car(align)!=CONST) error(-1);
+	n->sc = LVAR;
+	n->dsp = new_lvar_align(sz,caddr(align));
+    } else {
+	n->sc = LVAR;
+	n->dsp = new_lvar(sz);
+    }
+    return disp;
+}
+
+// for mc-parse.c
+extern int
+arg_alignment0(int args,NMTBL *n, int type0,int sz)
+{
+    return code_arg_alignment(args,n, type0,sz);
+}
+
 extern char *
 nm(NMTBL *n) {
     int e;
--- a/mc-codegen.h	Sun Nov 11 20:11:35 2007 +0900
+++ b/mc-codegen.h	Wed Nov 14 19:36:55 2007 +0900
@@ -26,6 +26,7 @@
 
 /* these architecture dependent values are defined in mc-code-*.c */
 
+extern int size_of_pointer;
 extern int size_of_int;
 extern int size_of_short;
 extern int size_of_float;
@@ -99,6 +100,7 @@
 extern void gen_label_call(int l);
 extern void flush_delayed_decl_data(int v);
 extern void jump(int e,int env);
+extern int arg_alignment(int disp0,NMTBL *n,int type0,int sz);
 
 
 /* used by mc-inline */
@@ -137,6 +139,10 @@
 extern void clear_ptr_cache() ;
 extern int get_ptr_cache(NMTBL *nptr);
 
+// standard 32bit alignment
+extern int code_arg_alignment0(int disp0,NMTBL *n,int type0,int sz);
+extern int code_lvar_alignment0(int disp0,NMTBL *n,int type0,int sz);
+
 extern int ilog(int i);
 
 extern char * nm(NMTBL *n) ;
--- a/mc-inline.c	Sun Nov 11 20:11:35 2007 +0900
+++ b/mc-inline.c	Wed Nov 14 19:36:55 2007 +0900
@@ -227,7 +227,10 @@
 	genswitch(cslist,cslabel);
     } else if (!cslist) {
 	if(dlabel) df_label(cslabel,dlabel);
-	else fwddef(cslabel);
+	else {
+	    fwddef(cslabel);
+	}
+	cslist= 1;
     }
 #else
     if (!(cst && cslist)) {
--- a/mc-parse.c	Sun Nov 11 20:11:35 2007 +0900
+++ b/mc-parse.c	Wed Nov 14 19:36:55 2007 +0900
@@ -1446,11 +1446,11 @@
     case ARRAY:
 	return(size(cadr(t))*caddr(t));
     case CODE:
-	return size_of_int;
+	return size_of_pointer;
     case FUNCTION:
-	return size_of_int;
+	return size_of_pointer;
     case POINTER:
-	return size_of_int;
+	return size_of_pointer;
     default:
 	error(DCERR);
     }
@@ -2239,12 +2239,7 @@
 
 	t = type_value(n1->ty);
 	sz = size(t);
-
-	n1->dsp = offset;
-	offset+= (scalar(t))?size_of_int:
-	         (t>0&&(car(t)==UNION||car(t)==STRUCT))?
-		    ((sz+(size_of_int-1))&~(size_of_int-1)):
-		    sz;
+	offset = code_arg_alignment(offset,n1,t,sz);
 
 	nargs=list4n(car(arg),nargs,caddr(arg),n1);
     }
@@ -2942,6 +2937,9 @@
 {
 #if CASE_CODE
     int l=0,clist=0,c,cst = (csvalue1 && car(csvalue1)==CONST);
+
+    // if (cst) clist means there is a matching constant
+
     if (!inmode && !cst)
 	l = fwdlabel();
     while(sym==CASE) {
@@ -3659,7 +3657,7 @@
 	}
 	if(car(type)!=POINTER)
 	    error(TYERR);
-	return(list4(UPREINC,e,dir*size(cadr(type)),size_of_int ));
+	return(list4(UPREINC,e,dir*size(cadr(type)),size_of_pointer ));
     case MUL: /* *p */
 	conv->prefix_(sym);
 	getsym(0);
@@ -3938,7 +3936,7 @@
 	if(car(type)!=POINTER)
 	    error(TYERR);
 	return(list4(UPOSTINC,e,
-	    op==INC?size(cadr(type)):-size(cadr(type)),size_of_int ));
+	    op==INC?size(cadr(type)):-size(cadr(type)),size_of_pointer ));
     }
     return e;
 }
@@ -5400,7 +5398,7 @@
 {
     int e;
 
-    e=getfree((size_of_int+size_of_longlong)/size_of_int);
+    e=getfree((sizeof(int)+size_of_longlong)/sizeof(int));
     heap[e]=e1;
     lcadr(e)=d1;
     return e;
@@ -5411,7 +5409,7 @@
 {
     int e;
 
-    e=getfree((size_of_int+size_of_longlong)/size_of_int);
+    e=getfree((sizeof(int)+size_of_longlong)/sizeof(int));
     heap[e]=e1;
     heap[e+1]=e2;
     lcaddr(e)=d1;
@@ -5427,7 +5425,7 @@
 {
     int e;
 
-    e=getfree((size_of_int+size_of_double)/size_of_int);
+    e=getfree((sizeof(int)+sizeof(double))/sizeof(int));
     heap[e]=e1;
     dcadr(e)=d1;
     return e;
@@ -5438,7 +5436,7 @@
 {
     int e;
 
-    e=getfree((size_of_int*2+size_of_double)/size_of_int);
+    e=getfree((sizeof(int)*2+sizeof(double))/sizeof(int));
     heap[e]=e1;
     heap[e+1]=e2;
     dcaddr(e)=d1;