+/* This function is courtesy of Sugimoto at NEC, via Seow Tan (Soew_Tan@el.nec.com) */
+static void
+divun
+(
+ unsigned int N,
+ unsigned long int als,
+ unsigned long int sfi,
+ unsigned long int * quotient_ptr,
+ unsigned long int * remainder_ptr,
+ boolean * overflow_ptr
+)
+{
+ unsigned long ald = sfi >> N - 1;
+ unsigned long alo = als;
+ unsigned int Q = 1;
+ unsigned int C;
+ unsigned int S = 0;
+ unsigned int i;
+ unsigned int R1 = 1;
+ unsigned int OV;
+ unsigned int DBZ = (als == 0) ? 1 : 0;
+ unsigned long alt = Q ? ~als : als;
+
+ /* 1st Loop */
+ alo = ald + alt + Q;
+ C = (alt >> 31) & (ald >> 31) | ((alt >> 31) ^ (ald >> 31)) & (~alo >> 31);
+ C = C ^ Q;
+ Q = ~(C ^ S) & 1;
+ R1 = (alo == 0) ? 0 : (R1 & Q);
+ if ((S ^ (alo>>31)) && !C)
+ {
+ DBZ = 1;
+ }
+ S = alo >> 31;
+ sfi = (sfi << (32-N+1)) | Q;
+ ald = (alo << 1) | (sfi >> 31);
+
+ /* 2nd - N-1th Loop */
+ for (i = 2; i < N; i++)
+ {
+ alt = Q ? ~als : als;
+ alo = ald + alt + Q;
+ C = (alt >> 31) & (ald >> 31) | ((alt >> 31) ^ (ald >> 31)) & (~alo >> 31);
+ C = C ^ Q;
+ Q = ~(C ^ S) & 1;
+ R1 = (alo == 0) ? 0 : (R1 & Q);
+ if ((S ^ (alo>>31)) && !C && !DBZ)
+ {
+ DBZ = 1;
+ }
+ S = alo >> 31;
+ sfi = (sfi << 1) | Q;
+ ald = (alo << 1) | (sfi >> 31);
+ }
+
+ /* Nth Loop */
+ alt = Q ? ~als : als;
+ alo = ald + alt + Q;
+ C = (alt >> 31) & (ald >> 31) | ((alt >> 31) ^ (ald >> 31)) & (~alo >> 31);
+ C = C ^ Q;
+ Q = ~(C ^ S) & 1;
+ R1 = (alo == 0) ? 0 : (R1 & Q);
+ if ((S ^ (alo>>31)) && !C)
+ {
+ DBZ = 1;
+ }
+
+ * quotient_ptr = (sfi << 1) | Q;
+ * remainder_ptr = Q ? alo : (alo + als);
+ * overflow_ptr = DBZ | R1;
+}
+
+/* This function is courtesy of Sugimoto at NEC, via Seow Tan (Soew_Tan@el.nec.com) */
+static void
+divn
+(
+ unsigned int N,
+ unsigned long int als,
+ unsigned long int sfi,
+ signed long int * quotient_ptr,
+ signed long int * remainder_ptr,
+ boolean * overflow_ptr
+)
+{
+ unsigned long ald = (signed long) sfi >> (N - 1);
+ unsigned long alo = als;
+ unsigned int SS = als >> 31;
+ unsigned int SD = sfi >> 31;
+ unsigned int R1 = 1;
+ unsigned int OV;
+ unsigned int DBZ = als == 0 ? 1 : 0;
+ unsigned int Q = ~(SS ^ SD) & 1;
+ unsigned int C;
+ unsigned int S;
+ unsigned int i;
+ unsigned long alt = Q ? ~als : als;
+
+
+ /* 1st Loop */
+
+ alo = ald + alt + Q;
+ C = (alt >> 31) & (ald >> 31) | ((alt >> 31) ^ (ald >> 31)) & (~alo >> 31);
+ Q = C ^ SS;
+ R1 = (alo == 0) ? 0 : (R1 & (Q ^ (SS ^ SD)));
+ S = alo >> 31;
+ sfi = (sfi << (32-N+1)) | Q;
+ ald = (alo << 1) | (sfi >> 31);
+ if ((alo >> 31) ^ (ald >> 31))
+ {
+ DBZ = 1;
+ }
+
+ /* 2nd - N-1th Loop */
+
+ for (i = 2; i < N; i++)
+ {
+ alt = Q ? ~als : als;
+ alo = ald + alt + Q;
+ C = (alt >> 31) & (ald >> 31) | ((alt >> 31) ^ (ald >> 31)) & (~alo >> 31);
+ Q = C ^ SS;
+ R1 = (alo == 0) ? 0 : (R1 & (Q ^ (SS ^ SD)));
+ S = alo >> 31;
+ sfi = (sfi << 1) | Q;
+ ald = (alo << 1) | (sfi >> 31);
+ if ((alo >> 31) ^ (ald >> 31))
+ {
+ DBZ = 1;
+ }
+ }
+
+ /* Nth Loop */
+ alt = Q ? ~als : als;
+ alo = ald + alt + Q;
+ C = (alt >> 31) & (ald >> 31) | ((alt >> 31) ^ (ald >> 31)) & (~alo >> 31);
+ Q = C ^ SS;
+ R1 = (alo == 0) ? 0 : (R1 & (Q ^ (SS ^ SD)));
+ sfi = (sfi << (32-N+1));
+ ald = alo;
+
+ /* End */
+ if (alo != 0)
+ {
+ alt = Q ? ~als : als;
+ alo = ald + alt + Q;
+ }
+ R1 = R1 & ((~alo >> 31) ^ SD);
+ if ((alo != 0) && ((Q ^ (SS ^ SD)) ^ R1)) alo = ald;
+ if (N != 32)
+ ald = sfi = (long) ((sfi >> 1) | (SS ^ SD) << 31) >> (32-N-1) | Q;
+ else
+ ald = sfi = sfi | Q;
+
+ OV = DBZ | ((alo == 0) ? 0 : R1);
+
+ * remainder_ptr = alo;
+
+ /* Adj */
+ if ((alo != 0) && ((SS ^ SD) ^ R1) || (alo == 0) && (SS ^ R1))
+ alo = ald + 1;
+ else
+ alo = ald;
+
+ OV = (DBZ | R1) ? OV : ((alo >> 31) & (~ald >> 31));
+
+ * quotient_ptr = alo;
+ * overflow_ptr = OV;
+}
+