@@ -1684,10 +1684,45 @@ NuCompileExpression(NuIrList *irl, AST *node) {
1684
1684
case AST_CAST :
1685
1685
{
1686
1686
int n = NuCompileExpression (irl , node -> right );
1687
- if (IsVoidType (node -> left ) && n ) {
1688
- // ignoring the results, so pop them
1689
- NuCompileDrop (irl , n );
1690
- n = 0 ;
1687
+ if (IsVoidType (node -> left )) {
1688
+ if (n > 0 ) {
1689
+ // ignoring the results, so pop them
1690
+ NuCompileDrop (irl , n );
1691
+ n = 0 ;
1692
+ }
1693
+ } else {
1694
+ // may have to widen or narrow
1695
+ // (We require here that any int <-> float conversions
1696
+ // happened in type analysis)
1697
+ int expectN = (TypeSize (node -> left ) + LONG_SIZE - 1 ) / LONG_SIZE ;
1698
+ if (expectN != n ) {
1699
+ if (!IsIntType (node -> left )) {
1700
+ ERROR (node , "Internal error, expected integer type" );
1701
+ }
1702
+ if (expectN < n ) {
1703
+ // narrowing, just drop words
1704
+ NuCompileDrop (irl , n - expectN );
1705
+ n = expectN ;
1706
+ } else {
1707
+ int needDups = (expectN - n ) - 1 ;
1708
+ // do we need to sign extend?
1709
+ if (IsUnsignedType (node -> left )) {
1710
+ // no, just pad with 0's
1711
+ NuEmitConst (irl , 0 );
1712
+ n ++ ;
1713
+ } else {
1714
+ // yes, dup the top and sign extend it
1715
+ NuEmitOp (irl , NU_OP_DUP );
1716
+ NuEmitConst (irl , 31 );
1717
+ NuEmitOp (irl , NU_OP_SAR );
1718
+ n ++ ;
1719
+ }
1720
+ while (needDups -- > 0 ) {
1721
+ NuEmitOp (irl , NU_OP_DUP );
1722
+ n ++ ;
1723
+ }
1724
+ }
1725
+ }
1691
1726
}
1692
1727
return n ;
1693
1728
}
0 commit comments