comparison mc-code-mips.c @ 276:ebaec1ae566e

MIPS double/longlong lib operand register conflict
author kono
date Fri, 21 May 2004 18:59:56 +0900
parents 8f09f8bbc494
children d5467cf30f58
comparison
equal deleted inserted replaced
275:8f09f8bbc494 276:ebaec1ae566e
256 #if FLOAT_CODE 256 #if FLOAT_CODE
257 257
258 258
259 static int code_d1(double d); 259 static int code_d1(double d);
260 static int code_d2(double d); 260 static int code_d2(double d);
261 static void code_double_lib(char *lib,int to,int reg,int oreg);
262 static void code_double_lib_c(char *lib,int from,int to,double value);
263
261 #endif 264 #endif
262 #if LONGLONG_CODE 265 #if LONGLONG_CODE
263 static int code_l1(long long ll); 266 static int code_l1(long long ll);
264 static int code_l2(long long ll); 267 static int code_l2(long long ll);
265 #endif 268 #endif
1664 set_lreg_operand(int reg,int mode) 1667 set_lreg_operand(int reg,int mode)
1665 { 1668 {
1666 // save_stack,clear_ptr_cache is assumed 1669 // save_stack,clear_ptr_cache is assumed
1667 if (!is_longlong_reg(reg)) { error(-1); return; } 1670 if (!is_longlong_reg(reg)) { error(-1); return; }
1668 if (mode) { 1671 if (mode) {
1669 if (regv_h(reg)!=DREGISTER_OPERAND_H) { 1672 lmove(LREGISTER_OPERAND,reg);
1670 printf("\tmove %s,%s\n",
1671 lregister_name_high(DREGISTER_OPERAND),lregister_name_high(reg));
1672 }
1673 if (regv_l(reg)!=DREGISTER_OPERAND_L) {
1674 printf("\tmove %s,%s\n",
1675 lregister_name_low(DREGISTER_OPERAND),lregister_name_low(reg));
1676 }
1677 } 1673 }
1678 } 1674 }
1679 1675
1680 static void 1676 static void
1681 set_lreg_operand1(int reg,int mode) 1677 set_lreg_operand1(int reg,int mode)
1682 { 1678 {
1683 // save_stack,clear_ptr_cache is assumed 1679 // save_stack,clear_ptr_cache is assumed
1684 if (!is_longlong_reg(reg)) { error(-1); return; } 1680 if (!is_longlong_reg(reg)) { error(-1); return; }
1685 if (mode) { 1681 if (mode) {
1686 if (regv_h(reg)!=DREGISTER_OPERAND_1_H) { 1682 lmove(LREGISTER_OPERAND_1,reg);
1687 printf("\tmove %s,%s\n",
1688 lregister_name_high(DREGISTER_OPERAND_1),lregister_name_high(reg));
1689 }
1690 if (regv_l(reg)!=DREGISTER_OPERAND_1_L) {
1691 printf("\tmove %s,%s\n",
1692 lregister_name_low(DREGISTER_OPERAND_1),lregister_name_low(reg));
1693 }
1694 } 1683 }
1695 } 1684 }
1696 1685
1697 static void 1686 static void
1698 set_dreg_operand(int reg,int mode) 1687 set_dreg_operand(int reg,int mode)
1747 if (tag==REGISTER) { 1736 if (tag==REGISTER) {
1748 /* regs[reg]==INPUT_REG case should be considered */ 1737 /* regs[reg]==INPUT_REG case should be considered */
1749 n->dsp = offset; 1738 n->dsp = offset;
1750 offset+=SIZE_OF_INT; 1739 offset+=SIZE_OF_INT;
1751 t = INT; 1740 t = INT;
1752 reg += reg_offset; /* for duplicated floating point argument */
1753 } else if (tag==FREGISTER) { 1741 } else if (tag==FREGISTER) {
1754 /* regs[reg]==INPUT_REG case should be considered */ 1742 /* regs[reg]==INPUT_REG case should be considered */
1755 n->dsp = offset; 1743 n->dsp = offset;
1756 t = n->ty; 1744 t = n->ty;
1757 if(t==FLOAT) { 1745 if(t==FLOAT) {
1758 offset+=SIZE_OF_FLOAT; reg_offset+=1; 1746 offset+=SIZE_OF_FLOAT; reg_offset+=1;
1759 if (reg==6||reg==7) { // int register case 1747 if (reg==6||reg==7) { // int register case
1760 tag = REGISTER; t = INT; 1748 tag = REGISTER; t = INT;
1761 } 1749 }
1762 } 1750 }
1763 else if(t==DOUBLE) { offset+=SIZE_OF_DOUBLE; reg_offset+=2; } 1751 // else if(t==DOUBLE) { offset+=SIZE_OF_DOUBLE; reg_offset+=2; }
1764 else error(-1); 1752 else error(-1);
1765 } else if (tag==DREGISTER) { 1753 } else if (tag==DREGISTER) {
1766 /* regs[reg]==INPUT_REG case should be considered */ 1754 /* regs[reg]==INPUT_REG case should be considered */
1767 n->dsp = offset; 1755 n->dsp = offset;
1768 t = n->ty; 1756 t = n->ty;
2296 2284
2297 static void 2285 static void
2298 lmove(int to,int from) 2286 lmove(int to,int from)
2299 { 2287 {
2300 int tmp; 2288 int tmp;
2301 if (regv_h(to)==regv_h(from)&&(regv_l(to)==regv_l(from))) 2289 if (regv_h(to)==regv_h(from)&&(regv_l(to)==regv_l(from))) {
2302 return; 2290 return;
2303 if (regv_h(to)==regv_l(from)&&(regv_l(to)==regv_h(from))) { 2291 } else if (regv_h(to)!=regv_l(from)) {
2292 if (regv_h(to)!=regv_h(from))
2293 printf("\tmove %s,%s\n",lregister_name_high(to),lregister_name_high(from));
2294 if (regv_l(to)!=regv_l(from))
2295 printf("\tmove %s,%s\n",lregister_name_low(to),lregister_name_low(from));
2296 } else if (regv_l(to)!=regv_h(from)) {
2297 if (regv_l(to)!=regv_l(from))
2298 printf("\tmove %s,%s\n",lregister_name_low(to),lregister_name_low(from));
2299 if (regv_h(to)!=regv_h(from))
2300 printf("\tmove %s,%s\n",lregister_name_high(to),lregister_name_high(from));
2301 } else {
2304 tmp = get_register(); 2302 tmp = get_register();
2305 printf("\tmove %s,%s\n",register_name(tmp),lregister_name_low(from)); 2303 printf("\tmove %s,%s\n",register_name(tmp),lregister_name_low(from));
2306 printf("\tmove %s,%s\n",lregister_name_high(to),lregister_name_high(from)); 2304 printf("\tmove %s,%s\n",lregister_name_high(to),lregister_name_high(from));
2307 printf("\tmove %s,%s\n",lregister_name_low(to),register_name(tmp)); 2305 printf("\tmove %s,%s\n",lregister_name_low(to),register_name(tmp));
2308 free_register(tmp); 2306 free_register(tmp);
2309 } else if (regv_h(to)==regv_l(from)) {
2310 printf("\tmove %s,%s\n",lregister_name_low(to),lregister_name_low(from));
2311 printf("\tmove %s,%s\n",lregister_name_high(to),lregister_name_high(from));
2312 } else {
2313 printf("\tmove %s,%s\n",lregister_name_low(to),lregister_name_low(from));
2314 printf("\tmove %s,%s\n",lregister_name_high(to),lregister_name_high(from));
2315 } 2307 }
2316 } 2308 }
2317 2309
2318 static void 2310 static void
2319 lstore(int e2,int creg) 2311 lstore(int e2,int creg)
3199 3191
3200 if (d) { 3192 if (d) {
3201 code_save_stacks(); 3193 code_save_stacks();
3202 clear_ptr_cache(); 3194 clear_ptr_cache();
3203 set_dreg(RET_DREGISTER,1); 3195 set_dreg(RET_DREGISTER,1);
3204 printf("\tli.d $6,%g\n",0.0); 3196 printf("\tli.d $6,%10.10g\n",0.0);
3205 extern_conv("dpcmp"); 3197 extern_conv("dpcmp");
3206 cmpreg = 2; 3198 cmpreg = 2;
3207 return; 3199 return;
3208 } 3200 }
3209 grn = register_name(greg = get_dregister(d)); 3201 grn = register_name(greg = get_dregister(d));
3326 char *frn; 3318 char *frn;
3327 use_float(d,freg); 3319 use_float(d,freg);
3328 if (d) { 3320 if (d) {
3329 code_save_stacks(); 3321 code_save_stacks();
3330 clear_ptr_cache(); 3322 clear_ptr_cache();
3331 set_lreg(LREGISTER_OPERAND_1,1); 3323 set_dreg(DREGISTER_OPERAND_1,1);
3332 printf("\tmove $4,$0\n"); 3324 printf("\tmove $4,$0\n");
3333 printf("\tmove $5,$0\n"); 3325 printf("\tmove $5,$0\n");
3334 /// set_dreg_operand(oreg,1); 3326 /// set_dreg_operand(oreg,1);
3335 extern_conv("dpsub"); 3327 extern_conv("dpsub");
3336 set_dreg(RET_DREGISTER,0); 3328 set_dreg(RET_DREGISTER,0);
3344 code_d2i(int reg) 3336 code_d2i(int reg)
3345 { 3337 {
3346 use_float(1,reg); 3338 use_float(1,reg);
3347 code_save_stacks(); 3339 code_save_stacks();
3348 clear_ptr_cache(); 3340 clear_ptr_cache();
3349 set_dreg(RET_DREGISTER,1); 3341 set_dreg(DREGISTER_OPERAND,1);
3350 extern_conv("dptoli"); 3342 extern_conv("dptoli");
3351 set_ireg(RET_REGISTER,0); 3343 set_ireg(RET_REGISTER,0);
3352 return; 3344 return;
3353 } 3345 }
3354 3346
3368 code_d2u(int reg) 3360 code_d2u(int reg)
3369 { 3361 {
3370 use_float(1,reg); 3362 use_float(1,reg);
3371 code_save_stacks(); 3363 code_save_stacks();
3372 clear_ptr_cache(); 3364 clear_ptr_cache();
3373 set_dreg(RET_DREGISTER,1); 3365 set_dreg(DREGISTER_OPERAND,1);
3374 extern_conv("dptoul"); 3366 extern_conv("dptoul");
3375 set_ireg(RET_REGISTER,0); 3367 set_ireg(RET_REGISTER,0);
3376 return; 3368 return;
3377 } 3369 }
3378 3370
3379 void 3371 void
3380 code_u2d(int reg) 3372 code_u2d(int reg)
3381 { 3373 {
3374 int tmp=new_lvar(SIZE_OF_INT);
3382 set_ireg(REGISTER_OPERAND,1); 3375 set_ireg(REGISTER_OPERAND,1);
3376 code_assign_lvar(tmp,REGISTER_OPERAND,0);
3383 code_save_stacks(); 3377 code_save_stacks();
3384 clear_ptr_cache(); 3378 clear_ptr_cache();
3385 extern_conv("litodp"); 3379 extern_conv("litodp");
3380 code_rlvar(tmp,REGISTER_OPERAND);
3381 printf("\tbgez\t%s,1f\n",register_name(REGISTER_OPERAND));
3382 code_double_lib_c("dpadd",RET_DREGISTER,RET_DREGISTER,4.294967296e9);
3383 printf("1:\n");
3386 set_dreg(RET_DREGISTER,0); 3384 set_dreg(RET_DREGISTER,0);
3387 use_float(1,reg); 3385 if (reg!=USE_CREG) {
3386 use_float(1,reg);
3387 if (reg!=RET_DREGISTER) {
3388 lmove(reg,RET_DREGISTER);
3389 }
3390 }
3391 free_lvar(tmp);
3388 return; 3392 return;
3389 } 3393 }
3390 3394
3391 void 3395 void
3392 code_d2f(int reg) { 3396 code_d2f(int reg) {
3393 set_dreg(RET_DREGISTER,1); 3397 set_dreg(DREGISTER_OPERAND,1);
3394 code_save_stacks(); 3398 code_save_stacks();
3395 clear_ptr_cache(); 3399 clear_ptr_cache();
3396 extern_conv("dptofp"); 3400 extern_conv("dptofp");
3397 set_freg(RET_FREGISTER,0); 3401 set_freg(RET_FREGISTER,0);
3398 use_float(0,reg); 3402 use_float(0,reg);
3410 return; 3414 return;
3411 } 3415 }
3412 3416
3413 void 3417 void
3414 code_f2i(int reg) { 3418 code_f2i(int reg) {
3419 #if 0
3420 int tmp=new_lvar(SIZE_OF_INT);
3415 use_int(reg); 3421 use_int(reg);
3416 printf("\ttrunc.w.s %s,%s,%s\n",register_name(freg), 3422 printf("\ttrunc.w.s %s,%s,%s\n",register_name(freg),
3417 register_name(freg),register_name(ireg)); 3423 register_name(freg),register_name(ireg));
3424 code_dassign_lvar(tmp,freg,1);
3425 code_rlvar(tmp,reg);
3426 free_lvar(tmp);
3427 #else
3428 use_int(reg);
3429 printf("\ttrunc.w.s %s,%s,%s\n",fregister_name(freg),
3430 fregister_name(freg),register_name(ireg));
3431 printf("\tmfc1 %s,%s\n",register_name(reg),fregister_name(freg));
3432 #endif
3418 } 3433 }
3419 3434
3420 void 3435 void
3421 code_f2u(int reg) { 3436 code_f2u(int reg) {
3422 int freg0 = freg; 3437 int freg0 = freg;
3459 code_assign_lvar(n,reg,0); 3474 code_assign_lvar(n,reg,0);
3460 reg = USE_CREG; 3475 reg = USE_CREG;
3461 use_float(0,reg); 3476 use_float(0,reg);
3462 code_drlvar(n,0,reg); 3477 code_drlvar(n,0,reg);
3463 printf("\tcvt.s.w %s,%s\n",register_name(freg),register_name(freg)); 3478 printf("\tcvt.s.w %s,%s\n",register_name(freg),register_name(freg));
3479 free_lvar(n);
3464 } 3480 }
3465 3481
3466 void 3482 void
3467 code_u2f(int reg) { 3483 code_u2f(int reg) {
3468 int n = new_lvar(SIZE_OF_FLOAT); 3484 int n = new_lvar(SIZE_OF_FLOAT);
3577 } 3593 }
3578 3594
3579 static void 3595 static void
3580 code_double_lib(char *lib,int to,int reg,int oreg) 3596 code_double_lib(char *lib,int to,int reg,int oreg)
3581 { 3597 {
3598 int tmp;
3582 code_save_stacks(); 3599 code_save_stacks();
3583 clear_ptr_cache(); 3600 clear_ptr_cache();
3584 set_dreg_operand(reg,1); 3601 if (regs[DREGISTER_OPERAND_L]||regs[DREGISTER_OPERAND_H]) {
3585 set_dreg_operand1(oreg,1); 3602 if (regs[DREGISTER_OPERAND_1_L]||regs[DREGISTER_OPERAND_1_H]) {
3603 tmp = new_lvar(SIZE_OF_DOUBLE);
3604 code_lassign_lvar(tmp,reg);
3605 set_dreg_operand1(oreg,1);
3606 code_lrlvar(tmp,DREGISTER_OPERAND);
3607 free_lvar(tmp);
3608 } else {
3609 set_dreg_operand1(oreg,1);
3610 set_dreg_operand(reg,1);
3611 }
3612 } else {
3613 set_dreg_operand(reg,1);
3614 set_dreg_operand1(oreg,1);
3615 }
3586 extern_conv(lib); 3616 extern_conv(lib);
3587 set_dreg(RET_DREGISTER,0); 3617 set_dreg(RET_DREGISTER,0);
3588 if (to!=RET_DREGISTER) { 3618 if (to!=RET_DREGISTER) {
3589 lmove(to,RET_DREGISTER); 3619 lmove(to,RET_DREGISTER);
3590 } 3620 }
3594 code_double_lib_c(char *lib,int from,int to,double value) 3624 code_double_lib_c(char *lib,int from,int to,double value)
3595 { 3625 {
3596 code_save_stacks(); 3626 code_save_stacks();
3597 clear_ptr_cache(); 3627 clear_ptr_cache();
3598 set_dreg_operand(from,1); 3628 set_dreg_operand(from,1);
3599 printf("\tli.d $6,%g\n",value); 3629 printf("\tli.d $6,%10.10g\n",value);
3600 extern_conv(lib); 3630 extern_conv(lib);
3601 set_dreg(RET_DREGISTER,0); 3631 set_dreg(RET_DREGISTER,0);
3602 if (to!=RET_DREGISTER) { 3632 if (to!=RET_DREGISTER) {
3603 lmove(to,RET_DREGISTER); 3633 lmove(to,RET_DREGISTER);
3604 } 3634 }
3762 } 3792 }
3763 free_register(g); 3793 free_register(g);
3764 } else { 3794 } else {
3765 if (car(e2)==DREGISTER) { 3795 if (car(e2)==DREGISTER) {
3766 use_float(d,reg); 3796 use_float(d,reg);
3797 code_save_stacks();
3767 code_double_lib_c("dpadd",cadr(e2),cadr(e2),dir); 3798 code_double_lib_c("dpadd",cadr(e2),cadr(e2),dir);
3768 if (reg!=cadr(e2)) lmove(reg,cadr(e2)); 3799 if (reg!=cadr(e2)) lmove(reg,cadr(e2));
3769 return; 3800 return;
3770 } 3801 }
3771 g_expr(e2); 3802 g_expr(e2);
3901 case DOP+NEQ: op1=DOP+CMP; break; 3932 case DOP+NEQ: op1=DOP+CMP; break;
3902 default: error(-1); 3933 default: error(-1);
3903 } 3934 }
3904 g_expr(list3(op1,e2,e1)); 3935 g_expr(list3(op1,e2,e1));
3905 switch(op) { 3936 switch(op) {
3906 case DOP+GT: printf("\tblez\t$2,$L_%d\n",l1);break; 3937 case DOP+GT: printf("\tbltz\t$2,$L_%d\n",l1);break;
3907 case DOP+GE: printf("\tbltz\t$2,$L_%d\n",l1);break; 3938 case DOP+GE: printf("\tblez\t$2,$L_%d\n",l1);break;
3908 case DOP+EQ: printf("\tbeq\t$2,$0,$L_%d\n",l1);break; 3939 case DOP+EQ: printf("\tbeq\t$2,$0,$L_%d\n",l1);break;
3909 case DOP+NEQ: printf("\tbne\t$2,$0,$L_%d\n",l1);break; 3940 case DOP+NEQ: printf("\tbne\t$2,$0,$L_%d\n",l1);break;
3910 case FOP+GT: printf("\tbc1t\t$L_%d\n",l1);break; 3941 case FOP+GT: printf("\tbc1t\t$L_%d\n",l1);break;
3911 case FOP+GE: printf("\tbc1t\t$L_%d\n",l1);break; 3942 case FOP+GE: printf("\tbc1t\t$L_%d\n",l1);break;
3912 case FOP+EQ: printf("\tbc1t\t$L_%d\n",l1);break; 3943 case FOP+EQ: printf("\tbc1t\t$L_%d\n",l1);break;
4367 } 4398 }
4368 4399
4369 static void 4400 static void
4370 code_longlong_lib(char *lib,int reg,int oreg) 4401 code_longlong_lib(char *lib,int reg,int oreg)
4371 { 4402 {
4403 int tmp;
4372 code_save_stacks(); 4404 code_save_stacks();
4373 clear_ptr_cache(); 4405 clear_ptr_cache();
4374 set_lreg_operand(reg,1); 4406 if (regs[LREGISTER_OPERAND_L]||regs[LREGISTER_OPERAND_H]) {
4375 set_lreg_operand1(oreg,1); 4407 if (regs[LREGISTER_OPERAND_1_L]||regs[LREGISTER_OPERAND_1_H]) {
4408 tmp = new_lvar(SIZE_OF_LONGLONG);
4409 code_lassign_lvar(tmp,reg);
4410 set_lreg_operand1(oreg,1);
4411 code_lrlvar(tmp,LREGISTER_OPERAND);
4412 free_lvar(tmp);
4413 } else {
4414 set_lreg_operand1(oreg,1);
4415 set_lreg_operand(reg,1);
4416 }
4417 } else {
4418 set_lreg_operand(reg,1);
4419 set_lreg_operand1(oreg,1);
4420 }
4376 extern_conv(lib); 4421 extern_conv(lib);
4377 set_lreg(RET_LREGISTER,0); 4422 set_lreg(RET_LREGISTER,0);
4378 } 4423 }
4379 4424
4380 #define code_ldiv_lib(reg,oreg) code_longlong_lib("__divdi3",reg,oreg) 4425 #define code_ldiv_lib(reg,oreg) code_longlong_lib("__divdi3",reg,oreg)