Mercurial > hg > CbC > old > device
annotate mc-code-mips.c @ 196:5f70abd9453d
*** empty log message ***
author | kono |
---|---|
date | Wed, 07 Apr 2004 21:14:19 +0900 |
parents | c193120ee2a6 |
children | 28baf6cd9ad1 |
rev | line source |
---|---|
131 | 1 /* Micro-C Code Generatation Part for MIPS (PS2Linux) */ |
130 | 2 /* $Id$ */ |
3 | |
4 #define EXTERN extern | |
5 #include "mc.h" | |
6 #include "mc-code.h" | |
7 #include "mc-codegen.h" | |
8 | |
173 | 9 char *l_include_path[] = { |
10 "/usr/include/", | |
11 0 | |
12 }; | |
13 | |
130 | 14 #define TEXT_EMIT_MODE 0 |
15 #define DATA_EMIT_MODE 1 | |
16 #define RODATA_EMIT_MODE 2 | |
17 | |
18 static void data_mode(char *name); | |
163 | 19 static void ld_indexx(int byte, int n, int xreg,int sign); |
130 | 20 static void local_table(void); |
21 static void shift(char *op, int reg); | |
22 static int struct_push(int e4,int t,int arg); | |
23 | |
24 static int output_mode = TEXT_EMIT_MODE; | |
25 static int data_alignment = 0; | |
26 | |
27 static int code_disp_label; | |
152 | 28 static int disp_label; |
130 | 29 static int r1_offset_label; |
30 static int lvar_offset_label; | |
152 | 31 static int cprestore_label; |
130 | 32 |
33 static int reg_save; | |
34 static int freg_save; | |
35 | |
149 | 36 static int freg,ireg,dreg; |
148 | 37 |
38 /* mips requires two registers for compare */ | |
39 static int cmpreg = -1; | |
40 | |
130 | 41 int size_of_int = 4; |
42 int size_of_float = 4; | |
43 int size_of_double = 8; | |
44 int size_of_longlong = 8; | |
45 int endian = 1; | |
46 | |
148 | 47 int reg_sp; /* REGister Stack-Pointer */ |
48 int reg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ | |
49 | |
50 /* floating point registers */ | |
51 | |
52 int freg_sp; /* floating point REGister Stack-Pointer */ | |
53 int freg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ | |
54 | |
55 /* double floating point registers */ | |
56 | |
57 int dreg_sp; /* floating point REGister Stack-Pointer */ | |
58 int dreg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ | |
130 | 59 |
60 #define REG_fp 1 | |
61 #define REG_sp 30 | |
62 #define REG_VAR_BASE 29 | |
131 | 63 #define REG_VAR_MIN 18 |
64 #define MIN_TMP_REG 4 | |
65 #define MAX_TMP_REG 11 | |
130 | 66 |
149 | 67 #define DREG_VAR_BASE 29 |
68 #define DREG_VAR_MIN 18 | |
69 #define MIN_TMP_DREG 4 | |
152 | 70 #define MAX_TMP_DREG 17 |
149 | 71 |
130 | 72 #define PTRC_REG 3 |
73 | |
74 #define FREG_VAR_BASE 31 | |
131 | 75 #define FREG_VAR_MIN 20 |
130 | 76 #define MIN_TMP_FREG 1 |
131 | 77 #define MAX_TMP_FREG 14 |
130 | 78 |
79 #define RET_REGISTER 3 | |
148 | 80 #define RET_FREGISTER (1+FREG_OFFSET) |
81 #define RET_DREGISTER (1+DREG_OFFSET) | |
130 | 82 |
148 | 83 int MAX_REGISTER=30; /* PowerPCのレジスタを10個まで使う*/ |
130 | 84 int MAX_FREGISTER=31; |
148 | 85 int MAX_DREGISTER=16; |
86 #define REAL_MAX_REGISTER 32 /* PowerPCのレジスタが32ということ*/ | |
87 #define REAL_MAX_FREGISTER 32 /* PowerPCのFレジスタが32ということ*/ | |
88 #define REAL_MAX_DREGISTER 31 /* PowerPCのDレジスタ番号が31ということ*/ | |
89 | |
90 #define FREG_OFFSET REAL_MAX_REGISTER | |
91 #define DREG_OFFSET (REAL_MAX_REGISTER+REAL_MAX_FREGISTER ) | |
130 | 92 |
131 | 93 int MAX_INPUT_REGISTER_VAR = 7-MIN_TMP_REG; |
94 int MAX_CODE_INPUT_REGISTER_VAR = 7-MIN_TMP_REG; | |
130 | 95 int MAX_INPUT_DREGISTER_VAR = 14-MIN_TMP_FREG; |
148 | 96 int MAX_INPUT_FREGISTER_VAR = 14-MIN_TMP_FREG; |
130 | 97 int MAX_CODE_INPUT_DREGISTER_VAR = 14-MIN_TMP_FREG; |
148 | 98 int MAX_CODE_INPUT_FREGISTER_VAR = 14-MIN_TMP_FREG; |
130 | 99 |
100 #define CREG_REGISTER MAX_TMP_REG | |
148 | 101 #define FREG_FREGISTER (MAX_TMP_FREG+FREG_OFFSET) |
149 | 102 #define DREG_DREGISTER (2+DREG_OFFSET) |
145 | 103 |
149 | 104 int powerpc_regs[REAL_MAX_REGISTER+REAL_MAX_FREGISTER+REAL_MAX_DREGISTER]; |
105 int powerpc_regv[REAL_MAX_REGISTER+REAL_MAX_FREGISTER+REAL_MAX_DREGISTER]; | |
138 | 106 |
151 | 107 int dreg_pair0[REAL_MAX_DREGISTER] = { |
148 | 108 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30 |
109 }; | |
151 | 110 int dreg_pair1[REAL_MAX_DREGISTER] = { |
148 | 111 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 |
112 }; | |
130 | 113 |
148 | 114 int *regv = powerpc_regv; |
115 int *regs = powerpc_regs; | |
130 | 116 |
117 static int max_reg_var, max_freg_var; | |
148 | 118 static int cond_reg=-1,cond_freg=-1,cond_dreg=-1; |
130 | 119 |
120 static char *reg_name[] = { | |
131 | 121 "$0","$1","$2","$3","$4","$5","$6","$7","$8","$9", |
122 "$10","$11","$12","$13","$14","$15","$16","$17","$18","$19", | |
123 "$20","$21","$22","$23","$24","$25","$26","$27","$28","$29", | |
148 | 124 "$30","$31", |
131 | 125 "$f0","$f1","$f2","$f3","$f4","$f5","$f6","$f7","$f8","$f9", |
126 "$f10","$f11","$f12","$f13","$f14","$f15","$f16","$f17","$f18","$f19", | |
127 "$f20","$f21","$f22","$f23","$f24","$f25","$f26","$f27","$f28","$f29", | |
128 "$f30","$f31" | |
130 | 129 }; |
130 | |
148 | 131 |
132 #define register_name(i) reg_name0(i) | |
133 #define fregister_name(i) reg_name0(i) | |
149 | 134 #define dregister_name0(i) reg_name1(i,dreg_pair0) |
135 #define dregister_name1(i) reg_name1(i,dreg_pair1) | |
148 | 136 |
149 | 137 static char * |
148 | 138 reg_name0(int i) |
139 { | |
140 if (i<=REAL_MAX_REGISTER+REAL_MAX_FREGISTER) | |
141 return reg_name[i]; | |
149 | 142 else { |
148 | 143 error(-1); |
149 | 144 return reg_name[0]; |
145 } | |
148 | 146 } |
147 | |
149 | 148 static char * |
151 | 149 reg_name1(int i,int *d) |
149 | 150 { |
151 if (i<=REAL_MAX_REGISTER+REAL_MAX_FREGISTER) { | |
152 error(-1); | |
153 return reg_name[0]; | |
154 } else | |
155 return reg_name[d[i-DREG_OFFSET]]; | |
156 } | |
157 | |
158 | |
148 | 159 #define is_int_reg(i) (0<=i&&i<REAL_MAX_REGISTER) |
160 #define is_float_reg(i) (REAL_MAX_REGISTER<=i&&i<REAL_MAX_FREGISTER+REAL_MAX_REGISTER) | |
149 | 161 #define is_double_reg(i) (REAL_MAX_REGISTER+REAL_MAX_FREGISTER<=i&&i<REAL_MAX_FREGISTER+REAL_MAX_REGISTER+REAL_MAX_DREGISTER) |
148 | 162 |
130 | 163 |
148 | 164 int use_int(int i) { |
165 if (!is_int_reg(i)) i = ireg; | |
166 if (!regs[i]) regs[i]=1; | |
167 return i; | |
168 } | |
169 | |
170 int use_float(int i) { | |
171 if (!is_float_reg(i)) i = freg; | |
172 if (!regs[i]) regs[i]=1; | |
173 return i; | |
174 } | |
175 | |
176 int use_double(int i) { | |
177 if (!is_double_reg(i)) i = dreg; | |
178 if (!regs[i]) regs[i]=1; | |
179 return i; | |
180 } | |
130 | 181 |
195 | 182 int use_longlong(int i) { |
183 return i; | |
184 } | |
185 | |
186 #if FLOAT_CODE | |
149 | 187 static int code_d1(double d); |
188 static int code_d2(double d); | |
195 | 189 #endif |
149 | 190 |
130 | 191 static void code_save_stacks(); |
192 static void code_save_input_registers(); | |
193 static void set_creg(int,int); | |
194 static void set_freg(int,int); | |
148 | 195 static void set_dreg(int,int); |
130 | 196 |
136
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
197 static int mask_label; |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
198 static int mask1_label; |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
199 static int fmask_label; |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
200 static int fmask1_label; |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
201 |
131 | 202 static FILE *asi; |
148 | 203 |
153 | 204 static int max_func_args; |
205 static int max_func_iargs; | |
206 static int my_func_args; | |
130 | 207 #define ARG_LVAR_OFFSET 0x10000000 |
208 | |
131 | 209 #define DOT_SIZE 1 |
210 | |
130 | 211 /* |
212 | |
152 | 213 Reorder is automatically done in assembler. |
214 delayed slot done within .set noreorder. | |
215 | |
130 | 216 r0 return value etc. |
152 | 217 $2,$3 return value. (dpcmp return value on $2) |
218 $0 special register | |
219 $4-$7 input register | |
130 | 220 r22-r29 saved register variable (input register for code segement) |
152 | 221 $31 stack pointer |
222 $fp frame pointer | |
130 | 223 |
152 | 224 $f0 return value etc. |
225 $f14,$f12 input register | |
226 $f20-$f31 saved register variable | |
130 | 227 |
228 function call stack frame | |
229 <------r1_offset------------------------------> | |
230 <------------lvar_offset-------> | |
231 r+ +------------+---+---------------+----------+--------------+----+ - | |
232 callee arg xx register save local caller arg xx | |
233 reg_save disp max_func_args*size_of_int | |
234 lvar>0 lvar<0 lvar>0x1000 0000 | |
235 | |
236 code segment stack frame | |
237 | |
238 * gotoを呼び出した関数のr1 ! r1(goto前のr1) | |
239 # * r30 <---r1_offset---------> r1 | |
240 r+ +----------+--+----------+----------------+-----------+----------+----+ | |
241 cousin arg xx reg save !callee arg !code local caller arg xx | |
242 r20-r29 lvar>0 lvar<0 lvar>0x1000 000 | |
243 f20-f31 <-my_func_args--><--disp-----><-max_func_arg-> | |
244 *size_of_int *size_of_int | |
245 | |
246 */ | |
247 int arg_offset = 24; int arg_offset1 = 24; int disp_offset = -12; | |
248 #define func_disp_offset 60 | |
249 #define r1_offset func_disp_offset+12 | |
250 int code_disp_offset = 0; int jump_offset = 0; | |
251 #define CODE_LVAR l+code_disp_offset | |
252 #define CODE_CALLER_ARG (l-ARG_LVAR_OFFSET)+arg_offset1 | |
253 #define FUNC_LVAR l+disp_offset | |
254 #define CALLER_ARG (l-ARG_LVAR_OFFSET)+arg_offset1 | |
255 #define CALLEE_ARG l+arg_offset | |
256 | |
257 void | |
258 code_offset_set() | |
259 { | |
260 #if 0 | |
261 int l; | |
262 #endif | |
263 int lvar_offsetv = -disp+max_func_args*size_of_int+func_disp_offset; | |
264 int r1_offsetv = -disp+max_func_args*size_of_int-reg_save+r1_offset; | |
153 | 265 printf("L_%d = %d\n",lvar_offset_label,lvar_offsetv); |
266 printf("L_%d = %d\n",r1_offset_label,r1_offsetv); | |
130 | 267 #if 0 |
268 printf("# function %s\n",fnptr->nm); | |
269 l = ARG_LVAR_OFFSET; | |
270 printf("# offset call0\t%d\n",CALLER_ARG); | |
271 l = ARG_LVAR_OFFSET+max_func_args*size_of_int; | |
272 printf("# offset calln\t%d %d\n",CALLER_ARG,max_func_args*size_of_int); | |
273 l = disp; | |
274 printf("# offset lvarn\t%d %d\n",FUNC_LVAR+lvar_offsetv,disp); | |
275 l = 0; | |
276 printf("# offset lvar0\t%d\n",FUNC_LVAR+lvar_offsetv); | |
277 l = -reg_save; | |
278 printf("# offset regs\t%d\n",FUNC_LVAR+lvar_offsetv); | |
279 printf("# offset r1off\t%d\n",r1_offsetv); | |
280 l = 0; | |
281 printf("# offset carg0\t%d\n",CALLEE_ARG+r1_offsetv); | |
282 l = my_func_args; | |
283 printf("# offset cargn\t%d %d\n",CALLEE_ARG+r1_offsetv,my_func_args); | |
284 #endif | |
285 } | |
286 | |
287 static void | |
131 | 288 lvar(int l) |
130 | 289 { |
290 if (fnptr->sc==CODE) { | |
148 | 291 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ |
292 printf("%d($fp)\n",CODE_CALLER_ARG); | |
293 } else | |
294 printf("%d($fp)\n",CODE_LVAR); | |
130 | 295 } else if (l<0) { /* local variable */ |
148 | 296 printf("%d+L_%d($fp)\n",FUNC_LVAR,lvar_offset_label); |
130 | 297 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ |
148 | 298 printf("%d($fp)\n",CALLER_ARG); |
130 | 299 } else { /* callee's arguments */ |
148 | 300 printf("%d+L_%d($fp)\n",CALLEE_ARG,r1_offset_label); |
130 | 301 } |
302 } | |
303 | |
304 static void | |
131 | 305 lvar_address(int l,int creg) |
130 | 306 { |
307 if (fnptr->sc==CODE) { | |
148 | 308 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ |
309 printf("\taddu\t%s,$fp,%d\n",register_name(creg),CODE_CALLER_ARG); | |
310 } else | |
311 printf("\taddu\t%s,$fp,%d\n",register_name(creg),CODE_LVAR); | |
130 | 312 } else if (l<0) { /* local variable */ |
148 | 313 printf("\taddu\t%s,$fp,%d+L_%d\n",register_name(creg),FUNC_LVAR,lvar_offset_label); |
130 | 314 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ |
148 | 315 printf("\taddu\t%s,$fp,%d\n",register_name(creg),CALLER_ARG); |
130 | 316 } else { /* callee's arguments */ |
148 | 317 printf("\taddu\t%s,$fp,%d+L_%d\n",register_name(creg),CALLEE_ARG,r1_offset_label); |
130 | 318 } |
319 } | |
320 | |
321 void | |
322 code_lvar(int e2,int creg) { | |
131 | 323 lvar_address(e2,creg); |
130 | 324 regv[creg]=1; |
325 } | |
326 | |
327 void | |
328 code_init(void) | |
329 { | |
131 | 330 /* this is called once program call */ |
130 | 331 } |
332 | |
333 void | |
334 gexpr_code_init(void){ | |
335 regv[creg]=0; | |
148 | 336 regv[freg]=0; |
130 | 337 } |
338 | |
137 | 339 void |
148 | 340 code_gexpr(int e){ |
341 if (is_int_reg(creg) && creg!=ireg) error(-1); | |
342 } | |
343 | |
344 | |
345 void | |
137 | 346 code_arg_register(NMTBL *fnptr) |
347 { | |
348 int args = fnptr->dsp; | |
349 NMTBL *n; | |
350 int reg_var = 0; | |
351 int freg_var = 0; | |
352 int type; | |
353 int reg; | |
354 int is_code0 = is_code(fnptr); | |
130 | 355 |
137 | 356 while (args) { |
357 /* process in reverse order */ | |
358 n = (NMTBL*)caddr(args); | |
359 type = n->ty; | |
360 if (scalar(type)) { | |
361 if ((reg = get_input_register_var(reg_var,n,is_code0))) { | |
362 n->sc = REGISTER; | |
363 n->dsp = cadr(reg); | |
364 regv[n->dsp]= 1; | |
365 regs[n->dsp]= INPUT_REG; | |
366 reg_var++; | |
367 cadddr(args)=size_of_int; /* why we need this? */ | |
368 } | |
369 } else if (type==FLOAT) { | |
138 | 370 if ((reg = get_input_dregister_var(freg_var,n,is_code0,0))) { |
141 | 371 n->sc = FREGISTER; |
137 | 372 n->dsp = cadr(reg); |
148 | 373 regv[n->dsp]= 1; |
374 regs[n->dsp]= INPUT_REG; | |
375 freg_var++; | |
137 | 376 cadddr(args)=size(type); /* why we need this? */ |
377 } | |
378 } else if (type==DOUBLE) { | |
141 | 379 if ((reg = get_input_dregister_var(reg_var,n,is_code0,1))) { |
137 | 380 n->sc = DREGISTER; |
381 n->dsp = cadr(reg); | |
148 | 382 regv[n->dsp]= 1; |
383 regs[n->dsp]= INPUT_REG; | |
141 | 384 reg_var+=2; |
137 | 385 cadddr(args)=size(type); /* why we need this? */ |
386 } | |
387 } | |
388 args = cadr(args); | |
389 } | |
130 | 390 if (is_function(fnptr)) |
148 | 391 code_save_input_registers(); |
130 | 392 } |
393 | |
394 int | |
395 get_register(void) | |
396 { /* 使われていないレジスタを調べる */ | |
397 int i,reg; | |
398 for(i=MAX_TMP_REG;i>MIN_TMP_REG;i--) { | |
399 if (regs[i]) continue; /* 使われている */ | |
400 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ | |
401 return i; /* その場所を表す番号を返す */ | |
402 } | |
403 /* search register stack */ | |
404 for(i=0;i<reg_sp;i++) { | |
405 if ((reg=reg_stack[i])>=0) { | |
406 code_assign_lvar( | |
407 (reg_stack[i]=new_lvar(size_of_int)),reg,0); | |
408 reg_stack[i]= reg_stack[i]-REG_LVAR_OFFSET; | |
409 return reg; | |
410 } | |
411 } | |
195 | 412 #if FLOAT_CODE |
148 | 413 /* search dregister stack */ |
414 for(i=0;i<dreg_sp;i++) { | |
415 if ((reg=dreg_stack[i])>=0) { | |
416 code_dassign_lvar( | |
417 (dreg_stack[i]=new_lvar(size_of_double)),reg,1); | |
418 dreg_stack[i]= dreg_stack[i]-REG_LVAR_OFFSET; | |
149 | 419 free_register(reg); |
148 | 420 return get_register(); /* 今度は必ずある */ |
421 } | |
422 } | |
195 | 423 #endif |
131 | 424 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) { |
425 reg =REG_VAR_BASE-i; | |
426 if (! regs[reg]) { /* 使われていないなら */ | |
427 regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */ | |
428 regv[reg]=0; | |
429 if (i>max_reg_var) max_reg_var=i; | |
430 return reg; | |
431 } | |
432 } | |
130 | 433 /* 空いている場所がないなら、エラー (いったい誰が使ってるの?) */ |
148 | 434 error(HPERR); return creg; |
130 | 435 } |
436 | |
437 int | |
438 pop_register(void) | |
439 { /* レジスタから値を取り出す */ | |
440 return reg_stack[--reg_sp]; | |
441 } | |
442 | |
195 | 443 #if FLOAT_CODE |
444 | |
148 | 445 static int |
446 get_dregister1() { | |
149 | 447 int i; |
151 | 448 for(i=MAX_TMP_DREG+DREG_OFFSET;i>MIN_TMP_DREG+DREG_OFFSET;i--) { |
148 | 449 if (regs[i]) continue; /* 使われている */ |
450 if (regs[dreg_pair0[i-DREG_OFFSET]]) continue; | |
451 if (regs[dreg_pair1[i-DREG_OFFSET]]) continue; | |
452 regs[dreg_pair0[i-DREG_OFFSET]]=USING_REG; | |
453 regs[dreg_pair1[i-DREG_OFFSET]]=USING_REG; | |
454 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ | |
455 return i; /* その場所を表す番号を返す */ | |
456 } | |
457 return -1; | |
458 } | |
459 | |
460 static int | |
461 get_dregister0() | |
462 { | |
149 | 463 int reg,i; |
148 | 464 /* とりあえず、空き int register pair を探す */ |
465 if ((i=get_dregister1())!=-1) { | |
466 return i; | |
467 } | |
468 /* search dregister stack */ | |
469 for(i=0;i<dreg_sp;i++) { | |
470 if ((reg=dreg_stack[i])>=0) { | |
471 code_dassign_lvar( | |
472 (dreg_stack[i]=new_lvar(size_of_double)),reg,1); | |
473 dreg_stack[i]= dreg_stack[i]-REG_LVAR_OFFSET; | |
152 | 474 return reg; |
148 | 475 } |
476 } | |
477 /* clear integer register stack */ | |
478 for(i=0;i<reg_sp;i++) { | |
479 if ((reg=reg_stack[i])>=0) { | |
480 code_assign_lvar( | |
481 (reg_stack[i]=new_lvar(size_of_int)),reg,0); | |
482 reg_stack[i]= reg_stack[i]-REG_LVAR_OFFSET; | |
483 free_register(reg); | |
484 } | |
485 } | |
486 if ((i=get_dregister1())!=-1) { | |
487 return i; | |
488 } | |
489 | |
490 error(REG_ERR); return dreg; | |
491 } | |
492 | |
493 static int | |
494 get_fregister0() | |
130 | 495 { /* 使われていないレジスタを調べる */ |
148 | 496 int i,reg; |
497 for(i=MAX_TMP_FREG+FREG_OFFSET;i>MIN_TMP_FREG+FREG_OFFSET;i--) { | |
498 if (regs[i]) continue; /* 使われている */ | |
499 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ | |
130 | 500 return i; /* その場所を表す番号を返す */ |
501 } | |
502 /* search register stack */ | |
503 for(i=0;i<freg_sp;i++) { | |
504 if ((reg=freg_stack[i])>=0) { | |
505 code_dassign_lvar( | |
153 | 506 (freg_stack[i]=new_lvar(size_of_float)),reg,0); |
130 | 507 freg_stack[i]= freg_stack[i]-REG_LVAR_OFFSET; |
508 return reg; | |
509 } | |
510 } | |
131 | 511 for(i=0;i<FREG_VAR_BASE-REG_VAR_MIN;i++) { |
148 | 512 reg =FREG_VAR_BASE-i+FREG_OFFSET; |
513 if (! regs[reg]) { /* 使われていないなら */ | |
514 regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */ | |
515 regv[reg]=0; | |
131 | 516 if (i>max_freg_var) max_freg_var=i; |
517 return reg; | |
518 } | |
519 } | |
130 | 520 /* 空いている場所がないなら、エラー (いったい誰が使ってるの?) */ |
521 error(REG_ERR); return freg; | |
522 } | |
523 | |
148 | 524 int |
525 get_dregister(int d) | |
149 | 526 { |
148 | 527 if (d) { |
528 return get_dregister0(); | |
529 } else { | |
530 return get_fregister0(); | |
531 } | |
532 } | |
533 | |
130 | 534 int |
535 pop_fregister(void) | |
536 { /* レジスタから値を取り出す */ | |
537 return freg_stack[--freg_sp]; | |
538 } | |
539 | |
148 | 540 int |
541 pop_dregister(void) | |
542 { /* レジスタから値を取り出す */ | |
543 return dreg_stack[--dreg_sp]; | |
544 } | |
195 | 545 #endif |
546 | |
547 #if LONGLONG_CODE | |
548 int | |
549 get_lregister_var(NMTBL *n) | |
550 { | |
551 return -1; | |
552 } | |
553 #endif | |
554 | |
148 | 555 |
130 | 556 void |
557 emit_pop_free(int xreg) | |
558 { | |
559 if (xreg>=0) | |
560 free_register(xreg); | |
561 } | |
562 | |
563 void | |
564 free_register(int i) { /* いらなくなったレジスタを開放 */ | |
148 | 565 int i0,i1; |
566 if (i<0||MAX_FREGISTER+FREG_OFFSET+REAL_MAX_DREGISTER<i) error(-1); | |
567 if (is_double_reg(i)) { | |
568 i0 = dreg_pair0[i-DREG_OFFSET]; | |
569 regv[i0]=regs[i0]=0; | |
570 i1 = dreg_pair1[i-DREG_OFFSET]; | |
571 regv[i1]=regs[i1]=0; | |
572 } | |
130 | 573 regv[i]=regs[i]=0; |
574 } | |
575 | |
576 int | |
138 | 577 get_input_dregister_var(int i,NMTBL *n,int is_code,int d) |
130 | 578 { |
148 | 579 if (d) { |
580 if (is_code) { | |
581 if(!(i<DREG_VAR_BASE-DREG_VAR_MIN)) return 0; | |
582 i = DREG_VAR_BASE-i+DREG_OFFSET; | |
141 | 583 } else { |
148 | 584 if (i<0||i>=MAX_INPUT_DREGISTER_VAR) return 0; |
585 i = i+MIN_TMP_DREG+DREG_OFFSET; | |
141 | 586 } |
148 | 587 return list3(DREGISTER,i,(int)n); |
141 | 588 } else { |
148 | 589 if (is_code) { |
590 if(!(i<FREG_VAR_BASE-FREG_VAR_MIN)) return 0; | |
591 i = FREG_VAR_BASE-i+FREG_OFFSET; | |
141 | 592 } else { |
148 | 593 if (i<0||i>=MAX_INPUT_FREGISTER_VAR) return 0; |
594 i = i+MIN_TMP_FREG+FREG_OFFSET; | |
141 | 595 } |
148 | 596 return list3(FREGISTER,i,(int)n); |
141 | 597 } |
130 | 598 } |
599 | |
600 int | |
601 get_input_register_var(int i,NMTBL *n,int is_code) | |
602 { | |
603 if (is_code) { | |
131 | 604 if(!(i<REG_VAR_BASE-REG_VAR_MIN)) return 0; |
130 | 605 i = REG_VAR_BASE-i; |
606 } else { | |
148 | 607 if (i<0||i>=MAX_INPUT_REGISTER_VAR) return 0; |
608 i = i+MIN_TMP_REG; | |
609 } | |
610 return list3(REGISTER,i,(int)n); | |
611 } | |
612 | |
613 /* double register case? */ | |
614 | |
615 int | |
616 get_input_register_var_1(int i,NMTBL *n,int is_code) | |
617 { | |
618 if (is_code) { | |
619 if(!(i<REG_VAR_BASE-REG_VAR_MIN)) return 0; | |
620 i = REG_VAR_BASE-i; | |
621 } else { | |
622 if (i<0||i>=MAX_INPUT_REGISTER_VAR+1) return 0; | |
130 | 623 i = i+MIN_TMP_REG; |
624 } | |
625 return list3(REGISTER,i,(int)n); | |
626 } | |
627 | |
628 int | |
137 | 629 free_register_count(int d) |
130 | 630 { |
631 int i,count,fcount; | |
632 fcount = count = 0; | |
633 for(i=0;i<MAX_REGISTER;i++) { | |
634 if (! regs[i] && ! regv[i]) count++; | |
635 } | |
636 for(i=0;i<MAX_FREGISTER;i++) { | |
148 | 637 if (! regs[i+FREG_OFFSET] && ! regv[i+FREG_OFFSET]) fcount++; |
130 | 638 } |
148 | 639 printf("# free reg %d freg %d\n",count,fcount); |
137 | 640 return d?fcount:count; |
130 | 641 } |
642 | |
643 int | |
644 register_full(void) | |
645 { | |
646 int i; | |
647 for(i=0;i<MAX_REGISTER;i++) { | |
648 if (! regs[i]) { | |
649 return 0; | |
650 } | |
651 } | |
652 return 1; | |
653 } | |
654 | |
655 void | |
656 free_all_register(void) | |
657 { | |
658 int i; | |
659 for(i=0;i<MAX_REGISTER;i++) { regs[i]=0; regv[i]=0; } | |
148 | 660 for(i=0;i<MAX_FREGISTER;i++) { regs[i+FREG_OFFSET]=0; regv[i+FREG_OFFSET]=0; } |
661 for(i=0;i<MAX_DREGISTER;i++) { regs[i+DREG_OFFSET]=0; regv[i+DREG_OFFSET]=0; } | |
130 | 662 creg = get_register(); |
195 | 663 #if FLOAT_CODE |
138 | 664 freg = get_dregister(0); |
150 | 665 dreg = DREG_DREGISTER; |
195 | 666 #endif |
130 | 667 set_creg(CREG_REGISTER,0); |
668 set_freg(FREG_FREGISTER,0); | |
148 | 669 set_dreg(DREG_DREGISTER,0); |
130 | 670 return; |
671 } | |
672 | |
673 void | |
674 register_usage(char *s) | |
675 { | |
676 #if 0 | |
677 int i; | |
678 #endif | |
679 if (chk) return; | |
680 if (!lsrc) return; | |
681 printf("# %d: %s:",lineno,s); | |
150 | 682 printf(" creg=%s ireg=%s freg=%s dreg=%s", |
683 is_int_reg(creg)?register_name(creg): | |
684 is_float_reg(creg)?fregister_name(creg): | |
685 is_double_reg(creg)?dregister_name0(creg):"bad", | |
686 register_name(ireg),fregister_name(freg),dregister_name0(dreg)); | |
130 | 687 #if 0 |
688 printf("\n# regs:"); | |
689 for(i=0;i<MAX_REGISTER;i++) { printf("%d",regv[i]); } | |
690 printf(":"); | |
691 for(i=0;i<MAX_REGISTER;i++) { printf("%d",regs[i]); } | |
692 printf("\n# freg:"); | |
148 | 693 for(i=0;i<MAX_FREGISTER;i++) { printf("%d",regs[i+FREG_OFFSET]); } |
130 | 694 for(i=reg_sp;i>=0;i--) { |
695 if(reg_stack[i]>=0) | |
148 | 696 printf(" %s",register_name(reg_stack[i])); |
130 | 697 } |
698 #endif | |
699 printf("\n"); | |
700 } | |
701 | |
702 void | |
703 gexpr_init(void) | |
704 { | |
705 while(reg_sp > 0) { | |
706 free_register(reg_stack[--reg_sp]); | |
707 } | |
148 | 708 while(freg_sp > 0) { |
709 free_register(freg_stack[--freg_sp]); | |
710 } | |
711 while(dreg_sp > 0) { | |
712 free_register(dreg_stack[--dreg_sp]); | |
713 } | |
130 | 714 if (cond_freg!=-1) { |
148 | 715 if(car(cond_freg)==FREGISTER) free_register(cadr(cond_freg)); |
130 | 716 cond_freg=-1; |
717 } | |
148 | 718 if (cond_dreg!=-1) { |
719 if(car(cond_dreg)==DREGISTER) free_register(cadr(cond_dreg)); | |
720 cond_dreg=-1; | |
721 } | |
130 | 722 if (cond_reg!=-1) { |
723 if(car(cond_reg)==REGISTER) free_register(cadr(cond_reg)); | |
724 cond_reg=-1; | |
725 } | |
148 | 726 cmpreg = -1; |
130 | 727 text_mode(); |
728 gexpr_code_init(); | |
729 register_usage("gexpr_init"); | |
730 } | |
731 | |
732 | |
733 void | |
734 emit_init(void) | |
735 { | |
736 free_all_register(); | |
737 max_reg_var=-1; max_freg_var=-1; | |
738 reg_sp = 0; | |
739 freg_sp = 0; | |
148 | 740 dreg_sp = 0; |
130 | 741 text_mode(); |
742 } | |
743 | |
744 int | |
745 register_var(int r) { | |
746 return r; | |
747 } | |
748 | |
749 | |
750 int | |
751 get_register_var(NMTBL *n) | |
752 { | |
753 int i; | |
754 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) { | |
148 | 755 if (! regs[REG_VAR_BASE-i]) { /* 使われていないなら */ |
756 /* そのレジスタを使うことを宣言し */ | |
757 regs[REG_VAR_BASE-i]=USING_REG; | |
758 regv[REG_VAR_BASE-i]=0; | |
130 | 759 if (i>max_reg_var) max_reg_var=i; |
760 /* その場所を表す番号を返す */ | |
761 return list3(REGISTER,REG_VAR_BASE-i,(int)n); | |
148 | 762 } |
130 | 763 } |
764 return list2(LVAR,new_lvar(size_of_int)); | |
765 } | |
766 | |
767 int | |
768 fregister_var(int r) { | |
769 return r; | |
770 } | |
771 | |
772 int | |
138 | 773 get_dregister_var(NMTBL *n,int d) |
130 | 774 { |
148 | 775 int i,j; |
776 if (d) { | |
777 for(i=0;i<DREG_VAR_BASE-DREG_VAR_MIN;i++) { | |
149 | 778 if (! regs[j=(DREG_VAR_BASE-i+DREG_OFFSET)]) { /* 使われていないなら */ |
148 | 779 if (regs[dreg_pair0[j]] || regs[dreg_pair1[j]]) continue; |
780 regs[DREG_VAR_BASE-i+DREG_OFFSET]=USING_REG; /*そのレジスタを使うことを宣言し*/ | |
781 regv[DREG_VAR_BASE-i+DREG_OFFSET]=0; | |
782 regs[dreg_pair0[j]] = regs[dreg_pair1[j]] = USING_REG; | |
783 regv[dreg_pair0[j]] = regv[dreg_pair1[j]] = 0; | |
149 | 784 if (dreg_pair1[j]>max_reg_var) max_reg_var=dreg_pair1[j]; |
148 | 785 /* その場所を表す番号を返す */ |
786 return list3(DREGISTER,DREG_VAR_BASE-i+DREG_OFFSET,(int)n); | |
787 } | |
788 } | |
789 return list2(LVAR,new_lvar(size_of_double)); | |
790 } else { | |
791 for(i=0;i<FREG_VAR_BASE-FREG_VAR_MIN;i++) { | |
792 if (! regs[FREG_VAR_BASE-i+FREG_OFFSET]) { /* 使われていないなら */ | |
793 regs[FREG_VAR_BASE-i+FREG_OFFSET]=USING_REG; /*そのレジスタを使うことを宣言し*/ | |
794 regv[FREG_VAR_BASE-i+FREG_OFFSET]=0; | |
795 if (i>max_freg_var) max_freg_var=i; | |
796 /* その場所を表す番号を返す */ | |
797 return list3(FREGISTER,FREG_VAR_BASE-i+FREG_OFFSET,(int)n); | |
798 } | |
799 } | |
800 return list2(LVAR,new_lvar(size_of_float)); | |
130 | 801 } |
802 } | |
803 | |
804 void | |
805 emit_push() | |
806 { | |
807 int new_reg; | |
808 if (reg_sp>MAX_MAX) error(-1); | |
809 new_reg = get_register(); | |
810 reg_stack[reg_sp++] = creg; /* push するかわりにレジスタを使う */ | |
148 | 811 ireg = creg = new_reg; |
130 | 812 regv[creg]=1; |
813 } | |
814 | |
815 int | |
816 emit_pop(int type) | |
817 { | |
818 int xreg,reg; | |
819 xreg=pop_register(); | |
820 if (xreg<= -REG_LVAR_OFFSET) { | |
821 reg = get_register(); | |
822 code_rlvar(REG_LVAR_OFFSET+xreg,reg); | |
823 free_lvar(REG_LVAR_OFFSET+xreg); | |
824 xreg = reg; | |
148 | 825 regv[creg]=1; |
130 | 826 } |
827 return xreg; | |
828 } | |
829 | |
830 void | |
831 code_label(int labelno) | |
832 { | |
833 printf("L_%d:\n",labelno); | |
834 } | |
835 | |
836 void | |
837 code_gvar(int e1,int creg) { | |
136
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
838 printf("\tla %s,%s\n",register_name(creg),((NMTBL*)cadr(e1))->nm); |
130 | 839 regv[creg]=1; |
840 } | |
841 | |
842 void | |
843 code_rgvar(int e1,int creg) { | |
136
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
844 printf("\tlw %s,%s\n",register_name(creg),((NMTBL*)cadr(e1))->nm); |
130 | 845 regv[creg]=1; |
846 } | |
167 | 847 char *cload(int sign,int sz) { return sz==1?(sign?"lbu":"lb"):(sz==size_of_short?(sign?"lhu":"lh"):"lw");} |
168 | 848 char *cstore(int sz) { return sz==1?"sb":(sz==size_of_short)?"sh":"sw";} |
130 | 849 void |
167 | 850 code_crgvar(int e1,int creg,int sign,int sz){ |
851 printf("\t%s %s,%s\n",cload(sign,sz),register_name(creg),((NMTBL*)cadr(e1))->nm); | |
130 | 852 regv[creg]=1; |
853 } | |
854 | |
855 | |
856 void | |
857 code_register(int e2,int creg) { | |
858 if (creg!=e2) | |
148 | 859 printf("\tmove %s,%s\n",register_name(creg),register_name(e2)); |
130 | 860 regv[creg]=1; |
861 } | |
862 | |
863 | |
864 void | |
865 code_rlvar(int e2,int reg) { | |
131 | 866 printf("\tlw %s,",register_name(reg)); |
130 | 867 lvar(e2); |
868 regv[creg]=1; | |
869 } | |
870 | |
871 | |
872 void | |
167 | 873 code_crlvar(int e2,int reg,int sign,int sz) { |
874 printf("\t%s %s,",cload(sign,sz),register_name(reg)); | |
130 | 875 lvar(e2); |
876 regv[reg]=1; | |
877 } | |
878 | |
879 | |
880 void | |
881 code_fname(NMTBL *n,int creg) { | |
136
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
882 printf("\tla %s,%s\n",register_name(creg),n->nm); |
130 | 883 regv[creg]=1; |
884 } | |
885 | |
886 | |
887 void | |
888 code_const(int e2,int creg) { | |
131 | 889 printf("\tli %s,%d\n",register_name(creg),e2); |
130 | 890 regv[creg]=1; |
891 } | |
892 | |
893 | |
894 void | |
895 code_neg(int creg) { | |
131 | 896 printf("\tsubu %s,$0,%s\n", register_name(creg), register_name(creg)); |
130 | 897 } |
898 | |
899 | |
900 void | |
901 code_not(int creg) { | |
902 printf("\tnor %s,%s,%s\n", | |
148 | 903 register_name(creg), register_name(creg),register_name(creg)); |
130 | 904 } |
905 | |
906 | |
907 void | |
908 code_lnot(int creg) { | |
131 | 909 /* if non zero 1 else 0 */ |
910 int dreg = get_register(); | |
911 printf("\txori %s,%s,0x0\n", | |
148 | 912 register_name(dreg),register_name(creg)); |
131 | 913 printf("\tsltu %s,%s,1\n", |
148 | 914 register_name(creg),register_name(dreg)); |
131 | 915 free_register(dreg); |
130 | 916 } |
917 | |
918 void | |
168 | 919 code_preinc(int e1,int e2,int dir,int sign,int sz,int reg) { |
130 | 920 char *xrn,*drn; |
921 int i,dreg; | |
922 if (car(e2)==REGISTER) { | |
148 | 923 printf("\taddu %s,%s,%d\n", |
168 | 924 register_name(cadr(e2)),register_name(cadr(e2)), dir); |
148 | 925 if (cadr(reg)!=e2) |
926 printf("\tmove %s,%s\n",register_name(cadr(reg)),register_name(e2)); | |
927 regv[reg]=1; | |
928 return; | |
130 | 929 } |
930 g_expr(e2); | |
931 xrn = register_name(creg); | |
932 dreg=get_register(); if (!dreg) error(-1); | |
933 drn = register_name(dreg); | |
168 | 934 printf("\t%s %s,0(%s)\n",cload(sign,sz),drn,xrn); |
935 printf("\taddu %s,%s,%d\n",drn,drn,dir); | |
936 printf("\t%s %s,0(%s)\n",cstore(sz),drn,xrn); | |
130 | 937 i=creg;creg=dreg;dreg=i; |
150 | 938 regv[creg]=1; ireg=creg; |
130 | 939 free_register(dreg); |
940 } | |
941 | |
942 | |
943 void | |
168 | 944 code_postinc(int e1,int e2,int dir,int sign,int sz,int reg) { |
130 | 945 char *xrn,*crn,*nrn; |
946 int dreg,nreg,i; | |
947 if (car(e2)==REGISTER) { | |
148 | 948 printf("\tmove %s,%s\n",register_name(reg),register_name(cadr(e2))); |
949 printf("\taddu %s,%s,%d\n", | |
168 | 950 register_name(cadr(e2)),register_name(cadr(e2)),dir); |
148 | 951 regv[reg]=1; |
952 return; | |
130 | 953 } |
954 g_expr(e2); | |
955 crn = register_name(creg); | |
956 dreg=get_register(); if (!dreg) error(-1); | |
957 xrn = register_name(dreg); | |
958 nreg=get_register(); if (!nreg) error(-1); | |
959 nrn = register_name(nreg); | |
168 | 960 printf("\t%s %s,0(%s)\n",cload(sign,sz),xrn,crn); |
961 printf("\taddu %s,%s,%d\n",nrn,xrn,dir); | |
962 printf("\t%s %s,0(%s)\n",cstore(sz),nrn,crn); | |
963 i=creg;creg=dreg;dreg=i; | |
130 | 964 free_register(nreg); |
965 free_register(dreg); | |
150 | 966 regv[creg]=1; ireg=creg; |
130 | 967 } |
968 | |
969 | |
970 | |
971 void | |
972 code_return(int creg) { | |
973 char *crn = register_name(creg); | |
131 | 974 printf("\tla %s,L_%d\n",crn,retcont); |
130 | 975 } |
976 | |
977 #define R1SAVE 1 | |
978 | |
979 void | |
980 code_environment(int creg) { | |
981 /* save frame pointer */ | |
982 #if R1SAVE | |
131 | 983 printf("\tlw %s,0($fp)\n",register_name(creg)); |
130 | 984 #else |
985 int l = 0; | |
131 | 986 printf("\taddu %s,",register_name(creg)); |
987 printf("$fp,%d+L_%d\n",FUNC_LVAR,lvar_offset_label); | |
130 | 988 #endif |
989 } | |
990 | |
991 void | |
992 code_bool(int e1) { | |
993 char *xrn; | |
994 int e2,e3; | |
995 b_expr(e1,1,e2=fwdlabel(),1); /* including > < ... */ | |
150 | 996 creg = use_int(creg); |
130 | 997 xrn = register_name(creg); |
998 printf("\tli %s,0\n",xrn); | |
999 jmp(e3=fwdlabel()); | |
1000 fwddef(e2); | |
1001 printf("\tli %s,1\n",xrn); | |
1002 fwddef(e3); | |
1003 } | |
1004 | |
1005 char * | |
1006 code_gt(int cond) { | |
152 | 1007 return (cond?"\tslt %s,%s,%s\n\tbeq %s,$0,L_%d\n": |
1008 "\tslt %s,%s,%s\n\tbne %s,$0,L_%d\n"); | |
130 | 1009 } |
1010 | |
1011 char * | |
1012 code_ugt(int cond) { | |
152 | 1013 return (cond?"\tsltu %s,%s,%s\n\tbeq %s,$0,L_%d\n": |
1014 "\tsltu %s,%s,%s\n\tbne %s,$0,L_%d\n"); | |
130 | 1015 } |
1016 | |
1017 char * | |
1018 code_ge(int cond) { | |
152 | 1019 return (cond?"\tslt %s,%s,%s\n\txori %s,%s,0x1\n\tbeq %s,$0,L_%d\n": |
1020 "\tslt %s,%s,%s\n\txori %s,%s,0x1\n\tbne %s,$0,L_%d\n"); | |
130 | 1021 } |
1022 | |
1023 char * | |
1024 code_uge(int cond) { | |
152 | 1025 return (cond?"\tsltu %s,%s,%s\n\txori %s,%s,0x1\n\tbeq %s,$0,L_%d\n": |
1026 "\tsltu %s,%s,%s\n\txori %s,%s,0x1\n\tbne %s,$0,L_%d\n"); | |
130 | 1027 } |
1028 | |
1029 char * | |
1030 code_eq(int cond) { | |
152 | 1031 return (cond?"\tbeq %s,%s,L_%d\n":"\tbne %s,%s,L_%d\n"); |
130 | 1032 } |
1033 | |
1034 void | |
167 | 1035 code_cmp_crgvar(int e1,int sz) { |
148 | 1036 if (cmpreg==-1) cmpreg = get_register(); |
167 | 1037 code_crgvar(cadr(e1),cmpreg,1,sz); |
148 | 1038 regv[cmpreg]=1; |
130 | 1039 } |
1040 | |
1041 | |
1042 void | |
167 | 1043 code_cmp_crlvar(int e2,int sz) { |
148 | 1044 if (cmpreg==-1) cmpreg = get_register(); |
167 | 1045 code_crlvar(e2,cmpreg,1,sz); |
148 | 1046 regv[cmpreg]=1; |
130 | 1047 } |
1048 | |
1049 | |
1050 void | |
1051 code_cmp_rgvar(int e1) { | |
148 | 1052 if (cmpreg==-1) cmpreg = get_register(); |
1053 code_rgvar(e1,cmpreg); | |
1054 regv[cmpreg]=1; | |
130 | 1055 } |
1056 | |
1057 | |
1058 void | |
1059 code_cmp_rlvar(int e2) { | |
148 | 1060 if (cmpreg==-1) cmpreg = get_register(); |
149 | 1061 code_rlvar(e2,cmpreg); |
148 | 1062 regv[cmpreg]=1; |
130 | 1063 } |
1064 | |
1065 | |
1066 void | |
1067 code_cmp_register(int e2) { | |
148 | 1068 cmpreg = e2; |
1069 /* prevent cmpreg freeing */ | |
1070 regv[cmpreg]=2; | |
130 | 1071 } |
1072 | |
1073 | |
1074 void | |
1075 ascii(char *s) | |
1076 { | |
1077 printf("\t.ascii \""); | |
1078 while(*s) { | |
1079 if (*s=='\n') | |
1080 printf("%cn",92); | |
1081 else if (*s<' ') | |
1082 printf("%c%03o",92,*s); | |
1083 else if (*s=='\\') | |
1084 printf("\\\\"); | |
1085 else if (*s==34) | |
1086 printf("%c%c",92,34); | |
1087 else | |
1088 printf("%c",*s); | |
1089 s++; | |
1090 } | |
148 | 1091 printf("\\0%c\n\t.align 2\n",34); |
130 | 1092 } |
1093 | |
1094 void | |
1095 code_string(int e1,int creg) | |
1096 { | |
1097 char *s,*crn; | |
1098 int lb; | |
1099 crn=register_name(creg); | |
1100 | |
1101 s=(char *)cadr(e1); | |
131 | 1102 printf("\t.rdata\n\t.align 2\n"); |
130 | 1103 lb=fwdlabel(); |
1104 printf("L_%d:\n",lb); | |
1105 ascii(s); | |
1106 if (output_mode==TEXT_EMIT_MODE) { | |
148 | 1107 printf(".text\n"); |
130 | 1108 } else { |
148 | 1109 text_mode(); |
130 | 1110 } |
131 | 1111 printf("\tla %s,L_%d\n",crn,lb); |
130 | 1112 } |
1113 | |
1114 #define MAX_COPY_LEN 20 | |
1115 | |
1116 void | |
1117 emit_copy(int from,int to,int length,int offset,int value,int det) | |
1118 { | |
1119 char *frn = register_name(from); | |
1120 char *trn = register_name(to); | |
1121 char *drn; | |
1122 int fix = 0; | |
1123 char *memmove = "memmove"; | |
1124 int dreg = get_register(); if (!dreg) error(-1); | |
1125 drn = register_name(dreg); | |
1126 | |
1127 /* length <0 means upward direction copy */ | |
1128 switch (length) { | |
148 | 1129 case 0: break; |
130 | 1130 case 1: case -1: |
148 | 1131 printf("\tlb %s,%d(%s)\n",drn,offset,frn); |
1132 printf("\tsb %s,%d(%s)\n",drn,offset,trn); | |
1133 break; | |
130 | 1134 case 2: case -2: |
148 | 1135 printf("\tlh %s,%d(%s)\n",drn,offset,frn); |
1136 printf("\tsh %s,%d(%s)\n",drn,offset,trn); | |
1137 break; | |
130 | 1138 case 4: case -4: |
148 | 1139 printf("\tlw %s,%d(%s)\n",drn,offset,frn); |
1140 printf("\tsw %s,%d(%s)\n",drn,offset,trn); | |
1141 break; | |
130 | 1142 default: |
148 | 1143 if (-MAX_COPY_LEN<length && length <0) { |
1144 for(;length<=4;length+=4,offset-=4) | |
1145 emit_copy(from,to,4,offset,0,det); | |
1146 for(;length<=2;length+=2,offset-=2) | |
1147 emit_copy(from,to,2,offset,0,det); | |
1148 if(length>0) | |
1149 emit_copy(from,to,length,offset,0,det); | |
1150 break; | |
1151 } else if (length <=MAX_COPY_LEN) { | |
1152 for(;length>=4;length-=4,offset+=4) | |
1153 emit_copy(from,to,4,offset,0,det); | |
1154 for(;length>=2;length-=2,offset+=2) | |
1155 emit_copy(from,to,2,offset,0,det); | |
1156 if(length>0) | |
1157 emit_copy(from,to,length,offset,0,det); | |
1158 break; | |
1159 } | |
1160 code_save_stacks(); | |
1161 printf("\tli $6,%d\n",length); | |
1162 printf("\tmr $5,%s\n",frn); | |
1163 printf("\tmr $4,%s\n",trn); | |
130 | 1164 /* overrap must be allowed */ |
148 | 1165 printf("\tbl L_%s$stub\n",memmove); |
130 | 1166 fix=0; |
148 | 1167 set_creg(RET_REGISTER,0); |
1168 if (creg!=to) { | |
1169 free_register(to); to = creg; | |
1170 } | |
1171 break; | |
130 | 1172 } |
149 | 1173 if (value) { |
130 | 1174 /* creg must point top of the destination data */ |
1175 /* this code is necessary for the value of assignment or function call */ | |
1176 /* otherwise we don't need this */ | |
148 | 1177 if (fix) printf("\taddi %s,%s,%d\n",trn,trn,fix); |
1178 if(creg!=to) { | |
1179 free_register(creg); creg=to; | |
1180 } | |
130 | 1181 } |
1182 free_register(dreg); | |
1183 regv[from]=regv[to]=regv[dreg]=0; | |
1184 regv[creg]=1; | |
1185 } | |
1186 | |
1187 int | |
1188 struct_push(int e4,int t,int arg) | |
1189 { | |
1190 int length,count; | |
1191 int dreg,sreg; char *drn,*crn,*srn; | |
1192 g_expr(e4); | |
1193 length=size(t); | |
1194 if(length%size_of_int) { | |
1195 length += size_of_int - (length%size_of_int); | |
1196 } | |
1197 dreg = get_register(); if (!dreg) error(-1); | |
1198 drn = register_name(dreg); | |
1199 crn = register_name(creg); | |
1200 if (length<MAX_COPY_LEN) { | |
1201 sreg = get_register(); if (!sreg) error(-1); | |
1202 srn = register_name(sreg); | |
1203 code_lvar(cadr(arg),sreg); | |
1204 for(count=0;length<MAX_COPY_LEN;count++,length-=size_of_int) { | |
1205 if (length==0) { | |
1206 free_register(sreg); | |
1207 free_register(dreg); | |
1208 return count; | |
1209 } else { | |
148 | 1210 printf("\tlw %s,%d(%s)\n",drn,length-size_of_int,crn); |
1211 printf("\tsw %s,%d(%s)\n",drn,length-size_of_int,srn); | |
130 | 1212 } |
1213 } | |
1214 } | |
1215 code_lvar(cadr(arg),dreg); | |
1216 /* downward direction copy */ | |
1217 emit_copy(creg,dreg,length,0,0,1); | |
1218 if (dreg) free_register(dreg); | |
1219 return length/size_of_int; | |
1220 } | |
1221 | |
1222 void | |
1223 set_creg(int reg,int mode) | |
1224 { | |
148 | 1225 if (!is_int_reg(reg)) error(-1); |
130 | 1226 if (reg!=creg) { |
148 | 1227 if (reg!=ireg && mode) |
150 | 1228 printf("\tmove %s,%s\n",register_name(reg),register_name(ireg)); |
130 | 1229 free_register(creg); |
148 | 1230 creg = ireg = reg; |
130 | 1231 regs[creg]=1; |
1232 } | |
1233 } | |
1234 | |
1235 void | |
1236 set_freg(int reg,int mode) | |
1237 { | |
148 | 1238 if (!is_float_reg(reg)) error(-1); |
1239 if (reg!=creg) { | |
1240 if (reg!=freg && mode) { | |
1241 printf("\tfmove %s,%s\n",fregister_name(reg),fregister_name(freg)); | |
1242 } | |
1243 free_register(creg); | |
1244 creg = freg = reg; | |
1245 regs[freg]=1; | |
130 | 1246 } |
1247 } | |
1248 | |
149 | 1249 static void |
1250 move_dreg(int reg,int dreg) | |
1251 { | |
1252 if (reg!=dreg) { | |
1253 printf("\tmove %s,%s\n",dregister_name0(reg), | |
1254 dregister_name0(dreg)); | |
1255 printf("\tmove %s,%s\n",dregister_name1(reg), | |
1256 dregister_name1(dreg)); | |
1257 } | |
1258 } | |
1259 | |
130 | 1260 void |
148 | 1261 set_dreg(int reg,int mode) |
1262 { | |
1263 if (!is_double_reg(reg)) error(-1); | |
1264 if (reg!=creg) { | |
149 | 1265 if (mode) { |
1266 move_dreg(reg,dreg); | |
148 | 1267 } |
1268 free_register(creg); | |
1269 creg = dreg = reg; | |
1270 regs[dreg]=1; | |
152 | 1271 regs[dreg_pair0[dreg-DREG_OFFSET]]=1; |
1272 regs[dreg_pair1[dreg-DREG_OFFSET]]=1; | |
148 | 1273 } |
1274 } | |
1275 | |
1276 | |
1277 void | |
130 | 1278 use_var(int arg) |
1279 { | |
1280 if (car(arg)==REGISTER) | |
1281 regs[cadr(arg)]=USING_REG; | |
148 | 1282 else if (car(arg)==FREGISTER) |
1283 regs[cadr(arg)]=USING_REG; | |
130 | 1284 else if (car(arg)==DREGISTER) |
148 | 1285 regs[cadr(arg)]=USING_REG; |
130 | 1286 } |
1287 | |
1288 void | |
1289 code_save_input_registers() | |
1290 { | |
1291 int args; | |
1292 NMTBL *n; | |
1293 int reg; | |
1294 int tag; | |
1295 int lvar; | |
1296 int t; | |
1297 /* fnptr->dsp=list4(type,fnptr->dsp,(int)n,0); */ | |
1298 int reg_offset = 0; | |
1299 int offset = 0; | |
1300 | |
1301 for(args = fnptr->dsp;args;args = cadr(args)) { | |
1302 n = (NMTBL *)caddr(args); | |
1303 tag = n->sc; | |
1304 reg = n->dsp; | |
1305 if (!n||n==&null_nptr) error(REG_ERR); | |
1306 if (tag==REGISTER) { | |
1307 /* regs[reg]==INPUT_REG case should be considered */ | |
1308 n->dsp = offset; | |
1309 offset+=size_of_int; | |
1310 t = INT; | |
1311 reg += reg_offset; /* for duplicated floating point argument */ | |
148 | 1312 } else if (tag==FREGISTER) { |
1313 /* fregs[reg]==INPUT_REG case should be considered */ | |
1314 n->dsp = offset; | |
1315 t = n->ty; | |
1316 if(t==FLOAT) { offset+=size_of_float; reg_offset+=1; } | |
1317 else if(t==DOUBLE) { offset+=size_of_double; reg_offset+=2; } | |
1318 else error(-1); | |
1319 } else if (tag==DREGISTER) { | |
1320 /* fregs[reg]==INPUT_REG case should be considered */ | |
1321 n->dsp = offset; | |
1322 t = n->ty; | |
1323 if(t==FLOAT) { offset+=size_of_float; reg_offset+=1; } | |
1324 else if(t==DOUBLE) { offset+=size_of_double; reg_offset+=2; } | |
1325 else error(-1); | |
130 | 1326 } else { |
1327 offset += size(n->ty); | |
1328 continue; | |
1329 } | |
1330 n->sc = LVAR; | |
1331 lvar = list2(LVAR,n->dsp); | |
1332 g_expr_u(assign_expr0(list2(LVAR,n->dsp),list3(tag,reg,(int)n),n->ty,t)); | |
148 | 1333 if (tag==REGISTER||tag==DREGISTER||tag==FREGISTER) { |
130 | 1334 free_register(reg); |
1335 } | |
1336 } | |
1337 my_func_args = offset; | |
1338 } | |
1339 | |
1340 int | |
1341 simple_args(int e3) | |
1342 { | |
1343 return | |
1344 !contains_in_list(e3,FUNCTION) && | |
1345 !contains_in_list(e3,CONV) && | |
1346 !contains_in_list(e3,RSTRUCT) && | |
164 | 1347 !contains_in_list(e3,STASS) |
130 | 1348 ; |
1349 } | |
1350 | |
1351 int | |
1352 caller_arg_offset_v(int arg) | |
1353 { | |
1354 return ARG_LVAR_OFFSET+arg*size_of_int; | |
1355 } | |
1356 | |
1357 int | |
1358 function(int e1) | |
1359 { | |
150 | 1360 int e2,e3,e4,nargs,t; |
130 | 1361 int arg,reg_arg,freg_arg,arg_assign; |
148 | 1362 int dots; |
130 | 1363 int reg_arg_list=0,ret_type,special_lvar; |
1364 NMTBL *fn = 0; | |
1365 int jmp = 0; | |
1366 char *jrn; | |
153 | 1367 int iargs=0; |
130 | 1368 |
1369 special_lvar = -1; | |
148 | 1370 ret_type = cadr(cadddr(e1)); |
1371 if (ret_type==CHAR) ret_type=INT; | |
1372 | |
1373 /* check argments type is DOTS? */ | |
1374 t = caddr(cadddr(e1)); | |
1375 if (t==0 || t==DOTS) dots = 1; | |
1376 else { | |
1377 dots = 0; | |
1378 for(t = caddr(cadddr(e1));t;t = cadr(t)) { | |
1379 if (car(t)==DOTS) dots = 1; | |
1380 } | |
1381 } | |
130 | 1382 |
1383 e2 = cadr(e1); | |
1384 if (car(e2) == FNAME) { | |
1385 fn=(NMTBL *)cadr(e2); | |
1386 } else { | |
1387 jmp = get_register_var(0); | |
1388 if (car(jmp)!=REGISTER) error(-1); | |
1389 reg_arg_list = list2(jmp,reg_arg_list); | |
1390 g_expr(e2); | |
1391 code_register(creg,cadr(jmp)); | |
1392 /* g_expr(assign_expr0(jmp,e2,INT,INT)); functions are lvalue */ | |
1393 } | |
1394 | |
1395 /* now all input register vars are free */ | |
1396 code_save_stacks(); | |
1397 set_creg(CREG_REGISTER,0); | |
1398 set_freg(FREG_FREGISTER,0); | |
148 | 1399 set_dreg(DREG_DREGISTER,0); |
130 | 1400 |
1401 nargs = reg_arg = freg_arg = arg_assign = 0; | |
1402 for (e3 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) { | |
1403 t=caddr(e3); | |
1404 e4 = car(e3); | |
1405 if(scalar(t)) { | |
1406 if (reg_arg>=MAX_INPUT_REGISTER_VAR) { | |
1407 arg = list2(LVAR,caller_arg_offset_v(nargs)); | |
1408 } else if (!simple_args(e3) && cadr(e3)) { | |
1409 arg = get_register_var(0); | |
1410 arg_assign = list2( | |
148 | 1411 assign_expr0(get_input_register_var(reg_arg,0,0), |
1412 arg,t,t), | |
130 | 1413 arg_assign); |
1414 } else { | |
1415 arg = get_input_register_var(reg_arg,0,0); | |
1416 } | |
1417 use_var(arg); /* protect from input register free */ | |
1418 reg_arg_list = list2(arg,reg_arg_list); | |
1419 g_expr_u(assign_expr0(arg,e4,t,t)); | |
153 | 1420 nargs ++ ; reg_arg++; iargs += size_of_int; |
130 | 1421 continue; |
1422 } else if (t==DOUBLE||t==FLOAT) { | |
1423 if (freg_arg>=MAX_INPUT_DREGISTER_VAR) { | |
1424 arg = list2(LVAR,caller_arg_offset_v(nargs)); | |
148 | 1425 } else if (!simple_args(e3) && cadr(e3)) { |
138 | 1426 arg = get_dregister_var(0,1); |
130 | 1427 arg_assign = list2( |
148 | 1428 assign_expr0(get_input_dregister_var(freg_arg,0,0,1), |
1429 arg,t,t), | |
130 | 1430 arg_assign); |
1431 } else { | |
138 | 1432 arg = get_input_dregister_var(freg_arg,0,0,1); |
130 | 1433 } |
1434 use_var(arg); /* protect from input register free */ | |
1435 reg_arg_list = list2(arg,reg_arg_list); | |
1436 g_expr_u(assign_expr0(arg,e4,t,t)); /* XXX */ | |
1437 freg_arg++; | |
1438 nargs += size(t)/size_of_int; | |
153 | 1439 if (t==DOUBLE) iargs += size(t); |
130 | 1440 continue; |
1441 } else if (car(t)==STRUCT||car(t)==UNION) { | |
1442 arg = list2(LVAR,caller_arg_offset_v(nargs)); | |
1443 nargs += struct_push(e4,t,arg); | |
153 | 1444 iargs += ((size(t)+3)/size_of_int)*size_of_int; |
130 | 1445 continue; |
1446 } else { | |
1447 error(TYERR); | |
1448 } | |
1449 ++nargs; | |
1450 } | |
1451 if (max_func_args<nargs) max_func_args=nargs; | |
153 | 1452 if (max_func_iargs<iargs) max_func_iargs=iargs; |
130 | 1453 for(;arg_assign;arg_assign=cadr(arg_assign)) { |
1454 g_expr_u(car(arg_assign)); | |
1455 } | |
1456 if (car(e2) == FNAME) { | |
1457 printf("\tbl\tL_%s$stub\n",fn->nm); | |
1458 } else { | |
1459 jrn = register_name(cadr(jmp)); | |
131 | 1460 printf("\tj %s\n",jrn); |
130 | 1461 } |
1462 for(;reg_arg_list;reg_arg_list=cadr(reg_arg_list)) { | |
1463 arg = car(reg_arg_list); | |
148 | 1464 if (car(arg)==REGISTER||car(arg)==DREGISTER||car(arg)==FREGISTER) |
1465 free_register(cadr(arg)); | |
130 | 1466 else if (car(arg)==LVAR&&cadr(arg)<0) free_lvar(cadr(arg)); |
1467 } | |
148 | 1468 if (ret_type==DOUBLE) { |
1469 set_dreg(RET_DREGISTER,0); | |
1470 regv[dreg]=1; regv[creg]=0; | |
1471 } else if (ret_type==FLOAT) { | |
130 | 1472 set_freg(RET_FREGISTER,0); |
148 | 1473 regv[freg]=1; regv[creg]=0; |
130 | 1474 } else if (ret_type==VOID) { |
148 | 1475 regv[freg]=0; regv[creg]=0; |
130 | 1476 } else { |
1477 set_creg(RET_REGISTER,0); | |
148 | 1478 regv[freg]=0; regv[creg]=1; |
130 | 1479 } |
1480 return ret_type; | |
1481 } | |
1482 | |
1483 void | |
1484 code_frame_pointer(int e3) { | |
1485 #if R1SAVE | |
131 | 1486 printf("\tmove $fp,%s\n",register_name(e3)); |
130 | 1487 #else |
131 | 1488 printf("\tmove $fp,%s\n",register_name(e3)); |
130 | 1489 #endif |
1490 } | |
1491 | |
1492 | |
1493 void | |
1494 code_fix_frame_pointer(int disp_offset) { | |
1495 int l = 0; | |
131 | 1496 printf("\tla $fp,"); |
1497 printf("%d+L_%d($sp)\n",FUNC_LVAR,lvar_offset_label); | |
130 | 1498 } |
1499 | |
1500 void | |
1501 code_jmp(char *s) { | |
1502 max_reg_var = REG_VAR_BASE-REG_VAR_MIN; | |
1503 max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN; | |
131 | 1504 printf("\tj L_%s\n",s); |
130 | 1505 } |
1506 | |
1507 | |
1508 void | |
1509 code_indirect_jmp(int e2) { | |
1510 max_reg_var = REG_VAR_BASE-REG_VAR_MIN; | |
1511 max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN; | |
131 | 1512 printf("\tj %s\n",register_name(e2)); |
130 | 1513 } |
1514 | |
1515 int | |
196 | 1516 code_rindirect(int e1, int offset, int us) |
1517 { | |
1518 char *crn; | |
1519 g_expr(e1); | |
1520 crn=register_name(creg); | |
1521 printf("\tlw %s,%d(%s)\n",crn,offset,crn); | |
1522 return INT; | |
1523 } | |
1524 | |
1525 int | |
1526 code_crindirect(int e1, int offset, int us) | |
130 | 1527 { |
1528 char *crn; | |
196 | 1529 g_expr(e1); |
1530 crn=register_name(creg); | |
1531 if (us) { | |
1532 printf("\tlbu %s,%d(%s)\n",crn,offset,crn); | |
1533 return UCHAR; | |
1534 } else { | |
1535 printf("\tlb %s,%d(%s)\n",crn,offset,crn); | |
1536 return CHAR; | |
130 | 1537 } |
196 | 1538 } |
1539 | |
1540 int | |
1541 code_srindirect(int e1, int offset, int us) | |
1542 { | |
1543 char *crn; | |
1544 g_expr(e1); | |
130 | 1545 crn=register_name(creg); |
196 | 1546 if (us) { |
1547 printf("\tlhu %s,%d(%s)\n",crn,offset,crn); | |
1548 return USHORT; | |
1549 } else { | |
1550 printf("\tlh %s,%d(%s)\n",crn,offset,crn); | |
1551 return SHORT; | |
1552 } | |
1553 } | |
1554 | |
1555 #if FLOAT_CODE | |
1556 int | |
1557 code_drindirect(int e1, int offset, int d) | |
1558 { | |
1559 char *crn; | |
1560 g_expr(e1); | |
1561 crn=register_name(creg); | |
1562 if (d) { | |
149 | 1563 printf("\tlw %s,%d(%s)\n", |
1564 dregister_name0(dreg),offset,crn); | |
1565 printf("\tlw %s,%d(%s)\n", | |
1566 dregister_name1(dreg),offset+size_of_int,crn); | |
1567 regv[creg]=0; regv[dreg]=1; | |
1568 creg = dreg; | |
148 | 1569 return DOUBLE; |
196 | 1570 } else { |
1571 printf("\tl.s %s,%d(%s)\n", fregister_name(freg),offset,crn); | |
1572 regv[creg]=0; regv[freg]=1; | |
1573 creg = freg; | |
1574 return FLOAT; | |
130 | 1575 } |
1576 } | |
196 | 1577 #endif |
1578 | |
1579 #if LONGLONG_CODE | |
1580 int | |
1581 code_lrindirect(int e1, int offset, int us) | |
1582 { | |
1583 char *crn; | |
1584 g_expr(e1); | |
1585 crn=register_name(creg); | |
1586 } | |
1587 #endif | |
130 | 1588 |
1589 void | |
1590 code_assign_gvar(int e2,int creg,int byte) { | |
151 | 1591 char *crn,*name; |
136
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
1592 |
151 | 1593 name = ((NMTBL*)cadr(e2))->nm; |
130 | 1594 crn=register_name(creg); |
167 | 1595 if (byte==1) { |
151 | 1596 printf("\tsb %s,%s\n",crn,name); |
167 | 1597 } if (byte==size_of_short) { |
1598 printf("\tsh %s,%s\n",crn,name); | |
130 | 1599 } else { |
151 | 1600 printf("\tsw %s,%s\n",crn,name); |
130 | 1601 } |
1602 } | |
1603 | |
1604 void | |
1605 code_assign_lvar(int e2,int creg,int byte) { | |
1606 char *crn; | |
1607 crn=register_name(creg); | |
167 | 1608 if (byte==1) { |
1609 printf("\tsb %s,",crn); | |
1610 } else if (byte==size_of_short) { | |
1611 printf("\tsh %s,",crn); | |
130 | 1612 } else { |
167 | 1613 printf("\tsw %s,",crn); |
130 | 1614 } |
167 | 1615 lvar(e2); |
130 | 1616 } |
1617 | |
1618 void | |
1619 code_assign_register(int e2,int byte,int creg) { | |
1620 if (e2!=creg) | |
148 | 1621 printf("\tmove %s,%s\n",register_name(e2),register_name(creg)); |
130 | 1622 } |
1623 | |
1624 void | |
1625 code_assign(int e2,int byte,int creg) { | |
1626 char *drn=register_name(e2); | |
1627 char *crn=register_name(creg); | |
1628 | |
167 | 1629 if (byte==1) { |
148 | 1630 printf("\tsb %s,0(%s)\n",crn,drn); |
167 | 1631 } else if (byte==size_of_short) { |
1632 printf("\tsh %s,0(%s)\n",crn,drn); | |
130 | 1633 } else { |
148 | 1634 printf("\tsw %s,0(%s)\n",crn,drn); |
130 | 1635 } |
148 | 1636 regv[creg]=1; |
130 | 1637 } |
1638 | |
1639 | |
1640 void | |
1641 code_register_assop(int e2,int op,int byte) { | |
1642 int reg; | |
1643 int xreg = creg; | |
1644 creg = reg = e2; | |
1645 tosop(op,xreg); | |
1646 creg = xreg; | |
1647 if (creg!=reg) | |
148 | 1648 printf("\tmove %s,%s\n",register_name(creg),register_name(reg)); |
1649 regv[creg]=1; | |
130 | 1650 } |
1651 | |
1652 | |
1653 void | |
163 | 1654 code_assop(int op,int byte,int sign) { |
130 | 1655 char *xrn,*crn,*drn; |
1656 int xreg; | |
1657 int edx = get_register(); if(!edx) error(-1); | |
1658 xrn = register_name(xreg = emit_pop(0)); /* pop e3 value */ | |
1659 regv[xreg]=regs[xreg]=1; | |
1660 printf("# assop\n\tmr %s,%s\n",register_name(edx),register_name(creg)); | |
1661 regv[edx]=1; | |
163 | 1662 ld_indexx(byte,0,edx,sign); |
130 | 1663 tosop(op,xreg); |
1664 crn = register_name(creg); | |
1665 drn = register_name(edx); | |
168 | 1666 printf("\t%s %s,0(%s)\n",cstore(byte),crn,drn); |
130 | 1667 free_register(edx); |
1668 emit_pop_free(xreg); | |
148 | 1669 regv[creg]=1; |
130 | 1670 } |
1671 | |
1672 | |
1673 void | |
1674 tosop(int op,int oreg) | |
1675 { | |
1676 int dx; | |
149 | 1677 char *orn,*crn; |
130 | 1678 |
1679 if(oreg==-1) { | |
1680 error(-1); | |
1681 } else if (oreg<= -REG_LVAR_OFFSET) { | |
1682 dx = get_register(); if (dx<0) error(-1); | |
1683 code_rlvar(oreg+REG_LVAR_OFFSET,dx); | |
1684 oreg = dx; | |
1685 regv[oreg]=1; | |
1686 } | |
1687 | |
1688 switch(op) { | |
1689 case LSHIFT: | |
1690 case ULSHIFT: | |
131 | 1691 shift("sll",oreg); |
148 | 1692 regv[creg]=1; |
130 | 1693 return; |
1694 case RSHIFT: | |
131 | 1695 shift("srl",oreg); |
148 | 1696 regv[creg]=1; |
130 | 1697 return; |
1698 case URSHIFT: | |
131 | 1699 shift("sra",oreg); |
148 | 1700 regv[creg]=1; |
130 | 1701 return; |
1702 } | |
1703 orn = register_name(oreg); | |
1704 crn = register_name(creg); | |
1705 switch(op) { | |
1706 case ADD: | |
131 | 1707 printf("\taddu %s,%s,%s\n",crn,crn,orn); |
130 | 1708 break; |
1709 case SUB: | |
131 | 1710 printf("\tsubu %s,%s,%s\n",crn,crn,orn); |
130 | 1711 break; |
1712 case CMP: | |
131 | 1713 printf("\tslt %s,%s\n",crn,orn); |
130 | 1714 break; |
1715 case BAND: | |
1716 printf("\tand %s,%s,%s\n",crn,crn,orn); | |
1717 break; | |
1718 case EOR: | |
1719 printf("\txor %s,%s,%s\n",crn,crn,orn); | |
1720 break; | |
1721 case BOR: | |
1722 printf("\tor %s,%s,%s\n",crn,crn,orn); | |
1723 break; | |
1724 case MUL: | |
131 | 1725 printf("\tmult %s,%s,%s\n",crn,crn,orn); |
130 | 1726 break; |
1727 case UMUL: | |
131 | 1728 printf("\tmultu %s,%s,%s\n",crn,crn,orn); |
130 | 1729 break; |
148 | 1730 case DIV: |
1731 printf("\tdivw %s,%s,%s\n",crn,crn,orn); | |
1732 break; | |
149 | 1733 case UDIV: case MOD: case UMOD: |
148 | 1734 printf("\t%s $0,%s,%s\n",(op==UDIV||op==UMOD)?"divu":"div",crn,orn); |
1735 printf("\t%s %s\n",(op==MOD||op==UMOD)?"mflo":"mfhi",crn); | |
1736 printf("\t.set noreorder\n"); | |
1737 printf("\tbeql %s,$0,1f\n",orn); | |
1738 printf("\tbreak 7\n"); | |
1739 printf("1:\n"); | |
1740 printf("\t.set reorder\n"); | |
1741 break; | |
130 | 1742 default: |
1743 error(-1); | |
1744 } | |
1745 if(oreg!=creg) free_register(oreg); | |
148 | 1746 regv[creg]=1; |
130 | 1747 } |
1748 | |
1749 | |
1750 void | |
1751 shift(char *op, int reg) | |
1752 { | |
1753 char *crn = register_name(creg); | |
1754 char *rrn = register_name(reg); | |
1755 printf("\t%s %s,%s,%s\n",op,crn,rrn,crn); | |
1756 } | |
1757 | |
189 | 1758 int |
1759 code_const_op_p(int op,int v) | |
1760 { | |
1761 if (op==BAND||op==DIV||op==UDIV||op==MOD||op==UMOD) return 0; | |
1762 return 0; | |
1763 } | |
1764 | |
1765 void | |
1766 oprtc(int op,int v) | |
1767 { | |
1768 } | |
1769 | |
1770 | |
130 | 1771 void |
163 | 1772 ld_indexx(int byte, int n, int xreg,int sign) |
130 | 1773 { |
1774 char *crn = register_name(creg); | |
168 | 1775 printf("\t%s %s,%d(%s)\n",cload(sign,byte),crn,n, |
1776 register_name(xreg)); | |
130 | 1777 } |
1778 | |
1779 int | |
1780 code_csvalue() | |
1781 { | |
1782 return creg; | |
1783 } | |
1784 | |
1785 void | |
1786 code_cmpdimm(int e, int csreg) | |
1787 { | |
1788 /* used in dosiwtch() */ | |
1789 if(chk) return; | |
150 | 1790 creg = use_int(creg); |
131 | 1791 printf("\tli %s,%d\n",register_name(creg),e); |
148 | 1792 cmpreg = csreg; |
1793 regv[cmpreg]=2; /* prevent from freeing */ | |
130 | 1794 } |
1795 | |
1796 void | |
136
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
1797 code_opening(char *s) |
130 | 1798 { |
131 | 1799 /* this is called once per month */ |
1800 char *p=cheapp; | |
1801 | |
136
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
1802 printf("\t.file \"%s\"\n",s); |
130 | 1803 /* printf("\t.version\t\"01.01\"\n"); */ |
1804 /* printf("gcc2_compiled.:\n"); */ | |
131 | 1805 printf("\t.abicalls\n"); |
1806 printf("\t.text\n"); | |
1807 | |
1808 if (asi) { | |
148 | 1809 fclose(asi); |
1810 asi = 0; | |
131 | 1811 } |
1812 while ((*cheapp++ = *s++)) { | |
1813 if (*s=='.') { | |
1814 *cheapp++=*s++; *cheapp++='i'; | |
148 | 1815 *cheapp++=0; |
131 | 1816 break; |
1817 } | |
1818 } | |
1819 asi = fopen(p,"w"); | |
136
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
1820 printf(".include \"%s\"\n",p); |
131 | 1821 if (!asi) error(-1); |
130 | 1822 } |
1823 | |
1824 void | |
1825 rexpr(int e1, int l1, char *s,int t) | |
1826 { | |
132 | 1827 char *crn,*drn; |
148 | 1828 if (cmpreg>=0) { free_register(cmpreg); cmpreg = -1; } |
132 | 1829 |
1830 g_expr(cadr(e1)); | |
1831 emit_push(); | |
1832 g_expr(caddr(e1)); | |
150 | 1833 cmpreg = emit_pop(0); |
132 | 1834 crn = register_name(creg); |
148 | 1835 drn = register_name(cmpreg); |
132 | 1836 |
1837 if (s[1] == 's') { | |
148 | 1838 if (s[16]=='x') { |
1839 /* slt $2,$2,$3; xroi $2,$2,0x1; beq $2,$0,L1 */ | |
1840 printf(s,crn,drn,drn,crn,crn,crn,l1); | |
1841 } else { | |
1842 /* slt $2,$2,$3; beq $2,$0,L1 */ | |
1843 printf(s,crn,drn,drn,crn,l1); | |
1844 } | |
132 | 1845 } else { |
148 | 1846 /* beq $2,$3,L1 */ |
1847 printf(s,crn,drn,l1); | |
132 | 1848 } |
148 | 1849 free_register(cmpreg) ; cmpreg = -1; |
130 | 1850 } |
1851 | |
1852 void | |
1853 jcond(int l, char cond) | |
131 | 1854 { |
130 | 1855 if (chk) return; |
148 | 1856 if (cmpreg==-1) error(-1); |
150 | 1857 printf("\tb%s %s,%s,L_%d\n", |
1858 cond?"ne":"eq", | |
1859 register_name(creg),register_name(cmpreg), | |
1860 l); | |
148 | 1861 if (regv[cmpreg]==1) { |
1862 free_register(cmpreg); cmpreg = -1; | |
132 | 1863 } |
131 | 1864 regv[creg]=0; |
130 | 1865 } |
1866 | |
1867 void | |
1868 jmp(int l) | |
1869 { | |
1870 control=0; | |
1871 if (chk) return; | |
131 | 1872 printf("\tj\tL_%d\n",l); |
130 | 1873 } |
1874 | |
1875 void | |
1876 gen_comment(char *s) | |
1877 { | |
1878 if (chk) return; | |
1879 printf("## %s",s); | |
1880 } | |
1881 | |
1882 void | |
1883 code_enter(char *name) | |
1884 { | |
1885 if (output_mode!=TEXT_EMIT_MODE) | |
1886 text_mode(); | |
1887 else | |
132 | 1888 printf("\t.align 3\n"); |
153 | 1889 /* if (stmode!=STATIC) |
1890 printf(".globl _%s\n",name); */ | |
132 | 1891 printf(".ent %s\n",name); |
130 | 1892 printf("_%s:\n",name); |
1893 code_disp_label=fwdlabel(); | |
132 | 1894 |
1895 printf("\t.set noreorder\n"); | |
1896 printf("\t.cpload $25\n"); | |
1897 printf("\t.set reorder\n"); | |
1898 printf("\tsubu $sp,$sp,L_%d\n",code_disp_label); | |
153 | 1899 printf("\t.cprestore L_%d\n",cprestore_label); |
148 | 1900 |
130 | 1901 max_func_args = 0; |
153 | 1902 max_func_iargs = 0; |
130 | 1903 } |
1904 | |
1905 | |
1906 void | |
1907 code_enter1(int args) | |
1908 { | |
1909 set_creg(CREG_REGISTER,0); | |
1910 set_freg(FREG_FREGISTER,0); | |
148 | 1911 set_dreg(DREG_DREGISTER,0); |
130 | 1912 } |
1913 | |
1914 void | |
1915 code_leave(char *name) | |
1916 { | |
1917 int r1_offsetv; | |
1918 disp&= -size_of_int; | |
1919 r1_offsetv = -disp+max_func_args*size_of_int+code_disp_offset; | |
1920 | |
132 | 1921 fprintf(asi,"L_%d=%d\n",code_disp_label,-r1_offsetv); |
148 | 1922 |
130 | 1923 local_table(); |
1924 free_all_register(); | |
1925 } | |
1926 | |
1927 void | |
1928 enter(char *name) | |
1929 { | |
1930 if (output_mode!=TEXT_EMIT_MODE) | |
1931 text_mode(); | |
1932 else | |
1933 printf("\t.align 2\n"); | |
153 | 1934 /* if (stmode!=STATIC) |
1935 printf(".globl _%s\n",name); */ | |
132 | 1936 printf(".ent %s\n",name); |
130 | 1937 printf("_%s:\n",name); |
132 | 1938 |
130 | 1939 r1_offset_label = fwdlabel(); |
1940 lvar_offset_label = fwdlabel(); | |
152 | 1941 disp_label = fwdlabel(); |
132 | 1942 mask_label = fwdlabel(); |
1943 mask1_label = fwdlabel(); | |
1944 fmask_label = fwdlabel(); | |
1945 fmask1_label = fwdlabel(); | |
152 | 1946 cprestore_label = fwdlabel(); |
132 | 1947 |
1948 printf("\t.frame $fp,L_%d,$31\n",r1_offset_label); | |
1949 printf("\t.mask L_%d,L_%d\n",mask_label,mask1_label); | |
1950 printf("\t.fmask L_%d,L_%d\n",fmask_label,fmask1_label); | |
1951 | |
1952 printf("\t.set noreorder\n"); | |
1953 printf("\t.cpload $25\n"); | |
1954 printf("\t.set reorder\n"); | |
152 | 1955 printf("\tsubu $sp,$sp,L_%d\n",disp_label); |
153 | 1956 printf("\t.cprestore L_%d\n",cprestore_label); |
130 | 1957 max_func_args = 0; |
153 | 1958 max_func_iargs = 0; |
148 | 1959 |
130 | 1960 } |
1961 | |
1962 void | |
1963 enter1() | |
1964 { | |
1965 set_creg(CREG_REGISTER,0); | |
1966 set_freg(FREG_FREGISTER,0); | |
148 | 1967 set_dreg(DREG_DREGISTER,0); |
130 | 1968 } |
1969 | |
153 | 1970 static unsigned int |
1971 code_mask_label() | |
130 | 1972 { |
153 | 1973 int i; |
1974 unsigned int mask=0; | |
1975 for(i=0;i<32;i++) { | |
1976 if (i==28||i==31||(REG_VAR_MIN<=i&&i<=REG_VAR_MIN+max_reg_var)) { | |
1977 mask |= (1<<i); | |
1978 } | |
1979 } | |
1980 return mask; | |
130 | 1981 } |
1982 | |
153 | 1983 static unsigned int |
1984 code_fmask_label() | |
1985 { | |
1986 int i; | |
1987 unsigned int mask=0; | |
1988 for(i=0;i<32;i++) { | |
1989 if (FREG_VAR_MIN<=i&&i<=FREG_VAR_MIN+max_freg_var) { | |
1990 mask |= (1<<i); | |
1991 } | |
1992 } | |
1993 return mask; | |
1994 } | |
1995 | |
1996 | |
130 | 1997 void |
1998 leave(int control, char *name) | |
1999 { | |
131 | 2000 int retcont1=0,sz; |
152 | 2001 int r1_offsetv; |
130 | 2002 |
2003 if (max_freg_var>=0 && max_freg_var<=3) max_freg_var=3; | |
153 | 2004 reg_save = |
2005 (REAL_MAX_REGISTER-(REG_VAR_BASE-max_reg_var))*size_of_int; | |
2006 freg_save = | |
2007 (REAL_MAX_FREGISTER-(FREG_VAR_BASE-max_freg_var))*size_of_float; | |
130 | 2008 |
2009 if (control) { | |
2010 code_set_return_register(1); | |
2011 } | |
2012 if (retcont) { | |
152 | 2013 /* return from CbC segement */ |
130 | 2014 if (control) jmp(retlabel); |
2015 retcont1 = fwdlabel(); | |
2016 fwddef(retcont); | |
152 | 2017 if (cadr(fnptr->ty)==FLOAT) { |
2018 if (freg!=RET_FREGISTER) | |
2019 printf("\tmov.s %s,%s\n",register_name(RET_FREGISTER), | |
2020 register_name(freg)); | |
2021 } else if (cadr(fnptr->ty)==DOUBLE) { | |
2022 move_dreg(RET_DREGISTER,dreg); | |
130 | 2023 } else if (cadr(fnptr->ty)>0&&( |
2024 car(cadr(fnptr->ty))==STRUCT || | |
2025 car(cadr(fnptr->ty))==UNION)) { | |
2026 sz = size(cadr(fnptr->ty)); | |
152 | 2027 printf("\tli $4,%d\n",sz); |
2028 printf("\tsubl $5,$4,$fp\n"); | |
2029 printf("\tlw $3,(%d)($fp)\n",(my_func_args-1)*size_of_int); | |
130 | 2030 emit_copy(6,3,sz,0,1,1); |
2031 } else if (cadr(fnptr->ty)!=VOID) { | |
152 | 2032 if (creg!=RET_REGISTER) |
2033 printf("\tmove $3,%s\n",register_name(creg)); | |
130 | 2034 } |
152 | 2035 printf("\tj L_%d\n",retcont1); |
130 | 2036 } |
2037 fwddef(retlabel); | |
2038 if (retcont) { | |
2039 fwddef(retcont1); | |
2040 } | |
2041 if (max_freg_var>=0) { | |
2042 } else { | |
2043 } | |
152 | 2044 fprintf(asi,"L_%d=%d\n",r1_offset_label,0); |
2045 fprintf(asi,"L_%d=%d\n",lvar_offset_label,0); | |
153 | 2046 fprintf(asi,"L_%d=0x%x\n",mask_label,code_mask_label()); |
152 | 2047 fprintf(asi,"L_%d=%d\n",mask1_label,0); |
153 | 2048 fprintf(asi,"L_%d=0x%x\n",fmask_label ,code_fmask_label()); |
152 | 2049 fprintf(asi,"L_%d=%d\n",fmask1_label,0); |
153 | 2050 fprintf(asi,"L_%d=%d\n",cprestore_label ,max_func_iargs); |
130 | 2051 |
2052 disp &= -size_of_int; | |
152 | 2053 r1_offsetv = 0; |
2054 | |
2055 printf("\tmove $sp,$fp\n"); | |
2056 printf("\tlw $31,%d($sp)\n",-disp); | |
2057 printf("\tlw $fp,%d($sp)\n",-disp-4); | |
2058 printf("\taddu $sp,$sp,%d\n",r1_offsetv); | |
2059 printf("\tj $31\n"); | |
2060 printf("\t.end print\n"); | |
2061 | |
2062 fprintf(asi,"L_%d=%d\n",disp_label,-r1_offsetv); | |
130 | 2063 |
2064 code_offset_set(); | |
2065 local_table(); | |
2066 labelno++; | |
2067 free_all_register(); | |
2068 } | |
2069 | |
2070 | |
2071 void | |
2072 code_set_return_register(int mode) { | |
148 | 2073 if (cadr(fnptr->ty)==DOUBLE) { |
2074 set_dreg(RET_DREGISTER,mode); | |
2075 } else if (cadr(fnptr->ty)==FLOAT) { | |
130 | 2076 set_freg(RET_FREGISTER,mode); |
148 | 2077 } else if (cadr(fnptr->ty)==VOID) { |
130 | 2078 } else { |
2079 set_creg(RET_REGISTER,mode); | |
2080 } | |
2081 } | |
2082 | |
189 | 2083 int |
2084 code_get_fixed_creg(int reg,int type) { | |
2085 return creg; | |
2086 } | |
2087 | |
130 | 2088 void |
189 | 2089 code_set_fixed_creg(int reg,int mode,int type) { |
148 | 2090 if (type==FLOAT) { |
189 | 2091 set_freg(reg,mode); |
148 | 2092 } else if (type==DOUBLE) { |
189 | 2093 set_dreg(reg,mode); |
130 | 2094 } else { |
189 | 2095 set_creg(reg,mode); |
130 | 2096 } |
2097 } | |
2098 | |
189 | 2099 |
130 | 2100 void |
2101 gen_gdecl(char *n, int gpc) | |
2102 { | |
2103 if (stmode!=STATIC) | |
153 | 2104 printf("\t.globl _%s\n",n); |
130 | 2105 } |
2106 | |
2107 void | |
2108 align(int t) | |
2109 { | |
2110 if (t!=CHAR) { | |
2111 if (data_alignment & 1) | |
2112 printf("\t.align 2\n"); | |
2113 data_alignment = 0; | |
2114 } | |
2115 } | |
2116 | |
2117 void | |
2118 emit_data(int e, int t, NMTBL *n) | |
2119 { | |
2120 int l; | |
195 | 2121 #if FLOAT_CODE |
130 | 2122 double d; |
2123 float f; | |
195 | 2124 #endif |
130 | 2125 char *name; |
2126 name = n->nm; | |
156 | 2127 if(mode!=GDECL&&mode!=STADECL) { |
130 | 2128 error(-1); return; |
2129 } | |
2130 if (chk) return; | |
2131 if (n->dsp != -1) { | |
2132 n->dsp = -1; /* initiallized flag */ | |
153 | 2133 /* printf(".globl\t_%s\n",name); */ |
130 | 2134 data_mode(name); |
2135 align(t); | |
2136 printf("_%s:\n",name); | |
2137 } else { | |
2138 data_mode(0); | |
2139 } | |
2140 if(car(e)==CONST) { | |
168 | 2141 if (t==CHAR||t==UCHAR) { |
130 | 2142 printf("\t.byte %d\n",cadr(e)); |
2143 if (data_alignment>0) | |
2144 data_alignment++; | |
2145 gpc += 1; | |
168 | 2146 } else if (t==SHORT||t==USHORT) { |
2147 printf("\t.short %d\n",cadr(e)); | |
130 | 2148 if (data_alignment>0) data_alignment++; |
2149 gpc += 2; | |
2150 } else { | |
148 | 2151 printf("\t.word %d\n",cadr(e)); |
130 | 2152 gpc += size_of_int; |
2153 } | |
195 | 2154 #if FLOAT_CODE |
130 | 2155 } else if(t==DOUBLE) { |
148 | 2156 d = dcadr(e); |
153 | 2157 printf("\t.word\t0x%x\n\t.word\t0x%x\n",code_d1(d),code_d2(d)); |
130 | 2158 } else if(t==FLOAT) { |
148 | 2159 f = dcadr(e); |
2160 printf("\t.word\t0x%x\n",*(int *)&f); | |
195 | 2161 #endif |
130 | 2162 } else if(t!=CHAR) { |
2163 gpc += size_of_int; | |
148 | 2164 if(car(e)==ADDRESS&&car(cadr(e))==GVAR) { |
2165 printf("\t.word _%s\n",((NMTBL *)cadr(cadr(e)))->nm); | |
2166 } else if(car(e)==FNAME) { | |
2167 printf("\t.word _%s\n",((NMTBL *)cadr(e))->nm); | |
2168 } else if(car(e)==GVAR) { | |
2169 printf("\t.word _%s\n",((NMTBL *)cadr(e))->nm); | |
2170 } else if(car(e)==STRING) { | |
2171 if (car(n->ty)!=ARRAY || cadr(n->ty)!=CHAR) { | |
2172 l = fwdlabel(); | |
2173 printf("\t.word L_%d\n",l); | |
2174 printf(".rdata\n\t.align 2\n"); | |
2175 printf("L_%d:\n",l); | |
2176 output_mode = RODATA_EMIT_MODE; | |
2177 } | |
2178 ascii((char *)cadr(e)); | |
130 | 2179 } else error(TYERR); |
168 | 2180 } else error(TYERR); |
130 | 2181 } |
2182 | |
2183 void | |
2184 emit_data_closing(NMTBL *n) | |
2185 { | |
2186 #ifdef DOT_SIZE | |
2187 int lb; | |
2188 #endif | |
2189 if (chk) return; | |
2190 if (mode==GDECL) { | |
2191 data_mode(0); | |
2192 #ifdef DOT_SIZE | |
2193 lb=fwdlabel(); | |
2194 printf("L_%d:\n",lb); | |
2195 printf("\t.size\t%s,L_%d-%s\n",n->nm,lb,n->nm); | |
2196 #endif | |
2197 } | |
2198 } | |
2199 | |
149 | 2200 void |
130 | 2201 global_table(void) |
2202 { | |
2203 NMTBL *n; | |
131 | 2204 int init; |
130 | 2205 init=0; |
2206 for(n=ntable;n < &ntable[GSYMS];n++) { | |
148 | 2207 if ((n->sc == GVAR) && n->dsp != -1) { |
2208 /* n->dsp = -1 means initialized global */ | |
2209 if (init==0) { | |
2210 data_mode(0); | |
2211 init=1; | |
2212 } | |
2213 printf(".comm _%s,%d\n",n->nm,size(n->ty)); | |
2214 } else if ((n->sc==STATIC) && n->dsp != -1) { | |
2215 /* n->dsp = -1 means initialized global */ | |
2216 if (init==0) { | |
2217 data_mode(0); | |
2218 init=1; | |
2219 } | |
2220 printf(".lcomm _%s,%d\n",n->nm,size(n->ty)); | |
2221 } | |
130 | 2222 } |
2223 } | |
2224 | |
2225 void | |
2226 local_table(void) | |
2227 { | |
2228 NMTBL *n; | |
2229 int init; | |
2230 init=0; | |
2231 /* static local variables */ | |
2232 for(n=ntable+GSYMS;n < &ntable[GSYMS+LSYMS];n++) { | |
2233 if (n->sc == GVAR) { | |
2234 if (init==0) { | |
2235 data_mode(0); | |
2236 init=1; | |
2237 } | |
156 | 2238 if (n->dsp!=-1) /* n->dsp = -1 means initialized global */ |
130 | 2239 printf(".lcomm _%s,%d\n",n->nm,size(n->ty)); |
2240 } | |
2241 } | |
2242 } | |
2243 | |
2244 void | |
2245 text_mode(void) | |
2246 { | |
2247 if (output_mode!=TEXT_EMIT_MODE) { | |
2248 printf(".text\n"); | |
2249 printf("\t.align 2\n"); | |
2250 output_mode = TEXT_EMIT_MODE; | |
2251 } | |
2252 } | |
2253 | |
2254 void | |
2255 data_mode(char *name) | |
2256 { | |
2257 if (output_mode!=DATA_EMIT_MODE) { | |
2258 printf(".data\n"); | |
2259 output_mode = DATA_EMIT_MODE; | |
2260 } | |
2261 if (name) | |
2262 printf("\t.type\t%s,@object\n",name); | |
2263 } | |
2264 | |
195 | 2265 #if FLOAT_CODE |
2266 | |
130 | 2267 char * |
2268 fstore(int d) | |
2269 { | |
148 | 2270 return (d?"stfd":"stfs"); |
130 | 2271 } |
2272 | |
2273 char * | |
2274 fload(int d) | |
2275 { | |
148 | 2276 return d?"lfd":"lfs"; |
130 | 2277 } |
2278 | |
153 | 2279 static |
2280 void code_dpfunc(char *f) | |
2281 { | |
2282 if (max_func_iargs<16) max_func_iargs=16; | |
2283 printf("\tjal %s\n",f); | |
2284 } | |
2285 | |
130 | 2286 void |
138 | 2287 code_cmp_dregister(int e2,int d) |
130 | 2288 { |
149 | 2289 char *frn,*grn; |
2290 int greg; | |
2291 | |
2292 if (d) { | |
2293 printf("\tli.d $6,%g\n",0.0); | |
2294 code_save_stacks(); | |
2295 move_dreg(4+DREG_OFFSET,freg); | |
153 | 2296 code_dpfunc("dpcmp"); |
2297 if (max_func_iargs<16) max_func_iargs=16; | |
149 | 2298 set_dreg(RET_DREGISTER,0); |
2299 return; | |
2300 } else { | |
2301 grn = register_name(greg = get_dregister(d)); | |
2302 frn = register_name(e2); | |
2303 printf("\tli.s %s,%g\n",grn,0.0); | |
2304 printf("\tc.eq.s %s,%s\n",grn,frn); | |
2305 free_register(greg); | |
2306 return; | |
2307 } | |
130 | 2308 } |
2309 | |
2310 void | |
138 | 2311 code_dregister(int e2,int freg,int d) |
130 | 2312 { |
141 | 2313 if (freg!=e2) { |
149 | 2314 if (d) { |
2315 if (!is_double_reg(e2)) error(-1); | |
2316 move_dreg(freg,e2); | |
2317 } else { | |
2318 if (!is_float_reg(e2)) error(-1); | |
2319 printf("\tfmr %s,%s\n",fregister_name(freg),fregister_name(e2)); | |
2320 } | |
141 | 2321 } |
148 | 2322 regv[freg]=1; |
130 | 2323 } |
2324 | |
2325 void code_dassign_gvar(int e2,int freg,int d) | |
2326 { | |
149 | 2327 NMTBL *n = (NMTBL*)cadr(e2); |
2328 if (d) { | |
2329 if (!is_double_reg(freg)) error(-1); | |
2330 printf("\tsw %s,0(%s)\n",dregister_name0(freg),n->nm); | |
2331 printf("\tsw %s,0(%s)\n",dregister_name1(freg),n->nm); | |
2332 } else { | |
2333 printf("\ts.s %s,0(%s)\n",fregister_name(freg),n->nm); | |
2334 } | |
148 | 2335 regv[freg]=1; |
130 | 2336 } |
2337 | |
2338 void code_dassign_lvar(int e2,int freg,int d) | |
2339 { | |
149 | 2340 if (d) { |
2341 if (!is_double_reg(freg)) error(-1); | |
2342 printf("\tsw %s,",dregister_name0(freg)); | |
2343 lvar(e2); | |
2344 printf("\tsw %s,",dregister_name1(freg)); | |
2345 e2 += size_of_double/2; | |
2346 } else { | |
2347 printf("\ts.s %s,",fregister_name(freg)); | |
2348 } | |
130 | 2349 lvar(e2); |
148 | 2350 regv[freg]=1; |
130 | 2351 } |
2352 | |
2353 void code_dassign(int e2,int freg,int d) | |
2354 { | |
149 | 2355 if (d) { |
2356 if (!is_double_reg(freg)) error(-1); | |
2357 printf("\tsw %s,0(%s)\n",dregister_name0(freg),register_name(e2)); | |
2358 printf("\tsw %s,4(%s)\n",dregister_name1(freg),register_name(e2)); | |
2359 } else { | |
2360 printf("\ts.s %s,0(%s)\n",fregister_name(freg),register_name(e2)); | |
2361 } | |
148 | 2362 regv[freg]=1; |
130 | 2363 } |
2364 | |
2365 void | |
138 | 2366 code_dassign_dregister(int e2,int d,int freg) { |
149 | 2367 /* これってさ、code_dregister と同じ? */ |
141 | 2368 if (e2!=freg) { |
149 | 2369 if (d) { |
2370 if (!is_double_reg(freg)) error(-1); | |
2371 move_dreg(freg,e2); | |
2372 } else { | |
2373 printf("\tmov.s %s,%s\n",fregister_name(e2),fregister_name(freg)); | |
2374 } | |
141 | 2375 } |
149 | 2376 |
130 | 2377 } |
2378 | |
136
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2379 static double d0 = 1.0; |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2380 |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2381 int |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2382 code_d1(double d) |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2383 { |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2384 int *i = (int *)&d0; int *j = (int *)&d; |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2385 return (i[1] == 0x3ff00000)?j[0]:j[1]; |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2386 } |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2387 |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2388 int |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2389 code_d2(double d) |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2390 { |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2391 int *i = (int *)&d0; int *j = (int *)&d; |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2392 return (i[1] == 0x3ff00000)?j[1]:j[0]; |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2393 } |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2394 |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2395 int |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2396 code_f(double d) |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2397 { |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2398 float f = d; |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2399 int *j = (int *)&f; |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2400 return *j; |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2401 } |
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2402 |
148 | 2403 void |
2404 code_dconst(int e2,int freg,int d) | |
130 | 2405 { |
138 | 2406 double value = dcadr(e2); |
149 | 2407 char *frn; |
2408 if (d) { | |
2409 printf("\tli.d %s,%g\n",dregister_name0(freg),value); | |
2410 } else { | |
2411 frn = fregister_name(freg); | |
2412 printf("\tli.s %s,%g\n",frn,value); | |
148 | 2413 } |
2414 regv[freg]=1; | |
130 | 2415 } |
2416 | |
136
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2417 |
138 | 2418 void code_dneg(int freg,int d) |
130 | 2419 { |
149 | 2420 char *frn; |
2421 if (d) { | |
2422 code_save_stacks(); | |
2423 move_dreg(4+DREG_OFFSET,freg); | |
153 | 2424 code_dpfunc("dpneg"); |
149 | 2425 set_dreg(RET_DREGISTER,0); |
2426 } else { | |
2427 frn = fregister_name(freg); | |
2428 printf("\tfneg %s,%s\n",frn,frn); | |
2429 } | |
130 | 2430 } |
2431 | |
148 | 2432 void code_d2i(int freg0) |
130 | 2433 { |
149 | 2434 code_save_stacks(); |
2435 set_dreg(RET_DREGISTER,1); | |
153 | 2436 code_dpfunc("dptoli"); |
149 | 2437 set_creg(RET_REGISTER,0); |
2438 regv[freg]=0; | |
148 | 2439 regv[creg]=1; |
130 | 2440 } |
2441 | |
148 | 2442 void code_i2d(int creg0) |
2443 { | |
141 | 2444 code_save_stacks(); |
148 | 2445 set_creg(RET_REGISTER,1); |
153 | 2446 code_dpfunc("litodp"); |
150 | 2447 set_dreg(RET_DREGISTER,0); |
148 | 2448 regv[freg]=1; |
149 | 2449 regv[creg]=0; |
141 | 2450 } |
136
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2451 |
148 | 2452 void code_d2u(int freg0) |
2453 { | |
141 | 2454 code_save_stacks(); |
149 | 2455 set_dreg(RET_DREGISTER,1); |
153 | 2456 code_dpfunc("dptoul"); |
148 | 2457 set_creg(RET_REGISTER,0); |
2458 regv[freg]=1; | |
141 | 2459 } |
2460 | |
148 | 2461 void code_u2d(int creg0) |
2462 { | |
2463 code_save_stacks(); | |
2464 set_creg(RET_REGISTER,1); | |
153 | 2465 code_dpfunc("ultodp"); |
149 | 2466 set_dreg(RET_DREGISTER,0); |
148 | 2467 regv[freg]=1; |
141 | 2468 } |
2469 | |
149 | 2470 void code_d2f(int freg) { |
2471 code_save_stacks(); | |
2472 set_dreg(RET_DREGISTER,1); | |
153 | 2473 code_dpfunc("dptofp"); |
149 | 2474 set_freg(RET_FREGISTER,0); |
2475 } | |
2476 | |
2477 void code_f2d(int freg) { | |
2478 code_save_stacks(); | |
2479 set_freg(RET_FREGISTER,1); | |
153 | 2480 code_dpfunc("fptodp"); |
149 | 2481 set_dreg(RET_DREGISTER,0); |
2482 } | |
2483 | |
2484 void code_f2i(int freg) { | |
2485 printf("\ttrunc.w.s %s,%s,%s\n",register_name(freg), | |
2486 register_name(freg),register_name(ireg)); | |
2487 creg = ireg; | |
2488 } | |
2489 | |
2490 void code_f2u(int freg) { | |
2491 printf("\ttrunc.w.s %s,%s,%s\n",register_name(freg), | |
2492 register_name(freg),register_name(ireg)); | |
2493 creg = ireg; | |
2494 } | |
2495 | |
2496 void code_i2f(int creg0) { | |
2497 printf("\tcvt.s.w %s,%s\n",register_name(freg),register_name(freg)); | |
2498 creg = freg; | |
2499 } | |
2500 | |
2501 void code_u2f(int creg0) { | |
2502 printf("\tcvt.s.w %s,%s\n",register_name(freg),register_name(freg)); | |
2503 creg = freg; | |
2504 } | |
136
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2505 |
130 | 2506 void code_drgvar(int e2,int d,int freg) |
2507 { | |
151 | 2508 char *name = ((NMTBL*)cadr(e2))->nm; |
149 | 2509 if (d) { |
151 | 2510 printf("\tlw %s,%s\n",dregister_name0(freg),name); |
2511 printf("\tlw %s,%s\n",dregister_name1(freg),name); | |
149 | 2512 } else { |
151 | 2513 printf("\tl.s %s,%s\n",fregister_name(freg),name); |
149 | 2514 } |
148 | 2515 regv[freg]=1; |
130 | 2516 } |
2517 | |
2518 | |
2519 void code_drlvar(int e2,int d,int freg) | |
2520 { | |
149 | 2521 if (d) { |
152 | 2522 printf("\tlw %s,",dregister_name0(freg)); lvar(e2); |
2523 printf("\tlw %s,",dregister_name1(freg)); lvar(e2+size_of_double/2); | |
149 | 2524 } else { |
2525 printf("\tl.s %s,",fregister_name(freg)); lvar(e2); | |
2526 } | |
148 | 2527 regv[freg]=1; |
130 | 2528 } |
2529 | |
138 | 2530 void code_cmp_drgvar(int e2,int d) |
130 | 2531 { |
149 | 2532 char *frn; |
2533 int g; | |
2534 if (d) { | |
2535 code_save_stacks(); | |
2536 set_dreg(RET_DREGISTER,1); | |
2537 code_drgvar(e2,d,RET_DREGISTER+2); | |
153 | 2538 code_dpfunc("dcmp"); |
149 | 2539 regv[dreg]=0; |
2540 } else { | |
2541 frn=fregister_name(freg); | |
2542 g=get_dregister(d); | |
2543 code_drgvar(e2,d,g); | |
2544 printf("\tfc.eq.s %s,%s\n",frn,fregister_name(g)); | |
2545 free_register(g); | |
2546 regv[freg]=0; | |
2547 } | |
130 | 2548 } |
2549 | |
138 | 2550 void code_cmp_drlvar(int e2,int d) |
130 | 2551 { |
2552 char *frn=fregister_name(freg); | |
149 | 2553 int g; |
2554 if (d) { | |
2555 code_save_stacks(); | |
2556 set_dreg(RET_DREGISTER,1); | |
2557 code_drgvar(e2,d,RET_DREGISTER+2); | |
153 | 2558 code_dpfunc("dcmp"); |
149 | 2559 regv[dreg]=0; |
2560 } else { | |
2561 g=get_dregister(d); | |
2562 code_drlvar(e2,d,g); | |
2563 printf("\tc.eq.s %s,%s\n",frn,fregister_name(g)); | |
2564 free_register(g); | |
2565 regv[freg]=0; | |
2566 } | |
2567 } | |
130 | 2568 |
149 | 2569 static void |
2570 dtosop0(char *opn,int e1,int d,int cmp) | |
2571 { | |
2572 char *frn; | |
2573 char *grn; | |
2574 if (d) { | |
2575 code_save_stacks(); | |
2576 set_dreg(RET_DREGISTER,1); | |
2577 move_dreg(RET_DREGISTER+2,e1); | |
153 | 2578 code_dpfunc(opn); |
149 | 2579 } else { |
2580 frn=fregister_name(freg); | |
2581 grn=fregister_name(e1); | |
2582 if (cmp) { | |
2583 printf("\t%s %s,%s\n",opn,frn,grn); | |
2584 } else { | |
2585 printf("\t%s %s,%s,%s\n",opn,frn,frn,grn); | |
2586 } | |
2587 } | |
2588 free_register(e1); | |
141 | 2589 } |
2590 | |
149 | 2591 |
130 | 2592 void dtosop(int op,int e1) |
2593 { | |
148 | 2594 regv[freg]=1; |
130 | 2595 switch(op) { |
149 | 2596 case FADD: dtosop0("fadd",e1,0,0); return; |
2597 case DADD: dtosop0("dpadd",e1,1,0); return; | |
2598 case FSUB: dtosop0("fadd",e1,0,0); return; | |
2599 case DSUB: dtosop0("dpsub",e1,1,0); return; | |
2600 case FDIV: dtosop0("fadd",e1,0,0); return; | |
2601 case DDIV: dtosop0("dpdiv",e1,1,0); return; | |
2602 case FMUL: dtosop0("fadd",e1,0,0); return; | |
2603 case DMUL: dtosop0("dpmul",e1,1,0); return; | |
141 | 2604 case DCMPGE: |
149 | 2605 case DCMP: dtosop0("dpcmp",e1,1,1); return; |
2606 case FCMPGE: dtosop0("c.le.s",e1,0,1); return; | |
2607 case FCMP: dtosop0("c.eq.s",e1,0,1); return; | |
136
069960078249
remove redundant funcall argument for prototyped code in PowerPC case.
kono
parents:
133
diff
changeset
|
2608 default: |
149 | 2609 error(-1); return; |
130 | 2610 } |
2611 } | |
2612 | |
2613 void | |
2614 code_dassop(int op,int d) { | |
2615 /* we have lvalue in creg, applied floating value is in freg */ | |
149 | 2616 char *frn; |
2617 int xreg; | |
130 | 2618 char *crn=register_name(creg); |
2619 | |
149 | 2620 if (d) { |
2621 xreg=emit_dpop(d); | |
2622 printf("\tlw %s,0(%s)\n",dregister_name0(freg),crn); | |
2623 printf("\tlw %s,%d(%s)\n",dregister_name1(freg),size_of_int,crn); | |
2624 dtosop(op,xreg); | |
2625 printf("\tsw %s,0(%s)\n",dregister_name0(freg),crn); | |
2626 printf("\tsw %s,%d(%s)\n",dregister_name1(freg),size_of_int,crn); | |
2627 emit_dpop_free(xreg,d); | |
2628 creg = dreg; | |
2629 } else { | |
2630 xreg=emit_dpop(d); | |
2631 frn=fregister_name(freg); | |
2632 crn=register_name(creg); | |
2633 | |
2634 printf("\tl.s %s,0(%s)\n",frn,crn); | |
2635 dtosop(op,xreg); | |
2636 printf("\ts.s %s,0(%s)\n",frn,crn); | |
2637 emit_dpop_free(xreg,d); | |
2638 creg = freg; | |
2639 } | |
2640 regv[creg]=1; | |
130 | 2641 } |
2642 | |
2643 | |
2644 void | |
2645 code_dpreinc(int e1,int e2,int d,int reg) { | |
2646 char *frn; | |
2647 char *crn; | |
2648 int g; | |
149 | 2649 char *grn; |
130 | 2650 |
2651 g_expr(e2); | |
2652 | |
149 | 2653 if (d) { |
2654 crn=register_name(creg); | |
2655 frn=fregister_name(freg); | |
130 | 2656 |
149 | 2657 code_save_stacks(); |
2658 set_dreg(RET_DREGISTER,0); | |
2659 printf("\tlw $4,0(%s)\n",crn); | |
2660 printf("\tlw $5,%d(%s)\n",size_of_int,crn); | |
2661 printf("\tli.d $6,1.0\n"); | |
2662 if (caddr(e1)>0) | |
153 | 2663 code_dpfunc("dpadd"); |
149 | 2664 else |
153 | 2665 code_dpfunc("dpsub"); |
149 | 2666 printf("\tsw $2,0(%s)\n",crn); |
2667 printf("\tsw $3,%d(%s)\n",size_of_int,crn); | |
2668 creg = dreg; | |
2669 } else { | |
2670 crn=register_name(creg); | |
2671 frn=fregister_name(freg); | |
2672 grn=fregister_name(g=get_dregister(d)); | |
2673 | |
2674 printf("\tl.s %s,0(%s)\n",frn,crn); | |
2675 printf("\tli.s %s,1.0\n",grn); | |
2676 if (caddr(e1)>0) | |
2677 printf("\tfadd %s,%s,%s\n",frn,frn,grn); | |
2678 else | |
2679 printf("\tfsub %s,%s,%s\n",frn,frn,grn); | |
2680 printf("\ts.s %s,0(%s)\n",frn,crn); | |
2681 free_register(g); | |
2682 creg = freg; | |
2683 } | |
2684 regv[creg]=1; | |
130 | 2685 } |
2686 | |
2687 void | |
2688 code_dpostinc(int e1,int e2,int d,int reg) { | |
2689 char *frn; | |
2690 char *crn; | |
2691 int g; | |
149 | 2692 char *grn; |
130 | 2693 |
2694 g_expr(e2); | |
2695 | |
149 | 2696 if (d) { |
2697 crn=register_name(creg); | |
2698 g = get_dregister(d); | |
2699 set_dreg(RET_DREGISTER,0); | |
2700 printf("\tlw $4,0(%s)\n",crn); | |
2701 printf("\tlw $5,%d(%s)\n",size_of_int,crn); | |
2702 move_dreg(g,4+DREG_OFFSET); | |
2703 printf("\tli.d $6,1.0\n"); | |
2704 if (caddr(e1)>0) | |
153 | 2705 code_dpfunc("dpadd"); |
149 | 2706 else |
153 | 2707 code_dpfunc("dpsub"); |
149 | 2708 set_dreg(RET_DREGISTER,0); |
2709 printf("\tsw $2,0(%s)\n",crn); | |
2710 printf("\tsw $3,%d(%s)\n",size_of_int,crn); | |
152 | 2711 free_register(dreg); |
149 | 2712 set_dreg(g,0); |
2713 creg = g; | |
2714 } else { | |
2715 crn=register_name(creg); | |
2716 frn=fregister_name(freg); | |
2717 grn=fregister_name(g=get_dregister(d)); | |
130 | 2718 |
149 | 2719 printf("\tl.s %s,0(%s)\n",frn,crn); |
2720 printf("\tli.s %s,1.0\n",grn); | |
2721 if (caddr(e1)>0) | |
2722 printf("\tfadd %s,%s,%s\n",frn,frn,grn); | |
2723 else | |
2724 printf("\tfsub %s,%s,%s\n",frn,frn,grn); | |
2725 printf("\ts.s %s,0(%s)\n",grn,crn); | |
2726 free_register(g); | |
2727 creg = freg; | |
2728 } | |
2729 regv[creg]=1; | |
2730 | |
130 | 2731 } |
2732 | |
2733 void | |
2734 drexpr(int e1, int e2,int l1, int op) | |
2735 { | |
149 | 2736 g_expr(list3(((op==FOP+EQ||op==FOP+NEQ)?DCMP:FCMPGE),e1,e2)); |
130 | 2737 switch(op) { |
149 | 2738 case DOP+GE: |
2739 printf("\tbgez\tL_%d\n",l1); | |
2740 break; | |
2741 case DOP+GT: | |
2742 printf("\tbltz\tL_%d\n",l1); | |
2743 break; | |
2744 case DOP+EQ: | |
2745 printf("\tbeq\tL_%d\n",l1); | |
2746 break; | |
2747 case DOP+NEQ: | |
2748 printf("\tbne\tL_%d\n",l1); | |
2749 break; | |
2750 case FOP+GE: | |
2751 printf("\tbc1tl\tL_%d\n",l1); | |
2752 break; | |
2753 case FOP+GT: | |
2754 printf("\tbc1tl\tL_%d\n",l1); | |
2755 break; | |
2756 case FOP+EQ: | |
2757 printf("\tbc1f\tL_%d\n",l1); | |
2758 break; | |
2759 case FOP+NEQ: | |
2760 printf("\tbc1f\tL_%d\n",l1); | |
2761 break; | |
130 | 2762 } |
2763 } | |
2764 | |
138 | 2765 int emit_dpop(int d) |
130 | 2766 { |
2767 int xreg,reg; | |
151 | 2768 if (d) |
2769 xreg=pop_dregister(); | |
2770 else | |
2771 xreg=pop_fregister(); | |
130 | 2772 if (xreg<= -REG_LVAR_OFFSET) { |
138 | 2773 reg = get_dregister(d); |
149 | 2774 code_drlvar(REG_LVAR_OFFSET+xreg,d,reg); |
130 | 2775 free_lvar(REG_LVAR_OFFSET+xreg); |
148 | 2776 regv[reg]=1; xreg=reg; |
130 | 2777 } |
2778 return xreg; | |
2779 } | |
2780 | |
138 | 2781 void emit_dpop_free(int e1,int d) |
130 | 2782 { |
148 | 2783 free_register(e1); |
130 | 2784 } |
2785 | |
133 | 2786 void emit_dpush(int d) |
130 | 2787 { |
2788 int new_reg; | |
2789 if (freg_sp>MAX_MAX) error(-1); | |
149 | 2790 new_reg = get_dregister(d); |
151 | 2791 if (d) { |
2792 dreg_stack[dreg_sp++] = dreg; /* push するかわりにレジスタを使う */ | |
2793 creg = dreg = new_reg; | |
2794 regv[dreg]=1; | |
2795 } else { | |
2796 freg_stack[freg_sp++] = freg; /* push するかわりにレジスタを使う */ | |
2797 creg = freg = new_reg; | |
2798 regv[freg]=1; | |
2799 } | |
130 | 2800 } |
2801 | |
195 | 2802 #endif |
2803 | |
130 | 2804 void |
2805 code_save_stacks() | |
2806 { | |
2807 int i,reg; | |
2808 for(i=0;i<reg_sp;i++) { | |
2809 if ((reg=reg_stack[i])>=0) { | |
2810 code_assign_lvar( | |
2811 (reg_stack[i]=new_lvar(size_of_int)),reg,0); | |
2812 reg_stack[i]= reg_stack[i]-REG_LVAR_OFFSET; | |
2813 } | |
2814 } | |
195 | 2815 #if FLOAT_CODE |
149 | 2816 for(i=0;i<dreg_sp;i++) { |
2817 if ((reg=dreg_stack[i])>=0) { | |
2818 code_dassign_lvar( | |
2819 (dreg_stack[i]=new_lvar(size_of_double)),reg,1); | |
2820 dreg_stack[i]= dreg_stack[i]-REG_LVAR_OFFSET; | |
2821 } | |
2822 } | |
130 | 2823 for(i=0;i<freg_sp;i++) { |
2824 if ((reg=freg_stack[i])>=0) { | |
2825 code_dassign_lvar( | |
149 | 2826 (freg_stack[i]=new_lvar(size_of_float)),reg,0); |
130 | 2827 freg_stack[i]= freg_stack[i]-REG_LVAR_OFFSET; |
2828 } | |
2829 } | |
195 | 2830 #endif |
130 | 2831 } |
2832 | |
2833 void | |
2834 emit_lib(char *p[]) | |
2835 { | |
2836 while(*p) { | |
2837 printf("%s\n",*p++); | |
2838 } | |
2839 } | |
2840 | |
2841 void | |
2842 code_closing() | |
2843 { | |
2844 global_table(); | |
2845 /* printf("\t.ident \"Micro-C compiled\"\n"); */ | |
149 | 2846 fclose(asi); |
130 | 2847 } |
2848 | |
195 | 2849 |
2850 #if LONGLONG_CODE | |
2851 | |
2852 | |
2853 /* 64bit int part */ | |
2854 | |
2855 void lrexpr(int e1, int e2,int l1, int op) | |
2856 { | |
2857 } | |
2858 | |
2859 int lpop_register() | |
2860 { | |
2861 return 0; | |
2862 } | |
2863 | |
2864 int emit_lpop() | |
2865 { | |
2866 return 0; | |
2867 } | |
2868 | |
2869 void code_lregister(int e2,int reg) | |
2870 { | |
2871 | |
2872 } | |
2873 | |
2874 void code_cmp_lregister(int reg) | |
2875 { | |
2876 | |
2877 } | |
2878 | |
2879 void code_cmp_lrgvar(int e1,int e2) | |
2880 { | |
2881 | |
2882 } | |
2883 | |
2884 void code_cmp_lrlvar(int e1,int e2) | |
2885 { | |
2886 | |
2887 } | |
2888 | |
2889 void code_lassign(int e1,int e2) | |
2890 { | |
2891 | |
2892 } | |
2893 | |
2894 void code_lassign_gvar(int e1,int e2) | |
2895 { | |
2896 | |
2897 } | |
2898 | |
2899 void code_lassign_lvar(int e1,int e2) | |
2900 { | |
2901 | |
2902 } | |
2903 | |
2904 void code_lassign_lregister(int e2,int reg) | |
2905 { | |
2906 | |
2907 } | |
2908 | |
2909 void code_lconst(int e1,int e2) | |
2910 { | |
2911 | |
2912 } | |
2913 | |
2914 void code_lneg(int e1,int e2) | |
2915 { | |
2916 | |
2917 } | |
2918 | |
2919 void code_lrgvar(int e1,int e2) | |
2920 { | |
2921 | |
2922 } | |
2923 | |
2924 void code_lrlvar(int e1,int e2) | |
2925 { | |
2926 | |
2927 } | |
2928 | |
2929 void ltosop(int e1,int e2) | |
2930 { | |
2931 | |
2932 } | |
2933 | |
2934 void emit_lpop_free(int e1) | |
2935 { | |
2936 | |
2937 } | |
2938 | |
2939 void emit_lpush() | |
2940 { | |
2941 | |
2942 } | |
2943 | |
2944 void code_i2ll(int creg) | |
2945 { | |
2946 | |
2947 } | |
2948 | |
2949 void code_i2ull(int creg) | |
2950 { | |
2951 | |
2952 } | |
2953 | |
2954 void code_u2ll(int creg) | |
2955 { | |
2956 | |
2957 } | |
2958 | |
2959 void code_u2ull(int creg) | |
2960 { | |
2961 | |
2962 } | |
2963 | |
2964 void code_ll2i(int creg) | |
2965 { | |
2966 | |
2967 } | |
2968 | |
2969 void code_ll2u(int creg) | |
2970 { | |
2971 | |
2972 } | |
2973 | |
2974 void code_ull2i(int creg) | |
2975 { | |
2976 | |
2977 } | |
2978 | |
2979 void code_ull2u(int creg) | |
2980 { | |
2981 | |
2982 } | |
2983 | |
2984 #if FLOAT_CODE | |
2985 void code_d2ll(int creg) | |
2986 { | |
2987 | |
2988 } | |
2989 | |
2990 void code_d2ull(int creg) | |
2991 { | |
2992 | |
2993 } | |
2994 | |
2995 void code_f2ll(int creg) | |
2996 { | |
2997 | |
2998 } | |
2999 | |
3000 void code_f2ull(int creg) | |
3001 { | |
3002 | |
3003 } | |
3004 | |
3005 void code_ll2d(int creg) | |
3006 { | |
3007 | |
3008 } | |
3009 | |
3010 void code_ll2f(int creg) | |
3011 { | |
3012 | |
3013 } | |
3014 | |
3015 void code_ull2d(int creg) | |
3016 { | |
3017 | |
3018 } | |
3019 | |
3020 void code_ull2f(int creg) | |
3021 { | |
3022 | |
3023 } | |
3024 | |
3025 void code_ull2ll(int creg) | |
3026 { | |
3027 | |
3028 } | |
3029 | |
3030 void code_ull2ull(int creg) | |
3031 { | |
3032 | |
3033 } | |
3034 | |
3035 #endif | |
3036 | |
3037 | |
3038 void code_lpreinc(int e1,int e2,int reg) | |
3039 { | |
3040 | |
3041 } | |
3042 | |
3043 void code_lpostinc(int e1,int e2,int reg) | |
3044 { | |
3045 | |
3046 } | |
3047 | |
3048 void code_lassop(int op) | |
3049 { | |
3050 | |
3051 } | |
3052 | |
3053 | |
3054 #endif | |
3055 | |
130 | 3056 /* end */ |
3057 |