Mercurial > hg > CbC > old > device
comparison 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 |
comparison
equal
deleted
inserted
replaced
666:7c42cf329666 | 667:dbfbeb05210c |
---|---|
32 #include "mc-include.c" | 32 #include "mc-include.c" |
33 | 33 |
34 // #undef __APPLE__ | 34 // #undef __APPLE__ |
35 | 35 |
36 static | 36 static |
37 char *init_src0 = "\ | 37 char *init_src0 = |
38 #ifdef __APPLE__ | |
39 "\ | |
38 #define __ppc__ 1\n\ | 40 #define __ppc__ 1\n\ |
39 #define __BIG_ENDIAN__ 1\n\ | 41 #define __BIG_ENDIAN__ 1\n\ |
40 #define __STDC__ 1\n\ | 42 #define __STDC__ 1\n\ |
41 #define __GNUC__ 1\n\ | 43 #define __GNUC__ 1\n\ |
42 #define __inline inline\n\ | 44 #define __inline inline\n\ |
47 #define alloca __builtin_alloca\n\ | 49 #define alloca __builtin_alloca\n\ |
48 #define __FLT_MIN__ 1.17549435e-38F\n\ | 50 #define __FLT_MIN__ 1.17549435e-38F\n\ |
49 #define __DBL_MIN__ 2.2250738585072014e-308\n\ | 51 #define __DBL_MIN__ 2.2250738585072014e-308\n\ |
50 #define __LDBL_MIN__ 2.00416836000897277799610805135016e-292L\n\ | 52 #define __LDBL_MIN__ 2.00416836000897277799610805135016e-292L\n\ |
51 " | 53 " |
54 #else | |
55 "\ | |
56 #define __inline inline\n\ | |
57 #define __extension__\n\ | |
58 #define __const const\n\ | |
59 #define __inline__ inline\n\ | |
60 #define __builtin_va_list int\n\ | |
61 #define __builtin_va_start(ap,arg) ap=(((int)(&arg))+sizeof(arg))\n\ | |
62 #define __builtin_va_arg(ap,type) (*((type *)ap)++)\n\ | |
63 #define alloca __builtin_alloca\n\ | |
64 #define __DBL_MIN_EXP__ (-1021)\n\ | |
65 #define __FLT_MIN__ 1.17549435e-38F\n\ | |
66 #define __CHAR_BIT__ 8\n\ | |
67 #define __WCHAR_MAX__ 2147483647\n\ | |
68 #define __DBL_DENORM_MIN__ 4.9406564584124654e-324\n\ | |
69 #define __FLT_EVAL_METHOD__ 0\n\ | |
70 #define __DBL_MIN_10_EXP__ (-307)\n\ | |
71 #define __FINITE_MATH_ONLY__ 0\n\ | |
72 #define __GNUC_PATCHLEVEL__ 0\n\ | |
73 #define __SHRT_MAX__ 32767\n\ | |
74 #define __LDBL_MAX__ 1.79769313486231580793728971405301e+308L\n\ | |
75 #define __UINTMAX_TYPE__ long long unsigned int\n\ | |
76 #define __linux 1\n\ | |
77 #define __CHAR_UNSIGNED__ 1\n\ | |
78 #define __LDBL_MAX_EXP__ 1024\n\ | |
79 #define __linux__ 1\n\ | |
80 #define __SCHAR_MAX__ 127\n\ | |
81 #define __USER_LABEL_PREFIX__ \n\ | |
82 #define __STDC_HOSTED__ 1\n\ | |
83 #define __LDBL_HAS_INFINITY__ 1\n\ | |
84 #define __DBL_DIG__ 15\n\ | |
85 #define __FLT_EPSILON__ 1.19209290e-7F\n\ | |
86 #define _CALL_SYSV 1\n\ | |
87 #define __LDBL_MIN__ 2.00416836000897277799610805135016e-292L\n\ | |
88 #define __unix__ 1\n\ | |
89 #define __DECIMAL_DIG__ 33\n\ | |
90 #define __gnu_linux__ 1\n\ | |
91 #define __LDBL_HAS_QUIET_NAN__ 1\n\ | |
92 #define __GNUC__ 4\n\ | |
93 #define __DBL_MAX__ 1.7976931348623157e+308\n\ | |
94 #define __DBL_HAS_INFINITY__ 1\n\ | |
95 #define __DBL_MAX_EXP__ 1024\n\ | |
96 #define __LONG_LONG_MAX__ 9223372036854775807LL\n\ | |
97 #define __PPC__ 1\n\ | |
98 #define __GXX_ABI_VERSION 1002\n\ | |
99 #define __FLT_MIN_EXP__ (-125)\n\ | |
100 #define __DBL_MIN__ 2.2250738585072014e-308\n\ | |
101 #define __DBL_HAS_QUIET_NAN__ 1\n\ | |
102 #define __REGISTER_PREFIX__ \n\ | |
103 #define __NO_INLINE__ 1\n\ | |
104 #define _ARCH_PPC 1\n\ | |
105 #define __FLT_MANT_DIG__ 24\n\ | |
106 #define __VERSION__ \"mc-powerpc\"\n\ | |
107 #define __BIG_ENDIAN__ 1\n\ | |
108 #define __powerpc__ 1\n\ | |
109 #define unix 1\n\ | |
110 #define __SIZE_TYPE__ unsigned int\n\ | |
111 #define __ELF__ 1\n\ | |
112 #define __FLT_RADIX__ 2\n\ | |
113 #define __LDBL_EPSILON__ 4.94065645841246544176568792868221e-324L\n\ | |
114 #define __GNUC_RH_RELEASE__ 3\n\ | |
115 #define __LDBL_DIG__ 31\n\ | |
116 #define __FLT_HAS_QUIET_NAN__ 1\n\ | |
117 #define __FLT_MAX_10_EXP__ 38\n\ | |
118 #define __LONG_MAX__ 2147483647L\n\ | |
119 #define __FLT_HAS_INFINITY__ 1\n\ | |
120 #define __unix 1\n\ | |
121 #define _BIG_ENDIAN 1\n\ | |
122 #define linux 1\n\ | |
123 #define __PPC 1\n\ | |
124 #define __LDBL_MANT_DIG__ 106\n\ | |
125 #define __WCHAR_TYPE__ long int\n\ | |
126 #define __FLT_DIG__ 6\n\ | |
127 #define __powerpc 1\n\ | |
128 #define __INT_MAX__ 2147483647\n\ | |
129 #define __LONG_DOUBLE_128__ 1\n\ | |
130 #define __FLT_MAX_EXP__ 128\n\ | |
131 #define __DBL_MANT_DIG__ 53\n\ | |
132 #define __WINT_TYPE__ unsigned int\n\ | |
133 #define __LDBL_MIN_EXP__ (-968)\n\ | |
134 #define __LDBL_MAX_10_EXP__ 308\n\ | |
135 #define __DBL_EPSILON__ 2.2204460492503131e-16\n\ | |
136 #define PPC 1\n\ | |
137 #define powerpc 1\n\ | |
138 #define __INTMAX_MAX__ 9223372036854775807LL\n\ | |
139 #define __FLT_DENORM_MIN__ 1.40129846e-45F\n\ | |
140 #define __FLT_MAX__ 3.40282347e+38F\n\ | |
141 #define __FLT_MIN_10_EXP__ (-37)\n\ | |
142 #define __INTMAX_TYPE__ long long int\n\ | |
143 #define __GNUC_MINOR__ 1\n\ | |
144 #define __DBL_MAX_10_EXP__ 308\n\ | |
145 #define __LDBL_DENORM_MIN__ 4.94065645841246544176568792868221e-324L\n\ | |
146 #define __STDC__ 1\n\ | |
147 #define __PTRDIFF_TYPE__ int\n\ | |
148 #define __LDBL_MIN_10_EXP__ (-291)\n\ | |
149 " | |
150 #endif | |
52 #ifdef __APPLE__ | 151 #ifdef __APPLE__ |
53 "#define __APPLE__ 1\n" | 152 "#define __APPLE__ 1\n" |
54 #endif | 153 #endif |
55 ; | 154 ; |
56 | 155 |
110 static int freg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ | 209 static int freg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ |
111 | 210 |
112 static int lreg_sp; /* longlong REGister Stack-Pointer */ | 211 static int lreg_sp; /* longlong REGister Stack-Pointer */ |
113 static int lreg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ | 212 static int lreg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ |
114 | 213 |
214 #ifdef __APPLE__ | |
115 #define REG_sp 1 | 215 #define REG_sp 1 |
116 #define REG_fp 30 | 216 #define REG_fp 30 |
117 #define REG_VAR_BASE 29 | 217 #define REG_VAR_BASE 29 |
118 #define REG_VAR_MIN 18 | 218 #define REG_VAR_MIN 18 |
119 #define MIN_TMP_REG 3 | 219 #define MIN_TMP_REG 3 |
121 | 221 |
122 #define FREG_VAR_BASE 31 | 222 #define FREG_VAR_BASE 31 |
123 #define FREG_VAR_MIN 20 | 223 #define FREG_VAR_MIN 20 |
124 #define MIN_TMP_FREG 1 | 224 #define MIN_TMP_FREG 1 |
125 #define MAX_TMP_FREG 14 | 225 #define MAX_TMP_FREG 14 |
226 #else | |
227 #define REG_sp 1 | |
228 #define REG_fp 31 | |
229 #define REG_VAR_BASE 29 | |
230 #define REG_VAR_MIN 18 | |
231 #define MIN_TMP_REG 3 | |
232 #define MAX_TMP_REG 11 | |
233 | |
234 #define FREG_VAR_BASE 31 | |
235 #define FREG_VAR_MIN 20 | |
236 #define MIN_TMP_FREG 1 | |
237 #define MAX_TMP_FREG 9 | |
238 #endif | |
126 | 239 |
127 int MAX_REGISTER=30; /* PowerPCのレジスタを10個まで使う*/ | 240 int MAX_REGISTER=30; /* PowerPCのレジスタを10個まで使う*/ |
128 int MAX_FREGISTER=31; | 241 int MAX_FREGISTER=31; |
129 #define REAL_MAX_REGISTER 32 /* PowerPCのレジスタが32ということ*/ | 242 #define REAL_MAX_REGISTER 32 /* PowerPCのレジスタが32ということ*/ |
130 #define REAL_MAX_FREGISTER 32 /* PowerPCのレジスタが32ということ*/ | 243 #define REAL_MAX_FREGISTER 32 /* PowerPCのレジスタが32ということ*/ |
139 #define RET_LREGISTER_L 4 /* low word */ | 252 #define RET_LREGISTER_L 4 /* low word */ |
140 #define RET_LREGISTER LREG_OFFSET | 253 #define RET_LREGISTER LREG_OFFSET |
141 | 254 |
142 int MAX_INPUT_REGISTER_VAR = 11-MIN_TMP_REG; | 255 int MAX_INPUT_REGISTER_VAR = 11-MIN_TMP_REG; |
143 int MAX_CODE_INPUT_REGISTER_VAR = 11-MIN_TMP_REG; | 256 int MAX_CODE_INPUT_REGISTER_VAR = 11-MIN_TMP_REG; |
144 int MAX_INPUT_DREGISTER_VAR = 14-MIN_TMP_FREG; | 257 int MAX_INPUT_DREGISTER_VAR = MAX_TMP_FREG-MIN_TMP_FREG; |
145 int MAX_INPUT_FREGISTER_VAR = 14-MIN_TMP_FREG; | 258 int MAX_INPUT_FREGISTER_VAR = MAX_TMP_FREG-MIN_TMP_FREG; |
146 int MAX_CODE_INPUT_DREGISTER_VAR = 14-MIN_TMP_FREG; | 259 int MAX_CODE_INPUT_DREGISTER_VAR = MAX_TMP_FREG-MIN_TMP_FREG; |
147 int MAX_CODE_INPUT_FREGISTER_VAR = 14-MIN_TMP_FREG; | 260 int MAX_CODE_INPUT_FREGISTER_VAR = MAX_TMP_FREG-MIN_TMP_FREG; |
148 | 261 |
149 static int powerpc_regs[REAL_MAX_REGISTER+REAL_MAX_FREGISTER+ | 262 static int powerpc_regs[REAL_MAX_REGISTER+REAL_MAX_FREGISTER+ |
150 REAL_MAX_LREGISTER]; | 263 REAL_MAX_LREGISTER]; |
151 static int regv_h0[REAL_MAX_LREGISTER]; | 264 static int regv_h0[REAL_MAX_LREGISTER]; |
152 static int regv_l0[REAL_MAX_LREGISTER]; | 265 static int regv_l0[REAL_MAX_LREGISTER]; |
343 r20-r29 lvar>0 lvar<0 lvar>0x1000 000 | 456 r20-r29 lvar>0 lvar<0 lvar>0x1000 000 |
344 f20-f31 <-my_func_args--><--disp-----><-max_func_arg-> | 457 f20-f31 <-my_func_args--><--disp-----><-max_func_arg-> |
345 *SIZE_OF_INT *SIZE_OF_INT | 458 *SIZE_OF_INT *SIZE_OF_INT |
346 | 459 |
347 */ | 460 */ |
461 | |
462 | |
463 #ifdef __APPLE__ | |
464 | |
348 #define arg_offset 24 | 465 #define arg_offset 24 |
349 #define arg_offset1 24 | 466 #define arg_offset1 24 |
350 int disp_offset = 0; | |
351 | 467 |
352 #define func_disp_offset 68 | 468 #define func_disp_offset 68 |
353 #define code_disp_offset0 (0) | 469 #define code_disp_offset0 (0) |
470 | |
471 #else | |
472 | |
473 #define arg_offset (-24) | |
474 #define arg_offset1 (-24) | |
475 | |
476 #define func_disp_offset (16) | |
477 #define code_disp_offset0 (0) | |
478 | |
479 #endif | |
480 | |
481 int disp_offset = 0; | |
354 | 482 |
355 #define CODE_LVAR(l) ((l)+code_disp_offset0) | 483 #define CODE_LVAR(l) ((l)+code_disp_offset0) |
356 #define CODE_CALLER_ARG(l) ((l)+arg_offset1) | 484 #define CODE_CALLER_ARG(l) ((l)+arg_offset1) |
357 #define FUNC_LVAR(l) ((l)+disp_offset) | 485 #define FUNC_LVAR(l) ((l)+disp_offset) |
358 #define CALLER_ARG(l) ((l)+arg_offset1) | 486 #define CALLER_ARG(l) ((l)+arg_offset1) |
495 if (!large_offset_reg) { | 623 if (!large_offset_reg) { |
496 if (is_code(fnptr)) { | 624 if (is_code(fnptr)) { |
497 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ | 625 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ |
498 printf("%d@l(1)\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); | 626 printf("%d@l(1)\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); |
499 } else | 627 } else |
500 printf("%d@l(30)\n",CODE_LVAR(l)); | 628 printf("%d@l(%d)\n",CODE_LVAR(l),REG_fp); |
501 } else if (l<0) { /* local variable */ | 629 } else if (l<0) { /* local variable */ |
502 printf("%d@l(30)\n",FUNC_LVAR(l)); | 630 printf("%d@l(%d)\n",FUNC_LVAR(l),REG_fp); |
503 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ | 631 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ |
504 printf("%d@l(1)\n",CALLER_ARG(l-ARG_LVAR_OFFSET)); | 632 printf("%d@l(1)\n",CALLER_ARG(l-ARG_LVAR_OFFSET)); |
505 } else { /* callee's arguments */ | 633 } else { /* callee's arguments */ |
506 printf("%d+%s%d@l(30)\n",CALLEE_ARG(l),lpfx,lvar_offset_label); | 634 printf("%d+%s%d@l(%d)\n",CALLEE_ARG(l),lpfx,lvar_offset_label,REG_fp); |
507 } | 635 } |
508 } else { | 636 } else { |
509 rn = register_name(large_offset_reg); | 637 rn = register_name(large_offset_reg); |
510 if (is_code(fnptr)) { | 638 if (is_code(fnptr)) { |
511 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ | 639 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ |
545 CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); | 673 CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); |
546 } | 674 } |
547 } else { | 675 } else { |
548 if (LARGE_OFFSET(CODE_LVAR(l))) { | 676 if (LARGE_OFFSET(CODE_LVAR(l))) { |
549 rn=register_name(large_offset_reg=get_register()); | 677 rn=register_name(large_offset_reg=get_register()); |
550 printf("\tla %s,30,%d@ha\n",rn,CODE_LVAR(l)); | 678 printf("\tla %s,%d,%d@ha\n",rn,REG_fp,CODE_LVAR(l)); |
551 } | 679 } |
552 } | 680 } |
553 } else if (l<0) { /* local variable */ | 681 } else if (l<0) { /* local variable */ |
554 if (LARGE_OFFSET(FUNC_LVAR(l))) { | 682 if (LARGE_OFFSET(FUNC_LVAR(l))) { |
555 rn=register_name(large_offset_reg=get_register()); | 683 rn=register_name(large_offset_reg=get_register()); |
556 printf("\tla %s,30,%d@ha\n",rn,FUNC_LVAR(l)); | 684 printf("\tla %s,%d,%d@ha\n",rn,REG_fp,FUNC_LVAR(l)); |
557 } | 685 } |
558 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ | 686 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ |
559 if (LARGE_OFFSET(CALLER_ARG(l-ARG_LVAR_OFFSET))) { | 687 if (LARGE_OFFSET(CALLER_ARG(l-ARG_LVAR_OFFSET))) { |
560 rn=register_name(large_offset_reg=get_register()); | 688 rn=register_name(large_offset_reg=get_register()); |
561 printf("\tla %s,1,%d@ha\n",rn,CALLER_ARG(l-ARG_LVAR_OFFSET)); | 689 printf("\tla %s,1,%d@ha\n",rn,CALLER_ARG(l-ARG_LVAR_OFFSET)); |
562 } | 690 } |
563 } else { /* callee's arguments */ | 691 } else { /* callee's arguments */ |
564 if (LARGE_OFFSET(CALLEE_ARG(l))) { | 692 if (LARGE_OFFSET(CALLEE_ARG(l))) { |
565 rn=register_name(large_offset_reg=get_register()); | 693 rn=register_name(large_offset_reg=get_register()); |
566 printf("\tla %s,30,%d+%s%d@ha\n", | 694 printf("\tla %s,%d,%d+%s%d@ha\n", |
567 rn,CALLEE_ARG(l),lpfx,lvar_offset_label); | 695 rn,REG_fp,CALLEE_ARG(l),lpfx,lvar_offset_label); |
568 } | 696 } |
569 } | 697 } |
570 } | 698 } |
571 #endif | 699 #endif |
572 | 700 |
1595 /* save frame pointer */ | 1723 /* save frame pointer */ |
1596 use_int(creg); | 1724 use_int(creg); |
1597 #if R1SAVE | 1725 #if R1SAVE |
1598 printf("\tlwz %s,0(%s)\n",register_name(creg),register_name(1)); | 1726 printf("\tlwz %s,0(%s)\n",register_name(creg),register_name(1)); |
1599 #else | 1727 #else |
1600 printf("\tmr %s,%s\n",register_name(creg),register_name(30)); | 1728 printf("\tmr %s,%s\n",register_name(creg),register_name(REG_fp)); |
1601 // int l = 0; | 1729 // int l = 0; |
1602 // printf("\tla %s,",register_name(creg)); | 1730 // printf("\tla %s,",register_name(creg)); |
1603 // printf("lo16(%d+L_%d)(r30)\n",FUNC_LVAR,lvar_offset_label); | 1731 // printf("lo16(%d+L_%d)(r30)\n",FUNC_LVAR,lvar_offset_label); |
1604 #endif | 1732 #endif |
1605 } | 1733 } |
2120 use_input_reg(cadr(arg),1); | 2248 use_input_reg(cadr(arg),1); |
2121 car(e3) = arg; | 2249 car(e3) = arg; |
2122 return reg_arg_list; | 2250 return reg_arg_list; |
2123 } | 2251 } |
2124 | 2252 |
2253 | |
2254 #ifdef __APPLE__ | |
2125 static void | 2255 static void |
2126 increment_function_arg(int e3,int *pnargs,int *preg_arg,int *pfreg_arg) { | 2256 increment_function_arg(int e3,int *pnargs,int *preg_arg,int *pfreg_arg) { |
2127 int nargs=0,reg_arg=0,freg_arg=0; | 2257 int nargs=0,reg_arg=0,freg_arg=0; |
2128 int t=type_value(caddr(e3)); | 2258 int t=type_value(caddr(e3)); |
2129 if (t>=0&&(car(t)==BIT_FIELD)) { | 2259 if (t>=0&&(car(t)==BIT_FIELD)) { |
2142 nargs += size(t)/SIZE_OF_INT; | 2272 nargs += size(t)/SIZE_OF_INT; |
2143 } else if (t==DOUBLE) { | 2273 } else if (t==DOUBLE) { |
2144 if (*preg_arg<MAX_INPUT_REGISTER_VAR) { | 2274 if (*preg_arg<MAX_INPUT_REGISTER_VAR) { |
2145 reg_arg += 2; | 2275 reg_arg += 2; |
2146 } | 2276 } |
2277 nargs += size(t)/SIZE_OF_INT; | |
2147 freg_arg++; | 2278 freg_arg++; |
2148 nargs += size(t)/SIZE_OF_INT; | |
2149 } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { | 2279 } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { |
2150 nargs += round4(size(t))/SIZE_OF_INT; | 2280 nargs += round4(size(t))/SIZE_OF_INT; |
2151 } else { | 2281 } else { |
2152 error(TYERR); | 2282 error(TYERR); |
2153 nargs ++ ; | 2283 nargs ++ ; |
2154 } | 2284 } |
2155 *pnargs += nargs; | 2285 *pnargs += nargs; |
2156 *preg_arg += reg_arg; | 2286 *preg_arg += reg_arg; |
2157 *pfreg_arg += freg_arg; | 2287 *pfreg_arg += freg_arg; |
2158 } | 2288 } |
2289 #else | |
2290 static void | |
2291 increment_function_arg(int e3,int *pnargs,int *preg_arg,int *pfreg_arg) { | |
2292 int nargs=0,reg_arg=0,freg_arg=0; | |
2293 int t=type_value(caddr(e3)); | |
2294 if (t>=0&&(car(t)==BIT_FIELD)) { | |
2295 t = type_value(cadr(t)); | |
2296 } | |
2297 if(scalar(t)) { | |
2298 nargs ++ ; reg_arg++; | |
2299 } else if (t==LONGLONG||t==ULONGLONG) { | |
2300 nargs ++ ; reg_arg++; | |
2301 nargs ++ ; reg_arg++; | |
2302 } else if (t==FLOAT) { | |
2303 freg_arg++; | |
2304 nargs += size(t)/SIZE_OF_INT; | |
2305 } else if (t==DOUBLE) { | |
2306 nargs += round4(size(t))/SIZE_OF_INT; | |
2307 freg_arg++; | |
2308 } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { | |
2309 nargs += round4(size(t))/SIZE_OF_INT; | |
2310 } else { | |
2311 error(TYERR); | |
2312 nargs ++ ; | |
2313 } | |
2314 *pnargs += nargs; | |
2315 *preg_arg += reg_arg; | |
2316 *pfreg_arg += freg_arg; | |
2317 } | |
2318 #endif | |
2159 | 2319 |
2160 #define AS_SAVE 1 | 2320 #define AS_SAVE 1 |
2161 #define AS_ARG 0 | 2321 #define AS_ARG 0 |
2162 | 2322 |
2163 static int | 2323 static int |
2190 return get_input_dregister_var(freg_arg,0,0,0); | 2350 return get_input_dregister_var(freg_arg,0,0,0); |
2191 } else if (t==DOUBLE) { | 2351 } else if (t==DOUBLE) { |
2192 if (mode==AS_SAVE) { | 2352 if (mode==AS_SAVE) { |
2193 return get_dregister_var(0,1); | 2353 return get_dregister_var(0,1); |
2194 } else if (freg_arg>=MAX_INPUT_DREGISTER_VAR) { | 2354 } else if (freg_arg>=MAX_INPUT_DREGISTER_VAR) { |
2195 return list3(LVAR,caller_arg_offset_v(nargs),0); | 2355 return list3(LVAR,caller_arg_offset_v(nargs)-36,0); |
2196 } else | 2356 } else |
2197 return get_input_dregister_var(freg_arg,0,0,1); | 2357 return get_input_dregister_var(freg_arg,0,0,1); |
2198 } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { | 2358 } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) { |
2199 if (mode==AS_SAVE) { | 2359 if (mode==AS_SAVE) { |
2200 return get_register_var(0); | 2360 return get_register_var(0); |
2207 } | 2367 } |
2208 | 2368 |
2209 int | 2369 int |
2210 function(int e1) | 2370 function(int e1) |
2211 { | 2371 { |
2212 int e2,e3,e4,e5,nargs,t,r0,r1; | 2372 int e2,e3,e4,e5,nargs,t,r0; |
2213 int arg,reg_arg,freg_arg,arg_assign; | 2373 int arg,reg_arg,freg_arg,arg_assign; |
2214 int dots; | 2374 int dots; |
2215 int reg_arg_list=0,ret_type,special_lvar; | 2375 int reg_arg_list=0,ret_type,special_lvar; |
2216 NMTBL *fn = 0; | 2376 NMTBL *fn = 0; |
2217 int jmp = 0; | 2377 int jmp = 0; |
2362 } | 2522 } |
2363 } | 2523 } |
2364 reg_arg_list = list2(arg,reg_arg_list); | 2524 reg_arg_list = list2(arg,reg_arg_list); |
2365 g_expr_u(assign_expr0(arg,e4,t,t)); | 2525 g_expr_u(assign_expr0(arg,e4,t,t)); |
2366 } else if (t==DOUBLE||t==FLOAT) { | 2526 } else if (t==DOUBLE||t==FLOAT) { |
2527 #ifdef __APPLE__ | |
2367 if (reg_arg<MAX_INPUT_REGISTER_VAR) { | 2528 if (reg_arg<MAX_INPUT_REGISTER_VAR) { |
2368 /* sigh... | 2529 /* sigh... |
2369 printf requires floating value in integer registers | 2530 printf requires floating value in integer registers |
2370 */ | 2531 */ |
2371 if (dots) { | 2532 if (dots) { |
2533 int r1; | |
2372 if (car(e4)==DRLVAR) { | 2534 if (car(e4)==DRLVAR) { |
2373 special_lvar = cadr(e4); | 2535 special_lvar = cadr(e4); |
2374 e5 = list3(LVAR,special_lvar,0); | 2536 e5 = list3(LVAR,special_lvar,0); |
2375 } else { | 2537 } else { |
2376 special_lvar = new_lvar(SIZE_OF_DOUBLE); | 2538 special_lvar = new_lvar(SIZE_OF_DOUBLE); |
2404 arg_assign = list2( | 2566 arg_assign = list2( |
2405 assign_expr0(list3(LVAR,caller_arg_offset_v(nargs),0), | 2567 assign_expr0(list3(LVAR,caller_arg_offset_v(nargs),0), |
2406 get_input_dregister_var(freg_arg,0,0,1),t,t), | 2568 get_input_dregister_var(freg_arg,0,0,1),t,t), |
2407 arg_assign); | 2569 arg_assign); |
2408 } | 2570 } |
2571 #endif | |
2409 reg_arg_list = list2(arg,reg_arg_list); | 2572 reg_arg_list = list2(arg,reg_arg_list); |
2410 if (car(arg)==DREGISTER) | 2573 if (car(arg)==DREGISTER) |
2411 use_input_reg(cadr(arg),1); /* protect from input register free */ | 2574 use_input_reg(cadr(arg),1); /* protect from input register free */ |
2412 g_expr_u(assign_expr0(arg,e4,t,t)); /* XXX */ | 2575 g_expr_u(assign_expr0(arg,e4,t,t)); /* XXX */ |
2413 } | 2576 } |
2416 if (max_func_args<nargs) max_func_args=nargs; | 2579 if (max_func_args<nargs) max_func_args=nargs; |
2417 for(;arg_assign;arg_assign=cadr(arg_assign)) { | 2580 for(;arg_assign;arg_assign=cadr(arg_assign)) { |
2418 g_expr_u(car(arg_assign)); | 2581 g_expr_u(car(arg_assign)); |
2419 } | 2582 } |
2420 clear_ptr_cache(); | 2583 clear_ptr_cache(); |
2584 #ifndef __APPLE__ | |
2585 if (dots && freg_arg) { | |
2586 // variadic function has floating value in register | |
2587 printf("\tcreqv 6,6,6\n"); | |
2588 // printf("\tcrxor 6,6,6\n"); for value in stack | |
2589 } | |
2590 #endif | |
2421 if (car(e2) == FNAME) { | 2591 if (car(e2) == FNAME) { |
2422 #ifdef __APPLE__ | 2592 #ifdef __APPLE__ |
2423 printf("\tbl\tL_%s$stub\n",fn->nm); | 2593 printf("\tbl\tL_%s$stub\n",fn->nm); |
2424 #else | 2594 #else |
2425 printf("\tbl\t%s\n",fn->nm); | 2595 printf("\tbl\t%s\n",fn->nm); |
2482 code_frame_pointer(int e3) { | 2652 code_frame_pointer(int e3) { |
2483 use_int(e3); | 2653 use_int(e3); |
2484 #if R1SAVE | 2654 #if R1SAVE |
2485 printf("\tmr %s,%s\n",register_name(1),register_name(e3)); | 2655 printf("\tmr %s,%s\n",register_name(1),register_name(e3)); |
2486 #else | 2656 #else |
2487 printf("\tmr %s,%s\n",register_name(30),register_name(e3)); | 2657 printf("\tmr %s,%s\n",register_name(REG_fp),register_name(e3)); |
2488 #endif | 2658 #endif |
2489 } | 2659 } |
2490 | 2660 |
2491 int | 2661 int |
2492 code_frame_pointer_register() | 2662 code_frame_pointer_register() |
3164 code_setup=fwdlabel(); | 3334 code_setup=fwdlabel(); |
3165 printf("\tmflr 0\n"); | 3335 printf("\tmflr 0\n"); |
3166 printf("\tbl .LC%d\n",code_setup); | 3336 printf("\tbl .LC%d\n",code_setup); |
3167 r1_offset_label = fwdlabel(); | 3337 r1_offset_label = fwdlabel(); |
3168 lvar_offset_label = fwdlabel(); | 3338 lvar_offset_label = fwdlabel(); |
3169 #if 0 | 3339 |
3170 printf("\taddi r30,r1,lo16(-L_%d)\n",lvar_offset_label); | 3340 printf("\taddi %d,%d,-%s%d@l\n",REG_fp,1,lpfx,lvar_offset_label); |
3171 printf("\tstwu r1,lo16(-L_%d)(r1)\n",r1_offset_label); | 3341 printf("\tlis %d,-%s%d@ha\n",30,lpfx,r1_offset_label); |
3172 // printf("\tmr r30,r1\n"); | 3342 printf("\taddi %d,%d,-%s%d@l\n",30,REG_fp,lpfx,r1_offset_label); |
3173 #else | 3343 printf("\tstwux 1,1,%d\n",30); |
3174 printf("\taddi 30,1,-%s%d@l\n",lpfx,lvar_offset_label); | |
3175 printf("\tlis 31,-%s%d@ha\n",lpfx,r1_offset_label); | |
3176 printf("\taddi 31,31,-%s%d@l\n",lpfx,r1_offset_label); | |
3177 printf("\tstwux 1,1,31\n"); | |
3178 #endif | |
3179 printf("\tmflr 31\n"); | |
3180 #endif | 3344 #endif |
3181 max_func_args = 0; | 3345 max_func_args = 0; |
3182 clear_ptr_cache(); | 3346 clear_ptr_cache(); |
3183 } | 3347 } |
3184 | 3348 |
3294 printf("\tsubl r6,r7,r30\n"); | 3458 printf("\tsubl r6,r7,r30\n"); |
3295 printf("\tlwz r3,lo16(%d)(r30)\n",(my_func_args-1)*SIZE_OF_INT); | 3459 printf("\tlwz r3,lo16(%d)(r30)\n",(my_func_args-1)*SIZE_OF_INT); |
3296 emit_copy(6,3,sz,0,1,1); | 3460 emit_copy(6,3,sz,0,1,1); |
3297 #else | 3461 #else |
3298 printf("\tli 7,%d\n",sz); | 3462 printf("\tli 7,%d\n",sz); |
3299 printf("\tsubl 6,7,30\n"); | 3463 printf("\tsubl 6,7,%d\n",REG_fp); |
3300 printf("\tlwz 3,%d@l(30)\n",(my_func_args-1)*SIZE_OF_INT); | 3464 printf("\tlwz 3,%d@l(%d)\n",(my_func_args-1)*SIZE_OF_INT,REG_fp); |
3301 emit_copy(6,3,sz,0,1,1); | 3465 emit_copy(6,3,sz,0,1,1); |
3302 #endif | 3466 #endif |
3303 } else if (cadr(fnptr->ty)!=VOID) { | 3467 } else if (cadr(fnptr->ty)!=VOID) { |
3304 printf("\tmr %s,%s\n",register_name(3),register_name(29)); | 3468 printf("\tmr %s,%s\n",register_name(3),register_name(29)); |
3305 } | 3469 } |
3316 } | 3480 } |
3317 #else | 3481 #else |
3318 #ifdef __APPLE__ | 3482 #ifdef __APPLE__ |
3319 printf("\taddi r1,r30,lo16(L_%d)\n",lvar_offset_label); | 3483 printf("\taddi r1,r30,lo16(L_%d)\n",lvar_offset_label); |
3320 #else | 3484 #else |
3321 printf("\taddi 1,30,.LC%d@l\n",lvar_offset_label); | 3485 printf("\taddi 1,%d,.LC%d@l\n",REG_fp,lvar_offset_label); |
3322 #endif | 3486 #endif |
3323 #endif | 3487 #endif |
3324 if (max_freg_var>=0) { | 3488 if (max_freg_var>=0) { |
3325 #ifdef __APPLE__ | 3489 #ifdef __APPLE__ |
3326 printf("\tlmw r%d,%d(%s)\n", | 3490 printf("\tlmw r%d,%d(%s)\n", |
5824 } else { | 5988 } else { |
5825 code_const(min,t); | 5989 code_const(min,t); |
5826 printf("\tsub\t%s,%s,%s\n",trn,crn,trn); | 5990 printf("\tsub\t%s,%s,%s\n",trn,crn,trn); |
5827 } | 5991 } |
5828 } else { | 5992 } else { |
5993 #ifdef __APPLE__ | |
5829 printf("\taddi\t%s,%s,lo16(%d)\n",trn,crn,-min); | 5994 printf("\taddi\t%s,%s,lo16(%d)\n",trn,crn,-min); |
5995 #else | |
5996 printf("\taddi\t%s,%s,%d@l\n",trn,crn,-min); | |
5997 #endif | |
5830 } | 5998 } |
5831 printf("\tcmplwi %s,%s,%d\n",crname(cmpflag),trn,max-min); | 5999 printf("\tcmplwi %s,%s,%d\n",crname(cmpflag),trn,max-min); |
5832 printf("\tbgt-\t%s,%s%d\n",crname(cmpflag),lpfx,dlabel); | 6000 printf("\tbgt-\t%s,%s%d\n",crname(cmpflag),lpfx,dlabel); |
5833 inc_cmpflag(); | 6001 inc_cmpflag(); |
5834 switch(delta) { | 6002 switch(delta) { |
5835 case 1: printf("\tslwi %s,%s,2\n",trn,trn); break; | 6003 case 1: printf("\tslwi %s,%s,2\n",trn,trn); break; |
5836 case 2: | 6004 case 2: |
5837 printf("\tli %s,1\n",srn); | 6005 printf("\tli %s,1\n",srn); |
5838 printf("\tand %s,%s,%s\n",srn,srn,trn); | 6006 printf("\tand %s,%s,%s\n",srn,srn,trn); |
5839 printf("\tcmplwi %s,%s,0\n",crname(cmpflag),srn); | 6007 printf("\tcmplwi %s,%s,0\n",crname(cmpflag),srn); |
5840 #ifdef __APPLE__ | 6008 printf("\tbne\t%s,%s%d\n",crname(cmpflag),lpfx,dlabel); |
5841 printf("\tbne\t%s,L_%d\n",crname(cmpflag),dlabel); | |
5842 #else | |
5843 printf("\tbne\t%s,.L%d\n",crname(cmpflag),dlabel); | |
5844 #endif | |
5845 printf("\tslwi %s,%s,1\n",trn,trn); | 6009 printf("\tslwi %s,%s,1\n",trn,trn); |
5846 break; | 6010 break; |
5847 case 4: | 6011 case 4: |
5848 printf("\tli %s,3\n",srn); | 6012 printf("\tli %s,3\n",srn); |
5849 printf("\tand %s,%s,%s\n",srn,srn,trn); | 6013 printf("\tand %s,%s,%s\n",srn,srn,trn); |
5850 printf("\tcmplwi %s,%s,0\n",crname(cmpflag),srn); | 6014 printf("\tcmplwi %s,%s,0\n",crname(cmpflag),srn); |
5851 #ifdef __APPLE__ | 6015 printf("\tbne\t%s,%s%d\n",crname(cmpflag),lpfx,dlabel); |
5852 printf("\tbne\t%s,L_%d\n",crname(cmpflag),dlabel); | |
5853 #else | |
5854 printf("\tbne\t%s,.L%d\n",crname(cmpflag),dlabel); | |
5855 #endif | |
5856 break; | 6016 break; |
5857 default: | 6017 default: |
5858 urn = register_name(u=get_register()); | 6018 urn = register_name(u=get_register()); |
5859 printf("\tli %s,%d\n",srn,delta); | 6019 printf("\tli %s,%d\n",srn,delta); |
5860 printf("\tdivwu %s,%s,%s\n",urn,trn,srn); | 6020 printf("\tdivwu %s,%s,%s\n",urn,trn,srn); |
5861 printf("\tmullw %s,%s,%s\n",srn,urn,srn); | 6021 printf("\tmullw %s,%s,%s\n",srn,urn,srn); |
5862 printf("\tsubf %s,%s,%s\n",srn,trn,srn); | 6022 printf("\tsubf %s,%s,%s\n",srn,trn,srn); |
5863 printf("\tcmplwi %s,%s,0\n",crname(cmpflag),srn); | 6023 printf("\tcmplwi %s,%s,0\n",crname(cmpflag),srn); |
5864 #ifdef __APPLE__ | 6024 printf("\tbne\t%s,%s%d\n",crname(cmpflag),lpfx,dlabel); |
5865 printf("\tbne\t%s,L_%d\n",crname(cmpflag),dlabel); | |
5866 #else | |
5867 printf("\tbne\t%s,.L%d\n",crname(cmpflag),dlabel); | |
5868 #endif | |
5869 printf("\tslwi %s,%s,2\n",trn,urn); | 6025 printf("\tslwi %s,%s,2\n",trn,urn); |
5870 } | 6026 } |
5871 #ifdef __APPLE__ | 6027 #ifdef __APPLE__ |
5872 printf("\taddis %s,r31,ha16(L_%d-L_%d)\n", | 6028 printf("\taddis %s,r31,ha16(L_%d-L_%d)\n", |
5873 srn,l,code_base); | 6029 srn,l,code_base); |
5877 printf("\tlwz r0,0(%s)\n",trn); | 6033 printf("\tlwz r0,0(%s)\n",trn); |
5878 printf("\tadd r0,r0,%s\n",srn); | 6034 printf("\tadd r0,r0,%s\n",srn); |
5879 printf("\tmtctr r0\n"); | 6035 printf("\tmtctr r0\n"); |
5880 printf("\tbctr\n"); | 6036 printf("\tbctr\n"); |
5881 #else | 6037 #else |
5882 printf("\taddis %s,31,L_%d@h\n", | 6038 printf("\taddis %s,31,%s%d@h\n", |
5883 srn,l); | 6039 srn,lpfx,l); |
5884 printf("\tla %s,L_%d@l(%s)\n", | 6040 printf("\tla %s,%s%d@l(%s)\n", |
5885 srn,l,srn); | 6041 srn,lpfx,l,srn); |
5886 printf("\tadd %s,%s,%s\n",trn,srn,trn); | 6042 printf("\tadd %s,%s,%s\n",trn,srn,trn); |
5887 printf("\tlwz 0,0(%s)\n",trn); | 6043 printf("\tlwz 0,0(%s)\n",trn); |
5888 printf("\tadd 0,0,%s\n",srn); | 6044 printf("\tadd 0,0,%s\n",srn); |
5889 printf("\tmtctr 0\n"); | 6045 printf("\tmtctr 0\n"); |
5890 printf("\tbctr\n"); | 6046 printf("\tbctr\n"); |