#include #include #include #include void add32(uint16_t ah, uint16_t al, uint16_t *rh, uint16_t *rl) { uint16_t bh, bl; int c = 0; bh = *rh; bl = *rl; *rl = al + bl; if (*rl < al || *rl < bl) c = 1; *rh = ah + bh + c; } void mul32(uint16_t ah, uint16_t al, uint16_t *rh, uint16_t *rl) { uint16_t bh, bl; int i; bh = *rh; bl = *rl; *rh = 0; *rl = 0; for (i = 0; i < 16; i++) { if (bl & 1) add32(ah, al, rh, rl); ah <<= 1; if (al & 0x8000) ah |= 1; al <<= 1; bl >>= 1; } for (i = 0; i < 16; i++) { if (bh & 1) add32(ah, al, rh, rl); ah <<= 1; if (al & 0x8000) ah |= 1; al <<= 1; bh >>= 1; } } int main(int argc, char **argv) { uint32_t a, b, r; uint16_t ah, al, bh, bl; a = strtoul(argv[1], NULL, 0); b = strtoul(argv[2], NULL, 0); ah = (a >> 16) & 0xFFFF; al = (a & 0xFFFF); bh = (b >> 16) & 0xFFFF; bl = (b & 0xFFFF); #if 0 add32(ah, al, &bh, &bl); r = ((uint32_t)bh << 16) | bl; if (!strncmp(argv[1], "0x", 2) || !strncmp(argv[2], "0x", 2)) printf("0x%08x ?= 0x%08x\n", a + b, r); else printf("%d ?= %d", a + b, r); #else mul32(ah, al, &bh, &bl); r = ((uint32_t)bh << 16) | bl; if (!strncmp(argv[1], "0x", 2) || !strncmp(argv[2], "0x", 2)) printf("0x%08x ?= 0x%08x\n", a * b, r); else printf("%d ?= %d\n", a * b, r); #endif return 0; }