changeset 673:442e90958386 ppc-almost-done

PS3 PPc almot done...
author kono
date Sat, 05 May 2007 08:10:56 +0900
parents 3f559c67bc86
children 68d70527b0c0
files mc-code-powerpc.c mc-macro.c mc-parse.c mc.h test/putenemy.c test/stackframe.c
diffstat 6 files changed, 311 insertions(+), 187 deletions(-) [+]
line wrap: on
line diff
--- a/mc-code-powerpc.c	Sat May 05 03:39:29 2007 +0900
+++ b/mc-code-powerpc.c	Sat May 05 08:10:56 2007 +0900
@@ -57,9 +57,13 @@
 #define __extension__\n\
 #define __const const\n\
 #define __inline__ inline\n\
-#define __builtin_va_list int\n\
-#define __builtin_va_start(ap,arg) ap=(((int)(&arg))+sizeof(arg))\n\
-#define __builtin_va_arg(ap,type)  (*((type *)ap)++)\n\
+#define __builtin_va_list struct __vv {int *p; double *d;}\n\
+#define __builtin_va_start(ap,arg) (ap.p=(((int)(&arg))+sizeof(arg)),\
+                                   (ap.d=(double*)(ap.p+7)))\n\
+#define __builtin_va_arg(ap,type)  \
+           ((!__builtin_type_is_float(type))?\
+		(*((type *)ap.p)++):\
+		((type)(*(ap.d++))))\n\
 #define alloca __builtin_alloca\n\
 #define __DBL_MIN_EXP__ (-1021)\n\
 #define __FLT_MIN__ 1.17549435e-38F\n\
@@ -686,29 +690,29 @@
         if (l>=ARG_LVAR_OFFSET) {  /* caller's arguments */
             if (LARGE_OFFSET(CODE_CALLER_ARG(l-ARG_LVAR_OFFSET))) {
                 rn=register_name(large_offset_reg=get_register());
-                printf("\tla %s,1,%d@ha\n",rn,
+                printf("\taddis %s,1,%d@ha\n",rn,
 		    CODE_CALLER_ARG(l-ARG_LVAR_OFFSET));
             }
         } else {
             if (LARGE_OFFSET(CODE_LVAR(l))) {
                 rn=register_name(large_offset_reg=get_register());
-                printf("\tla %s,%d,%d@ha\n",rn,REG_fp,CODE_LVAR(l));
+                printf("\taddis %s,%d,%d@ha\n",rn,REG_fp,CODE_LVAR(l));
             }
         }
     } else if (l<0) {  /* local variable */
         if (LARGE_OFFSET(FUNC_LVAR(l))) {
             rn=register_name(large_offset_reg=get_register());
-            printf("\tla %s,%d,%d@ha\n",rn,REG_fp,FUNC_LVAR(l));
+            printf("\taddis %s,%d,%d@ha\n",rn,REG_fp,FUNC_LVAR(l));
         }
     } else if (l>=ARG_LVAR_OFFSET) {  /* caller's arguments */
         if (LARGE_OFFSET(CALLER_ARG(l-ARG_LVAR_OFFSET))) {
             rn=register_name(large_offset_reg=get_register());
-            printf("\tla %s,1,%d@ha\n",rn,CALLER_ARG(l-ARG_LVAR_OFFSET));
+            printf("\taddis %s,1,%d@ha\n",rn,CALLER_ARG(l-ARG_LVAR_OFFSET));
         }
     } else { /* callee's arguments */
         if (LARGE_OFFSET(CALLEE_ARG(l))) {
             rn=register_name(large_offset_reg=get_register());
-            printf("\tla %s,%d,%d+%s%d@ha\n",
+            printf("\taddis %s,%d,%d+%s%d@ha\n",
                 rn,REG_fp,CALLEE_ARG(l),lpfx,lvar_offset_label);
         }
     }
@@ -824,6 +828,11 @@
     if (is_function(fnptr)) {
 	code_save_input_registers(dots);
 #ifndef __APPLE__
+	if (dots) {
+		arg_offset_v =
+		    (MAX_TMP_REG -MIN_TMP_REG )*SIZE_OF_INT +
+		    (MAX_TMP_FREG +MIN_TMP_FREG)*SIZE_OF_DOUBLE;
+	}
 	printf(".set %s%d, %d\n",lpfx, arg_offset_label,arg_offset_v);
 #endif
     }
@@ -1096,8 +1105,8 @@
 	    i = REG_VAR_BASE-i;
 	} else {
 	    if (i<0||i>=MAX_INPUT_REGISTER_VAR) return 0;
+            if (i%2==1) i++;
 	    i = i+MIN_TMP_REG;
-            if (i%2==1) i++;
 	}
 	ll = get_lregister1(i,i+1);
 #if ENDIAN_L==0
@@ -1813,7 +1822,9 @@
 inc_cmpflag()
 {
     //  gcc use cmpflag 4 and 7, and gcc4 believes flag 4 is preserved.
-    // cmpflag = (cmpflag+1)%8;
+    do {
+	cmpflag = (cmpflag+1)%8;
+    } while (cmpflag!=4 && cmpflag!=7);
 }
 
 #ifdef __APPLE__
@@ -2203,6 +2214,18 @@
 	    offset+=SIZE_OF_INT;
 	    reg_var++;
 	}
+#ifndef __APPLE__
+	int skip = fwdlabel();
+	int freg_var = 0;
+	printf("\tbne 1,%s%d\n",lpfx,skip);
+	while ((reg = get_input_dregister_var(freg_var,0,0,1))) {
+	    g_expr_u(assign_expr0(
+		list3(LVAR,offset,0),reg,DOUBLE,DOUBLE));
+	    offset+=SIZE_OF_DOUBLE;
+	    freg_var++;
+	}
+	fwddef(skip);
+#endif
     }
     my_func_args = offset;
 }
@@ -2615,10 +2638,13 @@
     }
     clear_ptr_cache();
 #ifndef __APPLE__
-    if (dots && freg_arg) {
+    if (dots) {
+	if (freg_arg) {
 	//  variadic function has floating value in register
-	printf("\tcreqv 6,6,6\n");
-	//  printf("\tcrxor 6,6,6\n"); for value in stack 
+	    printf("\tcreqv 6,6,6\n");
+	} else {
+	//    printf("\tcrxor 6,6,6\n"); // for value in stack 
+	}
     }
 #endif
     if (car(e2) == FNAME) {	
@@ -4351,18 +4377,13 @@
 ".text",
 "        .align 2",
 "i2d_:",
-"        mflr 0",
-"        bcl 20,31,__i2dL1$pb",
-"__i2dL1$pb:",
-"        mflr 10",
-"        mtlr 0",
 "        xoris 3,3,0x8000",
 "        stw 3,-28(1)",
 "        lis 0,0x4330",
 "        stw 0,-32(1)",
 "        lfd 0,-32(1)",
-"        addis 9,10,__i2dLC0-__i2dL1$pb@ha",
-"        lfd 1,__i2dLC0-__i2dL1$pb@l(9)",
+"        lis 9,__i2dLC0@ha",
+"        lfd 1,__i2dLC0@l(9)",
 "        fsub 1,0,1",
 "        blr",
 0
@@ -4426,13 +4447,8 @@
 ".text",
 "        .align 2",
 "d2u_:",
-"        mflr 0",
-"        bcl 20,31,__d2uL1$pb",
-"__d2uL1$pb:",
-"        mflr 10",
-"        mtlr 0",
-"        addis 9,10,__d2uLC0-__d2uL1$pb@ha",
-"        lfd 0,__d2uLC0-__d2uL1$pb@l(9)",
+"        lis 9,__d2uLC0@ha",
+"        lfd 0,__d2uLC0@l(9)",
 "        fcmpu 0,1,0",
 "        cror 2,1,2",
 "        beq- 0,__d2uL2",
@@ -4441,8 +4457,8 @@
 "        lwz 3,-28(1)",
 "        blr",
 "__d2uL2:",
-"        addis 9,10,__d2uLC0-__d2uL1$pb@ha",
-"        lfd 0,__d2uLC0-__d2uL1$pb@l(9)",
+"        lis 9,__d2uLC0@ha",
+"        lfd 0,__d2uLC0@l(9)",
 "        fsub 0,1,0",
 "        fctiwz 0,0",
 "        stfd 0,-24(1)",
@@ -4501,7 +4517,14 @@
 "        .long   0",
 ".text",
 "        .align 2",
-"u2d_:",
+".u2d_:",
+"        stw 3,-28(1)",
+"        lis 0,0x4330",
+"        stw 0,-32(1)",
+"        lfd 0,-32(1)",
+"        lis 9,__u2dLC1@ha",
+"        lfd 1,__u2dLC1@l(9)",
+"        fsub 1,0,1",
 "        blr",
 0
 };
@@ -4514,7 +4537,11 @@
     clear_ptr_cache();
     u2d_lib_used = 1;
     set_ireg(RET_REGISTER,1);
+#ifdef __APPLE__
     printf("\tbl u2d_\n");
+#else
+    printf("\tbl .u2d_\n");
+#endif
     set_freg(RET_FREGISTER,0);
 }
 
@@ -5203,25 +5230,25 @@
 ".lsrd__:",
 "       mr.     5,5",
 "       beqlr",
-"       subfic  2,5,32",
+"       subfic  8,5,32",
 "      stw     3,-32(1)",
 "      stw     4,-28(1)",
-"      cmpwi   7,2,0",
+"      cmpwi   7,8,0",
 "      bgt+    7,.L__lsrd1",
 "      neg     0,2",
-"      lwz     2,-32(1)",
+"      lwz     8,-32(1)",
 "      li      9,0",
-"      srw     2,2,0",
+"      srw     8,8,0",
 "      stw     9,-48(1)",
 "      b       .L__lsrd2",
 ".L__lsrd1:      lwz     0,-32(1)",
-"      slw     9,0,2",
-"      lwz     2,-28(1)",
+"      slw     9,0,8",
+"      lwz     8,-28(1)",
 "      srw     0,0,5",
-"      srw     2,2,5",
+"      srw     8,8,5",
 "      stw     0,-48(1)",
-"      or      2,2,9",
-".L__lsrd2:      stw     2,-44(1)",
+"      or      8,8,9",
+".L__lsrd2:      stw     8,-44(1)",
 "      lwz     3,-48(1)",
 "      lwz     4,-44(1)",
 "      blr",
@@ -5265,25 +5292,25 @@
 ".asld__:",
 "       mr.     5,5",
 "       beqlr",
-"       subfic  2,5,32",
+"       subfic  8,5,32",
 "      stw     3,-32(1)",
 "      stw     4,-28(1)",
-"      cmpwi   7,2,0",
+"      cmpwi   7,8,0",
 "      bgt+    7,.L__asld1",
-"      neg     0,2",
-"      lwz     2,-28(1)",
+"      neg     0,8",
+"      lwz     8,-28(1)",
 "      li      9,0",
-"      slw     2,2,0",
+"      slw     8,8,0",
 "      stw     9,-44(1)",
 "      b       .L__asld2",
 ".L__asld1:      lwz     0,-28(1)",
-"      srw     9,0,2",
-"      lwz     2,-32(1)",
+"      srw     9,0,8",
+"      lwz     8,-32(1)",
 "      slw     0,0,5",
-"      slw     2,2,5",
+"      slw     8,8,5",
 "      stw     0,-44(1)",
-"      or      2,2,9",
-".L__asld2:      stw     2,-48(1)",
+"      or      8,8,9",
+".L__asld2:      stw     8,-48(1)",
 "      lwz     3,-48(1)",
 "      lwz     4,-44(1)",
 "      blr",
@@ -5326,24 +5353,24 @@
 ".asrd__:",
 "       mr.     5,5",
 "       beqlr",
-"       subfic  2,5,32",
+"       subfic  8,5,32",
 "      stw     3,-32(1)",
 "      stw     4,-28(1)",
-"      cmpwi   7,2,0",
+"      cmpwi   7,8,0",
 "      bgt+    7,.L__asrd1",
 "      lwz     0,-32(1)",
-"      neg     2,2",
-"      sraw    2,0,2",
+"      neg     8,8",
+"      sraw    8,0,8",
 "      srawi   0,0,31",
 "      b       .L__asrd2",
 ".L__asrd1:      lwz     0,-32(1)",
-"      slw     9,0,2",
-"      lwz     2,-28(1)",
+"      slw     9,0,8",
+"      lwz     8,-28(1)",
 "      sraw    0,0,5",
-"      srw     2,2,5",
-"      or      2,2,9",
+"      srw     8,8,5",
+"      or      8,8,9",
 ".L__asrd2:      stw     0,-48(1)",
-"      stw     2,-44(1)",
+"      stw     8,-44(1)",
 "      lwz     3,-48(1)",
 "      lwz     4,-44(1)",
 "      blr",
--- a/mc-macro.c	Sat May 05 03:39:29 2007 +0900
+++ b/mc-macro.c	Sat May 05 08:10:56 2007 +0900
@@ -209,7 +209,7 @@
 getfname(int next)
 {
     int i,end='"',err=0;
-    char *s,*p=0,**pp,*name,*prev=0;
+    char *s,*p,**pp,*name,*prev=0;
     FILE *fp;
     struct cheap scheap;
     name = cheap->ptr;
--- a/mc-parse.c	Sat May 05 03:39:29 2007 +0900
+++ b/mc-parse.c	Sat May 05 08:10:56 2007 +0900
@@ -619,6 +619,7 @@
     reserve("__builtin_inf",BUILTIN_INF,RESERVE);
     reserve("__builtin_inff",BUILTIN_INFF,RESERVE);
     reserve("__builtin_infl",BUILTIN_INFL,RESERVE);
+    reserve("__builtin_type_is_float",BUILTIN_IS_FLOAT,RESERVE);
     reserve("__attribute__",ATTRIBUTE,RESERVE);
     reserve("__attribute",ATTRIBUTE,RESERVE);
     reserve("__label__",LABEL,RESERVE);
@@ -3592,6 +3593,44 @@
 	type = DOUBLE;
 	e = list2(op,0);
 	return e;
+    case BUILTIN_IS_FLOAT:
+        conv->prefix_(sym);
+        if(getsym(0)==LPAR) {
+            conv->lpar_();
+            if(typeid(getsym(0))) {
+		int smode = mode; mode = LDECL;
+		t=typename();
+                checksym(RPAR);
+                conv->type_(t);
+                conv->rpar_();
+		mode = smode;
+            } else {
+                e=expr0();
+                checksym(RPAR);
+                expr16(e);
+                if(sym==INC||sym==DEC) {   
+                    /* after this operation, type is extended */
+                    getsym(0);
+                    switch(type) {
+                    case CHAR:   type=INT; break;
+                    case SHORT:  type=INT; break;
+                    case UCHAR:  type=UNSIGNED; break;
+                    case USHORT: type=UNSIGNED; break;
+                    case FLOAT:
+                    case DOUBLE: break;
+                    default:
+                        if(!scalar(type))
+                            error(TYERR);
+                    }
+                }
+		t = type;
+                conv->rpar_();
+            }
+        } else {
+            expr13(); t = type;
+	}
+        type=INT;
+        return list2(CONST,(t==FLOAT || t==DOUBLE));
     case SIZEOF:
 	conv->prefix_(sym);
 	if(getsym(0)==LPAR) {
--- a/mc.h	Sat May 05 03:39:29 2007 +0900
+++ b/mc.h	Sat May 05 08:10:56 2007 +0900
@@ -192,28 +192,29 @@
 #define BUILTIN_INF	16
 #define BUILTIN_INFF	17
 #define BUILTIN_INFL	18
-#define LABEL  	19
+#define BUILTIN_IS_FLOAT	19
+#define LABEL  	20
 
 #define NULLARY_ARGS(i) (i==RETURN||i==ENVIRONMENT||i==LCALL||i==REGISTER||i==DREGISTER||i==FREGISTER||i==LREGISTER||(GVAR<=(i%SOP)&&(i%SOP)<=LABEL))
 
 /* unary  argments */
 
-#define ADDRESS	20
-#define MINUS  	21
-#define LNOT   	22
-#define BNOT   	23
-#define INC    	24
-#define PERIOD 	25
-#define ARROW  	26
-#define POSTINC	27
-#define UPOSTINC       	28
-#define PREINC 	29
-#define UPREINC	30
-#define POSTDEC	31
-#define UPOSTDEC       	32
-#define PREDEC 	33
-#define UPREDEC	34
-#define DEC    	35
+#define ADDRESS	21
+#define MINUS  	22
+#define LNOT   	23
+#define BNOT   	24
+#define INC    	25
+#define PERIOD 	26
+#define ARROW  	27
+#define POSTINC	28
+#define UPOSTINC       	29
+#define PREINC 	30
+#define UPREINC	31
+#define POSTDEC	32
+#define UPOSTDEC       	33
+#define PREDEC 	34
+#define UPREDEC	35
+#define DEC    	36
 #define CPOSTINC (COP+POSTINC)
 #define CUPOSTINC (COP+UPOSTINC)
 #define CPREINC (COP+PREINC)
@@ -238,9 +239,9 @@
 #define LPREINC (LOP+PREINC)
 #define LUPOSTINC       (LOP+UPOSTINC)
 #define LUPREINC        (LOP+UPREINC)
-#define INDIRECT       	36
-#define RINDIRECT      	37
-#define URINDIRECT     	38
+#define INDIRECT       	37
+#define RINDIRECT      	38
+#define URINDIRECT     	39
 #define CRINDIRECT      (COP+RINDIRECT)
 #define CURINDIRECT     (COP+URINDIRECT)
 #define SRINDIRECT      (SOP+RINDIRECT)
@@ -249,61 +250,61 @@
 #define DRINDIRECT      (DOP+RINDIRECT)
 #define LRINDIRECT      (LOP+RINDIRECT)
 #define LURINDIRECT     (LOP+URINDIRECT)
-#define RSTRUCT	39
-#define ALLOCA 	40
-#define BUILTINP 	41
-#define BUILTIN_EXPECT 	42
-#define BUILTIN_FABS	43
-#define BUILTIN_FABSF	44
-#define BUILTIN_FABSL	45
-#define ATTRIBUTE 	46
-#define BIT_FIELD 	47
-#define RBIT_FIELD 	48
-#define BPREINC 	49
-#define BPOSTINC 	50
-#define CONV   	51
+#define RSTRUCT	40
+#define ALLOCA 	41
+#define BUILTINP 	42
+#define BUILTIN_EXPECT 	43
+#define BUILTIN_FABS	44
+#define BUILTIN_FABSF	45
+#define BUILTIN_FABSL	46
+#define ATTRIBUTE 	47
+#define BIT_FIELD 	48
+#define RBIT_FIELD 	49
+#define BPREINC 	50
+#define BPOSTINC 	51
+#define CONV   	52
 
 #define UNARY_ARGS(i) (ADDRESS<=(i%SOP)&&(i%SOP)<=CONV)
 
 /* binary  argments */
 
-#define MUL    	52
-#define UMUL   	53
-#define DIV    	54
-#define UDIV   	55
-#define MOD    	56
-#define UMOD   	57
-#define ADD    	58
-#define SUB    	59
-#define CMP    	60      
-#define RSHIFT 	61
-#define URSHIFT	62
-#define LSHIFT 	63
-#define ULSHIFT	64
-#define GT     	65
-#define UGT    	66
-#define GE     	67
-#define UGE    	68
-#define LT     	69
-#define ULT    	70
-#define LE     	71
-#define ULE    	72
-#define EQ     	73
-#define NEQ    	74
-#define BAND   	75
-#define EOR    	76
-#define BOR    	77
-#define LAND   	78
-#define LOR    	79
-#define ASS    	80
-#define UCMP   	81
-#define UCMPGE 	82
-#define CMPGE  	83
-#define CMPEQ  	84
-#define CMPNEQ 	85
-#define ASSOP  	86
-#define UASSOP 	87
-#define COMMA  	88
+#define MUL    	53
+#define UMUL   	54
+#define DIV    	55
+#define UDIV   	56
+#define MOD    	57
+#define UMOD   	58
+#define ADD    	59
+#define SUB    	60
+#define CMP    	61      
+#define RSHIFT 	62
+#define URSHIFT	63
+#define LSHIFT 	64
+#define ULSHIFT	65
+#define GT     	66
+#define UGT    	67
+#define GE     	68
+#define UGE    	69
+#define LT     	70
+#define ULT    	71
+#define LE     	72
+#define ULE    	73
+#define EQ     	74
+#define NEQ    	75
+#define BAND   	76
+#define EOR    	77
+#define BOR    	78
+#define LAND   	79
+#define LOR    	80
+#define ASS    	81
+#define UCMP   	82
+#define UCMPGE 	83
+#define CMPGE  	84
+#define CMPEQ  	85
+#define CMPNEQ 	86
+#define ASSOP  	87
+#define UASSOP 	88
+#define COMMA  	89
 
 #define CASS   	(COP+ASS)
 #define CASSOP 	(COP+ASSOP)
@@ -363,21 +364,21 @@
 #define LEOR    (LOP+EOR)
 #define LBOR    (LOP+BOR)
 
-#define BASS   	89
-#define BASSOP 	90
-#define BFD_REPL 	91
+#define BASS   	90
+#define BASSOP 	91
+#define BFD_REPL 	92
 
-#define JUMP 	92
+#define JUMP 	93
 
-#define STASS  	93
+#define STASS  	94
 
 
 #define BINARY_ARGS(i) ((MUL<=(i%SOP)&&(i%SOP)<=STASS)||i==ARRAY)
 
 /* ternary  argments */
 
-#define COND   	94
-#define UCOND  	95
+#define COND   	95
+#define UCOND  	96
 #define SCOND   (SOP+COND)
 #define SUCOND   (SOP+UCOND)
 #define DCOND   (DOP+COND)
@@ -389,33 +390,33 @@
 
 /* not appeared as tags */
 
-#define LPAR   	96
-#define RPAR   	97
-#define LBRA   	98
-#define RBRA   	99
-#define LC     	100
-#define RC     	101
-#define COLON  	102
-#define SM     	103
-#define CNAME  	104
+#define LPAR   	97
+#define RPAR   	98
+#define LBRA   	99
+#define RBRA   	100
+#define LC     	101
+#define RC     	102
+#define COLON  	103
+#define SM     	104
+#define CNAME  	105
 
-#define I2C  	105
-#define I2S  	106
-#define I2I    	107
-#define I2U    	108
-#define I2D    	109
-#define I2F    	110
-#define I2LL   	111
-#define I2ULL  	112
+#define I2C  	106
+#define I2S  	107
+#define I2I    	108
+#define I2U    	109
+#define I2D    	110
+#define I2F    	111
+#define I2LL   	112
+#define I2ULL  	113
 
-#define U2UC  	113
-#define U2US  	114
-#define U2I    	115
-#define U2U    	116
-#define U2D    	117
-#define U2F    	118
-#define U2LL   	119
-#define U2ULL  	120
+#define U2UC  	114
+#define U2US  	115
+#define U2I    	116
+#define U2U    	117
+#define U2D    	118
+#define U2F    	119
+#define U2LL   	120
+#define U2ULL  	121
 
 
 #define D2I     (DOP+I2I)
@@ -450,27 +451,27 @@
 
 /* statement start */
 
-#define ST_DECL		121
-#define ST_IF		122
-#define ST_DO		123
-#define ST_WHILE	124
-#define ST_FOR		125
-#define ST_SWITCH	126
-#define ST_COMP		127
-#define ST_BREAK	128
-#define ST_CONTINUE	129
-#define ST_CASE		130
-#define ST_DEFAULT	131
-#define ST_RETURN	132
-#define ST_GOTO		133
-#define ST_ASM		134
-#define ST_LABEL	135
-#define ST_OP		136
-#define ST_COMMENT	137
+#define ST_DECL		122
+#define ST_IF		123
+#define ST_DO		124
+#define ST_WHILE	125
+#define ST_FOR		126
+#define ST_SWITCH	127
+#define ST_COMP		128
+#define ST_BREAK	129
+#define ST_CONTINUE	130
+#define ST_CASE		131
+#define ST_DEFAULT	132
+#define ST_RETURN	133
+#define ST_GOTO		134
+#define ST_ASM		135
+#define ST_LABEL	136
+#define ST_OP		137
+#define ST_COMMENT	138
 
 #define IS_STATEMENT(i) (i==INLINE||(ST_DECL<=i&&i<=ST_COMMENT))
 
-#define HAS_ADDRESS	138
+#define HAS_ADDRESS	139
 
 /* statement end */
 
--- a/test/putenemy.c	Sat May 05 03:39:29 2007 +0900
+++ b/test/putenemy.c	Sat May 05 08:10:56 2007 +0900
@@ -5,6 +5,9 @@
 
 extern int printf(char *,...);
 #define SANKAKU 100000
+#ifndef M_PI
+#define M_PI 3.1415962
+#endif
 
 static const double pi2 = M_PI * 2.0;
 
--- a/test/stackframe.c	Sat May 05 03:39:29 2007 +0900
+++ b/test/stackframe.c	Sat May 05 08:10:56 2007 +0900
@@ -17,9 +17,56 @@
 
 int dum;
 
+void *float_frame(int a0);
+
+static inline void frame_pointer(char *s) __attribute__((always_inline));
+
+static inline void frame_pointer(char *s)
+{
+    void *fr,*st;
+    __asm__("\tmr %0,31\n": "=r" (fr));
+    __asm__("\tmr %0,1\n": "=r" (st));
+    printf("fr=%08x st=%08x at %s\n",fr,st,s);
+}
+
+
+int
+int_frame(int a0)
+{
+    int i0;
+    int f0;
+    int *p;
+    int i1;
+    frame_pointer("int frame");
+
+    i0 = f0 = 0.3;
+    printf("int  0 offset: %08x\n",&a0-&i0);
+    printf("int  1 offset: %08x\n",&a0-&i1);
+    printf("int  1 offset: %08x\n",&a0-(int*)float_frame(A1));
+    printf("%d\n",f0);
+    return i0;
+}
+
+void *
+float_frame(int a0)
+{
+    int i0;
+    double f0;
+    int *p;
+    int i1;
+    frame_pointer("float frame");
+
+    f0 = 0.3;
+    printf("local0 offset: %08x\n",&a0-&i0);
+    printf("local1 offset: %08x\n",&a0-&i1);
+    printf("%g\n",f0);
+    return &i0;
+}
+
 void
 called(int a0,int a1,int a2)
 {
+    frame_pointer("called");
     dum = a0+a1+a2;
 }
 
@@ -31,6 +78,9 @@
     int *p;
     int i = 0;
     int l1 = L1;
+    frame_pointer("frame");
+    printf("alloca %08x\n",top);
+    printf("local  %08x\n",&l0);
 
     *top = L2;
     called(A3,A1,A4);
@@ -38,21 +88,21 @@
     i = -OFFSET;
     for(p = top-OFFSET;p<top+0x100; ) {
 	if (*p==(int)ret) {
-	    printf("%04x: ret address\n",i);
+	    printf("%08x: ret address\n",i);
 	} else if (*p==A0) {
-	    printf("%04x: caller arg 1\n",i);
+	    printf("%08x: caller arg 1\n",i);
 	} else if (*p==A2) {
-	    printf("%04x: caller arg last\n",i);
+	    printf("%08x: caller arg last\n",i);
 	} else if (*p==A3) {
-	    printf("%04x: callee arg 1\n",i);
+	    printf("%08x: callee arg 1\n",i);
 	} else if (*p==A4) {
-	    printf("%04x: callee arg last\n",i);
+	    printf("%08x: callee arg last\n",i);
 	} else if (*p==L0) {
-	    printf("%04x: local var top\n",i);
+	    printf("%08x: local var top\n",i);
 	} else if (*p==L1) {
-	    printf("%04x: local var end\n",i);
+	    printf("%08x: local var end\n",i);
 	} else if (*p==L2) {
-	    printf("%04x: stack top (alloca)\n",i);
+	    printf("%08x: stack top (alloca)\n",i);
 	}
 	i+= sizeof(int);
 	p++;
@@ -63,8 +113,12 @@
 int
 main()
 {
+    frame_pointer("main");
     ret = &&label;
     frame(A0,A1,A2);
+    printf("\n");
+    float_frame(A0);
+    int_frame(A0);
 label:
     return 0;
 }