aboutsummaryrefslogtreecommitdiffstats
path: root/src/arch/loong64/include/bits/bigint.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/loong64/include/bits/bigint.h')
-rw-r--r--src/arch/loong64/include/bits/bigint.h42
1 files changed, 37 insertions, 5 deletions
diff --git a/src/arch/loong64/include/bits/bigint.h b/src/arch/loong64/include/bits/bigint.h
index bec748beb..ec6ca4b89 100644
--- a/src/arch/loong64/include/bits/bigint.h
+++ b/src/arch/loong64/include/bits/bigint.h
@@ -357,10 +357,42 @@ bigint_done_raw ( const uint64_t *value0, unsigned int size __unused,
*(--out_byte) = *(value_byte++);
}
-extern void bigint_multiply_raw ( const uint64_t *multiplicand0,
- unsigned int multiplicand_size,
- const uint64_t *multiplier0,
- unsigned int multiplier_size,
- uint64_t *value0 );
+/**
+ * Multiply big integer elements
+ *
+ * @v multiplicand Multiplicand element
+ * @v multiplier Multiplier element
+ * @v result Result element pair
+ * @v carry Carry element
+ */
+static inline __attribute__ (( always_inline )) void
+bigint_multiply_one ( const uint64_t multiplicand, const uint64_t multiplier,
+ uint64_t *result, uint64_t *carry ) {
+ uint64_t discard_low;
+ uint64_t discard_high;
+ uint64_t discard_carry;
+
+ __asm__ __volatile__ ( /* Perform multiplication */
+ "mul.d %0, %6, %7\n\t"
+ "mulh.du %1, %6, %7\n\t"
+ /* Accumulate low half */
+ "add.d %3, %3, %0\n\t"
+ "sltu %2, %3, %0\n\t"
+ /* Add carry to high half (cannot overflow) */
+ "add.d %1, %1, %2\n\t"
+ /* Accumulate high half */
+ "add.d %4, %4, %1\n\t"
+ "sltu %2, %4, %1\n\t"
+ /* Accumulate carry (cannot overflow) */
+ "add.d %5, %5, %2\n\t"
+ : "=&r" ( discard_low ),
+ "=r" ( discard_high ),
+ "=r" ( discard_carry ),
+ "+r" ( result[0] ),
+ "+r" ( result[1] ),
+ "+r" ( *carry )
+ : "r" ( multiplicand ),
+ "r" ( multiplier ) );
+}
#endif /* _BITS_BIGINT_H */