Mercurial > hg > CbC > old > device
diff mc-code-powerpc.c @ 667:dbfbeb05210c before-ia32-function
*** empty log message ***
author | kono |
---|---|
date | Tue, 01 May 2007 13:26:42 +0900 |
parents | ec1bac997e50 |
children | 3f559c67bc86 |
line wrap: on
line diff
--- 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);