sh2 drc, fix 64 bit multiplication in ppc and riscv backends
authorkub <derkub@gmail.com>
Tue, 7 Mar 2023 21:54:36 +0000 (21:54 +0000)
committerkub <derkub@gmail.com>
Tue, 7 Mar 2023 21:54:36 +0000 (21:54 +0000)
cpu/drc/emit_ppc.c
cpu/drc/emit_riscv.c

index 9b49e67..d856f10 100644 (file)
@@ -420,23 +420,19 @@ enum { OPS_STD, OPS_STDU /*,OPS_STQ*/ };
 
 // "long" multiplication, 32x32 bit = 64 bit
 #define EMIT_PPC_MULLU_REG(dlo, dhi, s1, s2) do { \
-       EMIT(PPC_EXTUW_REG(s1, s1)); \
-       EMIT(PPC_EXTUW_REG(s2, s2)); \
-       EMIT(PPC_MULL(dlo, s1, s2)); \
-       EMIT(PPC_ASR_IMM(dhi, dlo, 32)); \
+       int at = (dlo == s1 || dlo == s2 ? AT : dlo); \
+       EMIT(PPC_MUL(at, s1, s2)); \
+       EMIT(PPC_MULHU(dhi, s1, s2)); \
+       if (at != dlo) emith_move_r_r(dlo, at); \
 } while (0)
 
 #define EMIT_PPC_MULLS_REG(dlo, dhi, s1, s2) do { \
-       EMIT(PPC_EXTSW_REG(s1, s1)); \
-       EMIT(PPC_EXTSW_REG(s2, s2)); \
-       EMIT(PPC_MULL(dlo, s1, s2)); \
+       EMIT(PPC_MUL(dlo, s1, s2)); \
        EMIT(PPC_ASR_IMM(dhi, dlo, 32)); \
 } while (0)
 
 #define EMIT_PPC_MACLS_REG(dlo, dhi, s1, s2) do { \
-       EMIT(PPC_EXTSW_REG(s1, s1)); \
-       EMIT(PPC_EXTSW_REG(s2, s2)); \
-       EMIT(PPC_MULL(AT, s1, s2)); \
+       EMIT(PPC_MUL(AT, s1, s2)); \
        EMIT(PPC_BFI_IMM(dlo, dhi, 0, 32)); \
        emith_add_r_r(dlo, AT); \
        EMIT(PPC_ASR_IMM(dhi, dlo, 32)); \
index 4c3448f..2b59760 100644 (file)
@@ -217,15 +217,20 @@ enum { F2_ALT=0x20, F2_MULDIV=0x01 };
 #define PTR_SCALE                      3
 
 // NB: must split 64 bit result into 2 32 bit registers
-// NB: expects 32 bit values in s1+s2, correctly sign extended to 64 bits
 #define EMIT_R5_MULLU_REG(dlo, dhi, s1, s2) do { \
+       EMIT(R5_LSL_IMM(AT, s1, 32)); \
+       EMIT(R5_LSL_IMM(dhi, s2, 32)); \
+       EMIT(R5_MULHU(dlo, AT, dhi)); \
+       EMIT(R5_ASR_IMM(dhi, dlo, 32)); \
+       EMIT(R5_ADDW_IMM(dlo, dlo, 0)); \
+} while (0)
+
+#define EMIT_R5_MULLS_REG(dlo, dhi, s1, s2) do { \
        EMIT(R5_MUL(dlo, s1, s2)); \
        EMIT(R5_ASR_IMM(dhi, dlo, 32)); \
        EMIT(R5_ADDW_IMM(dlo, dlo, 0)); \
 } while (0)
 
-#define EMIT_R5_MULLS_REG(dlo, dhi, s1, s2) \
-       EMIT_R5_MULLU_REG(dlo, dhi, s1, s2)
 #else
 #define R5_OP32                                0
 #define F1_P                           F1_W