--- /dev/null
+*
+!/.gitignore
+++ /dev/null
-/*
- N16 - a processor native type
-
- For binary operations: a op b -> c
-
- See the document on the proper use of the Natural types.
-
- On the subject of multiple pointers indicating the same location in memory:
-
- When a routine has multiple results, and one or more of the result location
- pointers point to the same storage, the routine will either return an error
- status, or have defined behavior.
-
- When a routine has multiple operands, in any combination, those
- pointers can point to the same location, and the routine will
- function as advertised.
-
- When an operand functions as both an input and a result, perhaps due
- to a result pointer pointing to the same place as an operand
- pointer, the routine will function as advertised. (Internally the
- routine might make a temporary copy of the operand to accomplish
- this.)
-*/
-
-#define N16路DEBUG
-
-#ifndef FACE
-#define N16路IMPLEMENTATION
-#define FACE
-#endif
-
-//--------------------------------------------------------------------------------
-// Interface
-
-#ifndef N16路FACE
-#define N16路FACE
-
- #include <stdint.h>
- #include <stdbool.h>
- #include <stdarg.h>
- #include <stdlib.h>
-
- //----------------------------------------
- // Instance Data (Declaration Only)
-
- typedef uint16_t Extent;
- typedef uint16_t Digit;
-
- typedef struct N16路T N16路T;
-
- extern N16路T *N16路zero;
- extern N16路T *N16路one;
- extern N16路T *N16路all_one_bit;
- extern N16路T *N16路lsb;
- extern N16路T *N16路msb;
-
- //----------------------------------------
- // Return/Error Status and handlers
-
- typedef enum{
- N16路Status路ok = 0
- ,N16路Status路overflow = 1
- ,N16路Status路accumulator1_overflow = 2
- ,N16路Status路carry = 3
- ,N16路Status路borrow = 4
- ,N16路Status路undefined_divide_by_zero = 5
- ,N16路Status路undefined_modulus_zero = 6
- ,N16路Status路gt_max_shift_count = 7
- ,N16路Status路spill_eq_operand = 8 // not currently signaled, result will be spill value
- ,N16路Status路one_word_product = 9
- ,N16路Status路two_word_product = 10
- } N16路Status;
-
- typedef enum{
- N16路Order_lt = -1
- ,N16路Order_eq = 0
- ,N16路Order_gt = 1
- } N16路Order;
-
- typedef N16路T *( *N16路Allocate_MemoryFault )(Extent);
-
- //----------------------------------------
- // Interface
-
- typedef struct{
-
- N16路T *(*allocate_array_zero)(Extent, N16路Allocate_MemoryFault);
- N16路T *(*allocate_array)(Extent, N16路Allocate_MemoryFault);
- void (*deallocate)(N16路T*);
-
- void (*copy)(N16路T*, N16路T*);
- void (*bit_and)(N16路T*, N16路T*, N16路T*);
- void (*bit_or)(N16路T*, N16路T*, N16路T*);
- void (*bit_complement)(N16路T*, N16路T*);
- void (*bit_twos_complement)(N16路T*, N16路T*);
- N16路Order (*compare)(N16路T*, N16路T*);
- bool (*lt)(N16路T*, N16路T*);
- bool (*gt)(N16路T*, N16路T*);
- bool (*eq)(N16路T*, N16路T*);
- bool (*eq_zero)(N16路T*);
- N16路Status (*accumulate)(N16路T *accumulator1 ,N16路T *accumulator0 ,...);
- N16路Status (*add)(N16路T*, N16路T*, N16路T*);
- bool (*increment)(N16路T *a);
- N16路Status (*subtract)(N16路T*, N16路T*, N16路T*);
- N16路Status (*multiply)(N16路T*, N16路T*, N16路T*, N16路T*);
- N16路Status (*divide)(N16路T*, N16路T*, N16路T*, N16路T*);
- N16路Status (*modulus)(N16路T*, N16路T*, N16路T*);
- N16路Status (*shift_left)(Extent, N16路T*, N16路T*, N16路T*);
- N16路Status (*shift_right)(Extent, N16路T*, N16路T*, N16路T*);
- N16路Status (*arithmetic_shift_right)(Extent, N16路T*, N16路T*);
-
- N16路T* (*access)(N16路T*, Extent);
- void (*from_uint32)(N16路T *destination ,uint32_t value);
- } N16路螞;
-
- Local const N16路螞 N16路位; // initialized in the LOCAL section
-
-#endif
-
-//--------------------------------------------------------------------------------
-// Implementation
-
-#ifdef N16路IMPLEMENTATION
-
- // this part goes into the library
- #ifndef LOCAL
-
- #include <stdarg.h>
- #include <stdlib.h>
-
- struct N16路T{
- Digit d0;
- };
-
- N16路T N16路constant[4] = {
- {.d0 = 0},
- {.d0 = 1},
- {.d0 = ~(uint16_t)0},
- {.d0 = 1 << 15}
- };
-
- N16路T *N16路zero = &N16路constant[0];
- N16路T *N16路one = &N16路constant[1];
- N16路T *N16路all_one_bit = &N16路constant[2];
- N16路T *N16路msb = &N16路constant[3];
- N16路T *N16路lsb = &N16路constant[1];
-
- // the allocate an array of N16
- N16路T *N16路allocate_array(Extent extent ,N16路Allocate_MemoryFault memory_fault){
- N16路T *instance = malloc((extent + 1) * sizeof(N16路T));
- if(!instance){
- return memory_fault ? memory_fault(extent) : NULL;
- }
- return instance;
- }
-
- N16路T *N16路allocate_array_zero(Extent extent ,N16路Allocate_MemoryFault memory_fault){
- N16路T *instance = calloc(extent + 1, sizeof(N16路T));
- if(!instance){
- return memory_fault ? memory_fault(extent) : NULL;
- }
- return instance;
- }
-
- void N16路deallocate(N16路T *unencumbered){
- free(unencumbered);
- }
-
-
- #endif
-
- // This part is included after the library user's code
- #ifdef LOCAL
-
- // instance
-
- struct N16路T{
- Digit d0;
- };
-
- // temporary variables
- Local N16路T N16路t[4];
-
- // allocation
-
- extern N16路T *N16路allocate_array(Extent, N16路Allocate_MemoryFault);
- extern N16路T *N16路allocate_array_zero(Extent, N16路Allocate_MemoryFault);
- extern void N16路deallocate(N16路T *);
-
- // so the user can access numbers in an array allocation
- Local N16路T* N16路access(N16路T *array ,Extent index){
- return &array[index];
- }
-
- Local void N16路from_uint32(N16路T *destination ,uint32_t value){
- if(destination == NULL) return;
- destination->d0 = (uint16_t)(value & 0xFFFF);
- }
-
- // copy, convenience copy
-
- Local void N16路copy(N16路T *destination ,N16路T *source){
- if(source == destination) return;
- *destination = *source;
- }
-
- Local void N16路set_to_zero(N16路T *instance){
- instance->d0 = 0;
- }
-
- Local void N16路set_to_one(N16路T *instance){
- instance->d0 = 1;
- }
-
- // bit operations
-
- Local void N16路bit_and(N16路T *result, N16路T *a, N16路T *b){
- result->d0 = a->d0 & b->d0;
- }
-
- Local void N16路bit_or(N16路T *result, N16路T *a, N16路T *b){
- result->d0 = a->d0 | b->d0;
- }
-
- Local void N16路bit_complement(N16路T *result, N16路T *a){
- result->d0 = ~a->d0;
- }
-
- Local void N16路bit_twos_complement(N16路T *result ,N16路T *a){
- result->d0 = (uint16_t)(~a->d0 + 1);
- }
-
- // test functions
-
- Local N16路Order N16路compare(N16路T *a, N16路T *b){
- if(a->d0 < b->d0) return N16路Order_lt;
- if(a->d0 > b->d0) return N16路Order_gt;
- return N16路Order_eq;
- }
-
- Local bool N16路lt(N16路T *a ,N16路T *b){
- return a->d0 < b->d0;
- }
-
- Local bool N16路gt(N16路T *a ,N16路T *b){
- return a->d0 > b->d0;
- }
-
- Local bool N16路eq(N16路T *a ,N16路T *b){
- return a->d0 == b->d0;
- }
-
- Local bool N16路eq_zero(N16路T *a){
- return a->d0 == 0;
- }
-
- // arithmetic operations
-
- Local N16路Status N16路accumulate(N16路T *accumulator1 ,N16路T *accumulator0 ,...){
-
- va_list args;
- va_start(args ,accumulator0);
- uint32_t sum = accumulator0->d0;
- uint32_t carry = 0;
- N16路T *current;
-
- while( (current = va_arg(args ,N16路T*)) ){
- sum += current->d0;
- if(sum < current->d0){
- (carry)++;
- if(carry == 0){
- va_end(args);
- return N16路Status路accumulator1_overflow;
- }
- }
- }
- va_end(args);
-
- accumulator1->d0 = (uint16_t)carry;
- return N16路Status路ok;
- }
-
- Local N16路Status N16路add(N16路T *sum ,N16路T *a ,N16路T *b){
- uint32_t result = (uint32_t)a->d0 + (uint32_t)b->d0;
- sum->d0 = (uint16_t)(result & 0xFFFF);
- return (result >> 16) ? N16路Status路carry : N16路Status路ok;
- }
-
- Local bool N16路increment(N16路T *a){
- a->d0++;
- return (a->d0 == 0);
- }
-
- Local N16路Status N16路subtract(N16路T *difference ,N16路T *a ,N16路T *b){
- uint32_t diff = (uint32_t)a->d0 - (uint32_t)b->d0;
- difference->d0 = (uint16_t)(diff & 0xFFFF);
- return (diff > a->d0) ? N16路Status路borrow : N16路Status路ok;
- }
-
- Local N16路Status N16路multiply(N16路T *product1 ,N16路T *product0 ,N16路T *a ,N16路T *b){
- uint32_t product = (uint32_t)a->d0 * (uint32_t)b->d0;
- product0->d0 = (uint16_t)(product & 0xFFFF);
- product1->d0 = (uint16_t)((product >> 16) & 0xFFFF);
-
- if(product1->d0 == 0) return N16路Status路one_word_product;
- return N16路Status路two_word_product;
- }
-
- Local N16路Status N16路divide(N16路T *remainder ,N16路T *quotient ,N16路T *a ,N16路T *b){
- if(b->d0 == 0) return N16路Status路undefined_divide_by_zero;
-
- uint32_t dividend = a->d0;
- uint32_t divisor = b->d0;
- quotient->d0 = (uint16_t)(dividend / divisor);
- remainder->d0 = (uint16_t)(dividend - (quotient->d0 * divisor));
-
- return N16路Status路ok;
- }
-
- Local N16路Status N16路modulus(N16路T *remainder ,N16路T *a ,N16路T *b){
- if(b->d0 == 0) return N16路Status路undefined_modulus_zero;
- uint32_t dividend = a->d0;
- uint32_t divisor = b->d0;
- uint32_t q = dividend / divisor;
- remainder->d0 = (uint16_t)(dividend - (q * divisor));
- return N16路Status路ok;
- }
-
- // bit motion
-
- typedef uint16_t (*ShiftOp)(uint16_t, uint16_t);
-
- Local uint16_t shift_left_op(uint16_t value, uint16_t amount){
- return value << amount;
- }
-
- Local uint16_t shift_right_op(uint16_t value, uint16_t amount){
- return (uint16_t)(value >> amount);
- }
-
- Local N16路Status N16路shift
- (
- uint16_t shift_count
- ,N16路T *spill
- ,N16路T *operand
- ,N16路T *fill
- ,ShiftOp shift_op
- ,ShiftOp complement_shift_op
- ){
-
- if(operand == NULL && spill == NULL) return N16路Status路ok;
-
- if(operand == NULL){
- operand = &N16路t[0];
- N16路copy(operand, N16路zero);
- }
-
- if(shift_count > 15) return N16路Status路gt_max_shift_count;
-
- N16路T *given_operand = &N16路t[1];
- N16路copy(given_operand, operand);
-
- operand->d0 = shift_op(given_operand->d0, shift_count);
- if(fill != NULL){
- fill->d0 = complement_shift_op(fill->d0, (16 - shift_count));
- N16路bit_or(operand, operand, fill);
- }
- if(spill != NULL){
- spill->d0 = shift_op(spill->d0, shift_count);
- spill->d0 += complement_shift_op(given_operand->d0, (16 - shift_count));
- }
-
- return N16路Status路ok;
- }
-
- Local N16路Status
- N16路shift_left(uint16_t shift_count, N16路T *spill, N16路T *operand, N16路T *fill){
- return N16路shift(shift_count, spill, operand, fill, shift_left_op, shift_right_op);
- }
-
- Local N16路Status
- N16路shift_right(uint16_t shift_count, N16路T *spill, N16路T *operand, N16路T *fill){
- return N16路shift(shift_count, spill, operand, fill, shift_right_op, shift_left_op);
- }
-
- Local N16路Status
- N16路arithmetic_shift_right(uint16_t shift_count, N16路T *operand, N16路T *spill){
-
- if(shift_count > 15) return N16路Status路gt_max_shift_count;
-
- if(operand == NULL){
- operand = &N16路t[0];
- N16路copy(operand, N16路zero);
- }
-
- N16路T *fill = (operand->d0 & 0x8000) ? N16路all_one_bit : N16路zero;
- return N16路shift_right(shift_count, spill, operand, fill);
- }
-
- Local const N16路螞 N16路位 = {
-
- .allocate_array = N16路allocate_array
- ,.allocate_array_zero = N16路allocate_array_zero
- ,.deallocate = N16路deallocate
-
- ,.copy = N16路copy
- ,.bit_and = N16路bit_and
- ,.bit_or = N16路bit_or
- ,.bit_complement = N16路bit_complement
- ,.bit_twos_complement = N16路bit_twos_complement
- ,.compare = N16路compare
- ,.lt = N16路lt
- ,.gt = N16路gt
- ,.eq = N16路eq
- ,.eq_zero = N16路eq_zero
- ,.accumulate = N16路accumulate
- ,.add = N16路add
- ,.increment = N16路increment
- ,.subtract = N16路subtract
- ,.multiply = N16路multiply
- ,.divide = N16路divide
- ,.modulus = N16路modulus
- ,.shift_left = N16路shift_left
- ,.shift_right = N16路shift_right
- ,.arithmetic_shift_right = N16路arithmetic_shift_right
-
- ,.access = N16路access
- ,.from_uint32 = N16路from_uint32
- };
-
- #endif
-
-#endif
--- /dev/null
+/*
+ N16 - a processor native type
+
+ For binary operations: a op b -> c
+
+ See the document on the proper use of the Natural types.
+
+ On the subject of multiple pointers indicating the same location in memory:
+
+ When a routine has multiple results, and one or more of the result location
+ pointers point to the same storage, the routine will either return an error
+ status, or have defined behavior.
+
+ When a routine has multiple operands, in any combination, those
+ pointers can point to the same location, and the routine will
+ function as advertised.
+
+ When an operand functions as both an input and a result, perhaps due
+ to a result pointer pointing to the same place as an operand
+ pointer, the routine will function as advertised. (Internally the
+ routine might make a temporary copy of the operand to accomplish
+ this.)
+*/
+
+#define N16n路DEBUG
+
+#ifndef FACE
+#define N16n路IMPLEMENTATION
+#define FACE
+#endif
+
+//--------------------------------------------------------------------------------
+// Interface
+
+#ifndef N16n路FACE
+#define N16n路FACE
+
+ #include <stdint.h>
+ #include <stdbool.h>
+ #include <stdarg.h>
+ #include <stdlib.h>
+
+ //----------------------------------------
+ // Instance Data (Declaration Only)
+
+ typedef uint16_t Extent;
+ typedef uint16_t Digit;
+
+ typedef struct N16n路T N16n路T;
+
+ extern N16n路T *N16n路zero;
+ extern N16n路T *N16n路one;
+ extern N16n路T *N16n路all_one_bit;
+ extern N16n路T *N16n路lsb;
+ extern N16n路T *N16n路msb;
+
+ //----------------------------------------
+ // Return/Error Status and handlers
+
+ typedef enum{
+ N16n路Status路ok = 0
+ ,N16n路Status路overflow = 1
+ ,N16n路Status路accumulator1_overflow = 2
+ ,N16n路Status路carry = 3
+ ,N16n路Status路borrow = 4
+ ,N16n路Status路undefined_divide_by_zero = 5
+ ,N16n路Status路undefined_modulus_zero = 6
+ ,N16n路Status路gt_max_shift_count = 7
+ ,N16n路Status路spill_eq_operand = 8 // not currently signaled, result will be spill value
+ ,N16n路Status路one_word_product = 9
+ ,N16n路Status路two_word_product = 10
+ } N16n路Status;
+
+ typedef enum{
+ N16n路Order_lt = -1
+ ,N16n路Order_eq = 0
+ ,N16n路Order_gt = 1
+ } N16n路Order;
+
+ typedef N16n路T *( *N16n路Allocate_MemoryFault )(Extent);
+
+ //----------------------------------------
+ // Interface
+
+ typedef struct{
+
+ N16n路T *(*allocate_array_zero)(Extent, N16n路Allocate_MemoryFault);
+ N16n路T *(*allocate_array)(Extent, N16n路Allocate_MemoryFault);
+ void (*deallocate)(N16n路T*);
+
+ void (*copy)(N16n路T*, N16n路T*);
+ void (*bit_and)(N16n路T*, N16n路T*, N16n路T*);
+ void (*bit_or)(N16n路T*, N16n路T*, N16n路T*);
+ void (*bit_complement)(N16n路T*, N16n路T*);
+ void (*bit_twos_complement)(N16n路T*, N16n路T*);
+ N16n路Order (*compare)(N16n路T*, N16n路T*);
+ bool (*lt)(N16n路T*, N16n路T*);
+ bool (*gt)(N16n路T*, N16n路T*);
+ bool (*eq)(N16n路T*, N16n路T*);
+ bool (*eq_zero)(N16n路T*);
+ N16n路Status (*accumulate)(N16n路T *accumulator1 ,N16n路T *accumulator0 ,...);
+ N16n路Status (*add)(N16n路T*, N16n路T*, N16n路T*);
+ bool (*increment)(N16n路T *a);
+ N16n路Status (*subtract)(N16n路T*, N16n路T*, N16n路T*);
+ N16n路Status (*multiply)(N16n路T*, N16n路T*, N16n路T*, N16n路T*);
+ N16n路Status (*divide)(N16n路T*, N16n路T*, N16n路T*, N16n路T*);
+ N16n路Status (*modulus)(N16n路T*, N16n路T*, N16n路T*);
+ N16n路Status (*shift_left)(Extent, N16n路T*, N16n路T*, N16n路T*);
+ N16n路Status (*shift_right)(Extent, N16n路T*, N16n路T*, N16n路T*);
+ N16n路Status (*arithmetic_shift_right)(Extent, N16n路T*, N16n路T*);
+
+ N16n路T* (*access)(N16n路T*, Extent);
+ void (*from_uint32)(N16n路T *destination ,uint32_t value);
+ } N16n路螞;
+
+ Local const N16n路螞 N16n路位; // initialized in the LOCAL section
+
+#endif
+
+//--------------------------------------------------------------------------------
+// Implementation
+
+#ifdef N16n路IMPLEMENTATION
+
+ // this part goes into the library
+ #ifndef LOCAL
+
+ #include <stdarg.h>
+ #include <stdlib.h>
+
+ struct N16n路T{
+ Digit d0;
+ };
+
+ N16n路T N16n路constant[4] = {
+ {.d0 = 0},
+ {.d0 = 1},
+ {.d0 = ~(uint16_t)0},
+ {.d0 = 1 << 15}
+ };
+
+ N16n路T *N16n路zero = &N16n路constant[0];
+ N16n路T *N16n路one = &N16n路constant[1];
+ N16n路T *N16n路all_one_bit = &N16n路constant[2];
+ N16n路T *N16n路msb = &N16n路constant[3];
+ N16n路T *N16n路lsb = &N16n路constant[1];
+
+ // the allocate an array of N16
+ N16n路T *N16n路allocate_array(Extent extent ,N16n路Allocate_MemoryFault memory_fault){
+ N16n路T *instance = malloc((extent + 1) * sizeof(N16n路T));
+ if(!instance){
+ return memory_fault ? memory_fault(extent) : NULL;
+ }
+ return instance;
+ }
+
+ N16n路T *N16n路allocate_array_zero(Extent extent ,N16n路Allocate_MemoryFault memory_fault){
+ N16n路T *instance = calloc(extent + 1, sizeof(N16n路T));
+ if(!instance){
+ return memory_fault ? memory_fault(extent) : NULL;
+ }
+ return instance;
+ }
+
+ void N16n路deallocate(N16n路T *unencumbered){
+ free(unencumbered);
+ }
+
+
+ #endif
+
+ // This part is included after the library user's code
+ #ifdef LOCAL
+
+ // instance
+
+ struct N16n路T{
+ Digit d0;
+ };
+
+ // temporary variables
+ Local N16n路T N16n路t[4];
+
+ // allocation
+
+ extern N16n路T *N16n路allocate_array(Extent, N16n路Allocate_MemoryFault);
+ extern N16n路T *N16n路allocate_array_zero(Extent, N16n路Allocate_MemoryFault);
+ extern void N16n路deallocate(N16n路T *);
+
+ // so the user can access numbers in an array allocation
+ Local N16n路T* N16n路access(N16n路T *array ,Extent index){
+ return &array[index];
+ }
+
+ Local void N16n路from_uint32(N16n路T *destination ,uint32_t value){
+ if(destination == NULL) return;
+ destination->d0 = (uint16_t)(value & 0xFFFF);
+ }
+
+ // copy, convenience copy
+
+ Local void N16n路copy(N16n路T *destination ,N16n路T *source){
+ if(source == destination) return;
+ *destination = *source;
+ }
+
+ Local void N16n路set_to_zero(N16n路T *instance){
+ instance->d0 = 0;
+ }
+
+ Local void N16n路set_to_one(N16n路T *instance){
+ instance->d0 = 1;
+ }
+
+ // bit operations
+
+ Local void N16n路bit_and(N16n路T *result, N16n路T *a, N16n路T *b){
+ result->d0 = a->d0 & b->d0;
+ }
+
+ Local void N16n路bit_or(N16n路T *result, N16n路T *a, N16n路T *b){
+ result->d0 = a->d0 | b->d0;
+ }
+
+ Local void N16n路bit_complement(N16n路T *result, N16n路T *a){
+ result->d0 = ~a->d0;
+ }
+
+ Local void N16n路bit_twos_complement(N16n路T *result ,N16n路T *a){
+ result->d0 = (uint16_t)(~a->d0 + 1);
+ }
+
+ // test functions
+
+ Local N16n路Order N16n路compare(N16n路T *a, N16n路T *b){
+ if(a->d0 < b->d0) return N16n路Order_lt;
+ if(a->d0 > b->d0) return N16n路Order_gt;
+ return N16n路Order_eq;
+ }
+
+ Local bool N16n路lt(N16n路T *a ,N16n路T *b){
+ return a->d0 < b->d0;
+ }
+
+ Local bool N16n路gt(N16n路T *a ,N16n路T *b){
+ return a->d0 > b->d0;
+ }
+
+ Local bool N16n路eq(N16n路T *a ,N16n路T *b){
+ return a->d0 == b->d0;
+ }
+
+ Local bool N16n路eq_zero(N16n路T *a){
+ return a->d0 == 0;
+ }
+
+ // arithmetic operations
+
+ Local N16n路Status N16n路accumulate(N16n路T *accumulator1 ,N16n路T *accumulator0 ,...){
+
+ va_list args;
+ va_start(args ,accumulator0);
+ uint32_t sum = accumulator0->d0;
+ uint32_t carry = 0;
+ N16n路T *current;
+
+ while( (current = va_arg(args ,N16n路T*)) ){
+ sum += current->d0;
+ if(sum < current->d0){
+ (carry)++;
+ if(carry == 0){
+ va_end(args);
+ return N16n路Status路accumulator1_overflow;
+ }
+ }
+ }
+ va_end(args);
+
+ accumulator1->d0 = (uint16_t)carry;
+ return N16n路Status路ok;
+ }
+
+ Local N16n路Status N16n路add(N16n路T *sum ,N16n路T *a ,N16n路T *b){
+ uint32_t result = (uint32_t)a->d0 + (uint32_t)b->d0;
+ sum->d0 = (uint16_t)(result & 0xFFFF);
+ return (result >> 16) ? N16n路Status路carry : N16n路Status路ok;
+ }
+
+ Local bool N16n路increment(N16n路T *a){
+ a->d0++;
+ return (a->d0 == 0);
+ }
+
+ Local N16n路Status N16n路subtract(N16n路T *difference ,N16n路T *a ,N16n路T *b){
+ uint32_t diff = (uint32_t)a->d0 - (uint32_t)b->d0;
+ difference->d0 = (uint16_t)(diff & 0xFFFF);
+ return (diff > a->d0) ? N16n路Status路borrow : N16n路Status路ok;
+ }
+
+ Local N16n路Status N16n路multiply(N16n路T *product1 ,N16n路T *product0 ,N16n路T *a ,N16n路T *b){
+ uint32_t product = (uint32_t)a->d0 * (uint32_t)b->d0;
+ product0->d0 = (uint16_t)(product & 0xFFFF);
+ product1->d0 = (uint16_t)((product >> 16) & 0xFFFF);
+
+ if(product1->d0 == 0) return N16n路Status路one_word_product;
+ return N16n路Status路two_word_product;
+ }
+
+ Local N16n路Status N16n路divide(N16n路T *remainder ,N16n路T *quotient ,N16n路T *a ,N16n路T *b){
+ if(b->d0 == 0) return N16n路Status路undefined_divide_by_zero;
+
+ uint32_t dividend = a->d0;
+ uint32_t divisor = b->d0;
+ quotient->d0 = (uint16_t)(dividend / divisor);
+ remainder->d0 = (uint16_t)(dividend - (quotient->d0 * divisor));
+
+ return N16n路Status路ok;
+ }
+
+ Local N16n路Status N16n路modulus(N16n路T *remainder ,N16n路T *a ,N16n路T *b){
+ if(b->d0 == 0) return N16n路Status路undefined_modulus_zero;
+ uint32_t dividend = a->d0;
+ uint32_t divisor = b->d0;
+ uint32_t q = dividend / divisor;
+ remainder->d0 = (uint16_t)(dividend - (q * divisor));
+ return N16n路Status路ok;
+ }
+
+ // bit motion
+
+ typedef uint16_t (*ShiftOp)(uint16_t, uint16_t);
+
+ Local uint16_t shift_left_op(uint16_t value, uint16_t amount){
+ return value << amount;
+ }
+
+ Local uint16_t shift_right_op(uint16_t value, uint16_t amount){
+ return (uint16_t)(value >> amount);
+ }
+
+ Local N16n路Status N16n路shift
+ (
+ uint16_t shift_count
+ ,N16n路T *spill
+ ,N16n路T *operand
+ ,N16n路T *fill
+ ,ShiftOp shift_op
+ ,ShiftOp complement_shift_op
+ ){
+
+ if(operand == NULL && spill == NULL) return N16n路Status路ok;
+
+ if(operand == NULL){
+ operand = &N16n路t[0];
+ N16n路copy(operand, N16n路zero);
+ }
+
+ if(shift_count > 15) return N16n路Status路gt_max_shift_count;
+
+ N16n路T *given_operand = &N16n路t[1];
+ N16n路copy(given_operand, operand);
+
+ operand->d0 = shift_op(given_operand->d0, shift_count);
+ if(fill != NULL){
+ fill->d0 = complement_shift_op(fill->d0, (16 - shift_count));
+ N16n路bit_or(operand, operand, fill);
+ }
+ if(spill != NULL){
+ spill->d0 = shift_op(spill->d0, shift_count);
+ spill->d0 += complement_shift_op(given_operand->d0, (16 - shift_count));
+ }
+
+ return N16n路Status路ok;
+ }
+
+ Local N16n路Status
+ N16n路shift_left(uint16_t shift_count, N16n路T *spill, N16n路T *operand, N16n路T *fill){
+ return N16n路shift(shift_count, spill, operand, fill, shift_left_op, shift_right_op);
+ }
+
+ Local N16n路Status
+ N16n路shift_right(uint16_t shift_count, N16n路T *spill, N16n路T *operand, N16n路T *fill){
+ return N16n路shift(shift_count, spill, operand, fill, shift_right_op, shift_left_op);
+ }
+
+ Local N16n路Status
+ N16n路arithmetic_shift_right(uint16_t shift_count, N16n路T *operand, N16n路T *spill){
+
+ if(shift_count > 15) return N16n路Status路gt_max_shift_count;
+
+ if(operand == NULL){
+ operand = &N16n路t[0];
+ N16n路copy(operand, N16n路zero);
+ }
+
+ N16n路T *fill = (operand->d0 & 0x8000) ? N16n路all_one_bit : N16n路zero;
+ return N16n路shift_right(shift_count, spill, operand, fill);
+ }
+
+ Local const N16n路螞 N16n路位 = {
+
+ .allocate_array = N16n路allocate_array
+ ,.allocate_array_zero = N16n路allocate_array_zero
+ ,.deallocate = N16n路deallocate
+
+ ,.copy = N16n路copy
+ ,.bit_and = N16n路bit_and
+ ,.bit_or = N16n路bit_or
+ ,.bit_complement = N16n路bit_complement
+ ,.bit_twos_complement = N16n路bit_twos_complement
+ ,.compare = N16n路compare
+ ,.lt = N16n路lt
+ ,.gt = N16n路gt
+ ,.eq = N16n路eq
+ ,.eq_zero = N16n路eq_zero
+ ,.accumulate = N16n路accumulate
+ ,.add = N16n路add
+ ,.increment = N16n路increment
+ ,.subtract = N16n路subtract
+ ,.multiply = N16n路multiply
+ ,.divide = N16n路divide
+ ,.modulus = N16n路modulus
+ ,.shift_left = N16n路shift_left
+ ,.shift_right = N16n路shift_right
+ ,.arithmetic_shift_right = N16n路arithmetic_shift_right
+
+ ,.access = N16n路access
+ ,.from_uint32 = N16n路from_uint32
+ };
+
+ #endif
+
+#endif
+++ /dev/null
-/*
- N32 - a processor native type
-
- For binary operations: a op b -> c
-
- See the document on the proper use of the Natural types.
-
- On the subject of multiple pointers indicating the same location in memory:
-
- When a routine has multiple results, and one or more of the result location
- pointers point to the same storage, the routine will either return an error
- status, or have defined behavior.
-
- When a routine has multiple operands, in any combination, those
- pointers can point to the same location, and the routine will
- function as advertised.
-
- When an operand functions as both an input and a result, perhaps due
- to a result pointer pointing to the same place as an operand
- pointer, the routine will function as advertised. (Internally the
- routine might make a temporary copy of the operand to accomplish
- this.)
-
-*/
-
-#define N32路DEBUG
-
-#ifndef FACE
-#define N32路IMPLEMENTATION
-#define FACE
-#endif
-
-//--------------------------------------------------------------------------------
-// Interface
-
-#ifndef N32路FACE
-#define N32路FACE
-
- #include <stdint.h>
- #include <stdbool.h>
- #include <stdarg.h>
- #include <stdlib.h>
-
- //----------------------------------------
- // Instance Data (Declaration Only)
-
- typedef uint32_t Extent;
- typedef uint32_t Digit;
-
- typedef struct N32路T N32路T;
-
- extern N32路T *N32路zero;
- extern N32路T *N32路one;
- extern N32路T *N32路all_one_bit;
- extern N32路T *N32路lsb;
- extern N32路T *N32路msb;
-
- //----------------------------------------
- // Return/Error Status and handlers
-
- typedef enum{
- N32路Status路ok = 0
- ,N32路Status路overflow = 1
- ,N32路Status路accumulator1_overflow = 2
- ,N32路Status路carry = 3
- ,N32路Status路borrow = 4
- ,N32路Status路undefined_divide_by_zero = 5
- ,N32路Status路undefined_modulus_zero = 6
- ,N32路Status路gt_max_shift_count = 7
- ,N32路Status路spill_eq_operand = 8 // not currently signaled, result will be spill value
- ,N32路Status路one_word_product = 9
- ,N32路Status路two_word_product = 10
- } N32路Status;
-
- typedef enum{
- N32路Order_lt = -1
- ,N32路Order_eq = 0
- ,N32路Order_gt = 1
- } N32路Order;
-
- typedef N32路T *( *N32路Allocate_MemoryFault )(Extent);
-
- //----------------------------------------
- // Interface
-
- typedef struct{
-
- N32路T *(*allocate_array_zero)(Extent, N32路Allocate_MemoryFault);
- N32路T *(*allocate_array)(Extent, N32路Allocate_MemoryFault);
- void (*deallocate)(N32路T*);
-
- void (*copy)(N32路T*, N32路T*);
- void (*bit_and)(N32路T*, N32路T*, N32路T*);
- void (*bit_or)(N32路T*, N32路T*, N32路T*);
- void (*bit_complement)(N32路T*, N32路T*);
- void (*bit_twos_complement)(N32路T*, N32路T*);
- N32路Order (*compare)(N32路T*, N32路T*);
- bool (*lt)(N32路T*, N32路T*);
- bool (*gt)(N32路T*, N32路T*);
- bool (*eq)(N32路T*, N32路T*);
- bool (*eq_zero)(N32路T*);
- N32路Status (*accumulate)(N32路T *accumulator1 ,N32路T *accumulator0 ,...);
- N32路Status (*add)(N32路T*, N32路T*, N32路T*);
- bool (*increment)(N32路T *a);
- N32路Status (*subtract)(N32路T*, N32路T*, N32路T*);
- N32路Status (*multiply)(N32路T*, N32路T*, N32路T*, N32路T*);
- N32路Status (*divide)(N32路T*, N32路T*, N32路T*, N32路T*);
- N32路Status (*modulus)(N32路T*, N32路T*, N32路T*);
- N32路Status (*shift_left)(Extent, N32路T*, N32路T*, N32路T*);
- N32路Status (*shift_right)(Extent, N32路T*, N32路T*, N32路T*);
- N32路Status (*arithmetic_shift_right)(Extent, N32路T*, N32路T*);
-
- N32路T* (*access)(N32路T*, Extent);
- void (*from_uint32)(N32路T *destination ,uint32_t value);
- } N32路螞;
-
- Local const N32路螞 N32路位; // initialized in the LOCAL section
-
-#endif
-
-//--------------------------------------------------------------------------------
-// Implementation
-
-#ifdef N32路IMPLEMENTATION
-
- // this part goes into the library
- #ifndef LOCAL
-
- #include <stdarg.h>
- #include <stdlib.h>
-
- struct N32路T{
- Digit d0;
- };
-
- N32路T N32路constant[4] = {
- {.d0 = 0},
- {.d0 = 1},
- {.d0 = ~(uint32_t)0},
- {.d0 = 1 << 31}
- };
-
- N32路T *N32路zero = &N32路constant[0];
- N32路T *N32路one = &N32路constant[1];
- N32路T *N32路all_one_bit = &N32路constant[2];
- N32路T *N32路msb = &N32路constant[3];
- N32路T *N32路lsb = &N32路constant[1];
-
- // the allocate an array of N32
- N32路T *N32路allocate_array(Extent extent ,N32路Allocate_MemoryFault memory_fault){
- N32路T *instance = malloc((extent + 1) * sizeof(N32路T) );
- if(!instance){
- return memory_fault ? memory_fault(extent) : NULL;
- }
- return instance;
- }
-
- N32路T *N32路allocate_array_zero(Extent extent ,N32路Allocate_MemoryFault memory_fault){
- N32路T *instance = calloc( extent + 1 ,sizeof(N32路T) );
- if(!instance){
- return memory_fault ? memory_fault(extent) : NULL;
- }
- return instance;
- }
-
- void N32路deallocate(N32路T *unencumbered){
- free(unencumbered);
- }
-
- #endif
-
- // This part is included after the library user's code
- #ifdef LOCAL
-
- // instance
-
- struct N32路T{
- Digit d0;
- };
-
- // temporary variables
- // making these LOCAL rather than reserving one block in the library is thread safe
- // allocating a block once is more efficient
- // library code writes these, they are not on the interface
-
- Local N32路T N32路t[4];
-
-
- // allocation
-
- extern N32路T *N32路allocate_array(Extent, N32路Allocate_MemoryFault);
- extern N32路T *N32路allocate_array_zero(Extent, N32路Allocate_MemoryFault);
- extern void N32路deallocate(N32路T *);
-
- // so the user can access numbers in an array allocation
- Local N32路T* N32路access(N32路T *array ,Extent index){
- return &array[index];
- }
-
- Local void N32路from_uint32(N32路T *destination ,uint32_t value){
- if(destination == NULL) return;
- destination->d0 = value;
- }
-
- // copy, convenience copy
-
- Local void N32路copy(N32路T *destination ,N32路T *source){
- if(source == destination) return; // that was easy!
- *destination = *source;
- }
-
- Local void N32路set_to_zero(N32路T *instance){
- instance->d0 = 0;
- }
-
- Local void N32路set_to_one(N32路T *instance){
- instance->d0 = 1;
- }
-
- // bit operations
-
- Local void N32路bit_and(N32路T *result, N32路T *a, N32路T *b){
- result->d0 = a->d0 & b->d0;
- }
-
- // result can be one of the operands
- Local void N32路bit_or(N32路T *result, N32路T *a, N32路T *b){
- result->d0 = a->d0 | b->d0;
- }
-
- // result can the same as the operand
- Local void N32路bit_complement(N32路T *result, N32路T *a){
- result->d0 = ~a->d0;
- }
-
- // result can the same as the operand
- Local void N32路bit_twos_complement(N32路T *result ,N32路T *a){
- result->d0 = ~a->d0 + 1;
- }
-
- // test functions
-
- Local N32路Order N32路compare(N32路T *a, N32路T *b){
- if(a->d0 < b->d0) return N32路Order_lt;
- if(a->d0 > b->d0) return N32路Order_gt;
- return N32路Order_eq;
- }
-
- Local bool N32路lt(N32路T *a ,N32路T *b){
- return a->d0 < b->d0;
- }
-
- Local bool N32路gt(N32路T *a ,N32路T *b){
- return a->d0 > b->d0;
- }
-
- Local bool N32路eq(N32路T *a ,N32路T *b){
- return a->d0 == b->d0;
- }
-
- Local bool N32路eq_zero(N32路T *a){
- return a->d0 == 0;
- }
-
-
- // arithmetic operations
-
- // For a large number of summands for the lower precision Natural implementations, for accumulate/add/sub, the 'overflow' operand could overflow and thus this routine will halt and return N32路Status路accumulator1_overflow
- //
- // When accumulator1 and accumulator0 point to the same location, the result is the accumulator1 value.
- Local N32路Status N32路accumulate(N32路T *accumulator1 ,N32路T *accumulator0 ,...){
-
- va_list args;
- va_start(args ,accumulator0);
- uint32_t sum = accumulator0->d0;
- uint32_t carry = 0;
- N32路T *current;
-
- while( (current = va_arg(args ,N32路T *)) ){
- sum += current->d0;
- if(sum < current->d0){ // Accumulator1 into carry
- (carry)++;
- if(carry == 0){
- va_end(args);
- return N32路Status路accumulator1_overflow;
- }
- }
- }
- va_end(args);
-
- // wipes out prior value of accumulator1
- accumulator1->d0 = carry;
-
- return N32路Status路ok;
- }
-
- Local N32路Status N32路add(N32路T *sum ,N32路T *a ,N32路T *b){
- uint64_t result = (uint64_t)a->d0 + (uint64_t)b->d0;
- sum->d0 = (uint32_t)result;
- return (result >> 32) ? N32路Status路carry : N32路Status路ok;
- }
-
- Local bool N32路increment(N32路T *a){
- a->d0++;
- return a->d0 == 0;
- }
-
- Local N32路Status N32路subtract(N32路T *difference ,N32路T *a ,N32路T *b){
- uint64_t diff = (uint64_t) a->d0 - (uint64_t) b->d0;
- difference->d0 = (uint32_t)diff;
- return (diff > a->d0) ? N32路Status路borrow : N32路Status路ok;
- }
-
-
- Local N32路Status N32路multiply(N32路T *product1 ,N32路T *product0 ,N32路T *a ,N32路T *b){
- uint64_t product = (uint64_t)a->d0 * (uint64_t)b->d0;
- product0->d0 = (uint32_t)product;
- product1->d0 = (uint32_t)(product >> 32);
-
- if(product1->d0 == 0) return N32路Status路one_word_product;
- return N32路Status路two_word_product;
- }
-
- Local N32路Status N32路divide(N32路T *remainder ,N32路T *quotient ,N32路T *a ,N32路T *b){
- if(b->d0 == 0) return N32路Status路undefined_divide_by_zero;
-
- quotient->d0 = a->d0 / b->d0;
- remainder->d0 = a->d0 - (quotient->d0 * b->d0);
-
- return N32路Status路ok;
- }
-
- Local N32路Status N32路modulus(N32路T *remainder ,N32路T *a ,N32路T *b){
- if(b->d0 == 0) return N32路Status路undefined_modulus_zero;
- uint32_t quotient = a->d0 / b->d0;
- remainder->d0 = a->d0 - (quotient * b->d0);
- return N32路Status路ok;
- }
-
- // bit motion
-
- typedef uint32_t (*ShiftOp)(uint32_t, uint32_t);
-
- Local uint32_t shift_left_op(uint32_t value, uint32_t amount){
- return value << amount;
- }
-
- Local uint32_t shift_right_op(uint32_t value, uint32_t amount){
- return value >> amount;
- }
-
- // modifies all three of its operands
- // in the case of duplicate operands this is the order: first modifies operand, then fill, then spill,
- Local N32路Status N32路shift
- (
- uint32_t shift_count
- ,N32路T *spill
- ,N32路T *operand
- ,N32路T *fill
- ,ShiftOp shift_op
- ,ShiftOp complement_shift_op
- ){
-
- // If no result is needed, return immediately.
- if(operand == NULL && spill == NULL) return N32路Status路ok;
-
- // Treat NULL operand as zero.
- if(operand == NULL){
- operand = &N32路t[0];
- N32路copy(operand, N32路zero);
- }
-
- // Shifting more than one word breaks our fill/spill model.
- if(shift_count > 31) return N32路Status路gt_max_shift_count;
-
- // The given operand is still required after it is modified, so we copy it.
- N32路T *given_operand = &N32路t[1];
- N32路copy(given_operand, operand);
-
- // Perform the shift
- operand->d0 = shift_op(given_operand->d0, shift_count);
- if(fill != NULL){
- fill->d0 = complement_shift_op(fill->d0, (32 - shift_count));
- N32路bit_or(operand, operand, fill);
- }
- if(spill != NULL){
- spill->d0 = shift_op(spill->d0, shift_count);
- spill->d0 += complement_shift_op(given_operand->d0, (32 - shift_count));
- }
-
- return N32路Status路ok;
- }
-
- // Define concrete shift functions using valid C function pointers
- Local N32路Status
- N32路shift_left(uint32_t shift_count, N32路T *spill, N32路T *operand, N32路T *fill){
- return N32路shift(shift_count, spill, operand, fill, shift_left_op, shift_right_op);
- }
-
- Local N32路Status
- N32路shift_right(uint32_t shift_count, N32路T *spill, N32路T *operand, N32路T *fill){
- return N32路shift(shift_count, spill, operand, fill, shift_right_op, shift_left_op);
- }
-
- Local N32路Status
- N32路arithmetic_shift_right(uint32_t shift_count, N32路T *operand, N32路T *spill){
-
- // Guard against excessive shift counts
- if(shift_count > 31) return N32路Status路gt_max_shift_count;
-
- // A NULL operand is treated as zero
- if(operand == NULL){
- operand = &N32路t[0];
- N32路copy(operand, N32路zero);
- }
-
- // Pick the fill value based on the sign bit
- N32路T *fill = (operand->d0 & 0x80000000) ? N32路all_one_bit : N32路zero;
-
- // Call shift_right with the appropriate fill
- return N32路shift_right(shift_count, spill, operand, fill);
- }
-
- Local const N32路螞 N32路位 = {
-
- .allocate_array = N32路allocate_array
- ,.allocate_array_zero = N32路allocate_array_zero
- ,.deallocate = N32路deallocate
-
- ,.copy = N32路copy
- ,.bit_and = N32路bit_and
- ,.bit_or = N32路bit_or
- ,.bit_complement = N32路bit_complement
- ,.bit_twos_complement = N32路bit_twos_complement
- ,.compare = N32路compare
- ,.lt = N32路lt
- ,.gt = N32路gt
- ,.eq = N32路eq
- ,.eq_zero = N32路eq_zero
- ,.accumulate = N32路accumulate
- ,.add = N32路add
- ,.increment = N32路increment
- ,.subtract = N32路subtract
- ,.multiply = N32路multiply
- ,.divide = N32路divide
- ,.modulus = N32路modulus
- ,.shift_left = N32路shift_left
- ,.shift_right = N32路shift_right
- ,.arithmetic_shift_right = N32路arithmetic_shift_right
-
- ,.access = N32路access
- ,.from_uint32 = N32路from_uint32
- };
-
- #endif
-
-#endif
--- /dev/null
+/*
+ N32 - a processor native type
+
+ For binary operations: a op b -> c
+
+ See the document on the proper use of the Natural types.
+
+ On the subject of multiple pointers indicating the same location in memory:
+
+ When a routine has multiple results, and one or more of the result location
+ pointers point to the same storage, the routine will either return an error
+ status, or have defined behavior.
+
+ When a routine has multiple operands, in any combination, those
+ pointers can point to the same location, and the routine will
+ function as advertised.
+
+ When an operand functions as both an input and a result, perhaps due
+ to a result pointer pointing to the same place as an operand
+ pointer, the routine will function as advertised. (Internally the
+ routine might make a temporary copy of the operand to accomplish
+ this.)
+
+*/
+
+#define N32n路DEBUG
+
+#ifndef FACE
+#define N32n路IMPLEMENTATION
+#define FACE
+#endif
+
+//--------------------------------------------------------------------------------
+// Interface
+
+#ifndef N32n路FACE
+#define N32n路FACE
+
+ #include <stdint.h>
+ #include <stdbool.h>
+ #include <stdarg.h>
+ #include <stdlib.h>
+
+ //----------------------------------------
+ // Instance Data (Declaration Only)
+
+ typedef uint32_t Extent;
+ typedef uint32_t Digit;
+
+ typedef struct N32n路T N32n路T;
+
+ extern N32n路T *N32n路zero;
+ extern N32n路T *N32n路one;
+ extern N32n路T *N32n路all_one_bit;
+ extern N32n路T *N32n路lsb;
+ extern N32n路T *N32n路msb;
+
+ //----------------------------------------
+ // Return/Error Status and handlers
+
+ typedef enum{
+ N32n路Status路ok = 0
+ ,N32n路Status路overflow = 1
+ ,N32n路Status路accumulator1_overflow = 2
+ ,N32n路Status路carry = 3
+ ,N32n路Status路borrow = 4
+ ,N32n路Status路undefined_divide_by_zero = 5
+ ,N32n路Status路undefined_modulus_zero = 6
+ ,N32n路Status路gt_max_shift_count = 7
+ ,N32n路Status路spill_eq_operand = 8 // not currently signaled, result will be spill value
+ ,N32n路Status路one_word_product = 9
+ ,N32n路Status路two_word_product = 10
+ } N32n路Status;
+
+ typedef enum{
+ N32n路Order_lt = -1
+ ,N32n路Order_eq = 0
+ ,N32n路Order_gt = 1
+ } N32n路Order;
+
+ typedef N32n路T *( *N32n路Allocate_MemoryFault )(Extent);
+
+ //----------------------------------------
+ // Interface
+
+ typedef struct{
+
+ N32n路T *(*allocate_array_zero)(Extent, N32n路Allocate_MemoryFault);
+ N32n路T *(*allocate_array)(Extent, N32n路Allocate_MemoryFault);
+ void (*deallocate)(N32n路T*);
+
+ void (*copy)(N32n路T*, N32n路T*);
+ void (*bit_and)(N32n路T*, N32n路T*, N32n路T*);
+ void (*bit_or)(N32n路T*, N32n路T*, N32n路T*);
+ void (*bit_complement)(N32n路T*, N32n路T*);
+ void (*bit_twos_complement)(N32n路T*, N32n路T*);
+ N32n路Order (*compare)(N32n路T*, N32n路T*);
+ bool (*lt)(N32n路T*, N32n路T*);
+ bool (*gt)(N32n路T*, N32n路T*);
+ bool (*eq)(N32n路T*, N32n路T*);
+ bool (*eq_zero)(N32n路T*);
+ N32n路Status (*accumulate)(N32n路T *accumulator1 ,N32n路T *accumulator0 ,...);
+ N32n路Status (*add)(N32n路T*, N32n路T*, N32n路T*);
+ bool (*increment)(N32n路T *a);
+ N32n路Status (*subtract)(N32n路T*, N32n路T*, N32n路T*);
+ N32n路Status (*multiply)(N32n路T*, N32n路T*, N32n路T*, N32n路T*);
+ N32n路Status (*divide)(N32n路T*, N32n路T*, N32n路T*, N32n路T*);
+ N32n路Status (*modulus)(N32n路T*, N32n路T*, N32n路T*);
+ N32n路Status (*shift_left)(Extent, N32n路T*, N32n路T*, N32n路T*);
+ N32n路Status (*shift_right)(Extent, N32n路T*, N32n路T*, N32n路T*);
+ N32n路Status (*arithmetic_shift_right)(Extent, N32n路T*, N32n路T*);
+
+ N32n路T* (*access)(N32n路T*, Extent);
+ void (*from_uint32)(N32n路T *destination ,uint32_t value);
+ } N32n路螞;
+
+ Local const N32n路螞 N32n路位; // initialized in the LOCAL section
+
+#endif
+
+//--------------------------------------------------------------------------------
+// Implementation
+
+#ifdef N32n路IMPLEMENTATION
+
+ // this part goes into the library
+ #ifndef LOCAL
+
+ #include <stdarg.h>
+ #include <stdlib.h>
+
+ struct N32n路T{
+ Digit d0;
+ };
+
+ N32n路T N32n路constant[4] = {
+ {.d0 = 0},
+ {.d0 = 1},
+ {.d0 = ~(uint32_t)0},
+ {.d0 = 1 << 31}
+ };
+
+ N32n路T *N32n路zero = &N32n路constant[0];
+ N32n路T *N32n路one = &N32n路constant[1];
+ N32n路T *N32n路all_one_bit = &N32n路constant[2];
+ N32n路T *N32n路msb = &N32n路constant[3];
+ N32n路T *N32n路lsb = &N32n路constant[1];
+
+ // the allocate an array of N32
+ N32n路T *N32n路allocate_array(Extent extent ,N32n路Allocate_MemoryFault memory_fault){
+ N32n路T *instance = malloc((extent + 1) * sizeof(N32n路T) );
+ if(!instance){
+ return memory_fault ? memory_fault(extent) : NULL;
+ }
+ return instance;
+ }
+
+ N32n路T *N32n路allocate_array_zero(Extent extent ,N32n路Allocate_MemoryFault memory_fault){
+ N32n路T *instance = calloc( extent + 1 ,sizeof(N32n路T) );
+ if(!instance){
+ return memory_fault ? memory_fault(extent) : NULL;
+ }
+ return instance;
+ }
+
+ void N32n路deallocate(N32n路T *unencumbered){
+ free(unencumbered);
+ }
+
+ #endif
+
+ // This part is included after the library user's code
+ #ifdef LOCAL
+
+ // instance
+
+ struct N32n路T{
+ Digit d0;
+ };
+
+ // temporary variables
+ // making these LOCAL rather than reserving one block in the library is thread safe
+ // allocating a block once is more efficient
+ // library code writes these, they are not on the interface
+
+ Local N32n路T N32n路t[4];
+
+
+ // allocation
+
+ extern N32n路T *N32n路allocate_array(Extent, N32n路Allocate_MemoryFault);
+ extern N32n路T *N32n路allocate_array_zero(Extent, N32n路Allocate_MemoryFault);
+ extern void N32n路deallocate(N32n路T *);
+
+ // so the user can access numbers in an array allocation
+ Local N32n路T* N32n路access(N32n路T *array ,Extent index){
+ return &array[index];
+ }
+
+ Local void N32n路from_uint32(N32n路T *destination ,uint32_t value){
+ if(destination == NULL) return;
+ destination->d0 = value;
+ }
+
+ // copy, convenience copy
+
+ Local void N32n路copy(N32n路T *destination ,N32n路T *source){
+ if(source == destination) return; // that was easy!
+ *destination = *source;
+ }
+
+ Local void N32n路set_to_zero(N32n路T *instance){
+ instance->d0 = 0;
+ }
+
+ Local void N32n路set_to_one(N32n路T *instance){
+ instance->d0 = 1;
+ }
+
+ // bit operations
+
+ Local void N32n路bit_and(N32n路T *result, N32n路T *a, N32n路T *b){
+ result->d0 = a->d0 & b->d0;
+ }
+
+ // result can be one of the operands
+ Local void N32n路bit_or(N32n路T *result, N32n路T *a, N32n路T *b){
+ result->d0 = a->d0 | b->d0;
+ }
+
+ // result can the same as the operand
+ Local void N32n路bit_complement(N32n路T *result, N32n路T *a){
+ result->d0 = ~a->d0;
+ }
+
+ // result can the same as the operand
+ Local void N32n路bit_twos_complement(N32n路T *result ,N32n路T *a){
+ result->d0 = ~a->d0 + 1;
+ }
+
+ // test functions
+
+ Local N32n路Order N32n路compare(N32n路T *a, N32n路T *b){
+ if(a->d0 < b->d0) return N32n路Order_lt;
+ if(a->d0 > b->d0) return N32n路Order_gt;
+ return N32n路Order_eq;
+ }
+
+ Local bool N32n路lt(N32n路T *a ,N32n路T *b){
+ return a->d0 < b->d0;
+ }
+
+ Local bool N32n路gt(N32n路T *a ,N32n路T *b){
+ return a->d0 > b->d0;
+ }
+
+ Local bool N32n路eq(N32n路T *a ,N32n路T *b){
+ return a->d0 == b->d0;
+ }
+
+ Local bool N32n路eq_zero(N32n路T *a){
+ return a->d0 == 0;
+ }
+
+
+ // arithmetic operations
+
+ // For a large number of summands for the lower precision Natural implementations, for accumulate/add/sub, the 'overflow' operand could overflow and thus this routine will halt and return N32n路Status路accumulator1_overflow
+ //
+ // When accumulator1 and accumulator0 point to the same location, the result is the accumulator1 value.
+ Local N32n路Status N32n路accumulate(N32n路T *accumulator1 ,N32n路T *accumulator0 ,...){
+
+ va_list args;
+ va_start(args ,accumulator0);
+ uint32_t sum = accumulator0->d0;
+ uint32_t carry = 0;
+ N32n路T *current;
+
+ while( (current = va_arg(args ,N32n路T *)) ){
+ sum += current->d0;
+ if(sum < current->d0){ // Accumulator1 into carry
+ (carry)++;
+ if(carry == 0){
+ va_end(args);
+ return N32n路Status路accumulator1_overflow;
+ }
+ }
+ }
+ va_end(args);
+
+ // wipes out prior value of accumulator1
+ accumulator1->d0 = carry;
+
+ return N32n路Status路ok;
+ }
+
+ Local N32n路Status N32n路add(N32n路T *sum ,N32n路T *a ,N32n路T *b){
+ uint64_t result = (uint64_t)a->d0 + (uint64_t)b->d0;
+ sum->d0 = (uint32_t)result;
+ return (result >> 32) ? N32n路Status路carry : N32n路Status路ok;
+ }
+
+ Local bool N32n路increment(N32n路T *a){
+ a->d0++;
+ return a->d0 == 0;
+ }
+
+ Local N32n路Status N32n路subtract(N32n路T *difference ,N32n路T *a ,N32n路T *b){
+ uint64_t diff = (uint64_t) a->d0 - (uint64_t) b->d0;
+ difference->d0 = (uint32_t)diff;
+ return (diff > a->d0) ? N32n路Status路borrow : N32n路Status路ok;
+ }
+
+
+ Local N32n路Status N32n路multiply(N32n路T *product1 ,N32n路T *product0 ,N32n路T *a ,N32n路T *b){
+ uint64_t product = (uint64_t)a->d0 * (uint64_t)b->d0;
+ product0->d0 = (uint32_t)product;
+ product1->d0 = (uint32_t)(product >> 32);
+
+ if(product1->d0 == 0) return N32n路Status路one_word_product;
+ return N32n路Status路two_word_product;
+ }
+
+ Local N32n路Status N32n路divide(N32n路T *remainder ,N32n路T *quotient ,N32n路T *a ,N32n路T *b){
+ if(b->d0 == 0) return N32n路Status路undefined_divide_by_zero;
+
+ quotient->d0 = a->d0 / b->d0;
+ remainder->d0 = a->d0 - (quotient->d0 * b->d0);
+
+ return N32n路Status路ok;
+ }
+
+ Local N32n路Status N32n路modulus(N32n路T *remainder ,N32n路T *a ,N32n路T *b){
+ if(b->d0 == 0) return N32n路Status路undefined_modulus_zero;
+ uint32_t quotient = a->d0 / b->d0;
+ remainder->d0 = a->d0 - (quotient * b->d0);
+ return N32n路Status路ok;
+ }
+
+ // bit motion
+
+ typedef uint32_t (*ShiftOp)(uint32_t, uint32_t);
+
+ Local uint32_t shift_left_op(uint32_t value, uint32_t amount){
+ return value << amount;
+ }
+
+ Local uint32_t shift_right_op(uint32_t value, uint32_t amount){
+ return value >> amount;
+ }
+
+ // modifies all three of its operands
+ // in the case of duplicate operands this is the order: first modifies operand, then fill, then spill,
+ Local N32n路Status N32n路shift
+ (
+ uint32_t shift_count
+ ,N32n路T *spill
+ ,N32n路T *operand
+ ,N32n路T *fill
+ ,ShiftOp shift_op
+ ,ShiftOp complement_shift_op
+ ){
+
+ // If no result is needed, return immediately.
+ if(operand == NULL && spill == NULL) return N32n路Status路ok;
+
+ // Treat NULL operand as zero.
+ if(operand == NULL){
+ operand = &N32n路t[0];
+ N32n路copy(operand, N32n路zero);
+ }
+
+ // Shifting more than one word breaks our fill/spill model.
+ if(shift_count > 31) return N32n路Status路gt_max_shift_count;
+
+ // The given operand is still required after it is modified, so we copy it.
+ N32n路T *given_operand = &N32n路t[1];
+ N32n路copy(given_operand, operand);
+
+ // Perform the shift
+ operand->d0 = shift_op(given_operand->d0, shift_count);
+ if(fill != NULL){
+ fill->d0 = complement_shift_op(fill->d0, (32 - shift_count));
+ N32n路bit_or(operand, operand, fill);
+ }
+ if(spill != NULL){
+ spill->d0 = shift_op(spill->d0, shift_count);
+ spill->d0 += complement_shift_op(given_operand->d0, (32 - shift_count));
+ }
+
+ return N32n路Status路ok;
+ }
+
+ // Define concrete shift functions using valid C function pointers
+ Local N32n路Status
+ N32n路shift_left(uint32_t shift_count, N32n路T *spill, N32n路T *operand, N32n路T *fill){
+ return N32n路shift(shift_count, spill, operand, fill, shift_left_op, shift_right_op);
+ }
+
+ Local N32n路Status
+ N32n路shift_right(uint32_t shift_count, N32n路T *spill, N32n路T *operand, N32n路T *fill){
+ return N32n路shift(shift_count, spill, operand, fill, shift_right_op, shift_left_op);
+ }
+
+ Local N32n路Status
+ N32n路arithmetic_shift_right(uint32_t shift_count, N32n路T *operand, N32n路T *spill){
+
+ // Guard against excessive shift counts
+ if(shift_count > 31) return N32n路Status路gt_max_shift_count;
+
+ // A NULL operand is treated as zero
+ if(operand == NULL){
+ operand = &N32n路t[0];
+ N32n路copy(operand, N32n路zero);
+ }
+
+ // Pick the fill value based on the sign bit
+ N32n路T *fill = (operand->d0 & 0x80000000) ? N32n路all_one_bit : N32n路zero;
+
+ // Call shift_right with the appropriate fill
+ return N32n路shift_right(shift_count, spill, operand, fill);
+ }
+
+ Local const N32n路螞 N32n路位 = {
+
+ .allocate_array = N32n路allocate_array
+ ,.allocate_array_zero = N32n路allocate_array_zero
+ ,.deallocate = N32n路deallocate
+
+ ,.copy = N32n路copy
+ ,.bit_and = N32n路bit_and
+ ,.bit_or = N32n路bit_or
+ ,.bit_complement = N32n路bit_complement
+ ,.bit_twos_complement = N32n路bit_twos_complement
+ ,.compare = N32n路compare
+ ,.lt = N32n路lt
+ ,.gt = N32n路gt
+ ,.eq = N32n路eq
+ ,.eq_zero = N32n路eq_zero
+ ,.accumulate = N32n路accumulate
+ ,.add = N32n路add
+ ,.increment = N32n路increment
+ ,.subtract = N32n路subtract
+ ,.multiply = N32n路multiply
+ ,.divide = N32n路divide
+ ,.modulus = N32n路modulus
+ ,.shift_left = N32n路shift_left
+ ,.shift_right = N32n路shift_right
+ ,.arithmetic_shift_right = N32n路arithmetic_shift_right
+
+ ,.access = N32n路access
+ ,.from_uint32 = N32n路from_uint32
+ };
+
+ #endif
+
+#endif
+++ /dev/null
-/*
- N64 - a 64-bit native type
-
- For binary operations: a op b -> c
-
- Similar to N32, but now each Digit is 64 bits. Where a 128-bit
- intermediate is necessary (e.g. multiplication), we handle it
- manually using two 64-bit parts.
-
- On the subject of multiple pointers indicating the same location in memory:
-
- When a routine has multiple results, and one or more of the result location
- pointers point to the same storage, the routine will either return an error
- status, or have defined behavior.
-
- When a routine has multiple operands, in any combination, those
- pointers can point to the same location, and the routine will
- function as advertised.
-
- When an operand functions as both an input and a result, perhaps due
- to a result pointer pointing to the same place as an operand
- pointer, the routine will function as advertised. (Internally the
- routine might make a temporary copy of the operand to accomplish
- this.)
-*/
-
-#define N64路DEBUG
-
-#ifndef FACE
-#define N64路IMPLEMENTATION
-#define FACE
-#endif
-
-//--------------------------------------------------------------------------------
-// Interface
-
-#ifndef N64路FACE
-#define N64路FACE
-
- #include <stdint.h>
- #include <stdbool.h>
- #include <stdarg.h>
- #include <stdlib.h>
-
- //----------------------------------------
- // Instance Data (Declaration Only)
-
- typedef uint64_t Extent;
- typedef uint64_t Digit;
-
- typedef struct N64路T N64路T;
-
- extern N64路T *N64路zero;
- extern N64路T *N64路one;
- extern N64路T *N64路all_one_bit;
- extern N64路T *N64路lsb;
- extern N64路T *N64路msb;
-
- //----------------------------------------
- // Return/Error Status and handlers
-
- typedef enum {
- N64路Status路ok = 0
- ,N64路Status路overflow = 1
- ,N64路Status路accumulator1_overflow = 2
- ,N64路Status路carry = 3
- ,N64路Status路borrow = 4
- ,N64路Status路undefined_divide_by_zero = 5
- ,N64路Status路undefined_modulus_zero = 6
- ,N64路Status路gt_max_shift_count = 7
- ,N64路Status路spill_eq_operand = 8 // not currently signaled, result will be spill value
- ,N64路Status路one_word_product = 9
- ,N64路Status路two_word_product = 10
- } N64路Status;
-
- typedef enum {
- N64路Order_lt = -1
- ,N64路Order_eq = 0
- ,N64路Order_gt = 1
- } N64路Order;
-
- typedef N64路T *(*N64路Allocate_MemoryFault)(Extent);
-
- //----------------------------------------
- // Interface
-
- typedef struct {
-
- N64路T *(*allocate_array_zero)(Extent, N64路Allocate_MemoryFault);
- N64路T *(*allocate_array)(Extent, N64路Allocate_MemoryFault);
- void (*deallocate)(N64路T*);
-
- void (*copy)(N64路T*, N64路T*);
- void (*bit_and)(N64路T*, N64路T*, N64路T*);
- void (*bit_or)(N64路T*, N64路T*, N64路T*);
- void (*bit_complement)(N64路T*, N64路T*);
- void (*bit_twos_complement)(N64路T*, N64路T*);
- N64路Order (*compare)(N64路T*, N64路T*);
- bool (*lt)(N64路T*, N64路T*);
- bool (*gt)(N64路T*, N64路T*);
- bool (*eq)(N64路T*, N64路T*);
- bool (*eq_zero)(N64路T*);
- N64路Status (*accumulate)(N64路T *accumulator1, N64路T *accumulator0, ...);
- N64路Status (*add)(N64路T*, N64路T*, N64路T*);
- bool (*increment)(N64路T *a);
- N64路Status (*subtract)(N64路T*, N64路T*, N64路T*);
- N64路Status (*multiply)(N64路T*, N64路T*, N64路T*, N64路T*);
- N64路Status (*divide)(N64路T*, N64路T*, N64路T*, N64路T*);
- N64路Status (*modulus)(N64路T*, N64路T*, N64路T*);
- N64路Status (*shift_left)(Extent, N64路T*, N64路T*, N64路T*);
- N64路Status (*shift_right)(Extent, N64路T*, N64路T*, N64路T*);
- N64路Status (*arithmetic_shift_right)(Extent, N64路T*, N64路T*);
-
- N64路T* (*access)(N64路T*, Extent);
- void (*from_uint64)(N64路T *destination, uint64_t value);
-
- } N64路螞;
-
- Local const N64路螞 N64路位; // initialized in the LOCAL section
-
-#endif
-
-//--------------------------------------------------------------------------------
-// Implementation
-
-#ifdef N64路IMPLEMENTATION
-
- // this part goes into the library
- #ifndef LOCAL
-
- #include <stdarg.h>
- #include <stdlib.h>
-
- struct N64路T {
- Digit d0;
- };
-
- // For constants, we store them in an array for convenience
- // 0, 1, all bits set (~0ULL), and MSB set (1ULL<<63)
- N64路T N64路constant[4] = {
- {.d0 = 0ULL},
- {.d0 = 1ULL},
- {.d0 = ~(uint64_t)0ULL},
- {.d0 = 1ULL << 63}
- };
-
- N64路T *N64路zero = &N64路constant[0];
- N64路T *N64路one = &N64路constant[1];
- N64路T *N64路all_one_bit = &N64路constant[2];
- N64路T *N64路msb = &N64路constant[3];
- N64路T *N64路lsb = &N64路constant[1];
-
- // allocate an array of N64
- N64路T *N64路allocate_array(Extent extent, N64路Allocate_MemoryFault memory_fault){
- N64路T *instance = malloc( (extent + 1) * sizeof(N64路T) );
- if(!instance){
- return memory_fault ? memory_fault(extent) : NULL;
- }
- return instance;
- }
-
- N64路T *N64路allocate_array_zero(Extent extent, N64路Allocate_MemoryFault memory_fault){
- N64路T *instance = calloc(extent + 1, sizeof(N64路T));
- if(!instance){
- return memory_fault ? memory_fault(extent) : NULL;
- }
- return instance;
- }
-
- void N64路deallocate(N64路T *unencumbered){
- free(unencumbered);
- }
-
- #endif
-
- // This part is included after the library user's code
- #ifdef LOCAL
-
- // instance
-
- struct N64路T {
- Digit d0;
- };
-
- // local temporary variables
- Local N64路T N64路t[4];
-
- // allocation references
- extern N64路T *N64路allocate_array(Extent, N64路Allocate_MemoryFault);
- extern N64路T *N64路allocate_array_zero(Extent, N64路Allocate_MemoryFault);
- extern void N64路deallocate(N64路T *);
-
- // Access array
- Local N64路T* N64路access(N64路T *array, Extent index){
- return &array[index];
- }
-
- Local void N64路from_uint64(N64路T *destination, uint64_t value){
- if(destination == NULL) return;
- destination->d0 = value;
- }
-
- // copy
- Local void N64路copy(N64路T *destination, N64路T *source){
- if(source == destination) return;
- *destination = *source;
- }
-
- // bit operations
-
- Local void N64路bit_and(N64路T *result, N64路T *a, N64路T *b){
- result->d0 = a->d0 & b->d0;
- }
-
- Local void N64路bit_or(N64路T *result, N64路T *a, N64路T *b){
- result->d0 = a->d0 | b->d0;
- }
-
- Local void N64路bit_complement(N64路T *result, N64路T *a){
- result->d0 = ~a->d0;
- }
-
- Local void N64路bit_twos_complement(N64路T *result, N64路T *a){
- result->d0 = ~a->d0 + 1ULL;
- }
-
- // compare & test functions
-
- Local N64路Order N64路compare(N64路T *a, N64路T *b){
- if(a->d0 < b->d0) return N64路Order_lt;
- if(a->d0 > b->d0) return N64路Order_gt;
- return N64路Order_eq;
- }
-
- Local bool N64路lt(N64路T *a, N64路T *b){
- return (a->d0 < b->d0);
- }
-
- Local bool N64路gt(N64路T *a, N64路T *b){
- return (a->d0 > b->d0);
- }
-
- Local bool N64路eq(N64路T *a, N64路T *b){
- return (a->d0 == b->d0);
- }
-
- Local bool N64路eq_zero(N64路T *a){
- return (a->d0 == 0ULL);
- }
-
- // arithmetic operations
-
- // accumulate
- Local N64路Status N64路accumulate(N64路T *accumulator1, N64路T *accumulator0, ...){
- va_list args;
- va_start(args, accumulator0);
-
- uint64_t sum = accumulator0->d0;
- uint64_t carry = 0;
- N64路T *current;
-
- while( (current = va_arg(args, N64路T*)) ){
- uint64_t prior = sum;
- sum += current->d0;
- if(sum < prior){ // indicates carry
- carry++;
- // if carry overflowed a 64-bit, that's an accumulator1 overflow
- if(carry == 0ULL){
- va_end(args);
- return N64路Status路accumulator1_overflow;
- }
- }
- }
- va_end(args);
-
- accumulator1->d0 = carry;
- return N64路Status路ok;
- }
-
- // add
- Local N64路Status N64路add(N64路T *sum, N64路T *a, N64路T *b){
- __uint128_t result = ( __uint128_t )a->d0 + ( __uint128_t )b->d0;
- // But to avoid using a GNU extension, we can do the simpler approach:
- // Actually let's do it directly with 64-bit since we only need to detect carry out of 64 bits:
- uint64_t temp = a->d0 + b->d0;
- sum->d0 = temp;
- if(temp < a->d0) return N64路Status路carry; // means we overflowed
- return N64路Status路ok;
- }
-
- Local bool N64路increment(N64路T *a){
- uint64_t old = a->d0;
- a->d0++;
- // if it wrapped around to 0, then it was 0xFFFFFFFFFFFFFFFF
- return (a->d0 < old);
- }
-
- // subtract
- Local N64路Status N64路subtract(N64路T *difference, N64路T *a, N64路T *b){
- uint64_t tmpA = a->d0;
- uint64_t tmpB = b->d0;
- uint64_t diff = tmpA - tmpB;
- difference->d0 = diff;
- if(diff > tmpA) return N64路Status路borrow; // indicates we borrowed
- return N64路Status路ok;
- }
-
- // multiply
- // We'll do a 64x64->128 using two 64-bit accumulators
- Local N64路Status N64路multiply(N64路T *product1, N64路T *product0, N64路T *a, N64路T *b){
- uint64_t A = a->d0;
- uint64_t B = b->d0;
-
- // Break each operand into high & low 32 bits
- uint64_t a_lo = (uint32_t)(A & 0xffffffffULL);
- uint64_t a_hi = A >> 32;
- uint64_t b_lo = (uint32_t)(B & 0xffffffffULL);
- uint64_t b_hi = B >> 32;
-
- // partial products
- uint64_t low = a_lo * b_lo; // 64-bit
- uint64_t cross = (a_lo * b_hi) + (a_hi * b_lo); // potentially up to 2 * 32 bits => 64 bits
- uint64_t high = a_hi * b_hi; // up to 64 bits
-
- // incorporate cross into low, high
- // cross is effectively the middle bits, so shift cross by 32 and add to low
- uint64_t cross_low = (cross & 0xffffffffULL) << 32; // lower part
- uint64_t cross_high = cross >> 32; // upper part
-
- // add cross_low to low, capture carry
- uint64_t old_low = low;
- low += cross_low;
- if(low < old_low) cross_high++;
-
- // final high
- high += cross_high;
-
- // store results
- product0->d0 = low;
- product1->d0 = high;
-
- if(high == 0ULL) return N64路Status路one_word_product;
- return N64路Status路two_word_product;
- }
-
- // divide
- Local N64路Status N64路divide(N64路T *remainder, N64路T *quotient, N64路T *a, N64路T *b){
- // we do not handle a > 64-bit, just the single 64-bit
- if(b->d0 == 0ULL) return N64路Status路undefined_divide_by_zero;
-
- uint64_t divd = a->d0; // dividend
- uint64_t divs = b->d0; // divisor
-
- quotient->d0 = divd / divs;
- remainder->d0 = divd - (quotient->d0 * divs);
-
- return N64路Status路ok;
- }
-
- // modulus
- Local N64路Status N64路modulus(N64路T *remainder, N64路T *a, N64路T *b){
- if(b->d0 == 0ULL) return N64路Status路undefined_modulus_zero;
-
- uint64_t divd = a->d0;
- uint64_t divs = b->d0;
- uint64_t q = divd / divs;
- remainder->d0 = divd - (q * divs);
-
- return N64路Status路ok;
- }
-
- // bit motion
-
- typedef uint64_t (*ShiftOp)(uint64_t, uint64_t);
-
- Local uint64_t shift_left_op(uint64_t value, uint64_t amount){
- return (value << amount);
- }
-
- Local uint64_t shift_right_op(uint64_t value, uint64_t amount){
- return (value >> amount);
- }
-
- // modifies all three of its operands
- // in the case of duplicate operands this is the order: first modifies operand, then fill, then spill
- Local N64路Status N64路shift
- (
- uint64_t shift_count,
- N64路T *spill,
- N64路T *operand,
- N64路T *fill,
- ShiftOp shift_op,
- ShiftOp complement_shift_op
- ){
- if(operand == NULL && spill == NULL) return N64路Status路ok;
-
- // Treat NULL operand as zero
- if(operand == NULL){
- operand = &N64路t[0];
- N64路copy(operand, N64路zero);
- }
-
- // Shifting more than 63 bits breaks fill/spill logic
- if(shift_count > 63ULL) return N64路Status路gt_max_shift_count;
-
- N64路T *given_operand = &N64路t[1];
- N64路copy(given_operand, operand);
-
- // Perform the shift
- operand->d0 = shift_op(given_operand->d0, shift_count);
- if(fill != NULL){
- fill->d0 = complement_shift_op(fill->d0, (64ULL - shift_count));
- N64路bit_or(operand, operand, fill);
- }
- if(spill != NULL){
- spill->d0 = shift_op(spill->d0, shift_count);
- spill->d0 += complement_shift_op(given_operand->d0, (64ULL - shift_count));
- }
-
- return N64路Status路ok;
- }
-
- Local N64路Status N64路shift_left(uint64_t shift_count, N64路T *spill, N64路T *operand, N64路T *fill){
- return N64路shift(shift_count, spill, operand, fill, shift_left_op, shift_right_op);
- }
-
- Local N64路Status N64路shift_right(uint64_t shift_count, N64路T *spill, N64路T *operand, N64路T *fill){
- return N64路shift(shift_count, spill, operand, fill, shift_right_op, shift_left_op);
- }
-
- Local N64路Status N64路arithmetic_shift_right(uint64_t shift_count, N64路T *operand, N64路T *spill){
- if(shift_count > 63ULL) return N64路Status路gt_max_shift_count;
-
- // A NULL operand is treated as zero
- if(operand == NULL){
- operand = &N64路t[0];
- N64路copy(operand, N64路zero);
- }
-
- // sign bit check
- N64路T *fill = (operand->d0 & (1ULL << 63)) ? N64路all_one_bit : N64路zero;
- return N64路shift_right(shift_count, spill, operand, fill);
- }
-
- Local const N64路螞 N64路位 = {
- .allocate_array = N64路allocate_array
- ,.allocate_array_zero = N64路allocate_array_zero
- ,.deallocate = N64路deallocate
-
- ,.copy = N64路copy
- ,.bit_and = N64路bit_and
- ,.bit_or = N64路bit_or
- ,.bit_complement = N64路bit_complement
- ,.bit_twos_complement = N64路bit_twos_complement
- ,.compare = N64路compare
- ,.lt = N64路lt
- ,.gt = N64路gt
- ,.eq = N64路eq
- ,.eq_zero = N64路eq_zero
- ,.accumulate = N64路accumulate
- ,.add = N64路add
- ,.increment = N64路increment
- ,.subtract = N64路subtract
- ,.multiply = N64路multiply
- ,.divide = N64路divide
- ,.modulus = N64路modulus
- ,.shift_left = N64路shift_left
- ,.shift_right = N64路shift_right
- ,.arithmetic_shift_right = N64路arithmetic_shift_right
-
- ,.access = N64路access
- ,.from_uint64 = N64路from_uint64
- };
-
- #endif
-
-#endif
--- /dev/null
+/*
+ N64 - a 64-bit native type
+
+ For binary operations: a op b -> c
+
+ Similar to N32, but now each Digit is 64 bits. Where a 128-bit
+ intermediate is necessary (e.g. multiplication), we handle it
+ manually using two 64-bit parts.
+
+ On the subject of multiple pointers indicating the same location in memory:
+
+ When a routine has multiple results, and one or more of the result location
+ pointers point to the same storage, the routine will either return an error
+ status, or have defined behavior.
+
+ When a routine has multiple operands, in any combination, those
+ pointers can point to the same location, and the routine will
+ function as advertised.
+
+ When an operand functions as both an input and a result, perhaps due
+ to a result pointer pointing to the same place as an operand
+ pointer, the routine will function as advertised. (Internally the
+ routine might make a temporary copy of the operand to accomplish
+ this.)
+*/
+
+#define N64n路DEBUG
+
+#ifndef FACE
+#define N64n路IMPLEMENTATION
+#define FACE
+#endif
+
+//--------------------------------------------------------------------------------
+// Interface
+
+#ifndef N64n路FACE
+#define N64n路FACE
+
+ #include <stdint.h>
+ #include <stdbool.h>
+ #include <stdarg.h>
+ #include <stdlib.h>
+
+ //----------------------------------------
+ // Instance Data (Declaration Only)
+
+ typedef uint64_t Extent;
+ typedef uint64_t Digit;
+
+ typedef struct N64n路T N64n路T;
+
+ extern N64n路T *N64n路zero;
+ extern N64n路T *N64n路one;
+ extern N64n路T *N64n路all_one_bit;
+ extern N64n路T *N64n路lsb;
+ extern N64n路T *N64n路msb;
+
+ //----------------------------------------
+ // Return/Error Status and handlers
+
+ typedef enum {
+ N64n路Status路ok = 0
+ ,N64n路Status路overflow = 1
+ ,N64n路Status路accumulator1_overflow = 2
+ ,N64n路Status路carry = 3
+ ,N64n路Status路borrow = 4
+ ,N64n路Status路undefined_divide_by_zero = 5
+ ,N64n路Status路undefined_modulus_zero = 6
+ ,N64n路Status路gt_max_shift_count = 7
+ ,N64n路Status路spill_eq_operand = 8 // not currently signaled, result will be spill value
+ ,N64n路Status路one_word_product = 9
+ ,N64n路Status路two_word_product = 10
+ } N64n路Status;
+
+ typedef enum {
+ N64n路Order_lt = -1
+ ,N64n路Order_eq = 0
+ ,N64n路Order_gt = 1
+ } N64n路Order;
+
+ typedef N64n路T *(*N64n路Allocate_MemoryFault)(Extent);
+
+ //----------------------------------------
+ // Interface
+
+ typedef struct {
+
+ N64n路T *(*allocate_array_zero)(Extent, N64n路Allocate_MemoryFault);
+ N64n路T *(*allocate_array)(Extent, N64n路Allocate_MemoryFault);
+ void (*deallocate)(N64n路T*);
+
+ void (*copy)(N64n路T*, N64n路T*);
+ void (*bit_and)(N64n路T*, N64n路T*, N64n路T*);
+ void (*bit_or)(N64n路T*, N64n路T*, N64n路T*);
+ void (*bit_complement)(N64n路T*, N64n路T*);
+ void (*bit_twos_complement)(N64n路T*, N64n路T*);
+ N64n路Order (*compare)(N64n路T*, N64n路T*);
+ bool (*lt)(N64n路T*, N64n路T*);
+ bool (*gt)(N64n路T*, N64n路T*);
+ bool (*eq)(N64n路T*, N64n路T*);
+ bool (*eq_zero)(N64n路T*);
+ N64n路Status (*accumulate)(N64n路T *accumulator1, N64n路T *accumulator0, ...);
+ N64n路Status (*add)(N64n路T*, N64n路T*, N64n路T*);
+ bool (*increment)(N64n路T *a);
+ N64n路Status (*subtract)(N64n路T*, N64n路T*, N64n路T*);
+ N64n路Status (*multiply)(N64n路T*, N64n路T*, N64n路T*, N64n路T*);
+ N64n路Status (*divide)(N64n路T*, N64n路T*, N64n路T*, N64n路T*);
+ N64n路Status (*modulus)(N64n路T*, N64n路T*, N64n路T*);
+ N64n路Status (*shift_left)(Extent, N64n路T*, N64n路T*, N64n路T*);
+ N64n路Status (*shift_right)(Extent, N64n路T*, N64n路T*, N64n路T*);
+ N64n路Status (*arithmetic_shift_right)(Extent, N64n路T*, N64n路T*);
+
+ N64n路T* (*access)(N64n路T*, Extent);
+ void (*from_uint64)(N64n路T *destination, uint64_t value);
+
+ } N64n路螞;
+
+ Local const N64n路螞 N64n路位; // initialized in the LOCAL section
+
+#endif
+
+//--------------------------------------------------------------------------------
+// Implementation
+
+#ifdef N64n路IMPLEMENTATION
+
+ // this part goes into the library
+ #ifndef LOCAL
+
+ #include <stdarg.h>
+ #include <stdlib.h>
+
+ struct N64n路T {
+ Digit d0;
+ };
+
+ // For constants, we store them in an array for convenience
+ // 0, 1, all bits set (~0ULL), and MSB set (1ULL<<63)
+ N64n路T N64n路constant[4] = {
+ {.d0 = 0ULL},
+ {.d0 = 1ULL},
+ {.d0 = ~(uint64_t)0ULL},
+ {.d0 = 1ULL << 63}
+ };
+
+ N64n路T *N64n路zero = &N64n路constant[0];
+ N64n路T *N64n路one = &N64n路constant[1];
+ N64n路T *N64n路all_one_bit = &N64n路constant[2];
+ N64n路T *N64n路msb = &N64n路constant[3];
+ N64n路T *N64n路lsb = &N64n路constant[1];
+
+ // allocate an array of N64
+ N64n路T *N64n路allocate_array(Extent extent, N64n路Allocate_MemoryFault memory_fault){
+ N64n路T *instance = malloc( (extent + 1) * sizeof(N64n路T) );
+ if(!instance){
+ return memory_fault ? memory_fault(extent) : NULL;
+ }
+ return instance;
+ }
+
+ N64n路T *N64n路allocate_array_zero(Extent extent, N64n路Allocate_MemoryFault memory_fault){
+ N64n路T *instance = calloc(extent + 1, sizeof(N64n路T));
+ if(!instance){
+ return memory_fault ? memory_fault(extent) : NULL;
+ }
+ return instance;
+ }
+
+ void N64n路deallocate(N64n路T *unencumbered){
+ free(unencumbered);
+ }
+
+ #endif
+
+ // This part is included after the library user's code
+ #ifdef LOCAL
+
+ // instance
+
+ struct N64n路T {
+ Digit d0;
+ };
+
+ // local temporary variables
+ Local N64n路T N64n路t[4];
+
+ // allocation references
+ extern N64n路T *N64n路allocate_array(Extent, N64n路Allocate_MemoryFault);
+ extern N64n路T *N64n路allocate_array_zero(Extent, N64n路Allocate_MemoryFault);
+ extern void N64n路deallocate(N64n路T *);
+
+ // Access array
+ Local N64n路T* N64n路access(N64n路T *array, Extent index){
+ return &array[index];
+ }
+
+ Local void N64n路from_uint64(N64n路T *destination, uint64_t value){
+ if(destination == NULL) return;
+ destination->d0 = value;
+ }
+
+ // copy
+ Local void N64n路copy(N64n路T *destination, N64n路T *source){
+ if(source == destination) return;
+ *destination = *source;
+ }
+
+ // bit operations
+
+ Local void N64n路bit_and(N64n路T *result, N64n路T *a, N64n路T *b){
+ result->d0 = a->d0 & b->d0;
+ }
+
+ Local void N64n路bit_or(N64n路T *result, N64n路T *a, N64n路T *b){
+ result->d0 = a->d0 | b->d0;
+ }
+
+ Local void N64n路bit_complement(N64n路T *result, N64n路T *a){
+ result->d0 = ~a->d0;
+ }
+
+ Local void N64n路bit_twos_complement(N64n路T *result, N64n路T *a){
+ result->d0 = ~a->d0 + 1ULL;
+ }
+
+ // compare & test functions
+
+ Local N64n路Order N64n路compare(N64n路T *a, N64n路T *b){
+ if(a->d0 < b->d0) return N64n路Order_lt;
+ if(a->d0 > b->d0) return N64n路Order_gt;
+ return N64n路Order_eq;
+ }
+
+ Local bool N64n路lt(N64n路T *a, N64n路T *b){
+ return (a->d0 < b->d0);
+ }
+
+ Local bool N64n路gt(N64n路T *a, N64n路T *b){
+ return (a->d0 > b->d0);
+ }
+
+ Local bool N64n路eq(N64n路T *a, N64n路T *b){
+ return (a->d0 == b->d0);
+ }
+
+ Local bool N64n路eq_zero(N64n路T *a){
+ return (a->d0 == 0ULL);
+ }
+
+ // arithmetic operations
+
+ // accumulate
+ Local N64n路Status N64n路accumulate(N64n路T *accumulator1, N64n路T *accumulator0, ...){
+ va_list args;
+ va_start(args, accumulator0);
+
+ uint64_t sum = accumulator0->d0;
+ uint64_t carry = 0;
+ N64n路T *current;
+
+ while( (current = va_arg(args, N64n路T*)) ){
+ uint64_t prior = sum;
+ sum += current->d0;
+ if(sum < prior){ // indicates carry
+ carry++;
+ // if carry overflowed a 64-bit, that's an accumulator1 overflow
+ if(carry == 0ULL){
+ va_end(args);
+ return N64n路Status路accumulator1_overflow;
+ }
+ }
+ }
+ va_end(args);
+
+ accumulator1->d0 = carry;
+ return N64n路Status路ok;
+ }
+
+ // add
+ Local N64n路Status N64n路add(N64n路T *sum, N64n路T *a, N64n路T *b){
+ __uint128_t result = ( __uint128_t )a->d0 + ( __uint128_t )b->d0;
+ // But to avoid using a GNU extension, we can do the simpler approach:
+ // Actually let's do it directly with 64-bit since we only need to detect carry out of 64 bits:
+ uint64_t temp = a->d0 + b->d0;
+ sum->d0 = temp;
+ if(temp < a->d0) return N64n路Status路carry; // means we overflowed
+ return N64n路Status路ok;
+ }
+
+ Local bool N64n路increment(N64n路T *a){
+ uint64_t old = a->d0;
+ a->d0++;
+ // if it wrapped around to 0, then it was 0xFFFFFFFFFFFFFFFF
+ return (a->d0 < old);
+ }
+
+ // subtract
+ Local N64n路Status N64n路subtract(N64n路T *difference, N64n路T *a, N64n路T *b){
+ uint64_t tmpA = a->d0;
+ uint64_t tmpB = b->d0;
+ uint64_t diff = tmpA - tmpB;
+ difference->d0 = diff;
+ if(diff > tmpA) return N64n路Status路borrow; // indicates we borrowed
+ return N64n路Status路ok;
+ }
+
+ // multiply
+ // We'll do a 64x64->128 using two 64-bit accumulators
+ Local N64n路Status N64n路multiply(N64n路T *product1, N64n路T *product0, N64n路T *a, N64n路T *b){
+ uint64_t A = a->d0;
+ uint64_t B = b->d0;
+
+ // Break each operand into high & low 32 bits
+ uint64_t a_lo = (uint32_t)(A & 0xffffffffULL);
+ uint64_t a_hi = A >> 32;
+ uint64_t b_lo = (uint32_t)(B & 0xffffffffULL);
+ uint64_t b_hi = B >> 32;
+
+ // partial products
+ uint64_t low = a_lo * b_lo; // 64-bit
+ uint64_t cross = (a_lo * b_hi) + (a_hi * b_lo); // potentially up to 2 * 32 bits => 64 bits
+ uint64_t high = a_hi * b_hi; // up to 64 bits
+
+ // incorporate cross into low, high
+ // cross is effectively the middle bits, so shift cross by 32 and add to low
+ uint64_t cross_low = (cross & 0xffffffffULL) << 32; // lower part
+ uint64_t cross_high = cross >> 32; // upper part
+
+ // add cross_low to low, capture carry
+ uint64_t old_low = low;
+ low += cross_low;
+ if(low < old_low) cross_high++;
+
+ // final high
+ high += cross_high;
+
+ // store results
+ product0->d0 = low;
+ product1->d0 = high;
+
+ if(high == 0ULL) return N64n路Status路one_word_product;
+ return N64n路Status路two_word_product;
+ }
+
+ // divide
+ Local N64n路Status N64n路divide(N64n路T *remainder, N64n路T *quotient, N64n路T *a, N64n路T *b){
+ // we do not handle a > 64-bit, just the single 64-bit
+ if(b->d0 == 0ULL) return N64n路Status路undefined_divide_by_zero;
+
+ uint64_t divd = a->d0; // dividend
+ uint64_t divs = b->d0; // divisor
+
+ quotient->d0 = divd / divs;
+ remainder->d0 = divd - (quotient->d0 * divs);
+
+ return N64n路Status路ok;
+ }
+
+ // modulus
+ Local N64n路Status N64n路modulus(N64n路T *remainder, N64n路T *a, N64n路T *b){
+ if(b->d0 == 0ULL) return N64n路Status路undefined_modulus_zero;
+
+ uint64_t divd = a->d0;
+ uint64_t divs = b->d0;
+ uint64_t q = divd / divs;
+ remainder->d0 = divd - (q * divs);
+
+ return N64n路Status路ok;
+ }
+
+ // bit motion
+
+ typedef uint64_t (*ShiftOp)(uint64_t, uint64_t);
+
+ Local uint64_t shift_left_op(uint64_t value, uint64_t amount){
+ return (value << amount);
+ }
+
+ Local uint64_t shift_right_op(uint64_t value, uint64_t amount){
+ return (value >> amount);
+ }
+
+ // modifies all three of its operands
+ // in the case of duplicate operands this is the order: first modifies operand, then fill, then spill
+ Local N64n路Status N64n路shift
+ (
+ uint64_t shift_count,
+ N64n路T *spill,
+ N64n路T *operand,
+ N64n路T *fill,
+ ShiftOp shift_op,
+ ShiftOp complement_shift_op
+ ){
+ if(operand == NULL && spill == NULL) return N64n路Status路ok;
+
+ // Treat NULL operand as zero
+ if(operand == NULL){
+ operand = &N64n路t[0];
+ N64n路copy(operand, N64n路zero);
+ }
+
+ // Shifting more than 63 bits breaks fill/spill logic
+ if(shift_count > 63ULL) return N64n路Status路gt_max_shift_count;
+
+ N64n路T *given_operand = &N64n路t[1];
+ N64n路copy(given_operand, operand);
+
+ // Perform the shift
+ operand->d0 = shift_op(given_operand->d0, shift_count);
+ if(fill != NULL){
+ fill->d0 = complement_shift_op(fill->d0, (64ULL - shift_count));
+ N64n路bit_or(operand, operand, fill);
+ }
+ if(spill != NULL){
+ spill->d0 = shift_op(spill->d0, shift_count);
+ spill->d0 += complement_shift_op(given_operand->d0, (64ULL - shift_count));
+ }
+
+ return N64n路Status路ok;
+ }
+
+ Local N64n路Status N64n路shift_left(uint64_t shift_count, N64n路T *spill, N64n路T *operand, N64n路T *fill){
+ return N64n路shift(shift_count, spill, operand, fill, shift_left_op, shift_right_op);
+ }
+
+ Local N64n路Status N64n路shift_right(uint64_t shift_count, N64n路T *spill, N64n路T *operand, N64n路T *fill){
+ return N64n路shift(shift_count, spill, operand, fill, shift_right_op, shift_left_op);
+ }
+
+ Local N64n路Status N64n路arithmetic_shift_right(uint64_t shift_count, N64n路T *operand, N64n路T *spill){
+ if(shift_count > 63ULL) return N64n路Status路gt_max_shift_count;
+
+ // A NULL operand is treated as zero
+ if(operand == NULL){
+ operand = &N64n路t[0];
+ N64n路copy(operand, N64n路zero);
+ }
+
+ // sign bit check
+ N64n路T *fill = (operand->d0 & (1ULL << 63)) ? N64n路all_one_bit : N64n路zero;
+ return N64n路shift_right(shift_count, spill, operand, fill);
+ }
+
+ Local const N64n路螞 N64n路位 = {
+ .allocate_array = N64n路allocate_array
+ ,.allocate_array_zero = N64n路allocate_array_zero
+ ,.deallocate = N64n路deallocate
+
+ ,.copy = N64n路copy
+ ,.bit_and = N64n路bit_and
+ ,.bit_or = N64n路bit_or
+ ,.bit_complement = N64n路bit_complement
+ ,.bit_twos_complement = N64n路bit_twos_complement
+ ,.compare = N64n路compare
+ ,.lt = N64n路lt
+ ,.gt = N64n路gt
+ ,.eq = N64n路eq
+ ,.eq_zero = N64n路eq_zero
+ ,.accumulate = N64n路accumulate
+ ,.add = N64n路add
+ ,.increment = N64n路increment
+ ,.subtract = N64n路subtract
+ ,.multiply = N64n路multiply
+ ,.divide = N64n路divide
+ ,.modulus = N64n路modulus
+ ,.shift_left = N64n路shift_left
+ ,.shift_right = N64n路shift_right
+ ,.arithmetic_shift_right = N64n路arithmetic_shift_right
+
+ ,.access = N64n路access
+ ,.from_uint64 = N64n路from_uint64
+ };
+
+ #endif
+
+#endif
+++ /dev/null
-/*
- N8 - a processor native type
-
- For binary operations: a op b -> c
-
- See the document on the proper use of the Natural types.
-
- On the subject of multiple pointers indicating the same location in memory:
-
- When a routine has multiple results, and one or more of the result location
- pointers point to the same storage, the routine will either return an error
- status, or have defined behavior.
-
- When a routine has multiple operands, in any combination, those
- pointers can point to the same location, and the routine will
- function as advertised.
-
- When an operand functions as both an input and a result, perhaps due
- to a result pointer pointing to the same place as an operand
- pointer, the routine will function as advertised. (Internally the
- routine might make a temporary copy of the operand to accomplish
- this.)
-*/
-
-#define N8路DEBUG
-
-#ifndef FACE
-#define N8路IMPLEMENTATION
-#define FACE
-#endif
-
-//--------------------------------------------------------------------------------
-// Interface
-
-#ifndef N8路FACE
-#define N8路FACE
-
- #include <stdint.h>
- #include <stdbool.h>
- #include <stdarg.h>
- #include <stdlib.h>
-
- //----------------------------------------
- // Instance Data (Declaration Only)
-
- typedef uint8_t Extent;
- typedef uint8_t Digit;
-
- typedef struct N8路T N8路T;
-
- extern N8路T *N8路zero;
- extern N8路T *N8路one;
- extern N8路T *N8路all_one_bit;
- extern N8路T *N8路lsb;
- extern N8路T *N8路msb;
-
- //----------------------------------------
- // Return/Error Status and handlers
-
- typedef enum{
- N8路Status路ok = 0
- ,N8路Status路overflow = 1
- ,N8路Status路accumulator1_overflow = 2
- ,N8路Status路carry = 3
- ,N8路Status路borrow = 4
- ,N8路Status路undefined_divide_by_zero = 5
- ,N8路Status路undefined_modulus_zero = 6
- ,N8路Status路gt_max_shift_count = 7
- ,N8路Status路spill_eq_operand = 8
- ,N8路Status路one_word_product = 9
- ,N8路Status路two_word_product = 10
- } N8路Status;
-
- typedef enum{
- N8路Order_lt = -1
- ,N8路Order_eq = 0
- ,N8路Order_gt = 1
- } N8路Order;
-
- typedef N8路T *( *N8路Allocate_MemoryFault )(Extent);
-
- //----------------------------------------
- // Interface
-
- typedef struct{
-
- N8路T *(*allocate_array_zero)(Extent, N8路Allocate_MemoryFault);
- N8路T *(*allocate_array)(Extent, N8路Allocate_MemoryFault);
- void (*deallocate)(N8路T*);
-
- void (*copy)(N8路T*, N8路T*);
- void (*bit_and)(N8路T*, N8路T*, N8路T*);
- void (*bit_or)(N8路T*, N8路T*, N8路T*);
- void (*bit_complement)(N8路T*, N8路T*);
- void (*bit_twos_complement)(N8路T*, N8路T*);
- N8路Order (*compare)(N8路T*, N8路T*);
- bool (*lt)(N8路T*, N8路T*);
- bool (*gt)(N8路T*, N8路T*);
- bool (*eq)(N8路T*, N8路T*);
- bool (*eq_zero)(N8路T*);
- N8路Status (*accumulate)(N8路T *accumulator1 ,N8路T *accumulator0 ,...);
- N8路Status (*add)(N8路T*, N8路T*, N8路T*);
- bool (*increment)(N8路T *a);
- N8路Status (*subtract)(N8路T*, N8路T*, N8路T*);
- N8路Status (*multiply)(N8路T*, N8路T*, N8路T*, N8路T*);
- N8路Status (*divide)(N8路T*, N8路T*, N8路T*, N8路T*);
- N8路Status (*modulus)(N8路T*, N8路T*, N8路T*);
- N8路Status (*shift_left)(Extent, N8路T*, N8路T*, N8路T*);
- N8路Status (*shift_right)(Extent, N8路T*, N8路T*, N8路T*);
- N8路Status (*arithmetic_shift_right)(Extent, N8路T*, N8路T*);
-
- N8路T* (*access)(N8路T*, Extent);
- void (*from_uint32)(N8路T *destination ,uint32_t value);
- } N8路螞;
-
- Local const N8路螞 N8路位; // initialized in the LOCAL section
-
-#endif
-
-//--------------------------------------------------------------------------------
-// Implementation
-
-#ifdef N8路IMPLEMENTATION
-
- // this part goes into the library
- #ifndef LOCAL
-
- #include <stdarg.h>
- #include <stdlib.h>
-
- struct N8路T{
- Digit d0;
- };
-
- N8路T N8路constant[4] = {
- {.d0 = 0},
- {.d0 = 1},
- {.d0 = ~(uint8_t)0},
- {.d0 = 1 << 7}
- };
-
- N8路T *N8路zero = &N8路constant[0];
- N8路T *N8路one = &N8路constant[1];
- N8路T *N8路all_one_bit = &N8路constant[2];
- N8路T *N8路msb = &N8路constant[3];
- N8路T *N8路lsb = &N8路constant[1];
-
- // the allocate an array of N8
- N8路T *N8路allocate_array(Extent extent ,N8路Allocate_MemoryFault memory_fault){
- N8路T *instance = malloc((extent + 1) * sizeof(N8路T));
- if(!instance){
- return memory_fault ? memory_fault(extent) : NULL;
- }
- return instance;
- }
-
- N8路T *N8路allocate_array_zero(Extent extent ,N8路Allocate_MemoryFault memory_fault){
- N8路T *instance = calloc(extent + 1, sizeof(N8路T));
- if(!instance){
- return memory_fault ? memory_fault(extent) : NULL;
- }
- return instance;
- }
-
- void N8路deallocate(N8路T *unencumbered){
- free(unencumbered);
- }
-
-
- #endif
-
- // This part is included after the library user's code
- #ifdef LOCAL
-
- // instance
-
- struct N8路T{
- Digit d0;
- };
-
- // temporary variables
- Local N8路T N8路t[4];
-
- // allocation
-
- extern N8路T *N8路allocate_array(Extent, N8路Allocate_MemoryFault);
- extern N8路T *N8路allocate_array_zero(Extent, N8路Allocate_MemoryFault);
- extern void N8路deallocate(N8路T *);
-
- // so the user can access numbers in an array allocation
- Local N8路T* N8路access(N8路T *array ,Extent index){
- return &array[index];
- }
-
- Local void N8路from_uint32(N8路T *destination ,uint32_t value){
- if(destination == NULL) return;
- destination->d0 = (uint8_t)(value & 0xFF);
- }
-
- // copy, convenience copy
-
- Local void N8路copy(N8路T *destination ,N8路T *source){
- if(source == destination) return;
- *destination = *source;
- }
-
- Local void N8路set_to_zero(N8路T *instance){
- instance->d0 = 0;
- }
-
- Local void N8路set_to_one(N8路T *instance){
- instance->d0 = 1;
- }
-
- // bit operations
-
- Local void N8路bit_and(N8路T *result, N8路T *a, N8路T *b){
- result->d0 = a->d0 & b->d0;
- }
-
- Local void N8路bit_or(N8路T *result, N8路T *a, N8路T *b){
- result->d0 = a->d0 | b->d0;
- }
-
- Local void N8路bit_complement(N8路T *result, N8路T *a){
- result->d0 = ~a->d0;
- }
-
- Local void N8路bit_twos_complement(N8路T *result ,N8路T *a){
- result->d0 = (uint8_t)(~a->d0 + 1);
- }
-
- // test functions
-
- Local N8路Order N8路compare(N8路T *a, N8路T *b){
- if(a->d0 < b->d0) return N8路Order_lt;
- if(a->d0 > b->d0) return N8路Order_gt;
- return N8路Order_eq;
- }
-
- Local bool N8路lt(N8路T *a ,N8路T *b){
- return a->d0 < b->d0;
- }
-
- Local bool N8路gt(N8路T *a ,N8路T *b){
- return a->d0 > b->d0;
- }
-
- Local bool N8路eq(N8路T *a ,N8路T *b){
- return a->d0 == b->d0;
- }
-
- Local bool N8路eq_zero(N8路T *a){
- return a->d0 == 0;
- }
-
- // arithmetic operations
-
- Local N8路Status N8路accumulate(N8路T *accumulator1 ,N8路T *accumulator0 ,...){
-
- va_list args;
- va_start(args ,accumulator0);
- uint32_t sum = accumulator0->d0;
- uint32_t carry = 0;
- N8路T *current;
-
- while( (current = va_arg(args ,N8路T*)) ){
- sum += current->d0;
- if(sum < current->d0){
- (carry)++;
- if(carry == 0){
- va_end(args);
- return N8路Status路accumulator1_overflow;
- }
- }
- }
- va_end(args);
-
- accumulator1->d0 = (uint8_t)carry;
- return N8路Status路ok;
- }
-
- Local N8路Status N8路add(N8路T *sum ,N8路T *a ,N8路T *b){
- uint32_t result = (uint32_t)a->d0 + (uint32_t)b->d0;
- sum->d0 = (uint8_t)(result & 0xFF);
- return (result >> 8) ? N8路Status路carry : N8路Status路ok;
- }
-
- Local bool N8路increment(N8路T *a){
- a->d0++;
- return (a->d0 == 0);
- }
-
- Local N8路Status N8路subtract(N8路T *difference ,N8路T *a ,N8路T *b){
- uint32_t diff = (uint32_t)a->d0 - (uint32_t)b->d0;
- difference->d0 = (uint8_t)(diff & 0xFF);
- return (diff > a->d0) ? N8路Status路borrow : N8路Status路ok;
- }
-
- Local N8路Status N8路multiply(N8路T *product1 ,N8路T *product0 ,N8路T *a ,N8路T *b){
- uint32_t product = (uint32_t)a->d0 * (uint32_t)b->d0;
- product0->d0 = (uint8_t)(product & 0xFF);
- product1->d0 = (uint8_t)((product >> 8) & 0xFF);
-
- if(product1->d0 == 0) return N8路Status路one_word_product;
- return N8路Status路two_word_product;
- }
-
- Local N8路Status N8路divide(N8路T *remainder ,N8路T *quotient ,N8路T *a ,N8路T *b){
- if(b->d0 == 0) return N8路Status路undefined_divide_by_zero;
-
- uint32_t dividend = a->d0;
- uint32_t divisor = b->d0;
- quotient->d0 = (uint8_t)(dividend / divisor);
- remainder->d0 = (uint8_t)(dividend - (quotient->d0 * divisor));
-
- return N8路Status路ok;
- }
-
- Local N8路Status N8路modulus(N8路T *remainder ,N8路T *a ,N8路T *b){
- if(b->d0 == 0) return N8路Status路undefined_modulus_zero;
- uint32_t dividend = a->d0;
- uint32_t divisor = b->d0;
- uint32_t q = dividend / divisor;
- remainder->d0 = (uint8_t)(dividend - (q * divisor));
- return N8路Status路ok;
- }
-
- // bit motion
-
- typedef uint8_t (*ShiftOp)(uint8_t, uint8_t);
-
- Local uint8_t shift_left_op(uint8_t value, uint8_t amount){
- return (uint8_t)(value << amount);
- }
-
- Local uint8_t shift_right_op(uint8_t value, uint8_t amount){
- return (uint8_t)(value >> amount);
- }
-
- Local N8路Status N8路shift
- (
- uint8_t shift_count
- ,N8路T *spill
- ,N8路T *operand
- ,N8路T *fill
- ,ShiftOp shift_op
- ,ShiftOp complement_shift_op
- ){
-
- if(operand == NULL && spill == NULL) return N8路Status路ok;
-
- if(operand == NULL){
- operand = &N8路t[0];
- N8路copy(operand, N8路zero);
- }
-
- if(shift_count > 7) return N8路Status路gt_max_shift_count;
-
- N8路T *given_operand = &N8路t[1];
- N8路copy(given_operand, operand);
-
- operand->d0 = shift_op(given_operand->d0, shift_count);
- if(fill != NULL){
- fill->d0 = complement_shift_op(fill->d0, (8 - shift_count));
- N8路bit_or(operand, operand, fill);
- }
- if(spill != NULL){
- spill->d0 = shift_op(spill->d0, shift_count);
- spill->d0 += complement_shift_op(given_operand->d0, (8 - shift_count));
- }
-
- return N8路Status路ok;
- }
-
- Local N8路Status
- N8路shift_left(uint8_t shift_count, N8路T *spill, N8路T *operand, N8路T *fill){
- return N8路shift(shift_count, spill, operand, fill, shift_left_op, shift_right_op);
- }
-
- Local N8路Status
- N8路shift_right(uint8_t shift_count, N8路T *spill, N8路T *operand, N8路T *fill){
- return N8路shift(shift_count, spill, operand, fill, shift_right_op, shift_left_op);
- }
-
- Local N8路Status
- N8路arithmetic_shift_right(uint8_t shift_count, N8路T *operand, N8路T *spill){
-
- if(shift_count > 7) return N8路Status路gt_max_shift_count;
-
- if(operand == NULL){
- operand = &N8路t[0];
- N8路copy(operand, N8路zero);
- }
-
- N8路T *fill = (operand->d0 & 0x80) ? N8路all_one_bit : N8路zero;
- return N8路shift_right(shift_count, spill, operand, fill);
- }
-
- Local const N8路螞 N8路位 = {
-
- .allocate_array = N8路allocate_array
- ,.allocate_array_zero = N8路allocate_array_zero
- ,.deallocate = N8路deallocate
-
- ,.copy = N8路copy
- ,.bit_and = N8路bit_and
- ,.bit_or = N8路bit_or
- ,.bit_complement = N8路bit_complement
- ,.bit_twos_complement = N8路bit_twos_complement
- ,.compare = N8路compare
- ,.lt = N8路lt
- ,.gt = N8路gt
- ,.eq = N8路eq
- ,.eq_zero = N8路eq_zero
- ,.accumulate = N8路accumulate
- ,.add = N8路add
- ,.increment = N8路increment
- ,.subtract = N8路subtract
- ,.multiply = N8路multiply
- ,.divide = N8路divide
- ,.modulus = N8路modulus
- ,.shift_left = N8路shift_left
- ,.shift_right = N8路shift_right
- ,.arithmetic_shift_right = N8路arithmetic_shift_right
-
- ,.access = N8路access
- ,.from_uint32 = N8路from_uint32
- };
-
- #endif
-
-#endif
--- /dev/null
+/*
+ N8n - a processor native type
+
+ For binary operations: a op b -> c
+
+ See the document on the proper use of the Natural types.
+
+ On the subject of multiple pointers indicating the same location in memory:
+
+ When a routine has multiple results, and one or more of the result location
+ pointers point to the same storage, the routine will either return an error
+ status, or have defined behavior.
+
+ When a routine has multiple operands, in any combination, those
+ pointers can point to the same location, and the routine will
+ function as advertised.
+
+ When an operand functions as both an input and a result, perhaps due
+ to a result pointer pointing to the same place as an operand
+ pointer, the routine will function as advertised. (Internally the
+ routine might make a temporary copy of the operand to accomplish
+ this.)
+*/
+
+#define N8n路DEBUG
+
+#ifndef FACE
+#define N8n路IMPLEMENTATION
+#define FACE
+#endif
+
+//--------------------------------------------------------------------------------
+// Interface
+
+#ifndef N8n路FACE
+#define N8n路FACE
+
+ #include <stdint.h>
+ #include <stdbool.h>
+ #include <stdarg.h>
+ #include <stdlib.h>
+
+ //----------------------------------------
+ // Instance Data (Declaration Only)
+
+ typedef uint8_t Extent;
+ typedef uint8_t Digit;
+
+ typedef struct N8n路T N8n路T;
+
+ extern N8n路T *N8n路zero;
+ extern N8n路T *N8n路one;
+ extern N8n路T *N8n路all_one_bit;
+ extern N8n路T *N8n路lsb;
+ extern N8n路T *N8n路msb;
+
+ //----------------------------------------
+ // Return/Error Status and handlers
+
+ typedef enum{
+ N8n路Status路ok = 0
+ ,N8n路Status路overflow = 1
+ ,N8n路Status路accumulator1_overflow = 2
+ ,N8n路Status路carry = 3
+ ,N8n路Status路borrow = 4
+ ,N8n路Status路undefined_divide_by_zero = 5
+ ,N8n路Status路undefined_modulus_zero = 6
+ ,N8n路Status路gt_max_shift_count = 7
+ ,N8n路Status路spill_eq_operand = 8
+ ,N8n路Status路one_word_product = 9
+ ,N8n路Status路two_word_product = 10
+ } N8n路Status;
+
+ typedef enum{
+ N8n路Order_lt = -1
+ ,N8n路Order_eq = 0
+ ,N8n路Order_gt = 1
+ } N8n路Order;
+
+ typedef N8n路T *( *N8n路Allocate_MemoryFault )(Extent);
+
+ //----------------------------------------
+ // Interface
+
+ typedef struct{
+
+ N8n路T *(*allocate_array_zero)(Extent, N8n路Allocate_MemoryFault);
+ N8n路T *(*allocate_array)(Extent, N8n路Allocate_MemoryFault);
+ void (*deallocate)(N8n路T*);
+
+ void (*copy)(N8n路T*, N8n路T*);
+ void (*bit_and)(N8n路T*, N8n路T*, N8n路T*);
+ void (*bit_or)(N8n路T*, N8n路T*, N8n路T*);
+ void (*bit_complement)(N8n路T*, N8n路T*);
+ void (*bit_twos_complement)(N8n路T*, N8n路T*);
+ N8n路Order (*compare)(N8n路T*, N8n路T*);
+ bool (*lt)(N8n路T*, N8n路T*);
+ bool (*gt)(N8n路T*, N8n路T*);
+ bool (*eq)(N8n路T*, N8n路T*);
+ bool (*eq_zero)(N8n路T*);
+ N8n路Status (*accumulate)(N8n路T *accumulator1 ,N8n路T *accumulator0 ,...);
+ N8n路Status (*add)(N8n路T*, N8n路T*, N8n路T*);
+ bool (*increment)(N8n路T *a);
+ N8n路Status (*subtract)(N8n路T*, N8n路T*, N8n路T*);
+ N8n路Status (*multiply)(N8n路T*, N8n路T*, N8n路T*, N8n路T*);
+ N8n路Status (*divide)(N8n路T*, N8n路T*, N8n路T*, N8n路T*);
+ N8n路Status (*modulus)(N8n路T*, N8n路T*, N8n路T*);
+ N8n路Status (*shift_left)(Extent, N8n路T*, N8n路T*, N8n路T*);
+ N8n路Status (*shift_right)(Extent, N8n路T*, N8n路T*, N8n路T*);
+ N8n路Status (*arithmetic_shift_right)(Extent, N8n路T*, N8n路T*);
+
+ N8n路T* (*access)(N8n路T*, Extent);
+ void (*from_uint32)(N8n路T *destination ,uint32_t value);
+ } N8n路螞;
+
+ Local const N8n路螞 N8n路位; // initialized in the LOCAL section
+
+#endif
+
+//--------------------------------------------------------------------------------
+// Implementation
+
+#ifdef N8n路IMPLEMENTATION
+
+ // this part goes into the library
+ #ifndef LOCAL
+
+ #include <stdarg.h>
+ #include <stdlib.h>
+
+ struct N8n路T{
+ Digit d0;
+ };
+
+ N8n路T N8n路constant[4] = {
+ {.d0 = 0},
+ {.d0 = 1},
+ {.d0 = ~(uint8_t)0},
+ {.d0 = 1 << 7}
+ };
+
+ N8n路T *N8n路zero = &N8n路constant[0];
+ N8n路T *N8n路one = &N8n路constant[1];
+ N8n路T *N8n路all_one_bit = &N8n路constant[2];
+ N8n路T *N8n路msb = &N8n路constant[3];
+ N8n路T *N8n路lsb = &N8n路constant[1];
+
+ // the allocate an array of N8
+ N8n路T *N8n路allocate_array(Extent extent ,N8n路Allocate_MemoryFault memory_fault){
+ N8n路T *instance = malloc((extent + 1) * sizeof(N8n路T));
+ if(!instance){
+ return memory_fault ? memory_fault(extent) : NULL;
+ }
+ return instance;
+ }
+
+ N8n路T *N8n路allocate_array_zero(Extent extent ,N8n路Allocate_MemoryFault memory_fault){
+ N8n路T *instance = calloc(extent + 1, sizeof(N8n路T));
+ if(!instance){
+ return memory_fault ? memory_fault(extent) : NULL;
+ }
+ return instance;
+ }
+
+ void N8n路deallocate(N8n路T *unencumbered){
+ free(unencumbered);
+ }
+
+
+ #endif
+
+ // This part is included after the library user's code
+ #ifdef LOCAL
+
+ // instance
+
+ struct N8n路T{
+ Digit d0;
+ };
+
+ // temporary variables
+ Local N8n路T N8n路t[4];
+
+ // allocation
+
+ extern N8n路T *N8n路allocate_array(Extent, N8n路Allocate_MemoryFault);
+ extern N8n路T *N8n路allocate_array_zero(Extent, N8n路Allocate_MemoryFault);
+ extern void N8n路deallocate(N8n路T *);
+
+ // so the user can access numbers in an array allocation
+ Local N8n路T* N8n路access(N8n路T *array ,Extent index){
+ return &array[index];
+ }
+
+ Local void N8n路from_uint32(N8n路T *destination ,uint32_t value){
+ if(destination == NULL) return;
+ destination->d0 = (uint8_t)(value & 0xFF);
+ }
+
+ // copy, convenience copy
+
+ Local void N8n路copy(N8n路T *destination ,N8n路T *source){
+ if(source == destination) return;
+ *destination = *source;
+ }
+
+ Local void N8n路set_to_zero(N8n路T *instance){
+ instance->d0 = 0;
+ }
+
+ Local void N8n路set_to_one(N8n路T *instance){
+ instance->d0 = 1;
+ }
+
+ // bit operations
+
+ Local void N8n路bit_and(N8n路T *result, N8n路T *a, N8n路T *b){
+ result->d0 = a->d0 & b->d0;
+ }
+
+ Local void N8n路bit_or(N8n路T *result, N8n路T *a, N8n路T *b){
+ result->d0 = a->d0 | b->d0;
+ }
+
+ Local void N8n路bit_complement(N8n路T *result, N8n路T *a){
+ result->d0 = ~a->d0;
+ }
+
+ Local void N8n路bit_twos_complement(N8n路T *result ,N8n路T *a){
+ result->d0 = (uint8_t)(~a->d0 + 1);
+ }
+
+ // test functions
+
+ Local N8n路Order N8n路compare(N8n路T *a, N8n路T *b){
+ if(a->d0 < b->d0) return N8n路Order_lt;
+ if(a->d0 > b->d0) return N8n路Order_gt;
+ return N8n路Order_eq;
+ }
+
+ Local bool N8n路lt(N8n路T *a ,N8n路T *b){
+ return a->d0 < b->d0;
+ }
+
+ Local bool N8n路gt(N8n路T *a ,N8n路T *b){
+ return a->d0 > b->d0;
+ }
+
+ Local bool N8n路eq(N8n路T *a ,N8n路T *b){
+ return a->d0 == b->d0;
+ }
+
+ Local bool N8n路eq_zero(N8n路T *a){
+ return a->d0 == 0;
+ }
+
+ // arithmetic operations
+
+ Local N8n路Status N8n路accumulate(N8n路T *accumulator1 ,N8n路T *accumulator0 ,...){
+
+ va_list args;
+ va_start(args ,accumulator0);
+ uint32_t sum = accumulator0->d0;
+ uint32_t carry = 0;
+ N8n路T *current;
+
+ while( (current = va_arg(args ,N8n路T*)) ){
+ sum += current->d0;
+ if(sum < current->d0){
+ (carry)++;
+ if(carry == 0){
+ va_end(args);
+ return N8n路Status路accumulator1_overflow;
+ }
+ }
+ }
+ va_end(args);
+
+ accumulator1->d0 = (uint8_t)carry;
+ return N8n路Status路ok;
+ }
+
+ Local N8n路Status N8n路add(N8n路T *sum ,N8n路T *a ,N8n路T *b){
+ uint32_t result = (uint32_t)a->d0 + (uint32_t)b->d0;
+ sum->d0 = (uint8_t)(result & 0xFF);
+ return (result >> 8) ? N8n路Status路carry : N8n路Status路ok;
+ }
+
+ Local bool N8n路increment(N8n路T *a){
+ a->d0++;
+ return (a->d0 == 0);
+ }
+
+ Local N8n路Status N8n路subtract(N8n路T *difference ,N8n路T *a ,N8n路T *b){
+ uint32_t diff = (uint32_t)a->d0 - (uint32_t)b->d0;
+ difference->d0 = (uint8_t)(diff & 0xFF);
+ return (diff > a->d0) ? N8n路Status路borrow : N8n路Status路ok;
+ }
+
+ Local N8n路Status N8n路multiply(N8n路T *product1 ,N8n路T *product0 ,N8n路T *a ,N8n路T *b){
+ uint32_t product = (uint32_t)a->d0 * (uint32_t)b->d0;
+ product0->d0 = (uint8_t)(product & 0xFF);
+ product1->d0 = (uint8_t)((product >> 8) & 0xFF);
+
+ if(product1->d0 == 0) return N8n路Status路one_word_product;
+ return N8n路Status路two_word_product;
+ }
+
+ Local N8n路Status N8n路divide(N8n路T *remainder ,N8n路T *quotient ,N8n路T *a ,N8n路T *b){
+ if(b->d0 == 0) return N8n路Status路undefined_divide_by_zero;
+
+ uint32_t dividend = a->d0;
+ uint32_t divisor = b->d0;
+ quotient->d0 = (uint8_t)(dividend / divisor);
+ remainder->d0 = (uint8_t)(dividend - (quotient->d0 * divisor));
+
+ return N8n路Status路ok;
+ }
+
+ Local N8n路Status N8n路modulus(N8n路T *remainder ,N8n路T *a ,N8n路T *b){
+ if(b->d0 == 0) return N8n路Status路undefined_modulus_zero;
+ uint32_t dividend = a->d0;
+ uint32_t divisor = b->d0;
+ uint32_t q = dividend / divisor;
+ remainder->d0 = (uint8_t)(dividend - (q * divisor));
+ return N8n路Status路ok;
+ }
+
+ // bit motion
+
+ typedef uint8_t (*ShiftOp)(uint8_t, uint8_t);
+
+ Local uint8_t shift_left_op(uint8_t value, uint8_t amount){
+ return (uint8_t)(value << amount);
+ }
+
+ Local uint8_t shift_right_op(uint8_t value, uint8_t amount){
+ return (uint8_t)(value >> amount);
+ }
+
+ Local N8n路Status N8n路shift
+ (
+ uint8_t shift_count
+ ,N8n路T *spill
+ ,N8n路T *operand
+ ,N8n路T *fill
+ ,ShiftOp shift_op
+ ,ShiftOp complement_shift_op
+ ){
+
+ if(operand == NULL && spill == NULL) return N8n路Status路ok;
+
+ if(operand == NULL){
+ operand = &N8n路t[0];
+ N8n路copy(operand, N8n路zero);
+ }
+
+ if(shift_count > 7) return N8n路Status路gt_max_shift_count;
+
+ N8n路T *given_operand = &N8n路t[1];
+ N8n路copy(given_operand, operand);
+
+ operand->d0 = shift_op(given_operand->d0, shift_count);
+ if(fill != NULL){
+ fill->d0 = complement_shift_op(fill->d0, (8 - shift_count));
+ N8n路bit_or(operand, operand, fill);
+ }
+ if(spill != NULL){
+ spill->d0 = shift_op(spill->d0, shift_count);
+ spill->d0 += complement_shift_op(given_operand->d0, (8 - shift_count));
+ }
+
+ return N8n路Status路ok;
+ }
+
+ Local N8n路Status
+ N8n路shift_left(uint8_t shift_count, N8n路T *spill, N8n路T *operand, N8n路T *fill){
+ return N8n路shift(shift_count, spill, operand, fill, shift_left_op, shift_right_op);
+ }
+
+ Local N8n路Status
+ N8n路shift_right(uint8_t shift_count, N8n路T *spill, N8n路T *operand, N8n路T *fill){
+ return N8n路shift(shift_count, spill, operand, fill, shift_right_op, shift_left_op);
+ }
+
+ Local N8n路Status
+ N8n路arithmetic_shift_right(uint8_t shift_count, N8n路T *operand, N8n路T *spill){
+
+ if(shift_count > 7) return N8n路Status路gt_max_shift_count;
+
+ if(operand == NULL){
+ operand = &N8n路t[0];
+ N8n路copy(operand, N8n路zero);
+ }
+
+ N8n路T *fill = (operand->d0 & 0x80) ? N8n路all_one_bit : N8n路zero;
+ return N8n路shift_right(shift_count, spill, operand, fill);
+ }
+
+ Local const N8n路螞 N8n路位 = {
+
+ .allocate_array = N8n路allocate_array
+ ,.allocate_array_zero = N8n路allocate_array_zero
+ ,.deallocate = N8n路deallocate
+
+ ,.copy = N8n路copy
+ ,.bit_and = N8n路bit_and
+ ,.bit_or = N8n路bit_or
+ ,.bit_complement = N8n路bit_complement
+ ,.bit_twos_complement = N8n路bit_twos_complement
+ ,.compare = N8n路compare
+ ,.lt = N8n路lt
+ ,.gt = N8n路gt
+ ,.eq = N8n路eq
+ ,.eq_zero = N8n路eq_zero
+ ,.accumulate = N8n路accumulate
+ ,.add = N8n路add
+ ,.increment = N8n路increment
+ ,.subtract = N8n路subtract
+ ,.multiply = N8n路multiply
+ ,.divide = N8n路divide
+ ,.modulus = N8n路modulus
+ ,.shift_left = N8n路shift_left
+ ,.shift_right = N8n路shift_right
+ ,.arithmetic_shift_right = N8n路arithmetic_shift_right
+
+ ,.access = N8n路access
+ ,.from_uint32 = N8n路from_uint32
+ };
+
+ #endif
+
+#endif
+++ /dev/null
-changequote([,])dnl
-define(NS, __NAMESPACE__)dnl
-define(DE, __DIGIT_EXTENT__)dnl
-define(DT, __DIGIT_TYPE__)dnl
-define(ET, __EXTENT_TYPE__)dnl
-changequote(`,')dnl
-
-/*
- [NS] - Parametric multi-digit type library (RT code format)
-
- Parameters:
- [NS]: Namespace prefix, e.g. N32路
- [DE]: Digit extent => total digits = DE + 1
- [DT]: Digit type, e.g. uint64_t or uint8_t
- [ET]: Loop counter type, e.g. uint64_t
-*/
-
-#define [NS]DEBUG
-
-#ifndef FACE
- #define [NS]IMPLEMENTATION
- #define FACE
-#endif
-
-//------------------------------------------------------------------------------
-// Interface Section
-
-#ifndef [NS]FACE
-#define [NS]FACE
-
- #include <stdint.h>
- #include <stdbool.h>
- #include <stdarg.h>
- #include <stdlib.h>
-
- // Digit count is DE + 1
- #define [NS]DIGIT_COUNT (DE + 1)
-
- typedef DT Digit;
- typedef struct [NS]T [NS]T;
-
- // For array allocations
- typedef ET ExtentType;
-
- // Status codes
- typedef enum{
- [NS]Status_ok = 0
- ,[NS]Status_overflow
- ,[NS]Status_accumulator1_overflow
- ,[NS]Status_carry
- ,[NS]Status_borrow
- ,[NS]Status_undefined_divide_by_zero
- ,[NS]Status_undefined_modulus_zero
- ,[NS]Status_gt_max_shift_count
- ,[NS]Status_spill_eq_operand
- ,[NS]Status_one_word_product
- ,[NS]Status_two_word_product
- } [NS]Status;
-
- typedef enum{
- [NS]Order_lt = -1
- ,[NS]Order_eq = 0
- ,[NS]Order_gt = 1
- } [NS]Order;
-
- // Allocation
- Digit *[NS]allocate_array(ExtentType extent ,[NS]T *(*fault_handler)(ExtentType));
- Digit *[NS]allocate_array_zero(ExtentType extent ,[NS]T *(*fault_handler)(ExtentType));
- void [NS]deallocate([NS]T *unencumbered);
-
- // Constant setters (no static global constants)
- void [NS]set_zero([NS]T *destination);
- void [NS]set_one([NS]T *destination);
- void [NS]set_all_bits([NS]T *destination);
- void [NS]set_msb([NS]T *destination);
-
- // Bitwise ops
- void [NS]bit_and([NS]T *result ,[NS]T *a ,[NS]T *b);
- void [NS]bit_or([NS]T *result ,[NS]T *a ,[NS]T *b);
- void [NS]bit_complement([NS]T *result ,[NS]T *a);
- void [NS]bit_twos_complement([NS]T *result ,[NS]T *a);
-
- // Comparison ops
- bool [NS]eq([NS]T *a ,[NS]T *b);
- bool [NS]eq_zero([NS]T *a);
- [NS]Order [NS]compare([NS]T *a ,[NS]T *b);
-
- // Arithmetic
- [NS]Status [NS]add([NS]T *sum ,[NS]T *a ,[NS]T *b);
- [NS]Status [NS]subtract([NS]T *diff ,[NS]T *a ,[NS]T *b);
-
- // Conversions
- void [NS]from_uint64([NS]T *destination ,uint64_t value);
-
-#endif // [NS]FACE
-
-
-//------------------------------------------------------------------------------
-// Implementation Section
-
-#ifdef [NS]IMPLEMENTATION
-
- #ifndef LOCAL
-
- #include <stdarg.h>
- #include <stdlib.h>
-
- struct [NS]T{
- Digit d[[NS]DIGIT_COUNT];
- };
-
- Digit *[NS]allocate_array(ExtentType extent ,[NS]T *(*fault_handler)(ExtentType)){
- [NS]T *instance = malloc((extent + 1) * sizeof([NS]T));
- if(!instance){
- if(fault_handler) return (Digit*)fault_handler(extent);
- return NULL;
- }
- return (Digit*)instance;
- }
-
- Digit *[NS]allocate_array_zero(ExtentType extent ,[NS]T *(*fault_handler)(ExtentType)){
- [NS]T *instance = calloc(extent + 1 ,sizeof([NS]T));
- if(!instance){
- if(fault_handler) return (Digit*)fault_handler(extent);
- return NULL;
- }
- return (Digit*)instance;
- }
-
- void [NS]deallocate([NS]T *unencumbered){
- free(unencumbered);
- }
-
- #endif // LOCAL not defined
-
-
- #ifdef LOCAL
-
- // local code implementing everything
- struct [NS]T{
- Digit d[[NS]DIGIT_COUNT];
- };
-
- // Constant Setters
-
- Local void [NS]set_zero([NS]T *destination){
- if(!destination) return;
- Digit *start = destination->d;
- Digit *end = destination->d + [NS]DIGIT_COUNT;
- for(Digit *p = start ; p < end ; p++){
- *p = 0;
- }
- }
-
- Local void [NS]set_one([NS]T *destination){
- if(!destination) return;
- [NS]set_zero(destination);
- destination->d[0] = 1;
- }
-
- Local void [NS]set_all_bits([NS]T *destination){
- if(!destination) return;
- Digit *start = destination->d;
- Digit *end = destination->d + [NS]DIGIT_COUNT;
- for(Digit *p = start ; p < end ; p++){
- *p = (Digit)(-1);
- }
- }
-
- Local void [NS]set_msb([NS]T *destination){
- if(!destination) return;
- [NS]set_zero(destination);
- // Set top bit in the highest digit
- destination->d[[NS]DIGIT_COUNT - 1] = ((Digit)1 << ((sizeof(Digit)*8) - 1));
- }
-
- // Bitwise
-
- Local void [NS]bit_and([NS]T *result ,[NS]T *a ,[NS]T *b){
- for(ExtentType i = 0 ; i < [NS]DIGIT_COUNT ; i++){
- result->d[i] = a->d[i] & b->d[i];
- }
- }
-
- Local void [NS]bit_or([NS]T *result ,[NS]T *a ,[NS]T *b){
- for(ExtentType i = 0 ; i < [NS]DIGIT_COUNT ; i++){
- result->d[i] = a->d[i] | b->d[i];
- }
- }
-
- Local void [NS]bit_complement([NS]T *result ,[NS]T *a){
- if(result == a){
- // same location
- for(ExtentType i = 0 ; i < [NS]DIGIT_COUNT ; i++){
- result->d[i] = ~result->d[i];
- }
- }else{
- for(ExtentType i = 0 ; i < [NS]DIGIT_COUNT ; i++){
- result->d[i] = ~a->d[i];
- }
- }
- }
-
- Local void [NS]bit_twos_complement([NS]T *result ,[NS]T *a){
- // ~ + 1 across [NS]DIGIT_COUNT digits
- // If result == a, we must do carefully
- [NS]T temp;
- if(result == a) {
- for(ExtentType i = 0 ; i < [NS]DIGIT_COUNT ; i++){
- temp.d[i] = ~a->d[i];
- }
- }else{
- for(ExtentType i = 0 ; i < [NS]DIGIT_COUNT ; i++){
- temp.d[i] = ~a->d[i];
- }
- }
- // now add 1
- Digit carry = 1;
- for(ExtentType i = 0 ; i < [NS]DIGIT_COUNT ; i++){
- unsigned __int128 v = (unsigned __int128)temp.d[i] + carry;
- temp.d[i] = (Digit)v;
- carry = (Digit)(v >> (sizeof(Digit)*8));
- }
- // copy back if needed
- if(result == a){
- for(ExtentType i = 0 ; i < [NS]DIGIT_COUNT ; i++){
- a->d[i] = temp.d[i];
- }
- }else{
- for(ExtentType i = 0 ; i < [NS]DIGIT_COUNT ; i++){
- result->d[i] = temp.d[i];
- }
- }
- }
-
- // Comparison
-
- Local [NS]Order [NS]compare([NS]T *a ,[NS]T *b){
- // compare from top to bottom
- for(ExtentType i = [NS]DIGIT_COUNT; i > 0 ; i--){
- ExtentType idx = i - 1;
- if(a->d[idx] < b->d[idx]) return [NS]Order_lt;
- if(a->d[idx] > b->d[idx]) return [NS]Order_gt;
- }
- return [NS]Order_eq;
- }
-
- Local bool [NS]eq([NS]T *a ,[NS]T *b){
- for(ExtentType i = 0 ; i < [NS]DIGIT_COUNT ; i++){
- if(a->d[i] != b->d[i]) return false;
- }
- return true;
- }
-
- Local bool [NS]eq_zero([NS]T *a){
- for(ExtentType i = 0 ; i < [NS]DIGIT_COUNT ; i++){
- if(a->d[i] != 0) return false;
- }
- return true;
- }
-
- // Arithmetic
-
- Local [NS]Status [NS]add([NS]T *sum ,[NS]T *a ,[NS]T *b){
- if(!sum || !a || !b) return [NS]Status_overflow;
- Digit carry = 0;
- for(ExtentType i = 0 ; i < [NS]DIGIT_COUNT ; i++){
- unsigned __int128 tmp = (unsigned __int128)a->d[i] + b->d[i] + carry;
- sum->d[i] = (Digit)tmp;
- carry = (Digit)(tmp >> (sizeof(Digit)*8));
- }
- return (carry != 0) ? [NS]Status_carry : [NS]Status_ok;
- }
-
- Local [NS]Status [NS]subtract([NS]T *diff ,[NS]T *a ,[NS]T *b){
- if(!diff || !a || !b) return [NS]Status_overflow;
- Digit borrow = 0;
- for(ExtentType i = 0 ; i < [NS]DIGIT_COUNT ; i++){
- unsigned __int128 tmpA = a->d[i];
- unsigned __int128 tmpB = b->d[i] + borrow;
- if(tmpA < tmpB){
- diff->d[i] = (Digit)((((unsigned __int128)1 << (sizeof(Digit)*8)) + tmpA) - tmpB);
- borrow = 1;
- }else{
- diff->d[i] = (Digit)(tmpA - tmpB);
- borrow = 0;
- }
- }
- return (borrow != 0) ? [NS]Status_borrow : [NS]Status_ok;
- }
-
- // Conversion
-
- Local void [NS]from_uint64([NS]T *destination ,uint64_t value){
- if(!destination) return;
- [NS]set_zero(destination);
- // store 'value' in the low words
- // note: if (DE + 1) < 2, we might only store partial
- destination->d[0] = (Digit)(value & 0xFFFFFFFFFFFFFFFFULL);
- #if DE >= 1
- if([NS]DIGIT_COUNT > 1){
- // store top half if digit is 32 bits etc, or 8 bits
- // we'll just do partial logic if digit < 64
- // for 32-bit digit, that means the next digit has (value >> 32)
- // for 8-bit digit, the next digits hold the rest, etc.
- // We'll keep it simple.
- // A more complete solution would loop if needed.
- if(sizeof(Digit)*8 < 64){
- // multi-split if needed
- // skipping for brevity
- }
- }
- #endif
- }
-
- #endif // LOCAL
-
-#endif // [NS]IMPLEMENTATION
--- /dev/null
+
+The currently the N{64,32,16,8} files make use of native types for 2x width accumulators.
+
+The generic multi-precision types with 0 digit array extent, will not have native types at 2x size but instead will use two digits.
--- /dev/null
+
+* 2025-02-14T16:12:47Z new namespace names for the current `.lib_std` files.
+done
+
+* 2025-02-14T16:20:52Z consider adding macros to replace multi-digit sequences with native types when available in some situations.
--- /dev/null
+changequote([,])dnl
+define(NS, __NAMESPACE__)dnl
+define(DE, __DIGIT_EXTENT__)dnl
+define(DT, __DIGIT_TYPE__)dnl
+define(ET, __EXTENT_TYPE__)dnl
+changequote(`,')dnl
+
+/*
+ [NS] - Parametric multi-digit type library (RT code format)
+
+ Parameters:
+ [NS]: Namespace prefix, e.g. N32路
+ [DE]: Digit extent => total digits = DE + 1
+ [DT]: Digit type, e.g. uint64_t or uint8_t
+ [ET]: Loop counter type, e.g. uint64_t
+*/
+
+#define [NS]DEBUG
+
+#ifndef FACE
+ #define [NS]IMPLEMENTATION
+ #define FACE
+#endif
+
+//------------------------------------------------------------------------------
+// Interface Section
+
+#ifndef [NS]FACE
+#define [NS]FACE
+
+ #include <stdint.h>
+ #include <stdbool.h>
+ #include <stdarg.h>
+ #include <stdlib.h>
+
+ // Digit count is DE + 1
+ #define [NS]DIGIT_COUNT (DE + 1)
+
+ typedef DT Digit;
+ typedef struct [NS]T [NS]T;
+
+ // For array allocations
+ typedef ET ExtentType;
+
+ // Status codes
+ typedef enum{
+ [NS]Status_ok = 0
+ ,[NS]Status_overflow
+ ,[NS]Status_accumulator1_overflow
+ ,[NS]Status_carry
+ ,[NS]Status_borrow
+ ,[NS]Status_undefined_divide_by_zero
+ ,[NS]Status_undefined_modulus_zero
+ ,[NS]Status_gt_max_shift_count
+ ,[NS]Status_spill_eq_operand
+ ,[NS]Status_one_word_product
+ ,[NS]Status_two_word_product
+ } [NS]Status;
+
+ typedef enum{
+ [NS]Order_lt = -1
+ ,[NS]Order_eq = 0
+ ,[NS]Order_gt = 1
+ } [NS]Order;
+
+ // Allocation
+ Digit *[NS]allocate_array(ExtentType extent ,[NS]T *(*fault_handler)(ExtentType));
+ Digit *[NS]allocate_array_zero(ExtentType extent ,[NS]T *(*fault_handler)(ExtentType));
+ void [NS]deallocate([NS]T *unencumbered);
+
+ // Constant setters (no static global constants)
+ void [NS]set_zero([NS]T *destination);
+ void [NS]set_one([NS]T *destination);
+ void [NS]set_all_bits([NS]T *destination);
+ void [NS]set_msb([NS]T *destination);
+
+ // Bitwise ops
+ void [NS]bit_and([NS]T *result ,[NS]T *a ,[NS]T *b);
+ void [NS]bit_or([NS]T *result ,[NS]T *a ,[NS]T *b);
+ void [NS]bit_complement([NS]T *result ,[NS]T *a);
+ void [NS]bit_twos_complement([NS]T *result ,[NS]T *a);
+
+ // Comparison ops
+ bool [NS]eq([NS]T *a ,[NS]T *b);
+ bool [NS]eq_zero([NS]T *a);
+ [NS]Order [NS]compare([NS]T *a ,[NS]T *b);
+
+ // Arithmetic
+ [NS]Status [NS]add([NS]T *sum ,[NS]T *a ,[NS]T *b);
+ [NS]Status [NS]subtract([NS]T *diff ,[NS]T *a ,[NS]T *b);
+
+ // Conversions
+ void [NS]from_uint64([NS]T *destination ,uint64_t value);
+
+#endif // [NS]FACE
+
+
+//------------------------------------------------------------------------------
+// Implementation Section
+
+#ifdef [NS]IMPLEMENTATION
+
+ #ifndef LOCAL
+
+ #include <stdarg.h>
+ #include <stdlib.h>
+
+ struct [NS]T{
+ Digit d[[NS]DIGIT_COUNT];
+ };
+
+ Digit *[NS]allocate_array(ExtentType extent ,[NS]T *(*fault_handler)(ExtentType)){
+ [NS]T *instance = malloc((extent + 1) * sizeof([NS]T));
+ if(!instance){
+ if(fault_handler) return (Digit*)fault_handler(extent);
+ return NULL;
+ }
+ return (Digit*)instance;
+ }
+
+ Digit *[NS]allocate_array_zero(ExtentType extent ,[NS]T *(*fault_handler)(ExtentType)){
+ [NS]T *instance = calloc(extent + 1 ,sizeof([NS]T));
+ if(!instance){
+ if(fault_handler) return (Digit*)fault_handler(extent);
+ return NULL;
+ }
+ return (Digit*)instance;
+ }
+
+ void [NS]deallocate([NS]T *unencumbered){
+ free(unencumbered);
+ }
+
+ #endif // LOCAL not defined
+
+
+ #ifdef LOCAL
+
+ // local code implementing everything
+ struct [NS]T{
+ Digit d[[NS]DIGIT_COUNT];
+ };
+
+ // Constant Setters
+
+ Local void [NS]set_zero([NS]T *destination){
+ if(!destination) return;
+ Digit *start = destination->d;
+ Digit *end = destination->d + [NS]DIGIT_COUNT;
+ for(Digit *p = start ; p < end ; p++){
+ *p = 0;
+ }
+ }
+
+ Local void [NS]set_one([NS]T *destination){
+ if(!destination) return;
+ [NS]set_zero(destination);
+ destination->d[0] = 1;
+ }
+
+ Local void [NS]set_all_bits([NS]T *destination){
+ if(!destination) return;
+ Digit *start = destination->d;
+ Digit *end = destination->d + [NS]DIGIT_COUNT;
+ for(Digit *p = start ; p < end ; p++){
+ *p = (Digit)(-1);
+ }
+ }
+
+ Local void [NS]set_msb([NS]T *destination){
+ if(!destination) return;
+ [NS]set_zero(destination);
+ // Set top bit in the highest digit
+ destination->d[[NS]DIGIT_COUNT - 1] = ((Digit)1 << ((sizeof(Digit)*8) - 1));
+ }
+
+ // Bitwise
+
+ Local void [NS]bit_and([NS]T *result ,[NS]T *a ,[NS]T *b){
+ for(ExtentType i = 0 ; i < [NS]DIGIT_COUNT ; i++){
+ result->d[i] = a->d[i] & b->d[i];
+ }
+ }
+
+ Local void [NS]bit_or([NS]T *result ,[NS]T *a ,[NS]T *b){
+ for(ExtentType i = 0 ; i < [NS]DIGIT_COUNT ; i++){
+ result->d[i] = a->d[i] | b->d[i];
+ }
+ }
+
+ Local void [NS]bit_complement([NS]T *result ,[NS]T *a){
+ if(result == a){
+ // same location
+ for(ExtentType i = 0 ; i < [NS]DIGIT_COUNT ; i++){
+ result->d[i] = ~result->d[i];
+ }
+ }else{
+ for(ExtentType i = 0 ; i < [NS]DIGIT_COUNT ; i++){
+ result->d[i] = ~a->d[i];
+ }
+ }
+ }
+
+ Local void [NS]bit_twos_complement([NS]T *result ,[NS]T *a){
+ // ~ + 1 across [NS]DIGIT_COUNT digits
+ // If result == a, we must do carefully
+ [NS]T temp;
+ if(result == a) {
+ for(ExtentType i = 0 ; i < [NS]DIGIT_COUNT ; i++){
+ temp.d[i] = ~a->d[i];
+ }
+ }else{
+ for(ExtentType i = 0 ; i < [NS]DIGIT_COUNT ; i++){
+ temp.d[i] = ~a->d[i];
+ }
+ }
+ // now add 1
+ Digit carry = 1;
+ for(ExtentType i = 0 ; i < [NS]DIGIT_COUNT ; i++){
+ unsigned __int128 v = (unsigned __int128)temp.d[i] + carry;
+ temp.d[i] = (Digit)v;
+ carry = (Digit)(v >> (sizeof(Digit)*8));
+ }
+ // copy back if needed
+ if(result == a){
+ for(ExtentType i = 0 ; i < [NS]DIGIT_COUNT ; i++){
+ a->d[i] = temp.d[i];
+ }
+ }else{
+ for(ExtentType i = 0 ; i < [NS]DIGIT_COUNT ; i++){
+ result->d[i] = temp.d[i];
+ }
+ }
+ }
+
+ // Comparison
+
+ Local [NS]Order [NS]compare([NS]T *a ,[NS]T *b){
+ // compare from top to bottom
+ for(ExtentType i = [NS]DIGIT_COUNT; i > 0 ; i--){
+ ExtentType idx = i - 1;
+ if(a->d[idx] < b->d[idx]) return [NS]Order_lt;
+ if(a->d[idx] > b->d[idx]) return [NS]Order_gt;
+ }
+ return [NS]Order_eq;
+ }
+
+ Local bool [NS]eq([NS]T *a ,[NS]T *b){
+ for(ExtentType i = 0 ; i < [NS]DIGIT_COUNT ; i++){
+ if(a->d[i] != b->d[i]) return false;
+ }
+ return true;
+ }
+
+ Local bool [NS]eq_zero([NS]T *a){
+ for(ExtentType i = 0 ; i < [NS]DIGIT_COUNT ; i++){
+ if(a->d[i] != 0) return false;
+ }
+ return true;
+ }
+
+ // Arithmetic
+
+ Local [NS]Status [NS]add([NS]T *sum ,[NS]T *a ,[NS]T *b){
+ if(!sum || !a || !b) return [NS]Status_overflow;
+ Digit carry = 0;
+ for(ExtentType i = 0 ; i < [NS]DIGIT_COUNT ; i++){
+ unsigned __int128 tmp = (unsigned __int128)a->d[i] + b->d[i] + carry;
+ sum->d[i] = (Digit)tmp;
+ carry = (Digit)(tmp >> (sizeof(Digit)*8));
+ }
+ return (carry != 0) ? [NS]Status_carry : [NS]Status_ok;
+ }
+
+ Local [NS]Status [NS]subtract([NS]T *diff ,[NS]T *a ,[NS]T *b){
+ if(!diff || !a || !b) return [NS]Status_overflow;
+ Digit borrow = 0;
+ for(ExtentType i = 0 ; i < [NS]DIGIT_COUNT ; i++){
+ unsigned __int128 tmpA = a->d[i];
+ unsigned __int128 tmpB = b->d[i] + borrow;
+ if(tmpA < tmpB){
+ diff->d[i] = (Digit)((((unsigned __int128)1 << (sizeof(Digit)*8)) + tmpA) - tmpB);
+ borrow = 1;
+ }else{
+ diff->d[i] = (Digit)(tmpA - tmpB);
+ borrow = 0;
+ }
+ }
+ return (borrow != 0) ? [NS]Status_borrow : [NS]Status_ok;
+ }
+
+ // Conversion
+
+ Local void [NS]from_uint64([NS]T *destination ,uint64_t value){
+ if(!destination) return;
+ [NS]set_zero(destination);
+ // store 'value' in the low words
+ // note: if (DE + 1) < 2, we might only store partial
+ destination->d[0] = (Digit)(value & 0xFFFFFFFFFFFFFFFFULL);
+ #if DE >= 1
+ if([NS]DIGIT_COUNT > 1){
+ // store top half if digit is 32 bits etc, or 8 bits
+ // we'll just do partial logic if digit < 64
+ // for 32-bit digit, that means the next digit has (value >> 32)
+ // for 8-bit digit, the next digits hold the rest, etc.
+ // We'll keep it simple.
+ // A more complete solution would loop if needed.
+ if(sizeof(Digit)*8 < 64){
+ // multi-split if needed
+ // skipping for brevity
+ }
+ }
+ #endif
+ }
+
+ #endif // LOCAL
+
+#endif // [NS]IMPLEMENTATION
# -D__EXTENT_TYPE__=uint64_t \
# src/N_template.lib.c.m4 > src/N128.lib.c
-# m4 -D__NAMESPACE__=N32路 -D__DIGIT_EXTENT__=0 -D__DIGIT_TYPE__=uint32_t -D__EXTENT_TYPE__=uint32_t cc馃枆/N_template.lib.c.m4 > cc馃枆N32.lib.c
+# m4 -D__NAMESPACE__=N32路 -D__DIGIT_EXTENT__=0 -D__DIGIT_TYPE__=uint32_t -D__EXTENT_TYPE__=uint32_t m4馃枆/N_template.lib.c.m4 > cc/N32.lib.c
/bin/make -f tool馃枆/makefile $@