@@ -443,18 +443,14 @@ static void asm_conv(ASMState *as, IRIns *ir)
443443 /* y = (x ^ 0x8000000) + 2147483648.0 */
444444 Reg left = ra_alloc1 (as , lref , RSET_GPR );
445445 Reg tmp = ra_scratch (as , rset_exclude (RSET_FPR , dest ));
446- emit_fgh (as , irt_isfloat (ir -> t ) ? MIPSI_ADD_S : MIPSI_ADD_D ,
447- dest , dest , tmp );
448- emit_fg (as , irt_isfloat (ir -> t ) ? MIPSI_CVT_S_W : MIPSI_CVT_D_W ,
449- dest , dest );
450446 if (irt_isfloat (ir -> t ))
451- emit_lsptr (as , MIPSI_LWC1 , ( tmp & 31 ),
452- ( void * ) lj_ir_k64_find ( as -> J , U64x ( 4f 000000 , 4f 000000 )),
453- RSET_GPR );
454- else
455- emit_lsptr (as , MIPSI_LDC1 , (tmp & 31 ),
456- (void * )lj_ir_k64_find (as -> J , U64x (41e00000 ,00000000 )),
457- RSET_GPR );
447+ emit_fg (as , MIPSI_CVT_S_D , dest , dest );
448+ /* Must perform arithmetic with doubles to keep the precision. */
449+ emit_fgh ( as , MIPSI_ADD_D , dest , dest , tmp );
450+ emit_fg ( as , MIPSI_CVT_D_W , dest , dest );
451+ emit_lsptr (as , MIPSI_LDC1 , (tmp & 31 ),
452+ (void * )lj_ir_k64_find (as -> J , U64x (41e00000 ,00000000 )),
453+ RSET_GPR );
458454 emit_tg (as , MIPSI_MTC1 , RID_TMP , dest );
459455 emit_dst (as , MIPSI_XOR , RID_TMP , RID_TMP , left );
460456 emit_ti (as , MIPSI_LUI , RID_TMP , 0x8000 );
0 commit comments