/***** * * Michael Riff * Multiprecision main program version 1.0 Februar 2022. * * Main routine calling the assember implemented multiprecision routines: * div3.s : 128/16 bits division (using divu assembler instruction) * * March 2022 clear renaming of routines and reordering in the files: * Addition of a 128:95 bits division test *****/ #include #include typedef struct { unsigned long high; unsigned long low; } Unsigned64; /* Unsigned 64 type defined in Toolbox as typdef struct { unsigned long high; unsignd long low; } Int64bit; */ // Signed 64 type defined typedef struct{ long high; //TBC unsigned long low; } Signed64; typedef struct { unsigned long high; unsigned long middle; unsigned long low; } Unsigned96; typedef struct { unsigned long high; unsigned long middle_u; unsigned long middle_l; unsigned long low; } Unsigned128; typedef struct { long high; long middle_u; long middle_l; long low; } Signed128; void shift_l1(Unsigned128* Dividend, unsigned int shift); void shift_r1(Unsigned128* Dividend, Unsigned96* divisor, unsigned int *shift); void shift_l2(Unsigned128* Dividend, unsigned int shift); void shift_r2(Unsigned128* Dividend, Unsigned96* divisor, unsigned int *shift); /* Backwards calculation for 128:64 bits division */ void Print128(Unsigned128 *Result) { printf("128 div rev %x %x %x %x\n", Result->high, Result->middle_u, Result->middle_l, Result->low); } Unsigned128 Test_128; Unsigned96 Divisor_96; unsigned int shift; int main() { unsigned int rem; printf("hello world\n"); // To test second set of shift routines #define shift_l1 shift_l2 #define shift_r1 shift_r2 /* Right shift: */ // <32 // LDZ = 3 (+32) Divisor_96.high = 0x12345678; Divisor_96.middle = 0x9ABCDEF0; Divisor_96.low = 0x12345678; // LDZ = 27 -> 35-27 = 8 Test_128.high = 0x12; Test_128.middle_u = 0x3456789A; Test_128.middle_l = 0xBCDEF012; Test_128.low = 0x13467900; // Expected shift of 2 0x0 0x12345678 0x9ABCDEF0 0x12134679 shift = 0xFFFF; shift_r1 (&Test_128, &Divisor_96, &shift); printf("<32 %d bit shift %x %x %x %x\n", shift, Test_128.high, Test_128.middle_u , Test_128.middle_l, Test_128.low); // =32 Divisor_96.high = 0x12345678; Divisor_96.middle = 0x9ABCDEF0; Divisor_96.low = 0x12345678; Test_128.high = 0x12345678; Test_128.middle_u = 0x9ABCDEF0; Test_128.middle_l = 0x12345678; Test_128.low = 0x13467900; // Expected shift of 8 0x0 0x12345678 0x9ABCDEF0 0x12345678 shift = 0xFFFF; shift_r1 (&Test_128, &Divisor_96, &shift); printf("32 %d bit shift %x %x %x %x\n", shift, Test_128.high, Test_128.middle_u , Test_128.middle_l, Test_128.low); // <64 // LDZ = 27 (+32) Divisor_96.high = 0x12; Divisor_96.middle = 0x3456789A; Divisor_96.low = 0xBCDF0123; // LDZ = 3 -> 59-3 = 56 Test_128.high = 0x12345678; Test_128.middle_u = 0x9ABCDEF0; Test_128.middle_l = 0x12345678; Test_128.low = 0x13467900; // Expected shift of 14 0x0 0x0012 0x3456789A 0xBCDEF012 shift = 0xFFFF; shift_r1 (&Test_128, &Divisor_96, &shift); printf("<64 %d bit shift %x %x %x %x\n", shift, Test_128.high, Test_128.middle_u , Test_128.middle_l, Test_128.low); // =64 Divisor_96.high = 0x0; Divisor_96.middle = 0x12345678; Divisor_96.low = 0x9ABCDEF0; Test_128.high = 0x12345678; Test_128.middle_u = 0x9ABCDEF0; Test_128.middle_l = 0x12345678; Test_128.low = 0x13467900; // Expected shift of 16 0x00 0x00 0x12345678 0x9ABCDEF0 shift = 0xFFFF; shift_r1 (&Test_128, &Divisor_96, &shift); printf("64 %d bit shift %x %x %x %x\n", shift, Test_128.high, Test_128.middle_u , Test_128.middle_l, Test_128.low); //<96 // LDZ = 55 (+32) Divisor_96.high = 0x0; Divisor_96.middle = 0x123; Divisor_96.low = 0x456789AB; // LDZ = 3 -> 87-3 = 84 Test_128.high = 0x12345678; Test_128.middle_u = 0x9ABCDEF0; Test_128.middle_l = 0x12345678; Test_128.low = 0x1346790F; // Expected shift of 21 0x00 0x00 0x0123 0x456789AB shift = 0xFFFF; shift_r1 (&Test_128, &Divisor_96, &shift); printf("<96 %d bit shift %x %x %x %x\n", shift, Test_128.high, Test_128.middle_u , Test_128.middle_l, Test_128.low); // =96 Divisor_96.high = 0x0; Divisor_96.middle = 0x0; Divisor_96.low = 0x12345678; Test_128.high = 0x12345678; Test_128.middle_u = 0x9ABCDEF0; Test_128.middle_l = 0x12345678; Test_128.low = 0x13467900; // Expected shift of 24 0x00 0x00 0x00 0x12345678 shift = 0xFFFF; shift_r1 (&Test_128, &Divisor_96, &shift); printf("96 %d bit shift %x %x %x %x\n", shift, Test_128.high, Test_128.middle_u , Test_128.middle_l, Test_128.low); //<128 // LDZ = 71 (+32) Divisor_96.high = 0x0; Divisor_96.middle = 0x0; Divisor_96.low = 0x01234567; // LDZ = 3 -> 103-3 = 100 Test_128.high = 0x12345678; Test_128.middle_u = 0x9ABCDEF0; Test_128.middle_l = 0x13579BDF; Test_128.low = 0x2468ACE0; // Expected shift of 25 0x00 0x00 0x00 0x01234567 shift = 0xFFFF; shift_r1 (&Test_128, &Divisor_96, &shift); printf("<128 %d bit shift %x %x %x %x\n", shift, Test_128.high, Test_128.middle_u , Test_128.middle_l, Test_128.low); /* Left shift: */ // <32 Test_128.high = 0x12; Test_128.middle_u = 0x3456789A; Test_128.middle_l = 0xBCDEF012; Test_128.low = 0x13467900; // Expected shift of 2 0x 0x 0x 0x shift_l1 (&Test_128, 8); printf("<32 bit shift %x %x %x %x\n", Test_128.high, Test_128.middle_u , Test_128.middle_l, Test_128.low); // =32 Test_128.high = 0x0FFFF; Test_128.middle_u = 0x12345678; Test_128.middle_l = 0x9ABCDEF0; Test_128.low = 0x13579BDF; // Expected shift of 8 0x 0x 0x 0x shift_l1 (&Test_128, 32); printf("=32 bit shift %x %x %x %x\n", Test_128.high, Test_128.middle_u , Test_128.middle_l, Test_128.low); // <64 Test_128.high = 0x0; Test_128.middle_u = 0xFFBB1234; Test_128.middle_l = 0xC56789AB; Test_128.low = 0x1346790F; // Expected shift of 10 0xBB1234C5 0x6789AB13 0x46790F00 0x00 shift_l1 (&Test_128, 40); printf("<64 bit shift %x %x %x %x\n", Test_128.high, Test_128.middle_u , Test_128.middle_l, Test_128.low); // =64 Test_128.high = 0x12345678; Test_128.middle_u = 0x9ABCDEF0; Test_128.middle_l = 0x12345678; Test_128.low = 0x13467908; // Expected shift of 16 0x12345678 0x13467908 0x00 0x00 shift_l1 (&Test_128, 64); printf("64 bit shift %x %x %x %x\n", Test_128.high, Test_128.middle_u , Test_128.middle_l, Test_128.low); //<96 Test_128.high = 0x0; Test_128.middle_u = 0x0FFFF; Test_128.middle_l = 0xFFA12345; Test_128.low = 0x6789ABCD; // Expected shift of 17 0xFA123456 0x789ABCD0 0x00 0x00 shift_l1 (&Test_128, 68); printf("<96 bit shift %x %x %x %x\n", Test_128.high, Test_128.middle_u , Test_128.middle_l, Test_128.low); // =96 Test_128.high = 0x0; Test_128.middle_u = 0x0; Test_128.middle_l = 0x0FFFF; Test_128.low = 0xA1234567; // Expected shift of 24 0x 0x 0x 0x shift_l1 (&Test_128, 96); printf("96 bit shift %x %x %x %x\n", Test_128.high, Test_128.middle_u , Test_128.middle_l, Test_128.low); //<128 Test_128.high = 0x0; Test_128.middle_u = 0x0; Test_128.middle_l = 0x0; Test_128.low = 0x00012345; // Expected shift of 27 0x12345000 0x00 0x00 0x00 shift_l1 (&Test_128, 108); printf("<128 bit shift %x %x %x %x\n", Test_128.high, Test_128.middle_u , Test_128.middle_l, Test_128.low); Test_128.high = 0x1468ace0; Test_128.middle_u = 0x98765432; Test_128.middle_l = 0x0abcdef1; Test_128.low = 0x7531fbd9; Divisor_96.high = 0x0; Divisor_96.middle = 0x6378fba1; Divisor_96.low = 0x4c5d209e; /* LDZ = 3 | 64+1 => Shift R 62 +1 = 32 + 31 Shift L 128-63 = 65 = 64 + 1 Expected: 0x1579bde2 0xea63fb72 0x0 0x0 */ shift_l1 (&Test_128, 65); printf("128_96 shift %x %x %x %x\n", Test_128.high, Test_128.middle_u, Test_128.middle_l, Test_128.low); Test_128.high = 0x58765432; Test_128.middle_u = 0x1fedcba0; Test_128.middle_l = 0x2468ace0; Test_128.low = 0x13579bdf; Divisor_96.high = 0x68ace240; Divisor_96.middle = 0xfdb97531; Divisor_96.low = 0x3b4c9a1f; /* LDZ = 1 | 32+1 => Shift R 32 +1 = 32 + 1 Shift L 128-33 = 95 = 64 + 31 Expected: 0x9abcdef 0x80000000 0x0 0x0 */ shift_l1 (&Test_128, 95); printf("128_96 shift %x %x %x %x\n", Test_128.high, Test_128.middle_u, Test_128.middle_l, Test_128.low); return EXIT_SUCCESS; }