@@ -620,28 +620,30 @@ static void ei_cast(IR *ir) {
620620 }
621621 } else {
622622 // fix->fix
623- assert (ir -> dst -> vsize != ir -> opr1 -> vsize );
624623 int pows = ir -> opr1 -> vsize ;
625624 int powd = ir -> dst -> vsize ;
626625 assert (0 <= pows && pows < 4 );
627626 assert (0 <= powd && powd < 4 );
628627 int pow = MIN (powd , pows );
629628 const char * dst = kReg64s [ir -> dst -> phys ], * src = kReg64s [ir -> opr1 -> phys ];
630-
631- if (ir -> flag & IRF_UNSIGNED ) {
632- switch (pow ) {
633- case 0 : ZEXT_B (dst , src ); break ;
634- case 1 : ZEXT_H (dst , src ); break ;
635- case 2 : ZEXT_W (dst , src ); break ;
636- default : assert (false); break ;
637- }
638- } else {
639- switch (pow ) {
640- case 0 : SEXT_B (dst , src ); break ;
641- case 1 : SEXT_H (dst , src ); break ;
642- case 2 : SEXT_W (dst , src ); break ;
643- default : assert (false); break ;
629+ if (pow < 3 ) {
630+ if (((ir -> flag & IRF_UNSIGNED ) != 0 ) == (powd > pows )) {
631+ switch (pow ) {
632+ case 0 : ZEXT_B (dst , src ); break ;
633+ case 1 : ZEXT_H (dst , src ); break ;
634+ case 2 : ZEXT_W (dst , src ); break ;
635+ default : assert (false); break ;
636+ }
637+ } else {
638+ switch (pow ) {
639+ case 0 : SEXT_B (dst , src ); break ;
640+ case 1 : SEXT_H (dst , src ); break ;
641+ case 2 : SEXT_W (dst , src ); break ;
642+ default : assert (false); break ;
643+ }
644644 }
645+ } else if (ir -> dst -> phys != ir -> opr1 -> phys ) {
646+ MV (dst , src );
645647 }
646648 }
647649}
0 commit comments