Mercurial > hg > CbC > old > device
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) |