Mercurial > hg > CbC > old > device
comparison mc-code-powerpc.c @ 205:a50f90d0b63a
*** empty log message ***
author | kono |
---|---|
date | Thu, 15 Apr 2004 01:01:51 +0900 |
parents | 4c614334f3d0 |
children | 4170cefb48f6 |
comparison
equal
deleted
inserted
replaced
204:4c614334f3d0 | 205:a50f90d0b63a |
---|---|
31 static int lvar_offset_label; | 31 static int lvar_offset_label; |
32 | 32 |
33 static int reg_save; | 33 static int reg_save; |
34 static int freg_save; | 34 static int freg_save; |
35 | 35 |
36 static int freg,ireg; | 36 static int freg,ireg,lreg; |
37 | 37 |
38 int size_of_int = 4; | 38 int size_of_int = 4; |
39 int size_of_short = 2; | 39 int size_of_short = 2; |
40 int size_of_float = 4; | 40 int size_of_float = 4; |
41 int size_of_double = 8; | 41 int size_of_double = 8; |
42 int size_of_longlong = 8; | 42 int size_of_longlong = 8; |
43 int endian = 1; | 43 int endian = 1; |
44 | 44 |
45 int reg_sp; /* REGister Stack-Pointer */ | 45 static int reg_sp; /* REGister Stack-Pointer */ |
46 int reg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ | 46 static int reg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ |
47 | 47 |
48 /* floating point registers */ | 48 /* floating point registers */ |
49 | 49 |
50 int freg_sp; /* floating point REGister Stack-Pointer */ | 50 static int freg_sp; /* floating point REGister Stack-Pointer */ |
51 int freg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ | 51 static int freg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ |
52 | 52 |
53 #define REG_fp 1 | 53 #define REG_fp 1 |
54 #define REG_sp 30 | 54 #define REG_sp 30 |
55 #define REG_VAR_BASE 29 | 55 #define REG_VAR_BASE 29 |
56 #define REG_VAR_MIN 18 | 56 #define REG_VAR_MIN 18 |
64 #define MIN_TMP_FREG 1 | 64 #define MIN_TMP_FREG 1 |
65 #define MAX_TMP_FREG 14 | 65 #define MAX_TMP_FREG 14 |
66 | 66 |
67 #define RET_REGISTER 3 | 67 #define RET_REGISTER 3 |
68 #define RET_FREGISTER (1+FREG_OFFSET) | 68 #define RET_FREGISTER (1+FREG_OFFSET) |
69 #define RET_LREGISTER_L 4 /* low word */ | |
70 #define RET_LREGISTER_H 3 /* high word */ | |
69 | 71 |
70 int MAX_REGISTER=30; /* PowerPCのレジスタを10個まで使う*/ | 72 int MAX_REGISTER=30; /* PowerPCのレジスタを10個まで使う*/ |
71 int MAX_FREGISTER=31; | 73 int MAX_FREGISTER=31; |
72 #define REAL_MAX_REGISTER 32 /* PowerPCのレジスタが32ということ*/ | 74 #define REAL_MAX_REGISTER 32 /* PowerPCのレジスタが32ということ*/ |
73 #define REAL_MAX_FREGISTER 32 /* PowerPCのレジスタが32ということ*/ | 75 #define REAL_MAX_FREGISTER 32 /* PowerPCのレジスタが32ということ*/ |
82 int MAX_CODE_INPUT_FREGISTER_VAR = 14-MIN_TMP_FREG; | 84 int MAX_CODE_INPUT_FREGISTER_VAR = 14-MIN_TMP_FREG; |
83 | 85 |
84 #define CREG_REGISTER MAX_TMP_REG | 86 #define CREG_REGISTER MAX_TMP_REG |
85 #define FREG_FREGISTER (MAX_TMP_FREG+FREG_OFFSET) | 87 #define FREG_FREGISTER (MAX_TMP_FREG+FREG_OFFSET) |
86 | 88 |
87 int powerpc_regs[REAL_MAX_REGISTER+REAL_MAX_FREGISTER]; | 89 static int powerpc_regs[REAL_MAX_REGISTER+REAL_MAX_FREGISTER]; |
88 int powerpc_regv[REAL_MAX_REGISTER+REAL_MAX_FREGISTER]; | 90 |
89 | 91 static int *regs = powerpc_regs; |
90 int *regv = powerpc_regv; | |
91 int *regs = powerpc_regs; | |
92 | 92 |
93 static int max_reg_var, max_freg_var; | 93 static int max_reg_var, max_freg_var; |
94 static int cond_reg=-1,cond_freg=-1; | |
95 | 94 |
96 static char *reg_name[] = { | 95 static char *reg_name[] = { |
97 "r0","r1","r2","r3","r4","r5","r6","r7","r8","r9", | 96 "r0","r1","r2","r3","r4","r5","r6","r7","r8","r9", |
98 "r10","r11","r12","r13","r14","r15","r16","r17","r18","r19", | 97 "r10","r11","r12","r13","r14","r15","r16","r17","r18","r19", |
99 "r20","r21","r22","r23","r24","r25","r26","r27","r28","r29", | 98 "r20","r21","r22","r23","r24","r25","r26","r27","r28","r29", |
102 "f10","f11","f12","f13","f14","f15","f16","f17","f18","f19", | 101 "f10","f11","f12","f13","f14","f15","f16","f17","f18","f19", |
103 "f20","f21","f22","f23","f24","f25","f26","f27","f28","f29", | 102 "f20","f21","f22","f23","f24","f25","f26","f27","f28","f29", |
104 "f30","f31" | 103 "f30","f31" |
105 }; | 104 }; |
106 | 105 |
107 #define register_name(i) reg_name[i] | 106 #define register_name(i) reg_name[cadr(i)] |
108 #define fregister_name(i) reg_name[i] | 107 #define fregister_name(i) reg_name[cadr(i)] |
109 | 108 #define lregister_name_low(i) reg_name[cadr(i)] |
110 #define is_int_reg(i) (0<=i&&i<REAL_MAX_REGISTER) | 109 #define lregister_name_high(i) reg_name[caddr(i)] |
111 #define is_float_reg(i) (REAL_MAX_REGISTER<=i&&i<REAL_MAX_FREGISTER+REAL_MAX_REGISTER) | 110 |
111 #define is_int_reg_0(i) (0<=i&&i<REAL_MAX_REGISTER) | |
112 #define is_float_reg_0(i) (REAL_MAX_REGISTER<=i&&i<REAL_MAX_FREGISTER+REAL_MAX_REGISTER) | |
113 | |
114 #define is_int_reg(i) (car(i)==REGISTER) | |
115 #define is_float_reg(i) (car(i)==DREGISTER) | |
116 #define is_longlong_reg(i) (car(i)==LREGISTER) | |
112 | 117 |
113 | 118 |
114 int use_int(int i) { | 119 int use_int(int i) { |
115 if (!is_int_reg(i)) i = ireg; | 120 if (lreg) { |
116 if (!regs[i]) regs[i]=1; | 121 free_register(lreg); lreg = 0; |
122 } | |
123 if (!is_int_reg(i)) { | |
124 if (!ireg) ireg = get_register(); | |
125 i = lreg; | |
126 } | |
117 return i; | 127 return i; |
118 } | 128 } |
119 | 129 |
120 int use_float(int i) { | 130 int use_float(int i) { |
121 if (!is_float_reg(i)) i = freg; | 131 if (!is_float_reg(i)) i = freg; |
128 if (!regs[i]) regs[i]=1; | 138 if (!regs[i]) regs[i]=1; |
129 return i; | 139 return i; |
130 } | 140 } |
131 | 141 |
132 int use_longlong(int i) { | 142 int use_longlong(int i) { |
143 if (ireg) { | |
144 free_register(ireg); ireg = 0; | |
145 } | |
146 if (!is_longlong_reg(i)) { | |
147 if (!lreg) lreg = get_lregister(); | |
148 i = lreg; | |
149 } | |
133 return i; | 150 return i; |
134 } | 151 } |
135 | 152 |
136 | 153 |
137 #if FLOAT_CODE | 154 #if FLOAT_CODE |
301 void | 318 void |
302 code_lvar(int e2,int creg) { | 319 code_lvar(int e2,int creg) { |
303 lvar_intro(e2); | 320 lvar_intro(e2); |
304 printf("\tla %s,",register_name(creg)); | 321 printf("\tla %s,",register_name(creg)); |
305 lvar(e2); | 322 lvar(e2); |
306 regv[creg]=1; | |
307 } | 323 } |
308 | 324 |
309 void | 325 void |
310 code_init(void) | 326 code_init(void) |
311 { | 327 { |
324 if (is_int_reg(creg)) { | 340 if (is_int_reg(creg)) { |
325 dm = get_register(); | 341 dm = get_register(); |
326 new_reg = get_register(); | 342 new_reg = get_register(); |
327 old_reg = creg; | 343 old_reg = creg; |
328 ireg = creg = new_reg; | 344 ireg = creg = new_reg; |
345 free_register(old_reg); | |
346 free_register(dm); | |
329 } else if (is_float_reg(creg)) { | 347 } else if (is_float_reg(creg)) { |
330 dm = get_dregister(1); | 348 dm = get_dregister(1); |
331 new_reg = get_dregister(1); | 349 new_reg = get_dregister(1); |
332 old_reg = creg; | 350 old_reg = creg; |
333 freg = creg = new_reg; | 351 freg = creg = new_reg; |
334 } | 352 free_register(old_reg); |
335 free_register(old_reg); | 353 free_register(dm); |
336 free_register(dm); | 354 } |
337 #endif | 355 #endif |
338 regv[creg]=0; | |
339 regv[freg]=0; | |
340 } | 356 } |
341 | 357 |
342 void | 358 void |
343 code_gexpr(int e){ | 359 code_gexpr(int e){ |
344 if (is_int_reg(creg) && creg!=ireg) error(-1); | 360 if (is_int_reg(creg) && creg!=ireg) error(-1); |
361 n = (NMTBL*)caddr(args); | 377 n = (NMTBL*)caddr(args); |
362 type = n->ty; | 378 type = n->ty; |
363 if (scalar(type)) { | 379 if (scalar(type)) { |
364 if ((reg = get_input_register_var(reg_var,n,is_code0))) { | 380 if ((reg = get_input_register_var(reg_var,n,is_code0))) { |
365 n->sc = REGISTER; | 381 n->sc = REGISTER; |
366 n->dsp = cadr(reg); | 382 n->dsp = reg; |
367 regv[n->dsp]= 1; | 383 regs[cadr(n->dsp)]= INPUT_REG; |
368 regs[n->dsp]= INPUT_REG; | |
369 reg_var++; | 384 reg_var++; |
370 cadddr(args)=size_of_int; /* why we need this? */ | 385 cadddr(args)=size_of_int; |
371 } | 386 } |
372 } else if (type==FLOAT) { | 387 } else if (type==FLOAT) { |
373 if ((reg = get_input_dregister_var(freg_var,n,is_code0,0))) { | 388 if ((reg = get_input_dregister_var(freg_var,n,is_code0,0))) { |
374 n->sc = DREGISTER; | 389 n->sc = DREGISTER; |
375 n->dsp = cadr(reg); | 390 n->dsp = reg; |
376 regv[n->dsp]= 1; | 391 regs[cadr(n->dsp)]= INPUT_REG; |
377 regs[n->dsp]= INPUT_REG; | |
378 freg_var++; | 392 freg_var++; |
379 cadddr(args)=size(type); /* why we need this? */ | 393 cadddr(args)=size(type); |
380 } | 394 } |
381 } else if (type==DOUBLE) { | 395 } else if (type==DOUBLE) { |
382 if ((reg = get_input_dregister_var(freg_var,n,is_code0,1))) { | 396 if ((reg = get_input_dregister_var(freg_var,n,is_code0,1))) { |
383 n->sc = DREGISTER; | 397 n->sc = DREGISTER; |
384 n->dsp = cadr(reg); | 398 n->dsp = reg; |
385 regv[n->dsp]= 1; | 399 regs[cadr(n->dsp)]= INPUT_REG; |
386 regs[n->dsp]= INPUT_REG; | |
387 freg_var++; | 400 freg_var++; |
388 cadddr(args)=size(type); /* why we need this? */ | 401 cadddr(args)=size(type); |
402 } | |
403 } else if (type==LONGLONG||type==ULONGLONG) { | |
404 if ((reg = get_input_lregister_var(reg_var,n,is_code0))) { | |
405 n->sc = LREGISTER; | |
406 n->dsp = reg; | |
407 regs[cadr(n->dsp)]= INPUT_REG; | |
408 regs[caddr(n->dsp)]= INPUT_REG; | |
409 reg_var+=2; | |
410 cadddr(args)=size(type); | |
389 } | 411 } |
390 } | 412 } |
391 args = cadr(args); | 413 args = cadr(args); |
392 } | 414 } |
393 if (is_function(fnptr)) | 415 if (is_function(fnptr)) |
399 { /* 使われていないレジスタを調べる */ | 421 { /* 使われていないレジスタを調べる */ |
400 int i,reg; | 422 int i,reg; |
401 for(i=MAX_TMP_REG;i>MIN_TMP_REG;i--) { | 423 for(i=MAX_TMP_REG;i>MIN_TMP_REG;i--) { |
402 if (regs[i]) continue; /* 使われている */ | 424 if (regs[i]) continue; /* 使われている */ |
403 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ | 425 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ |
404 return i; /* その場所を表す番号を返す */ | 426 return glist2(REGISTER,i); /* その場所を表す番号を返す */ |
405 } | 427 } |
406 /* PTR_CACHE をつぶす */ | 428 /* PTR_CACHE をつぶす */ |
407 for(i=MAX_TMP_REG;i>MIN_TMP_REG;i--) { | 429 for(i=MAX_TMP_REG;i>MIN_TMP_REG;i--) { |
408 if (regs[i]==PTRC_REG) { | 430 if (regs[i]==PTRC_REG) { |
409 clear_ptr_cache_reg(i); | 431 clear_ptr_cache_reg(i); |
410 } else | 432 } else |
411 continue; | 433 continue; |
412 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ | 434 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ |
413 return i; /* その場所を表す番号を返す */ | 435 return glist2(REGISTER,i); /* その場所を表す番号を返す */ |
414 } | 436 } |
415 /* search register stack */ | 437 /* search register stack */ |
416 for(i=0;i<reg_sp;i++) { | 438 for(i=0;i<reg_sp;i++) { |
417 if ((reg=reg_stack[i])>=0) { | 439 if ((reg=reg_stack[i])>=0) { |
418 code_assign_lvar( | 440 code_assign_lvar( |
423 } | 445 } |
424 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) { | 446 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) { |
425 reg =REG_VAR_BASE-i; | 447 reg =REG_VAR_BASE-i; |
426 if (! regs[reg]) { /* 使われていないなら */ | 448 if (! regs[reg]) { /* 使われていないなら */ |
427 regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */ | 449 regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */ |
428 regv[reg]=0; | |
429 if (i>max_reg_var) max_reg_var=i; | 450 if (i>max_reg_var) max_reg_var=i; |
430 return reg; | 451 return glist2(REGISTER,reg); /* その場所を表す番号を返す */ |
431 } | 452 } |
432 } | 453 } |
433 /* 空いている場所がないなら、エラー (いったい誰が使ってるの?) */ | 454 /* 空いている場所がないなら、エラー (いったい誰が使ってるの?) */ |
434 error(HPERR); return creg; | 455 error(HPERR); return creg; |
435 } | 456 } |
446 { /* 使われていないレジスタを調べる */ | 467 { /* 使われていないレジスタを調べる */ |
447 int i,reg; | 468 int i,reg; |
448 for(i=MAX_TMP_FREG+FREG_OFFSET;i>MIN_TMP_FREG+FREG_OFFSET;i--) { | 469 for(i=MAX_TMP_FREG+FREG_OFFSET;i>MIN_TMP_FREG+FREG_OFFSET;i--) { |
449 if (regs[i]) continue; /* 使われている */ | 470 if (regs[i]) continue; /* 使われている */ |
450 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ | 471 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ |
451 return i; /* その場所を表す番号を返す */ | 472 return glist2(DREGISTER,i); /* その場所を表す番号を返す */ |
452 } | 473 } |
453 /* search register stack */ | 474 /* search register stack */ |
454 for(i=0;i<freg_sp;i++) { | 475 for(i=0;i<freg_sp;i++) { |
455 if ((reg=freg_stack[i])>=0) { | 476 if ((reg=freg_stack[i])>=0) { |
456 code_dassign_lvar( | 477 code_dassign_lvar( |
461 } | 482 } |
462 for(i=0;i<FREG_VAR_BASE-REG_VAR_MIN;i++) { | 483 for(i=0;i<FREG_VAR_BASE-REG_VAR_MIN;i++) { |
463 reg =FREG_VAR_BASE-i+FREG_OFFSET; | 484 reg =FREG_VAR_BASE-i+FREG_OFFSET; |
464 if (! regs[reg]) { /* 使われていないなら */ | 485 if (! regs[reg]) { /* 使われていないなら */ |
465 regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */ | 486 regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */ |
466 regv[reg]=0; | |
467 if (i>max_freg_var) max_freg_var=i; | 487 if (i>max_freg_var) max_freg_var=i; |
468 return reg; | 488 return glist2(DREGISTER,reg); /* その場所を表す番号を返す */ |
469 } | 489 } |
470 } | 490 } |
471 /* 空いている場所がないなら、エラー (いったい誰が使ってるの?) */ | 491 /* 空いている場所がないなら、エラー (いったい誰が使ってるの?) */ |
472 error(REG_ERR); return freg; | 492 error(REG_ERR); return freg; |
473 } | 493 } |
479 } | 499 } |
480 #endif | 500 #endif |
481 | 501 |
482 #if LONGLONG_CODE | 502 #if LONGLONG_CODE |
483 int | 503 int |
504 get_lregister() | |
505 { | |
506 int h,l,h0,l0; | |
507 h = get_register(); h0 = cadr(h); | |
508 l = get_register(); l0 = cadr(l); | |
509 free_glist2(h); free_glist2(l); | |
510 return glist3(LREGISTER,l0,h0); | |
511 } | |
512 | |
513 int | |
484 get_lregister_var(NMTBL *n) | 514 get_lregister_var(NMTBL *n) |
485 { | 515 { |
486 return list2(LVAR,new_lvar(size_of_longlong)); | 516 return list2(LVAR,new_lvar(size_of_longlong)); |
487 } | 517 } |
488 #endif | 518 #endif |
495 } | 525 } |
496 | 526 |
497 void | 527 void |
498 free_register(int i) { /* いらなくなったレジスタを開放 */ | 528 free_register(int i) { /* いらなくなったレジスタを開放 */ |
499 if (i<0||MAX_FREGISTER+FREG_OFFSET<i) error(-1); | 529 if (i<0||MAX_FREGISTER+FREG_OFFSET<i) error(-1); |
500 regv[i]=regs[i]=0; | 530 regs[i]=0; |
501 } | 531 } |
502 | 532 |
503 int | 533 int |
504 get_input_dregister_var(int i,NMTBL *n,int is_code,int d) | 534 get_input_dregister_var(int i,NMTBL *n,int is_code,int d) |
505 { | 535 { |
508 i = FREG_VAR_BASE-i+FREG_OFFSET; | 538 i = FREG_VAR_BASE-i+FREG_OFFSET; |
509 } else { | 539 } else { |
510 if (i<0||i>=MAX_INPUT_DREGISTER_VAR) return 0; | 540 if (i<0||i>=MAX_INPUT_DREGISTER_VAR) return 0; |
511 i = i+MIN_TMP_FREG+FREG_OFFSET; | 541 i = i+MIN_TMP_FREG+FREG_OFFSET; |
512 } | 542 } |
513 return list3(DREGISTER,i,(int)n); | 543 return list3(DREGISTER,glist2(DREGISTER,i),(int)n); |
514 } | 544 } |
515 | 545 |
516 int | 546 int |
517 get_input_register_var(int i,NMTBL *n,int is_code) | 547 get_input_lregister_var(int i,NMTBL *n,int is_code) |
518 { | 548 { |
519 if (is_code) { | 549 if (is_code) { |
520 if(!(i<REG_VAR_BASE-REG_VAR_MIN)) return 0; | 550 if(!(i<REG_VAR_BASE-REG_VAR_MIN)) return 0; |
521 i = REG_VAR_BASE-i; | 551 i = REG_VAR_BASE-i; |
522 } else { | 552 } else { |
523 if (i<0||i>=MAX_INPUT_REGISTER_VAR) return 0; | 553 if (i<0||i>=MAX_INPUT_REGISTER_VAR) return 0; |
524 i = i+MIN_TMP_REG; | 554 i = i+MIN_TMP_REG; |
525 } | 555 } |
526 return list3(REGISTER,i,(int)n); | 556 return list3(LREGISTER,glist3(LREGISTER,i+1,i),(int)n); |
557 } | |
558 | |
559 int | |
560 get_input_register_var(int i,NMTBL *n,int is_code) | |
561 { | |
562 if (is_code) { | |
563 if(!(i<REG_VAR_BASE-REG_VAR_MIN)) return 0; | |
564 i = REG_VAR_BASE-i; | |
565 } else { | |
566 if (i<0||i>=MAX_INPUT_REGISTER_VAR) return 0; | |
567 i = i+MIN_TMP_REG; | |
568 } | |
569 return list3(REGISTER,glist2(REGISTER,i),(int)n); | |
527 } | 570 } |
528 | 571 |
529 /* double register case? */ | 572 /* double register case? */ |
530 | 573 |
531 int | 574 int |
536 i = REG_VAR_BASE-i; | 579 i = REG_VAR_BASE-i; |
537 } else { | 580 } else { |
538 if (i<0||i>=MAX_INPUT_REGISTER_VAR+1) return 0; | 581 if (i<0||i>=MAX_INPUT_REGISTER_VAR+1) return 0; |
539 i = i+MIN_TMP_REG; | 582 i = i+MIN_TMP_REG; |
540 } | 583 } |
541 return list3(REGISTER,i,(int)n); | 584 return list3(REGISTER,glist2(REGISTER,i),(int)n); |
542 } | 585 } |
543 | 586 |
544 int | 587 int |
545 free_register_count(int d) | 588 free_register_count(int d) |
546 { | 589 { |
547 int i,count,fcount; | 590 int i,count,fcount; |
548 fcount = count = 0; | 591 fcount = count = 0; |
549 for(i=0;i<MAX_REGISTER;i++) { | 592 for(i=0;i<MAX_REGISTER;i++) { |
550 if (! regs[i] && ! regv[i]) count++; | 593 if (! regs[i]) count++; |
551 } | 594 } |
552 for(i=0;i<MAX_FREGISTER;i++) { | 595 for(i=0;i<MAX_FREGISTER;i++) { |
553 if (! regs[i+FREG_OFFSET] && ! regv[i+FREG_OFFSET]) fcount++; | 596 if (! regs[i+FREG_OFFSET]) fcount++; |
554 } | 597 } |
555 printf("# free reg %d freg %d\n",count,fcount); | 598 printf("# free reg %d freg %d\n",count,fcount); |
556 return d?fcount:count; | 599 return d?fcount:count; |
557 } | 600 } |
558 | 601 |
559 int | 602 #if 0 |
603 static int | |
560 register_full(void) | 604 register_full(void) |
561 { | 605 { |
562 int i; | 606 int i; |
563 for(i=0;i<MAX_REGISTER;i++) { | 607 for(i=0;i<MAX_REGISTER;i++) { |
564 if (! regs[i]) { | 608 if (! regs[i]) { |
565 return 0; | 609 return 0; |
566 } | 610 } |
567 } | 611 } |
568 return 1; | 612 return 1; |
569 } | 613 } |
614 #endif | |
570 | 615 |
571 void | 616 void |
572 free_all_register(void) | 617 free_all_register(void) |
573 { | 618 { |
574 int i; | 619 int i; |
575 for(i=0;i<MAX_REGISTER;i++) { regs[i]=0; regv[i]=0; } | 620 for(i=0;i<MAX_REGISTER;i++) { regs[i]=0; } |
576 for(i=0;i<MAX_FREGISTER;i++) { regs[i+FREG_OFFSET]=0; regv[i+FREG_OFFSET]=0; } | 621 for(i=0;i<MAX_FREGISTER;i++) { regs[i+FREG_OFFSET]=0; } |
577 #if FLOAT_CODE | 622 #if FLOAT_CODE |
578 freg = get_dregister(1); | 623 freg = get_dregister(1); |
579 set_freg(FREG_FREGISTER,0); | 624 set_freg(FREG_FREGISTER,0); |
580 #endif | 625 #endif |
581 ireg = creg = get_register(); | 626 ireg = creg = get_register(); |
593 if (!lsrc) return; | 638 if (!lsrc) return; |
594 printf("# %d: %s:",lineno,s); | 639 printf("# %d: %s:",lineno,s); |
595 printf(" creg=%s fgreg=%s",register_name(creg),fregister_name(freg)); | 640 printf(" creg=%s fgreg=%s",register_name(creg),fregister_name(freg)); |
596 #if 0 | 641 #if 0 |
597 printf("\n# regs:"); | 642 printf("\n# regs:"); |
598 for(i=0;i<MAX_REGISTER;i++) { printf("%d",regv[i]); } | |
599 printf(":"); | |
600 for(i=0;i<MAX_REGISTER;i++) { printf("%d",regs[i]); } | 643 for(i=0;i<MAX_REGISTER;i++) { printf("%d",regs[i]); } |
601 printf("\n# freg:"); | 644 printf("\n# freg:"); |
602 for(i=0;i<MAX_FREGISTER;i++) { printf("%d",regs[i+FREG_OFFSET]); } | 645 for(i=0;i<MAX_FREGISTER;i++) { printf("%d",regs[i+FREG_OFFSET]); } |
603 for(i=reg_sp;i>=0;i--) { | 646 for(i=reg_sp;i>=0;i--) { |
604 if(reg_stack[i]>=0) | 647 if(reg_stack[i]>=0) |
615 free_register(reg_stack[--reg_sp]); | 658 free_register(reg_stack[--reg_sp]); |
616 } | 659 } |
617 while(freg_sp > 0) { | 660 while(freg_sp > 0) { |
618 free_register(freg_stack[--freg_sp]); | 661 free_register(freg_stack[--freg_sp]); |
619 } | 662 } |
620 if (cond_freg!=-1) { | |
621 if(car(cond_freg)==DREGISTER) free_register(cadr(cond_freg)); | |
622 else if(car(cond_freg)==FREGISTER) free_register(cadr(cond_freg)); | |
623 cond_freg=-1; | |
624 } | |
625 if (cond_reg!=-1) { | |
626 if(car(cond_reg)==REGISTER) free_register(cadr(cond_reg)); | |
627 cond_reg=-1; | |
628 } | |
629 text_mode(); | 663 text_mode(); |
630 gexpr_code_init(); | 664 gexpr_code_init(); |
631 register_usage("gexpr_init"); | 665 register_usage("gexpr_init"); |
632 } | 666 } |
633 | 667 |
640 reg_sp = 0; | 674 reg_sp = 0; |
641 freg_sp = 0; | 675 freg_sp = 0; |
642 text_mode(); | 676 text_mode(); |
643 } | 677 } |
644 | 678 |
645 int | |
646 register_var(int r) { | |
647 return r; | |
648 } | |
649 | |
650 | 679 |
651 int | 680 int |
652 get_register_var(NMTBL *n) | 681 get_register_var(NMTBL *n) |
653 { | 682 { |
654 int i; | 683 int i; |
655 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) { | 684 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) { |
656 if (! regs[REG_VAR_BASE-i]) { /* 使われていないなら */ | 685 if (! regs[REG_VAR_BASE-i]) { /* 使われていないなら */ |
657 /* そのレジスタを使うことを宣言し */ | 686 /* そのレジスタを使うことを宣言し */ |
658 regs[REG_VAR_BASE-i]=USING_REG; | 687 regs[REG_VAR_BASE-i]=USING_REG; |
659 regv[REG_VAR_BASE-i]=0; | |
660 if (i>max_reg_var) max_reg_var=i; | 688 if (i>max_reg_var) max_reg_var=i; |
661 /* その場所を表す番号を返す */ | 689 /* その場所を表す番号を返す */ |
662 return list3(REGISTER,REG_VAR_BASE-i,(int)n); | 690 return list3(REGISTER,REG_VAR_BASE-i,(int)n); |
663 } | 691 } |
664 } | 692 } |
675 { | 703 { |
676 int i; | 704 int i; |
677 for(i=0;i<FREG_VAR_BASE-FREG_VAR_MIN;i++) { | 705 for(i=0;i<FREG_VAR_BASE-FREG_VAR_MIN;i++) { |
678 if (! regs[FREG_VAR_BASE-i+FREG_OFFSET]) { /* 使われていないなら */ | 706 if (! regs[FREG_VAR_BASE-i+FREG_OFFSET]) { /* 使われていないなら */ |
679 regs[FREG_VAR_BASE-i+FREG_OFFSET]=USING_REG; /*そのレジスタを使うことを宣言し*/ | 707 regs[FREG_VAR_BASE-i+FREG_OFFSET]=USING_REG; /*そのレジスタを使うことを宣言し*/ |
680 regv[FREG_VAR_BASE-i+FREG_OFFSET]=0; | |
681 if (i>max_freg_var) max_freg_var=i; | 708 if (i>max_freg_var) max_freg_var=i; |
682 /* その場所を表す番号を返す */ | 709 /* その場所を表す番号を返す */ |
683 return list3(DREGISTER,FREG_VAR_BASE-i+FREG_OFFSET,(int)n); | 710 return list3(DREGISTER,FREG_VAR_BASE-i+FREG_OFFSET,(int)n); |
684 } | 711 } |
685 } | 712 } |
692 int new_reg; | 719 int new_reg; |
693 if (reg_sp>MAX_MAX) error(-1); | 720 if (reg_sp>MAX_MAX) error(-1); |
694 new_reg = get_register(); | 721 new_reg = get_register(); |
695 reg_stack[reg_sp++] = creg; /* push するかわりにレジスタを使う */ | 722 reg_stack[reg_sp++] = creg; /* push するかわりにレジスタを使う */ |
696 ireg = creg = new_reg; | 723 ireg = creg = new_reg; |
697 regv[creg]=1; | |
698 } | 724 } |
699 | 725 |
700 int | 726 int |
701 emit_pop(int type) | 727 emit_pop(int type) |
702 { | 728 { |
705 if (xreg<= -REG_LVAR_OFFSET) { | 731 if (xreg<= -REG_LVAR_OFFSET) { |
706 reg = get_register(); | 732 reg = get_register(); |
707 code_rlvar(REG_LVAR_OFFSET+xreg,reg); | 733 code_rlvar(REG_LVAR_OFFSET+xreg,reg); |
708 free_lvar(REG_LVAR_OFFSET+xreg); | 734 free_lvar(REG_LVAR_OFFSET+xreg); |
709 xreg = reg; | 735 xreg = reg; |
710 regv[creg]=1; | |
711 } | 736 } |
712 return xreg; | 737 return xreg; |
713 } | 738 } |
714 | 739 |
715 int | 740 int |
837 code_gvar(int e1,int creg) { | 862 code_gvar(int e1,int creg) { |
838 int r; | 863 int r; |
839 r = get_ptr_cache((NMTBL*)cadr(e1)); | 864 r = get_ptr_cache((NMTBL*)cadr(e1)); |
840 if(r!=creg) | 865 if(r!=creg) |
841 printf("\tmr %s,%s\n",register_name(creg),register_name(r)); | 866 printf("\tmr %s,%s\n",register_name(creg),register_name(r)); |
842 regv[creg]=1; | |
843 return; | 867 return; |
844 } | 868 } |
845 | 869 |
846 void | 870 void |
847 code_rgvar(int e1,int creg) { | 871 code_rgvar(int e1,int creg) { |
848 if (!is_int_reg(creg)) error(-1); | 872 if (!is_int_reg(creg)) error(-1); |
849 printf("\tlwz %s,0(%s)\n",register_name(creg), | 873 printf("\tlwz %s,0(%s)\n",register_name(creg), |
850 register_name(get_ptr_cache((NMTBL*)cadr(e1)))); | 874 register_name(get_ptr_cache((NMTBL*)cadr(e1)))); |
851 regv[creg]=1; | |
852 } | 875 } |
853 | 876 |
854 void | 877 void |
855 code_crgvar(int e1,int creg,int sign,int sz){ | 878 code_crgvar(int e1,int creg,int sign,int sz){ |
856 char *crn = register_name(creg); | 879 char *crn = register_name(creg); |
857 printf("\t%s %s,0(%s)\n",cload(sz),crn, | 880 printf("\t%s %s,0(%s)\n",cload(sz),crn, |
858 register_name(get_ptr_cache((NMTBL*)cadr(e1)))); | 881 register_name(get_ptr_cache((NMTBL*)cadr(e1)))); |
859 if (sign) | 882 if (sign) |
860 printf("\t%s %s,%s\n",cext(sz),crn,crn); | 883 printf("\t%s %s,%s\n",cext(sz),crn,crn); |
861 regv[creg]=1; | |
862 } | 884 } |
863 | 885 |
864 | 886 |
865 | 887 |
866 void | 888 void |
867 code_register(int e2,int creg) { | 889 code_register(int e2,int creg) { |
868 if (creg!=e2) | 890 if (creg!=e2) |
869 printf("\tmr %s,%s\n",register_name(creg),register_name(e2)); | 891 printf("\tmr %s,%s\n",register_name(creg),register_name(e2)); |
870 regv[creg]=1; | |
871 } | 892 } |
872 | 893 |
873 | 894 |
874 void | 895 void |
875 code_rlvar(int e2,int reg) { | 896 code_rlvar(int e2,int reg) { |
876 lvar_intro(e2); | 897 lvar_intro(e2); |
877 if (!is_int_reg(reg)) error(-1); | 898 if (!is_int_reg(reg)) error(-1); |
878 printf("\tlwz %s,",register_name(reg)); | 899 printf("\tlwz %s,",register_name(reg)); |
879 lvar(e2); | 900 lvar(e2); |
880 regv[creg]=1; | |
881 } | 901 } |
882 | 902 |
883 void | 903 void |
884 code_crlvar(int e2,int reg,int sign,int sz) { | 904 code_crlvar(int e2,int reg,int sign,int sz) { |
885 lvar_intro(e2); | 905 lvar_intro(e2); |
886 printf("\t%s %s,",cload(sz),register_name(reg)); | 906 printf("\t%s %s,",cload(sz),register_name(reg)); |
887 lvar(e2); | 907 lvar(e2); |
888 if (sign) | 908 if (sign) |
889 printf("\t%s %s,%s\n",cext(sz),register_name(reg),register_name(reg)); | 909 printf("\t%s %s,%s\n",cext(sz),register_name(reg),register_name(reg)); |
890 regv[creg]=1; | |
891 } | 910 } |
892 | 911 |
893 | 912 |
894 | 913 |
895 | 914 |
898 code_fname(NMTBL *n,int creg) { | 917 code_fname(NMTBL *n,int creg) { |
899 int r; | 918 int r; |
900 r = get_ptr_cache(n); | 919 r = get_ptr_cache(n); |
901 if(r!=creg) | 920 if(r!=creg) |
902 printf("\tmr %s,%s\n",register_name(creg),register_name(r)); | 921 printf("\tmr %s,%s\n",register_name(creg),register_name(r)); |
903 regv[creg]=1; | |
904 return; | 922 return; |
905 } | 923 } |
906 | 924 |
907 | 925 |
908 void | 926 void |
912 printf("\tli %s,%d\n",crn,e2); | 930 printf("\tli %s,%d\n",crn,e2); |
913 else { | 931 else { |
914 printf("\tlis %s,ha16(%d)\n",crn,e2); | 932 printf("\tlis %s,ha16(%d)\n",crn,e2); |
915 printf("\taddi %s,%s,lo16(%d)\n",crn,crn,e2); | 933 printf("\taddi %s,%s,lo16(%d)\n",crn,crn,e2); |
916 } | 934 } |
917 regv[creg]=1; | |
918 } | 935 } |
919 | 936 |
920 | 937 |
921 void | 938 void |
922 code_neg(int creg) { | 939 code_neg(int creg) { |
944 if (car(e2)==REGISTER) { | 961 if (car(e2)==REGISTER) { |
945 printf("\taddi %s,%s,%d\n", | 962 printf("\taddi %s,%s,%d\n", |
946 register_name(cadr(e2)),register_name(cadr(e2)), dir); | 963 register_name(cadr(e2)),register_name(cadr(e2)), dir); |
947 if (cadr(reg)!=e2) | 964 if (cadr(reg)!=e2) |
948 printf("\tmr %s,%s\n",register_name(cadr(reg)),register_name(e2)); | 965 printf("\tmr %s,%s\n",register_name(cadr(reg)),register_name(e2)); |
949 regv[reg]=1; | |
950 return; | 966 return; |
951 } | 967 } |
952 g_expr(e2); | 968 g_expr(e2); |
953 xrn = register_name(creg); | 969 xrn = register_name(creg); |
954 dreg=get_register(); if (!dreg) error(-1); | 970 dreg=get_register(); if (!dreg) error(-1); |
957 if (use && sign && sz!=size_of_int) | 973 if (use && sign && sz!=size_of_int) |
958 printf("\t%s %s,%s\n",cext(sz),drn,drn); | 974 printf("\t%s %s,%s\n",cext(sz),drn,drn); |
959 printf("\taddi %s,%s,%d\n",drn,drn,dir); | 975 printf("\taddi %s,%s,%d\n",drn,drn,dir); |
960 printf("\t%s %s,0(%s)\n",cstore(sz),drn,xrn); | 976 printf("\t%s %s,0(%s)\n",cstore(sz),drn,xrn); |
961 i=creg;creg=dreg;dreg=i; | 977 i=creg;creg=dreg;dreg=i; |
962 regv[creg]=1; ireg=creg; | 978 ireg=creg; |
963 free_register(dreg); | 979 free_register(dreg); |
964 } | 980 } |
965 | 981 |
966 | 982 |
967 void | 983 void |
970 int dreg,nreg,i; | 986 int dreg,nreg,i; |
971 if (car(e2)==REGISTER) { | 987 if (car(e2)==REGISTER) { |
972 printf("\tmr %s,%s\n",register_name(reg),register_name(cadr(e2))); | 988 printf("\tmr %s,%s\n",register_name(reg),register_name(cadr(e2))); |
973 printf("\taddi %s,%s,%d\n", | 989 printf("\taddi %s,%s,%d\n", |
974 register_name(cadr(e2)),register_name(cadr(e2)),dir); | 990 register_name(cadr(e2)),register_name(cadr(e2)),dir); |
975 regv[reg]=1; | |
976 return; | 991 return; |
977 } | 992 } |
978 g_expr(e2); | 993 g_expr(e2); |
979 crn = register_name(creg); | 994 crn = register_name(creg); |
980 dreg=get_register(); if (!dreg) error(-1); | 995 dreg=get_register(); if (!dreg) error(-1); |
987 printf("\taddi %s,%s,%d\n",nrn,xrn,dir); | 1002 printf("\taddi %s,%s,%d\n",nrn,xrn,dir); |
988 printf("\t%s %s,0(%s)\n",cstore(sz),nrn,crn); | 1003 printf("\t%s %s,0(%s)\n",cstore(sz),nrn,crn); |
989 i=creg;creg=dreg;dreg=i; | 1004 i=creg;creg=dreg;dreg=i; |
990 free_register(nreg); | 1005 free_register(nreg); |
991 free_register(dreg); | 1006 free_register(dreg); |
992 regv[creg]=1; ireg=creg; | 1007 ireg=creg; |
993 } | 1008 } |
994 | 1009 |
995 | 1010 |
996 void | 1011 void |
997 code_return(int creg) { | 1012 code_return(int creg) { |
1058 int r; | 1073 int r; |
1059 char *crn = register_name(creg); | 1074 char *crn = register_name(creg); |
1060 r = get_ptr_cache((NMTBL*)cadr(e1)); | 1075 r = get_ptr_cache((NMTBL*)cadr(e1)); |
1061 printf("\t%s %s,0(%s)\n",cload(sz),crn,register_name(r)); | 1076 printf("\t%s %s,0(%s)\n",cload(sz),crn,register_name(r)); |
1062 printf("\tcmpwi cr0,%s,0\n",crn); | 1077 printf("\tcmpwi cr0,%s,0\n",crn); |
1063 regv[creg]=0; | |
1064 } | 1078 } |
1065 | 1079 |
1066 | 1080 |
1067 void | 1081 void |
1068 code_cmp_crlvar(int e2,int sz) { | 1082 code_cmp_crlvar(int e2,int sz) { |
1069 char *crn = register_name(creg); | 1083 char *crn = register_name(creg); |
1070 lvar_intro(e2); | 1084 lvar_intro(e2); |
1071 printf("\t%s %s,",cload(sz),crn); | 1085 printf("\t%s %s,",cload(sz),crn); |
1072 lvar(e2); | 1086 lvar(e2); |
1073 code_cmp_register(creg); | 1087 code_cmp_register(creg); |
1074 regv[creg]=0; | |
1075 } | 1088 } |
1076 | 1089 |
1077 | 1090 |
1078 void | 1091 void |
1079 code_cmp_rgvar(int e1) { | 1092 code_cmp_rgvar(int e1) { |
1081 char *crn = register_name(creg); | 1094 char *crn = register_name(creg); |
1082 if (!is_int_reg(creg)) error(-1); | 1095 if (!is_int_reg(creg)) error(-1); |
1083 r = get_ptr_cache((NMTBL*)cadr(e1)); | 1096 r = get_ptr_cache((NMTBL*)cadr(e1)); |
1084 printf("\tlwz %s,0(%s)\n",crn,register_name(r)); | 1097 printf("\tlwz %s,0(%s)\n",crn,register_name(r)); |
1085 code_cmp_register(creg); | 1098 code_cmp_register(creg); |
1086 regv[creg]=0; | |
1087 } | 1099 } |
1088 | 1100 |
1089 | 1101 |
1090 void | 1102 void |
1091 code_cmp_rlvar(int e2) { | 1103 code_cmp_rlvar(int e2) { |
1092 char *crn = register_name(creg); | 1104 char *crn = register_name(creg); |
1093 lvar_intro(e2); | 1105 lvar_intro(e2); |
1094 printf("\tlwz %s,",crn); | 1106 printf("\tlwz %s,",crn); |
1095 lvar(e2); | 1107 lvar(e2); |
1096 code_cmp_register(creg); | 1108 code_cmp_register(creg); |
1097 regv[creg]=0; | |
1098 } | 1109 } |
1099 | 1110 |
1100 | 1111 |
1101 void | 1112 void |
1102 code_cmp_register(int e2) { | 1113 code_cmp_register(int e2) { |
1214 if(creg!=to) { | 1225 if(creg!=to) { |
1215 free_register(creg); creg=to; | 1226 free_register(creg); creg=to; |
1216 } | 1227 } |
1217 } | 1228 } |
1218 free_register(dreg); | 1229 free_register(dreg); |
1219 regv[from]=regv[to]=regv[dreg]=0; | |
1220 regv[creg]=1; | |
1221 } | 1230 } |
1222 | 1231 |
1223 int | 1232 int |
1224 struct_push(int e4,int t,int arg) | 1233 struct_push(int e4,int t,int arg) |
1225 { | 1234 { |
1514 free_register(cadr(arg)); | 1523 free_register(cadr(arg)); |
1515 else if (car(arg)==LVAR&&cadr(arg)<0) free_lvar(cadr(arg)); | 1524 else if (car(arg)==LVAR&&cadr(arg)<0) free_lvar(cadr(arg)); |
1516 } | 1525 } |
1517 if (ret_type==DOUBLE||ret_type==FLOAT) { | 1526 if (ret_type==DOUBLE||ret_type==FLOAT) { |
1518 set_freg(RET_FREGISTER,0); | 1527 set_freg(RET_FREGISTER,0); |
1519 regv[freg]=1; regv[creg]=0; | |
1520 } else if (ret_type==VOID) { | 1528 } else if (ret_type==VOID) { |
1521 regv[freg]=0; regv[creg]=0; | |
1522 } else { | 1529 } else { |
1523 set_creg(RET_REGISTER,0); | 1530 set_creg(RET_REGISTER,0); |
1524 regv[freg]=0; regv[creg]=1; | |
1525 } | 1531 } |
1526 return ret_type; | 1532 return ret_type; |
1527 } | 1533 } |
1528 | 1534 |
1529 void | 1535 void |
1608 char *crn; | 1614 char *crn; |
1609 g_expr(e1); | 1615 g_expr(e1); |
1610 crn=register_name(creg); | 1616 crn=register_name(creg); |
1611 printf("\t%s %s,%d(%s)\n",fload(d), | 1617 printf("\t%s %s,%d(%s)\n",fload(d), |
1612 fregister_name(freg),offset,crn); | 1618 fregister_name(freg),offset,crn); |
1613 regv[creg]=0; regv[freg]=1; | |
1614 creg = freg; | 1619 creg = freg; |
1615 return DOUBLE; | 1620 return DOUBLE; |
1616 } | 1621 } |
1617 #endif | 1622 #endif |
1618 | 1623 |
1675 } else if (byte==size_of_short) { | 1680 } else if (byte==size_of_short) { |
1676 printf("\tsth %s,0(%s)\n",crn,drn); | 1681 printf("\tsth %s,0(%s)\n",crn,drn); |
1677 } else { | 1682 } else { |
1678 printf("\tstw %s,0(%s)\n",crn,drn); | 1683 printf("\tstw %s,0(%s)\n",crn,drn); |
1679 } | 1684 } |
1680 regv[creg]=1; | |
1681 } | 1685 } |
1682 | 1686 |
1683 | 1687 |
1684 void | 1688 void |
1685 code_register_assop(int e2,int op,int byte) { | 1689 code_register_assop(int e2,int op,int byte) { |
1688 creg = reg = e2; | 1692 creg = reg = e2; |
1689 tosop(op,xreg); | 1693 tosop(op,xreg); |
1690 creg = xreg; | 1694 creg = xreg; |
1691 if (creg!=reg) | 1695 if (creg!=reg) |
1692 printf("\tmr %s,%s\n",register_name(creg),register_name(reg)); | 1696 printf("\tmr %s,%s\n",register_name(creg),register_name(reg)); |
1693 regv[creg]=1; | |
1694 } | 1697 } |
1695 | 1698 |
1696 | 1699 |
1697 void | 1700 void |
1698 code_assop(int op,int byte,int sign) { | 1701 code_assop(int op,int byte,int sign) { |
1699 char *xrn,*crn,*drn; | 1702 char *xrn,*crn,*drn; |
1700 int xreg; | 1703 int xreg; |
1701 int edx = get_register(); if(!edx) error(-1); | 1704 int edx = get_register(); if(!edx) error(-1); |
1702 xrn = register_name(xreg = emit_pop(0)); /* pop e3 value */ | 1705 xrn = register_name(xreg = emit_pop(0)); /* pop e3 value */ |
1703 regv[xreg]=regs[xreg]=1; | |
1704 printf("# assop\n\tmr %s,%s\n",register_name(edx),register_name(creg)); | 1706 printf("# assop\n\tmr %s,%s\n",register_name(edx),register_name(creg)); |
1705 regv[edx]=1; | |
1706 ld_indexx(byte,0,edx,sign); | 1707 ld_indexx(byte,0,edx,sign); |
1707 tosop(op,xreg); | 1708 tosop(op,xreg); |
1708 crn = register_name(creg); | 1709 crn = register_name(creg); |
1709 drn = register_name(edx); | 1710 drn = register_name(edx); |
1710 if (byte==1) { | 1711 if (byte==1) { |
1714 } else { | 1715 } else { |
1715 printf("\tstw %s,0(%s)\n",crn,drn); | 1716 printf("\tstw %s,0(%s)\n",crn,drn); |
1716 } | 1717 } |
1717 free_register(edx); | 1718 free_register(edx); |
1718 emit_pop_free(xreg); | 1719 emit_pop_free(xreg); |
1719 regv[creg]=1; | |
1720 } | 1720 } |
1721 | 1721 |
1722 | 1722 |
1723 void | 1723 void |
1724 tosop(int op,int oreg) | 1724 tosop(int op,int oreg) |
1730 error(-1); | 1730 error(-1); |
1731 } else if (oreg<= -REG_LVAR_OFFSET) { | 1731 } else if (oreg<= -REG_LVAR_OFFSET) { |
1732 dx = get_register(); if (dx<0) error(-1); | 1732 dx = get_register(); if (dx<0) error(-1); |
1733 code_rlvar(oreg+REG_LVAR_OFFSET,dx); | 1733 code_rlvar(oreg+REG_LVAR_OFFSET,dx); |
1734 oreg = dx; | 1734 oreg = dx; |
1735 regv[oreg]=1; | |
1736 } | 1735 } |
1737 | 1736 |
1738 switch(op) { | 1737 switch(op) { |
1739 case LSHIFT: | 1738 case LSHIFT: |
1740 case ULSHIFT: | 1739 case ULSHIFT: |
1741 shift("slw",oreg); | 1740 shift("slw",oreg); |
1742 regv[creg]=1; | |
1743 return; | 1741 return; |
1744 case RSHIFT: | 1742 case RSHIFT: |
1745 shift("sraw",oreg); | 1743 shift("sraw",oreg); |
1746 regv[creg]=1; | |
1747 return; | 1744 return; |
1748 case URSHIFT: | 1745 case URSHIFT: |
1749 shift("srw",oreg); | 1746 shift("srw",oreg); |
1750 regv[creg]=1; | |
1751 return; | 1747 return; |
1752 } | 1748 } |
1753 orn = register_name(oreg); | 1749 orn = register_name(oreg); |
1754 crn = register_name(creg); | 1750 crn = register_name(creg); |
1755 switch(op) { | 1751 switch(op) { |
1801 break; | 1797 break; |
1802 default: | 1798 default: |
1803 error(-1); | 1799 error(-1); |
1804 } | 1800 } |
1805 if(oreg!=creg) free_register(oreg); | 1801 if(oreg!=creg) free_register(oreg); |
1806 regv[creg]=1; | |
1807 } | 1802 } |
1808 | 1803 |
1809 int | 1804 int |
1810 code_const_op_p(int op,int v) | 1805 code_const_op_p(int op,int v) |
1811 { | 1806 { |
2406 { | 2401 { |
2407 if (freg!=e2) { | 2402 if (freg!=e2) { |
2408 if (is_int_reg(e2)) error(-1); | 2403 if (is_int_reg(e2)) error(-1); |
2409 printf("\tfmr %s,%s\n",fregister_name(freg),fregister_name(e2)); | 2404 printf("\tfmr %s,%s\n",fregister_name(freg),fregister_name(e2)); |
2410 } | 2405 } |
2411 regv[freg]=1; | |
2412 } | 2406 } |
2413 | 2407 |
2414 void code_dassign_gvar(int e2,int freg,int d) | 2408 void code_dassign_gvar(int e2,int freg,int d) |
2415 { | 2409 { |
2416 int r; | 2410 int r; |
2417 r = get_ptr_cache((NMTBL*)cadr(e2)); | 2411 r = get_ptr_cache((NMTBL*)cadr(e2)); |
2418 if (!is_float_reg(freg)) error(-1); | 2412 if (!is_float_reg(freg)) error(-1); |
2419 printf("\t%s %s,0(%s)\n",fstore(d),fregister_name(freg),register_name(r)); | 2413 printf("\t%s %s,0(%s)\n",fstore(d),fregister_name(freg),register_name(r)); |
2420 regv[freg]=1; | |
2421 } | 2414 } |
2422 | 2415 |
2423 void code_dassign_lvar(int e2,int freg,int d) | 2416 void code_dassign_lvar(int e2,int freg,int d) |
2424 { | 2417 { |
2425 lvar_intro(e2); | 2418 lvar_intro(e2); |
2426 if (!is_float_reg(freg)) error(-1); | 2419 if (!is_float_reg(freg)) error(-1); |
2427 printf("\t%s %s,",fstore(d),fregister_name(freg)); | 2420 printf("\t%s %s,",fstore(d),fregister_name(freg)); |
2428 lvar(e2); | 2421 lvar(e2); |
2429 regv[freg]=1; | |
2430 } | 2422 } |
2431 | 2423 |
2432 void code_dassign(int e2,int freg,int d) | 2424 void code_dassign(int e2,int freg,int d) |
2433 { | 2425 { |
2434 if (!is_float_reg(freg)) error(-1); | 2426 if (!is_float_reg(freg)) error(-1); |
2435 printf("\t%s %s,0(%s)\n",fstore(d),fregister_name(freg),register_name(e2)); | 2427 printf("\t%s %s,0(%s)\n",fstore(d),fregister_name(freg),register_name(e2)); |
2436 regv[freg]=1; | |
2437 } | 2428 } |
2438 | 2429 |
2439 void | 2430 void |
2440 code_dassign_dregister(int e2,int d,int freg) { | 2431 code_dassign_dregister(int e2,int d,int freg) { |
2441 if (e2!=freg) { | 2432 if (e2!=freg) { |
2510 printf("\tlfd %s,0(%s)\n",frn,rrn); | 2501 printf("\tlfd %s,0(%s)\n",frn,rrn); |
2511 } else { | 2502 } else { |
2512 printf("\tlfs %s,0(%s)\n",frn,rrn); | 2503 printf("\tlfs %s,0(%s)\n",frn,rrn); |
2513 } | 2504 } |
2514 free_register(r); | 2505 free_register(r); |
2515 regv[freg]=1; | |
2516 } | 2506 } |
2517 | 2507 |
2518 | 2508 |
2519 void code_dneg(int freg,int d) | 2509 void code_dneg(int freg,int d) |
2520 { | 2510 { |
2539 printf("\tfctiwz %s,%s\n",frn,frn); | 2529 printf("\tfctiwz %s,%s\n",frn,frn); |
2540 lvar_intro(e2); | 2530 lvar_intro(e2); |
2541 printf("\tstfd %s,",frn); lvar(e2); | 2531 printf("\tstfd %s,",frn); lvar(e2); |
2542 lvar_intro(e2+size_of_double-size_of_int); | 2532 lvar_intro(e2+size_of_double-size_of_int); |
2543 printf("\tlwz %s,",crn); lvar(e2+size_of_double-size_of_int); | 2533 printf("\tlwz %s,",crn); lvar(e2+size_of_double-size_of_int); |
2544 regv[creg]=1; | |
2545 } | 2534 } |
2546 | 2535 |
2547 static int i2d_lib_used=0; | 2536 static int i2d_lib_used=0; |
2548 static char *i2d_lib[] = { | 2537 static char *i2d_lib[] = { |
2549 ".data", | 2538 ".data", |
2578 clear_ptr_cache(); | 2567 clear_ptr_cache(); |
2579 code_save_stacks(); | 2568 code_save_stacks(); |
2580 set_creg(RET_REGISTER,1); | 2569 set_creg(RET_REGISTER,1); |
2581 printf("\tbl i2d_\n"); | 2570 printf("\tbl i2d_\n"); |
2582 set_freg(RET_FREGISTER,0); | 2571 set_freg(RET_FREGISTER,0); |
2583 regv[freg]=1; | |
2584 } | 2572 } |
2585 | 2573 |
2586 static int d2u_lib_used=0; | 2574 static int d2u_lib_used=0; |
2587 static char *d2u_lib[] = { | 2575 static char *d2u_lib[] = { |
2588 /* ".literal8", */ | 2576 /* ".literal8", */ |
2625 clear_ptr_cache(); | 2613 clear_ptr_cache(); |
2626 d2u_lib_used=1; | 2614 d2u_lib_used=1; |
2627 set_freg(RET_FREGISTER,1); | 2615 set_freg(RET_FREGISTER,1); |
2628 printf("\tbl d2u_\n"); | 2616 printf("\tbl d2u_\n"); |
2629 set_creg(RET_REGISTER,0); | 2617 set_creg(RET_REGISTER,0); |
2630 regv[freg]=1; | |
2631 } | 2618 } |
2632 | 2619 |
2633 static int u2d_lib_used=0; | 2620 static int u2d_lib_used=0; |
2634 static char *u2d_lib[] = { | 2621 static char *u2d_lib[] = { |
2635 ".data", | 2622 ".data", |
2663 clear_ptr_cache(); | 2650 clear_ptr_cache(); |
2664 u2d_lib_used = 1; | 2651 u2d_lib_used = 1; |
2665 set_creg(RET_REGISTER,1); | 2652 set_creg(RET_REGISTER,1); |
2666 printf("\tbl u2d_\n"); | 2653 printf("\tbl u2d_\n"); |
2667 set_freg(FREG_FREGISTER,0); | 2654 set_freg(FREG_FREGISTER,0); |
2668 regv[freg]=1; | |
2669 } | 2655 } |
2670 | 2656 |
2671 void code_d2f(int freg) { } | 2657 void code_d2f(int freg) { } |
2672 void code_f2d(int freg) { } | 2658 void code_f2d(int freg) { } |
2673 void code_f2i(int freg) { code_d2i(freg); } | 2659 void code_f2i(int freg) { code_d2i(freg); } |
2678 void code_drgvar(int e2,int d,int freg) | 2664 void code_drgvar(int e2,int d,int freg) |
2679 { | 2665 { |
2680 int r; | 2666 int r; |
2681 r = get_ptr_cache((NMTBL*)cadr(e2)); | 2667 r = get_ptr_cache((NMTBL*)cadr(e2)); |
2682 printf("\t%s %s,0(%s)\n",fload(d),fregister_name(freg),register_name(r)); | 2668 printf("\t%s %s,0(%s)\n",fload(d),fregister_name(freg),register_name(r)); |
2683 regv[freg]=1; | |
2684 } | 2669 } |
2685 | 2670 |
2686 | 2671 |
2687 void code_drlvar(int e2,int d,int freg) | 2672 void code_drlvar(int e2,int d,int freg) |
2688 { | 2673 { |
2689 lvar_intro(e2); | 2674 lvar_intro(e2); |
2690 printf("\t%s %s,",fload(d),fregister_name(freg)); lvar(e2); | 2675 printf("\t%s %s,",fload(d),fregister_name(freg)); lvar(e2); |
2691 regv[freg]=1; | |
2692 } | 2676 } |
2693 | 2677 |
2694 void code_cmp_drgvar(int e2,int d) | 2678 void code_cmp_drgvar(int e2,int d) |
2695 { | 2679 { |
2696 int r; | 2680 int r; |
2699 char *grn=fregister_name(g); | 2683 char *grn=fregister_name(g); |
2700 r = get_ptr_cache((NMTBL*)cadr(e2)); | 2684 r = get_ptr_cache((NMTBL*)cadr(e2)); |
2701 printf("\t%s %s,0(%s)\n",fload(1),grn,register_name(r)); | 2685 printf("\t%s %s,0(%s)\n",fload(1),grn,register_name(r)); |
2702 printf("\tfcmpu cr0,%s,%s\n",frn,grn); | 2686 printf("\tfcmpu cr0,%s,%s\n",frn,grn); |
2703 free_register(g); | 2687 free_register(g); |
2704 regv[freg]=0; | |
2705 } | 2688 } |
2706 | 2689 |
2707 void code_cmp_drlvar(int e2,int d) | 2690 void code_cmp_drlvar(int e2,int d) |
2708 { | 2691 { |
2709 char *frn=fregister_name(freg); | 2692 char *frn=fregister_name(freg); |
2712 | 2695 |
2713 lvar_intro(e2); | 2696 lvar_intro(e2); |
2714 printf("\t%s %s,",fload(1),grn); lvar(e2); | 2697 printf("\t%s %s,",fload(1),grn); lvar(e2); |
2715 printf("\tfcmpu cr0,%s,%s\n",frn,grn); | 2698 printf("\tfcmpu cr0,%s,%s\n",frn,grn); |
2716 free_register(g); | 2699 free_register(g); |
2717 regv[freg]=0; | |
2718 } | 2700 } |
2719 | 2701 |
2720 void dtosop(int op,int e1) | 2702 void dtosop(int op,int e1) |
2721 { | 2703 { |
2722 char *opn=""; | 2704 char *opn=""; |
2723 char *frn=fregister_name(freg); | 2705 char *frn=fregister_name(freg); |
2724 char *grn=fregister_name(e1); | 2706 char *grn=fregister_name(e1); |
2725 regv[freg]=1; | |
2726 switch(op) { | 2707 switch(op) { |
2727 case FADD: | 2708 case FADD: |
2728 case DADD: opn="fadd"; break; | 2709 case DADD: opn="fadd"; break; |
2729 case FSUB: | 2710 case FSUB: |
2730 case DSUB: opn="fsub"; break; | 2711 case DSUB: opn="fsub"; break; |
2744 return; | 2725 return; |
2745 default: | 2726 default: |
2746 error(-1); return; | 2727 error(-1); return; |
2747 } | 2728 } |
2748 printf("\t%s %s,%s,%s\n",opn,frn,frn,grn); | 2729 printf("\t%s %s,%s,%s\n",opn,frn,frn,grn); |
2749 regv[freg]=1; | |
2750 free_register(e1); | 2730 free_register(e1); |
2751 } | 2731 } |
2752 | 2732 |
2753 void | 2733 void |
2754 code_dassop(int op,int d) { | 2734 code_dassop(int op,int d) { |
2760 if (!is_float_reg(freg)) error(-1); | 2740 if (!is_float_reg(freg)) error(-1); |
2761 printf("\t%s %s,0(%s)\n",fload(d),frn,crn); | 2741 printf("\t%s %s,0(%s)\n",fload(d),frn,crn); |
2762 dtosop(op,xreg); | 2742 dtosop(op,xreg); |
2763 printf("\t%s %s,0(%s)\n",fstore(d),frn,crn); | 2743 printf("\t%s %s,0(%s)\n",fstore(d),frn,crn); |
2764 emit_dpop_free(xreg,d); | 2744 emit_dpop_free(xreg,d); |
2765 regv[freg]=1; | |
2766 } | 2745 } |
2767 | 2746 |
2768 | 2747 |
2769 void | 2748 void |
2770 code_dpreinc(int e1,int e2,int d,int reg) { | 2749 code_dpreinc(int e1,int e2,int d,int reg) { |
2793 else | 2772 else |
2794 printf("\tfsub %s,%s,%s\n",frn,frn,grn); | 2773 printf("\tfsub %s,%s,%s\n",frn,frn,grn); |
2795 if (!is_float_reg(freg)) error(-1); | 2774 if (!is_float_reg(freg)) error(-1); |
2796 printf("\t%s %s,0(%s)\n",fstore(d),frn,crn); | 2775 printf("\t%s %s,0(%s)\n",fstore(d),frn,crn); |
2797 free_register(g); | 2776 free_register(g); |
2798 regv[freg]=1; | |
2799 regv[ireg]=0; | |
2800 creg = freg; | 2777 creg = freg; |
2801 } | 2778 } |
2802 | 2779 |
2803 void | 2780 void |
2804 code_dpostinc(int e1,int e2,int d,int reg) { | 2781 code_dpostinc(int e1,int e2,int d,int reg) { |
2827 else | 2804 else |
2828 printf("\tfsub %s,%s,%s\n",grn,frn,grn); | 2805 printf("\tfsub %s,%s,%s\n",grn,frn,grn); |
2829 if (!is_float_reg(freg)) error(-1); | 2806 if (!is_float_reg(freg)) error(-1); |
2830 printf("\t%s %s,0(%s)\n",fstore(d),grn,crn); | 2807 printf("\t%s %s,0(%s)\n",fstore(d),grn,crn); |
2831 free_register(g); | 2808 free_register(g); |
2832 regv[freg]=1; | |
2833 regv[ireg]=0; | |
2834 creg = freg; | 2809 creg = freg; |
2835 } | 2810 } |
2836 | 2811 |
2837 void | 2812 void |
2838 drexpr(int e1, int e2,int l1, int op) | 2813 drexpr(int e1, int e2,int l1, int op) |
2865 xreg=pop_fregister(); | 2840 xreg=pop_fregister(); |
2866 if (xreg<= -REG_LVAR_OFFSET) { | 2841 if (xreg<= -REG_LVAR_OFFSET) { |
2867 reg = get_dregister(d); | 2842 reg = get_dregister(d); |
2868 code_drlvar(REG_LVAR_OFFSET+xreg,1,reg); | 2843 code_drlvar(REG_LVAR_OFFSET+xreg,1,reg); |
2869 free_lvar(REG_LVAR_OFFSET+xreg); | 2844 free_lvar(REG_LVAR_OFFSET+xreg); |
2870 regv[reg]=1; xreg=reg; | 2845 xreg=reg; |
2871 } | 2846 } |
2872 return xreg; | 2847 return xreg; |
2873 } | 2848 } |
2874 | 2849 |
2875 void emit_dpop_free(int e1,int d) | 2850 void emit_dpop_free(int e1,int d) |
2882 int new_reg; | 2857 int new_reg; |
2883 if (freg_sp>MAX_MAX) error(-1); | 2858 if (freg_sp>MAX_MAX) error(-1); |
2884 new_reg = get_dregister(1); | 2859 new_reg = get_dregister(1); |
2885 freg_stack[freg_sp++] = freg; /* push するかわりにレジスタを使う */ | 2860 freg_stack[freg_sp++] = freg; /* push するかわりにレジスタを使う */ |
2886 creg = freg = new_reg; | 2861 creg = freg = new_reg; |
2887 regv[freg]=1; | |
2888 } | 2862 } |
2889 | 2863 |
2890 #endif | 2864 #endif |
2891 | 2865 |
2892 #if LONGLONG_CODE | 2866 #if LONGLONG_CODE |