Code:

/* SmartDeck arbitrary sized number support.
Copyright (c) 2001 Aspects Software Ltd.
*/
#ifndef __multosarith_H
#define __multosarith_H
#include <melasm.h>
/* support for N byte block arithmetic */
#define BLOCKCAST(N) *(struct { unsigned char __x[N]; }*)
/* OP N block at RHS to block at LHS */
#define ASSIGN_BINARY_OPN(N, OP, LHS, RHS) \
__push(BLOCKCAST(N)(__typechk(unsigned char *, RHS))); \
__code(OP, __typechk(unsigned char *, LHS), N); \
__code(POPN, N)
/* OP N blocks at OP1 and OP2 and store in SUM */
#define BINARY_OPN(N, OP, SUM, OP1, OP2) \
do { \
__push(BLOCKCAST(N)(__typechk(unsigned char *, OP1))); \
__push(BLOCKCAST(N)(__typechk(unsigned char *, OP2))); \
__code(OP, N); \
__code(POPN, N); \
__code(STORE, __typechk(unsigned char *, SUM), N); \
} while (0)
/* OP N block */
#define UNARY_OPN(N, OP, V) \
__code(OP, V, N);
#define ASSIGN_ADDN(N, LHS, RHS) ASSIGN_BINARY_OPN(N, ADDN, LHS, RHS)
#define ADDN(N, SUM, OP1, OP2) BINARY_OPN(N, ADDN, SUM, OP1, OP2)
#define ASSIGN_ANDN(N, LHS, RHS) ASSIGN_BINARY_OPN(N, ANDN, LHS, RHS)
#define ANDN(N, SUM, OP1, OP2) BINARY_OPN(N, ANDN, SUM, OP1, OP2)
#define ASSIGN_ORN(N, LHS, RHS) ASSIGN_BINARY_OPN(N, ORN, LHS, RHS)
#define ORN(N, SUM, OP1, OP2) BINARY_OPN(N, ORN, SUM, OP1, OP2)
#define ASSIGN_SUBN(N, LHS, RHS) ASSIGN_BINARY_OPN(N, SUBN, LHS, RHS)
#define SUBN(N, SUM, OP1, OP2) BINARY_OPN(N, SUBN, SUM, OP1, OP2)
#define ASSIGN_XORN(N, LHS, RHS) ASSIGN_BINARY_OPN(N, XORN, LHS, RHS)
#define XORN(N, SUM, OP1, OP2) BINARY_OPN(N, XORN, SUM, OP1, OP2)
#define CLEARN(N, V) UNARY_OPN(N, CLEARN, V)
#define INCN(N, V) UNARY_OPN(N, INCN, V)
#define DECN(N, V) UNARY_OPN(N, DECN, V);
#define NOTN(N, V) UNARY_OPN(N, NOTN, V);
#define TESTN(N, V) UNARY_OPN(N, TESTN, V);
/* Truncating assignment multiplication - note carry flag will NOT be set */
#define ASSIGN_MULN(N, LHS, RHS) \
do { \
__push(BLOCKCAST(N)(__typechk(unsigned char *, LHS))); \
__push(BLOCKCAST(N)(__typechk(unsigned char *, RHS))); \
__code(PRIM, 0x10, N); \
__code(STORE, LHS, N); \
__code(POPN, N); \
} while (0)
/* N byte multiplication product must be 2 * N sized */
#define MULN(N, PRODUCT, OP1, OP2) \
do { \
__push(BLOCKCAST(N)(__typechk(unsigned char *, OP1))); \
__push(BLOCKCAST(N)(__typechk(unsigned char *, OP2))); \
__code(PRIM, 0x10, N); \
__code(STORE, __typechk(unsigned char *, PRODUCT), N*2); \
} while (0)
/* N byte division QUOTIENT = NUMERATOR / DEMONIMATOR, REMAINDER = NUMERATOR % DENOMINATOR */
#define DIVN(N, NUMERATOR, DENOMINATOR, QUOTIENT, REMAINDER) \
do { \
__push(BLOCKCAST(N)(__typechk(unsigned char *, NUMERATOR))); \
__push(BLOCKCAST(N)(__typechk(unsigned char *, DENOMINATOR))); \
__code(PRIM, 0x08, N); \
__code(STORE, __typechk(unsigned char *, REMAINDER), N); \
__code(STORE, __typechk(unsigned char *, QUOTIENT), N); \
} while (0)
/* assignment division - quotient replaces numerator and remainder replaces denomator */
#define ASSIGN_DIVN(N, NUMERATOR, DENOMINATOR) \
DIVN(N, NUMERATOR, DENOMINATOR, NUMERATOR, DENOMINATOR)
/* RES = DATA << NUMBITS */
#define SHLN(N, DATA, NUMBITS, RES) \
do { \
__push(BLOCKCAST(N)(__typechk(unsigned char *, DATA))); \
__code(PRIM, 0x02, N, NUMBITS); \
__code(STORE, __typechk(unsigned char *, RES), N); \
} while (0)
/* DATA <<= NUMBITS */
#define ASSIGN_SHLN(N, DATA, NUMBITS) \
SHLN(N, DATA, NUMBITS, DATA)
/* RES = DATA >> NUMBITS */
#define SHRN(N, DATA, NUMBITS, RES) \
do { \
__push(BLOCKCAST(N)(__typechk(unsigned char *, DATA))); \
__code(PRIM, 0x03, N, NUMBITS); \
__code(STORE, __typechk(unsigned char *, RES), N); \
} while (0)
/* DATA >>= NUMBITS */
#define ASSIGN_SHRN(N, DATA, NUMBITS) \
SHRN(N, DATA, NUMBITS, DATA)
#define CMPN(N, OP1, OP2) memcmp(OP1, OP2, N)
/* N byte copy */
#define COPYN(N, DEST, SRC) \
do { \
__push(__typechk(unsigned char *, DEST)); \
__push(__typechk(unsigned char *, SRC)); \
__code(PRIM, 0x0e, N); \
} while (0)
#define CHECKSUM(SIZE, BLOCK, SUM) \
do { \
__push(__typechk(unsigned int, SIZE)); \
__push(__typechk(unsigned char *, BLOCK)); \
__code(PRIM, 0x82); \
__code(STORE, __typechk(unsigned long *, SUM), 4); \
} while (0)
#endif