Mercurial > hg > CbC > old > device
changeset 667:dbfbeb05210c before-ia32-function
*** empty log message ***
author | kono |
---|---|
date | Tue, 01 May 2007 13:26:42 +0900 |
parents | 7c42cf329666 |
children | adbb9c25eb1a |
files | Makefile.powerpc mc-code-powerpc.c mc-parse.c test/stackframe.c |
diffstat | 4 files changed, 268 insertions(+), 53 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile.powerpc Mon Apr 30 02:19:48 2007 +0900 +++ b/Makefile.powerpc Tue May 01 13:26:42 2007 +0900 @@ -55,6 +55,9 @@ mc-arm : mc-code-arm.o $(COMPLIB) $(CONVERTER) $(CC) $(LDFLAGS) -g mc-code-arm.o $(COMPLIB) $(CONVERTER) -o $@ +mc-spu : mc-code-arm.o $(COMPLIB) $(CONVERTER) + $(CC) $(LDFLAGS) -g mc-code-spu.o $(COMPLIB) $(CONVERTER) -o $@ + conv/conv.h: conv_func.tbl tools/conv_func.pl perl tools/conv_func.pl conv/convdef.h: conv_func.tbl tools/conv_func.pl
--- a/mc-code-powerpc.c Mon Apr 30 02:19:48 2007 +0900 +++ b/mc-code-powerpc.c Tue May 01 13:26:42 2007 +0900 @@ -34,7 +34,9 @@ // #undef __APPLE__ static -char *init_src0 = "\ +char *init_src0 = +#ifdef __APPLE__ +"\ #define __ppc__ 1\n\ #define __BIG_ENDIAN__ 1\n\ #define __STDC__ 1\n\ @@ -49,6 +51,103 @@ #define __DBL_MIN__ 2.2250738585072014e-308\n\ #define __LDBL_MIN__ 2.00416836000897277799610805135016e-292L\n\ " +#else +"\ +#define __inline inline\n\ +#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 alloca __builtin_alloca\n\ +#define __DBL_MIN_EXP__ (-1021)\n\ +#define __FLT_MIN__ 1.17549435e-38F\n\ +#define __CHAR_BIT__ 8\n\ +#define __WCHAR_MAX__ 2147483647\n\ +#define __DBL_DENORM_MIN__ 4.9406564584124654e-324\n\ +#define __FLT_EVAL_METHOD__ 0\n\ +#define __DBL_MIN_10_EXP__ (-307)\n\ +#define __FINITE_MATH_ONLY__ 0\n\ +#define __GNUC_PATCHLEVEL__ 0\n\ +#define __SHRT_MAX__ 32767\n\ +#define __LDBL_MAX__ 1.79769313486231580793728971405301e+308L\n\ +#define __UINTMAX_TYPE__ long long unsigned int\n\ +#define __linux 1\n\ +#define __CHAR_UNSIGNED__ 1\n\ +#define __LDBL_MAX_EXP__ 1024\n\ +#define __linux__ 1\n\ +#define __SCHAR_MAX__ 127\n\ +#define __USER_LABEL_PREFIX__ \n\ +#define __STDC_HOSTED__ 1\n\ +#define __LDBL_HAS_INFINITY__ 1\n\ +#define __DBL_DIG__ 15\n\ +#define __FLT_EPSILON__ 1.19209290e-7F\n\ +#define _CALL_SYSV 1\n\ +#define __LDBL_MIN__ 2.00416836000897277799610805135016e-292L\n\ +#define __unix__ 1\n\ +#define __DECIMAL_DIG__ 33\n\ +#define __gnu_linux__ 1\n\ +#define __LDBL_HAS_QUIET_NAN__ 1\n\ +#define __GNUC__ 4\n\ +#define __DBL_MAX__ 1.7976931348623157e+308\n\ +#define __DBL_HAS_INFINITY__ 1\n\ +#define __DBL_MAX_EXP__ 1024\n\ +#define __LONG_LONG_MAX__ 9223372036854775807LL\n\ +#define __PPC__ 1\n\ +#define __GXX_ABI_VERSION 1002\n\ +#define __FLT_MIN_EXP__ (-125)\n\ +#define __DBL_MIN__ 2.2250738585072014e-308\n\ +#define __DBL_HAS_QUIET_NAN__ 1\n\ +#define __REGISTER_PREFIX__ \n\ +#define __NO_INLINE__ 1\n\ +#define _ARCH_PPC 1\n\ +#define __FLT_MANT_DIG__ 24\n\ +#define __VERSION__ \"mc-powerpc\"\n\ +#define __BIG_ENDIAN__ 1\n\ +#define __powerpc__ 1\n\ +#define unix 1\n\ +#define __SIZE_TYPE__ unsigned int\n\ +#define __ELF__ 1\n\ +#define __FLT_RADIX__ 2\n\ +#define __LDBL_EPSILON__ 4.94065645841246544176568792868221e-324L\n\ +#define __GNUC_RH_RELEASE__ 3\n\ +#define __LDBL_DIG__ 31\n\ +#define __FLT_HAS_QUIET_NAN__ 1\n\ +#define __FLT_MAX_10_EXP__ 38\n\ +#define __LONG_MAX__ 2147483647L\n\ +#define __FLT_HAS_INFINITY__ 1\n\ +#define __unix 1\n\ +#define _BIG_ENDIAN 1\n\ +#define linux 1\n\ +#define __PPC 1\n\ +#define __LDBL_MANT_DIG__ 106\n\ +#define __WCHAR_TYPE__ long int\n\ +#define __FLT_DIG__ 6\n\ +#define __powerpc 1\n\ +#define __INT_MAX__ 2147483647\n\ +#define __LONG_DOUBLE_128__ 1\n\ +#define __FLT_MAX_EXP__ 128\n\ +#define __DBL_MANT_DIG__ 53\n\ +#define __WINT_TYPE__ unsigned int\n\ +#define __LDBL_MIN_EXP__ (-968)\n\ +#define __LDBL_MAX_10_EXP__ 308\n\ +#define __DBL_EPSILON__ 2.2204460492503131e-16\n\ +#define PPC 1\n\ +#define powerpc 1\n\ +#define __INTMAX_MAX__ 9223372036854775807LL\n\ +#define __FLT_DENORM_MIN__ 1.40129846e-45F\n\ +#define __FLT_MAX__ 3.40282347e+38F\n\ +#define __FLT_MIN_10_EXP__ (-37)\n\ +#define __INTMAX_TYPE__ long long int\n\ +#define __GNUC_MINOR__ 1\n\ +#define __DBL_MAX_10_EXP__ 308\n\ +#define __LDBL_DENORM_MIN__ 4.94065645841246544176568792868221e-324L\n\ +#define __STDC__ 1\n\ +#define __PTRDIFF_TYPE__ int\n\ +#define __LDBL_MIN_10_EXP__ (-291)\n\ +" +#endif #ifdef __APPLE__ "#define __APPLE__ 1\n" #endif @@ -112,6 +211,7 @@ static int lreg_sp; /* longlong REGister Stack-Pointer */ static int lreg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ +#ifdef __APPLE__ #define REG_sp 1 #define REG_fp 30 #define REG_VAR_BASE 29 @@ -123,6 +223,19 @@ #define FREG_VAR_MIN 20 #define MIN_TMP_FREG 1 #define MAX_TMP_FREG 14 +#else +#define REG_sp 1 +#define REG_fp 31 +#define REG_VAR_BASE 29 +#define REG_VAR_MIN 18 +#define MIN_TMP_REG 3 +#define MAX_TMP_REG 11 + +#define FREG_VAR_BASE 31 +#define FREG_VAR_MIN 20 +#define MIN_TMP_FREG 1 +#define MAX_TMP_FREG 9 +#endif int MAX_REGISTER=30; /* PowerPCのレジスタを10個まで使う*/ int MAX_FREGISTER=31; @@ -141,10 +254,10 @@ int MAX_INPUT_REGISTER_VAR = 11-MIN_TMP_REG; int MAX_CODE_INPUT_REGISTER_VAR = 11-MIN_TMP_REG; -int MAX_INPUT_DREGISTER_VAR = 14-MIN_TMP_FREG; -int MAX_INPUT_FREGISTER_VAR = 14-MIN_TMP_FREG; -int MAX_CODE_INPUT_DREGISTER_VAR = 14-MIN_TMP_FREG; -int MAX_CODE_INPUT_FREGISTER_VAR = 14-MIN_TMP_FREG; +int MAX_INPUT_DREGISTER_VAR = MAX_TMP_FREG-MIN_TMP_FREG; +int MAX_INPUT_FREGISTER_VAR = MAX_TMP_FREG-MIN_TMP_FREG; +int MAX_CODE_INPUT_DREGISTER_VAR = MAX_TMP_FREG-MIN_TMP_FREG; +int MAX_CODE_INPUT_FREGISTER_VAR = MAX_TMP_FREG-MIN_TMP_FREG; static int powerpc_regs[REAL_MAX_REGISTER+REAL_MAX_FREGISTER+ REAL_MAX_LREGISTER]; @@ -345,13 +458,28 @@ *SIZE_OF_INT *SIZE_OF_INT */ + + +#ifdef __APPLE__ + #define arg_offset 24 #define arg_offset1 24 -int disp_offset = 0; #define func_disp_offset 68 #define code_disp_offset0 (0) +#else + +#define arg_offset (-24) +#define arg_offset1 (-24) + +#define func_disp_offset (16) +#define code_disp_offset0 (0) + +#endif + +int disp_offset = 0; + #define CODE_LVAR(l) ((l)+code_disp_offset0) #define CODE_CALLER_ARG(l) ((l)+arg_offset1) #define FUNC_LVAR(l) ((l)+disp_offset) @@ -497,13 +625,13 @@ if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ printf("%d@l(1)\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); } else - printf("%d@l(30)\n",CODE_LVAR(l)); + printf("%d@l(%d)\n",CODE_LVAR(l),REG_fp); } else if (l<0) { /* local variable */ - printf("%d@l(30)\n",FUNC_LVAR(l)); + printf("%d@l(%d)\n",FUNC_LVAR(l),REG_fp); } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ printf("%d@l(1)\n",CALLER_ARG(l-ARG_LVAR_OFFSET)); } else { /* callee's arguments */ - printf("%d+%s%d@l(30)\n",CALLEE_ARG(l),lpfx,lvar_offset_label); + printf("%d+%s%d@l(%d)\n",CALLEE_ARG(l),lpfx,lvar_offset_label,REG_fp); } } else { rn = register_name(large_offset_reg); @@ -547,13 +675,13 @@ } else { if (LARGE_OFFSET(CODE_LVAR(l))) { rn=register_name(large_offset_reg=get_register()); - printf("\tla %s,30,%d@ha\n",rn,CODE_LVAR(l)); + printf("\tla %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,30,%d@ha\n",rn,FUNC_LVAR(l)); + printf("\tla %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))) { @@ -563,8 +691,8 @@ } else { /* callee's arguments */ if (LARGE_OFFSET(CALLEE_ARG(l))) { rn=register_name(large_offset_reg=get_register()); - printf("\tla %s,30,%d+%s%d@ha\n", - rn,CALLEE_ARG(l),lpfx,lvar_offset_label); + printf("\tla %s,%d,%d+%s%d@ha\n", + rn,REG_fp,CALLEE_ARG(l),lpfx,lvar_offset_label); } } } @@ -1597,7 +1725,7 @@ #if R1SAVE printf("\tlwz %s,0(%s)\n",register_name(creg),register_name(1)); #else - printf("\tmr %s,%s\n",register_name(creg),register_name(30)); + printf("\tmr %s,%s\n",register_name(creg),register_name(REG_fp)); // int l = 0; // printf("\tla %s,",register_name(creg)); // printf("lo16(%d+L_%d)(r30)\n",FUNC_LVAR,lvar_offset_label); @@ -2122,6 +2250,8 @@ return reg_arg_list; } + +#ifdef __APPLE__ static void increment_function_arg(int e3,int *pnargs,int *preg_arg,int *pfreg_arg) { int nargs=0,reg_arg=0,freg_arg=0; @@ -2144,8 +2274,8 @@ if (*preg_arg<MAX_INPUT_REGISTER_VAR) { reg_arg += 2; } + nargs += size(t)/SIZE_OF_INT; freg_arg++; - nargs += size(t)/SIZE_OF_INT; } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { nargs += round4(size(t))/SIZE_OF_INT; } else { @@ -2156,6 +2286,36 @@ *preg_arg += reg_arg; *pfreg_arg += freg_arg; } +#else +static void +increment_function_arg(int e3,int *pnargs,int *preg_arg,int *pfreg_arg) { + int nargs=0,reg_arg=0,freg_arg=0; + int t=type_value(caddr(e3)); + if (t>=0&&(car(t)==BIT_FIELD)) { + t = type_value(cadr(t)); + } + if(scalar(t)) { + nargs ++ ; reg_arg++; + } else if (t==LONGLONG||t==ULONGLONG) { + nargs ++ ; reg_arg++; + nargs ++ ; reg_arg++; + } else if (t==FLOAT) { + freg_arg++; + nargs += size(t)/SIZE_OF_INT; + } else if (t==DOUBLE) { + nargs += round4(size(t))/SIZE_OF_INT; + freg_arg++; + } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { + nargs += round4(size(t))/SIZE_OF_INT; + } else { + error(TYERR); + nargs ++ ; + } + *pnargs += nargs; + *preg_arg += reg_arg; + *pfreg_arg += freg_arg; +} +#endif #define AS_SAVE 1 #define AS_ARG 0 @@ -2192,7 +2352,7 @@ if (mode==AS_SAVE) { return get_dregister_var(0,1); } else if (freg_arg>=MAX_INPUT_DREGISTER_VAR) { - return list3(LVAR,caller_arg_offset_v(nargs),0); + return list3(LVAR,caller_arg_offset_v(nargs)-36,0); } else return get_input_dregister_var(freg_arg,0,0,1); } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { @@ -2209,7 +2369,7 @@ int function(int e1) { - int e2,e3,e4,e5,nargs,t,r0,r1; + int e2,e3,e4,e5,nargs,t,r0; int arg,reg_arg,freg_arg,arg_assign; int dots; int reg_arg_list=0,ret_type,special_lvar; @@ -2364,11 +2524,13 @@ reg_arg_list = list2(arg,reg_arg_list); g_expr_u(assign_expr0(arg,e4,t,t)); } else if (t==DOUBLE||t==FLOAT) { +#ifdef __APPLE__ if (reg_arg<MAX_INPUT_REGISTER_VAR) { /* sigh... printf requires floating value in integer registers */ if (dots) { + int r1; if (car(e4)==DRLVAR) { special_lvar = cadr(e4); e5 = list3(LVAR,special_lvar,0); @@ -2406,6 +2568,7 @@ get_input_dregister_var(freg_arg,0,0,1),t,t), arg_assign); } +#endif reg_arg_list = list2(arg,reg_arg_list); if (car(arg)==DREGISTER) use_input_reg(cadr(arg),1); /* protect from input register free */ @@ -2418,6 +2581,13 @@ g_expr_u(car(arg_assign)); } clear_ptr_cache(); +#ifndef __APPLE__ + if (dots && 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 + } +#endif if (car(e2) == FNAME) { #ifdef __APPLE__ printf("\tbl\tL_%s$stub\n",fn->nm); @@ -2484,7 +2654,7 @@ #if R1SAVE printf("\tmr %s,%s\n",register_name(1),register_name(e3)); #else - printf("\tmr %s,%s\n",register_name(30),register_name(e3)); + printf("\tmr %s,%s\n",register_name(REG_fp),register_name(e3)); #endif } @@ -3166,17 +3336,11 @@ printf("\tbl .LC%d\n",code_setup); r1_offset_label = fwdlabel(); lvar_offset_label = fwdlabel(); -#if 0 - printf("\taddi r30,r1,lo16(-L_%d)\n",lvar_offset_label); - printf("\tstwu r1,lo16(-L_%d)(r1)\n",r1_offset_label); - // printf("\tmr r30,r1\n"); -#else - printf("\taddi 30,1,-%s%d@l\n",lpfx,lvar_offset_label); - printf("\tlis 31,-%s%d@ha\n",lpfx,r1_offset_label); - printf("\taddi 31,31,-%s%d@l\n",lpfx,r1_offset_label); - printf("\tstwux 1,1,31\n"); -#endif - printf("\tmflr 31\n"); + + printf("\taddi %d,%d,-%s%d@l\n",REG_fp,1,lpfx,lvar_offset_label); + printf("\tlis %d,-%s%d@ha\n",30,lpfx,r1_offset_label); + printf("\taddi %d,%d,-%s%d@l\n",30,REG_fp,lpfx,r1_offset_label); + printf("\tstwux 1,1,%d\n",30); #endif max_func_args = 0; clear_ptr_cache(); @@ -3296,8 +3460,8 @@ emit_copy(6,3,sz,0,1,1); #else printf("\tli 7,%d\n",sz); - printf("\tsubl 6,7,30\n"); - printf("\tlwz 3,%d@l(30)\n",(my_func_args-1)*SIZE_OF_INT); + printf("\tsubl 6,7,%d\n",REG_fp); + printf("\tlwz 3,%d@l(%d)\n",(my_func_args-1)*SIZE_OF_INT,REG_fp); emit_copy(6,3,sz,0,1,1); #endif } else if (cadr(fnptr->ty)!=VOID) { @@ -3318,7 +3482,7 @@ #ifdef __APPLE__ printf("\taddi r1,r30,lo16(L_%d)\n",lvar_offset_label); #else - printf("\taddi 1,30,.LC%d@l\n",lvar_offset_label); + printf("\taddi 1,%d,.LC%d@l\n",REG_fp,lvar_offset_label); #endif #endif if (max_freg_var>=0) { @@ -5826,7 +5990,11 @@ printf("\tsub\t%s,%s,%s\n",trn,crn,trn); } } else { +#ifdef __APPLE__ printf("\taddi\t%s,%s,lo16(%d)\n",trn,crn,-min); +#else + printf("\taddi\t%s,%s,%d@l\n",trn,crn,-min); +#endif } printf("\tcmplwi %s,%s,%d\n",crname(cmpflag),trn,max-min); printf("\tbgt-\t%s,%s%d\n",crname(cmpflag),lpfx,dlabel); @@ -5837,22 +6005,14 @@ printf("\tli %s,1\n",srn); printf("\tand %s,%s,%s\n",srn,srn,trn); printf("\tcmplwi %s,%s,0\n",crname(cmpflag),srn); -#ifdef __APPLE__ - printf("\tbne\t%s,L_%d\n",crname(cmpflag),dlabel); -#else - printf("\tbne\t%s,.L%d\n",crname(cmpflag),dlabel); -#endif + printf("\tbne\t%s,%s%d\n",crname(cmpflag),lpfx,dlabel); printf("\tslwi %s,%s,1\n",trn,trn); break; case 4: printf("\tli %s,3\n",srn); printf("\tand %s,%s,%s\n",srn,srn,trn); printf("\tcmplwi %s,%s,0\n",crname(cmpflag),srn); -#ifdef __APPLE__ - printf("\tbne\t%s,L_%d\n",crname(cmpflag),dlabel); -#else - printf("\tbne\t%s,.L%d\n",crname(cmpflag),dlabel); -#endif + printf("\tbne\t%s,%s%d\n",crname(cmpflag),lpfx,dlabel); break; default: urn = register_name(u=get_register()); @@ -5861,11 +6021,7 @@ printf("\tmullw %s,%s,%s\n",srn,urn,srn); printf("\tsubf %s,%s,%s\n",srn,trn,srn); printf("\tcmplwi %s,%s,0\n",crname(cmpflag),srn); -#ifdef __APPLE__ - printf("\tbne\t%s,L_%d\n",crname(cmpflag),dlabel); -#else - printf("\tbne\t%s,.L%d\n",crname(cmpflag),dlabel); -#endif + printf("\tbne\t%s,%s%d\n",crname(cmpflag),lpfx,dlabel); printf("\tslwi %s,%s,2\n",trn,urn); } #ifdef __APPLE__ @@ -5879,10 +6035,10 @@ printf("\tmtctr r0\n"); printf("\tbctr\n"); #else - printf("\taddis %s,31,L_%d@h\n", - srn,l); - printf("\tla %s,L_%d@l(%s)\n", - srn,l,srn); + printf("\taddis %s,31,%s%d@h\n", + srn,lpfx,l); + printf("\tla %s,%s%d@l(%s)\n", + srn,lpfx,l,srn); printf("\tadd %s,%s,%s\n",trn,srn,trn); printf("\tlwz 0,0(%s)\n",trn); printf("\tadd 0,0,%s\n",srn);
--- a/mc-parse.c Mon Apr 30 02:19:48 2007 +0900 +++ b/mc-parse.c Tue May 01 13:26:42 2007 +0900 @@ -2043,15 +2043,16 @@ arg_disp = args; args = 0; disp=0; - if (!inmode) + control=1; + if (!inmode) { arg_register(fnptr); + } typedefed=0; conv->function_(fnptr,sd); conv->lc_(); init_vars=0; /* local variable declaration */ local_decl(1); - control=1; cslabel = -1; if (!inmode && !chk) gen_enter1(); emit_init_vars();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/stackframe.c Tue May 01 13:26:42 2007 +0900 @@ -0,0 +1,55 @@ +extern int printf(const char *,...); +// extern void *alloca(int); + +#define A0 0xa0a0a0a0 +#define A1 0xa1a1a1a1 +#define A2 0xa2a2a2a2 +#define A3 0xa3a3a3a3 +#define A4 0xa4a4a4a4 + +#define L0 0xb0b0b0b0 +#define L1 0xb1b1b1b1 +#define L2 0xb2b2b2b2 +#define L3 0xb3b3b3b3 +#define L4 0xb4b4b4b4 + +void *ret; + +void +frame(int a0,int a1,int a2) +{ + int l0 = L0; + int *top = (int *)__builtin_alloca(16); + int *p; + int i = 0; + int l1 = L1; + + *top = L2; + for(p = top;p<top+0x100; ) { + if (*p==(int)ret) { + printf("%04x: ret address\n",i); + } else if (*p==A0) { + printf("%04x: caller arg 1\n",i); + } else if (*p==A2) { + printf("%04x: caller arg last\n",i); + } else if (*p==L0) { + printf("%04x: local var top\n",i); + } else if (*p==L1) { + printf("%04x: local var end\n",i); + } else if (*p==L2) { + printf("%04x: stack top (alloca)\n",i); + } + i+= sizeof(int); + p++; + } +} + + +int +main() +{ + ret = &&label; + frame(A0,A1,A2); +label: + return 0; +}