--- /dev/null
+/*
+ N_32 - 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 N_32路DEBUG
+
+#ifndef IFACE
+#define N_32路IMPLEMENTATION
+#define IFACE
+#endif
+
+//--------------------------------------------------------------------------------
+// Interface
+
+#ifndef N_32路IFACE
+#define N_32路IFACE
+
+#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 N_32 N_32;
+
+extern N_32 *N_32路zero;
+extern N_32 *N_32路one;
+extern N_32 *N_32路all_one_bit;
+extern N_32 *N_32路lsb;
+extern N_32 *N_32路msb;
+
+//----------------------------------------
+// Return/Error Status and handlers
+
+typedef enum{
+ N_32路Status路ok = 0
+ ,N_32路Status路overflow = 1
+ ,N_32路Status路accumulator1_overflow = 2
+ ,N_32路Status路carry = 3
+ ,N_32路Status路borrow = 4
+ ,N_32路Status路undefined_divide_by_zero = 5
+ ,N_32路Status路undefined_modulus_zero = 6
+ ,N_32路Status路gt_max_lsb_index = 7
+ ,N_32路Status路spill_eq_operand = 8 // not currently signaled, result will be spill value
+ ,N_32路Status路one_word_product = 9
+ ,N_32路Status路two_word_product = 10
+} N_32路Status;
+
+typedef enum{
+ N_32路Order_lt = -1
+ ,N_32路Order_eq = 0
+ ,N_32路Order_gt = 1
+} N_32路Order;
+
+typedef N_32 *( *N_32路Allocate_MemoryFault )(Extent);
+
+//----------------------------------------
+// Interface
+
+typedef struct{
+ N_32 *( *allocate )(Extent, N_32路Allocate_MemoryFault);
+ void ( *deallocate )(N_32 *);
+ void ( *copy )(N_32 *, N_32 *);
+ void ( *bit_and )(N_32 *, N_32 *, N_32 *);
+ void ( *bit_or )(N_32 *, N_32 *, N_32 *);
+ void ( *bit_complement )(N_32 *, N_32 *);
+ void ( *bit_twos_complement )(N_32 *, N_32 *);
+ N_32路Order ( *compare )(N_32 *, N_32 *);
+ bool ( *lt )(N_32 *, N_32 *);
+ bool ( *gt )(N_32 *, N_32 *);
+ bool ( *eq )(N_32 *, N_32 *);
+ N_32路Status ( *add )(N_32 *, N_32 *, N_32 *);
+ N_32路Status ( *subtract )(N_32 *, N_32 *, N_32 *);
+ N_32路Status ( *multiply )(N_32 *, N_32 *, N_32 *, N_32 *);
+ N_32路Status ( *divide )(N_32 *, N_32 *, N_32 *, N_32 *);
+ void ( *shift_left )(Extent, N_32 *, N_32 *, N_32 *);
+ void ( *shift_right )(Extent, N_32 *, N_32 *, N_32 *);
+} N_32路Interface;
+
+extern const N_32路Interface N_32路interface;
+
+#endif
+
+//--------------------------------------------------------------------------------
+// Implementation
+
+#ifdef N_32路IMPLEMENTATION
+
+// this part goes into the library
+#ifndef LOCAL
+
+#include <stdarg.h>
+#include <stdlib.h>
+
+struct N_32{
+ Digit d0;
+};
+
+N_32 N_32路constant[4] ={
+ {.d0 = 0},
+ {.d0 = 1},
+ {.d0 = ~(uint32_t)0},
+ {.d0 = 1 << 31}
+};
+
+N_32 *N_32路zero = &N_32路constant[0];
+N_32 *N_32路one = &N_32路constant[1];
+N_32 *N_32路all_one_bit = &N_32路constant[2];
+N_32 *N_32路msb = &N_32路constant[3];
+N_32 *N_32路lsb = &N_32路constant[1];
+
+// the allocate an array of N_32
+N_32 *N_32路allocate_array( Extent extent ,N_32 *(*memory_fault)(Extent) ){
+ N_32 *instance = malloc((extent + 1) * sizeof(N_32) );
+ if(!instance){
+ return memory_fault ? memory_fault(extent) : NULL;
+ }
+ return instance;
+}
+
+N_32 *N_32路alloc_array_zero( Extent extent ,N_32 *(*memory_fault)(Extent) ){
+ N_32 *instance = calloc( extent + 1 ,sizeof(N_32) );
+ if(!instance){
+ return memory_fault ? memory_fault(extent) : NULL;
+ }
+ return instance;
+}
+
+void N_32路deallocate(N_32 *unencumbered){
+ free(unencumbered);
+}
+
+
+#endif
+
+// This part is included after the library user's code
+#ifdef LOCAL
+
+// instance
+
+struct N_32{
+ 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 N_32 N_32路t[4]
+
+
+// allocation
+
+extern N_32 *N_32路allocate_array(Extent, N_32路Allocate_MemoryFault);
+extern N_32 *N_32路alloc_array_zero(Extent, N_32路Allocate_MemoryFault);
+extern void N_32路deallocate(N_32 *);
+
+// copy, convenience copy
+
+Local void N_32路copy(N_32 *destination ,N_32 *source){
+ if(source == destination) return; // that was easy!
+ *destination = *source;
+}
+
+Local void N_32路set_to_zero(N_32 *instance){
+ instance->d0 = 0;
+}
+
+Local void N_32路set_to_one(N_32 *instance){
+ instance->d0 = 1;
+}
+
+// bit operations
+
+Local void N_32路bit_and(N_32 *result, N_32 *a, N_32 *b){
+ result->d0 = a->d0 & b->d0;
+}
+
+// result can be one of the operands
+Local void N_32路bit_or(N_32 *result, N_32 *a, N_32 *b){
+ result->d0 = a->d0 | b->d0;
+}
+
+// result can the same as the operand
+Local void N_32路bit_complement(N_32 *result, N_32 *a){
+ result->d0 = ~a->d0;
+}
+
+// result can the same as the operand
+Local void N_32路bit_twos_complement(N_32 *result ,N_32 *a){
+ result->d0 = ~a->d0 + 1;
+}
+
+// test functions
+
+Local N_32路Order N_32路compare(N_32 *a, N_32 *b){
+ if (a->d0 < b->d0) return N_32路Order_lt;
+ if (a->d0 > b->d0) return N_32路Order_gt;
+ return N_32路Order_eq;
+}
+
+Local bool N_32路lt(N_32 *a ,N_32 *b){
+ return a->d0 < b->d0;
+}
+
+Local bool N_32路gt(N_32 *a ,N_32 *b){
+ return a->d0 > b->d0;
+}
+
+Local bool N_32路eq(N_32 *a ,N_32 *b){
+ return a->d0 == b->d0;
+}
+
+Local bool N_32路eq_zero(N_32 *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 N_32路Status路accumulator1_overflow
+//
+// When accumulator1 and accumulator0 point to the same location, the result is the accumulator1 value.
+Local N_32路Status N_32路accumulate(N_32 *accumulator1 ,N_32 *accumulator0 ,...){
+
+ va_list args;
+ va_start(args ,accumulator0);
+
+ uint64_t *sum = &accumulator0->d0;
+ uint64_t *carry = 0;
+ N_32 *current;
+
+ while( (current = va_arg(args ,N_32 *)) ){
+ *sum += current->d0;
+ if(*sum < current->d0){ // Accumulator1 into carry
+ (*carry)++;
+ if(*carry == 0){
+ va_end(args);
+ return N_32路Status路accumulator1_overflow;
+ }
+ }
+ }
+ va_end(args);
+
+ // wipes out prior value of accumulator1
+ accumulator1->d0 = carry;
+
+ return N_32路Status路ok;
+}
+
+Local N_32路Status N_32路add(N_32 *sum ,N_32 *a ,N_32 *b){
+ uint64_t result = (uint64_t)a->d0 + (uint64_t)b->d0;
+ sum->d0 = (uint32_t)result;
+ return (result >> 32) ? N_32路Status路carry : N_32路Status路ok;
+}
+
+Local bool N_32路increment(N_32 *a){
+ a->d0++;
+ return a->d0 == 0;
+}
+
+Local N_32路Status N_32路subtract(N_32 *difference ,N_32 *a ,N_32 *b){
+ uint64_t diff = (uint64_t)a->d0 - (uint64_t)b->d0;
+ difference->d0 = (uint32_t)diff;
+ return (diff > a->d0) ? N_32路Status路borrow : N_32路Status路ok;
+}
+
+
+Local N_32路Status N_32路multiply(N_32 *product1 ,N_32 *product0 ,N_32 *a ,N_32 *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 N_32路status路one_word_product;
+ return N_32路status路two_word_product;
+}
+
+Local N_32路Status N_32路divide(N_32 *remainder ,N_32 *quotient ,N_32 *a ,N_32 *b){
+ if(b->d0 == 0) return N_32路Status路undefined_divide_by_zero;
+
+ quotient->d0 = a->d0 / b->d0;
+ remainder->d0 = a->d0 - (quotient->d0 * b->d0);
+
+ return N_32路Status路ok;
+}
+
+Local N_32路Status N_32路modulus(N_32 *remainder ,N_32 *a ,N_32 *b){
+ if(b->d0 == 0) return N_32路Status路undefined_modulus_zero;
+ uint32_t quotient = a->d0 / b->d0;
+ remainder->d0 = a->d0 - (quotient * b->d0);
+ return N_32路Status路ok;
+}
+
+// bit motion
+
+// This is a bit shift, not a word shift. If you have a general shift count, shift words by
+// the div of the shift count, then call this with the modulus 32 of the shift count.
+//
+// If spill and operand or fill are the same value, the result is the spill (for both).
+//
+// `new_lsb_index` aka the `shift_count`
+// shifts a binary number the lsb bit index to as far as 31
+// NULL operand treated as zero
+Local N_32路Status N_32路shift_left
+ (
+ uint32_t new_lsb_index
+ ,N_32 *spill
+ ,N_32 *operand
+ ,N_32 *fill
+ ){
+
+ // If the caller doesn't want a result back, we are all done.
+ if(operand == NULL && spill == NULL) return N_32路Status路ok;
+
+ #ifdef N_32路DEBUG
+ if( spill == operand ){
+ fprintf(stderr, "N_32路shift_left spill == operand\n");
+ }
+ #endif
+
+ // For the sake of setting spill, we will treat a NULL operand as zero.
+ if(operand == NULL){
+ operand = &N_32路t[0];
+ N_32路copy(operand ,N_32路zero);
+ }
+
+ // Shifting more than one word breaks our fill/spill model.
+ if(new_lsb_index > 31) return N_32路Status路gt_max_lsb_index;
+
+ // The given operand is still required after it is modified, so we copy it.
+ N_32 *given_operand = &N_32路t[1];
+ N_32路copy(given_operand ,operand);
+
+ // spill is overwritten with a new value
+ operand->d0 = given_operand->d0 << new_lsb_index;
+ if(fill != NULL){
+ fill->d0 = fill->d0 >> (32 - new_lsb_index);
+ N_32路bit_or(operand ,operand ,fill);
+ }
+ if(spill != NULL){
+ spill->d0 = spill->d0 << new_lsb_index;
+ spill->d0 += given_operand->d0 >> (32 - new_lsb_index);
+ }
+ return N_32路Status路ok;
+}
+
+Local N_32路Status N_32路shift_right
+ (
+ uint32_t msb_index_offset
+ ,N_32 *spill
+ ,N_32 *operand
+ ,N_32 *fill
+ ){
+
+ // If the caller doesn't want a result back, we are all done.
+ if(operand == NULL && spill == NULL) return N_32路Status路ok;
+
+ // For the sake of setting spill, we will treat a NULL operand as zero.
+ if(operand == NULL){
+ operand = &N_32路t[0];
+ N_32路copy(operand ,N_32路zero);
+ }
+
+ // Shifting more than one word breaks our fill/spill model.
+ if(msb_index_offset > 31) return N_32路Status路gt_max_lsb_index;
+
+ // In theory, fill should not have any bits in common with the shifted operand.
+ #ifdef N_32路DEBUG
+ if( !N_32路eq_zero(fill->d0 << (32 - msb_index_offset)) ){
+ fprintf(stderr, "N_32路shift_right fill value overlaps with shifted operand\n");
+ }
+ #endif
+
+ // The given operand is still required after it is modified, so we copy it.
+ N_32 *given_operand = &N_32路t[1];
+ N_32路copy(given_operand ,operand);
+
+ // spill is overwritten with a new value
+ operand->d0 = given_operand->d0 >> msb_index_offset;
+ if(fill != NULL){
+ fill->d0 = fill->d0 << (32 - msb_index_offset);
+ N_32路bit_or(operand ,operand ,fill);
+ }
+ if(spill != NULL){
+ spill->d0 = spill->d0 >> msb_index_offset;
+ spill->d0 += given_operand->d0 << (32 - msb_index_offset);
+ }
+ return N_32路Status路ok;
+}
+
+
+Local void N_32路arithmetic_shift_right(Extent shift, N_32 *operand, N_32 *spill) {
+
+ // caller wants us to do nothing, a little strange, but Ok ..
+ if (operand == NULL || spill == NULL) return N_32路Status路ok;
+
+ // check if we are shifting in ones or zeros
+ N_32路bit_and(&N_32路t[0], operand, N_32路msb);
+ N_32 *source_pt = N_32路eq_zero(&N_32路t[0]) ? N_32路zero : N_32路all_one_bit;
+
+ // uses `t[2]` because shift_right uses `t[0]` and `t[1]`
+ N_32路copy(&N_32路t[2], source_pt);
+ N_32路shift_right(shift, &N_32路t[2], operand, spill);
+}
+
+// an interface instance
+
+Local const N_32路Interface N_32路interface = {
+ .copy = N_32路copy
+ ,.bit_and = N_32路bit_and
+ ,.bit_or = N_32路bit_or
+ ,.bit_complement = N_32路bit_complement
+ ,.bit_twos_complement = N_32路bit_twos_complement
+ ,.compare = N_32路compare
+ ,.lt = N_32路lt
+ ,.gt = N_32路gt
+ ,.eq = N_32路eq
+ ,.eq_zero = N_32路eq_zero
+ ,.eq_one = N_32路eq_one
+ ,.accumulate = N_32路accumulate
+ ,.add = N_32路add
+ ,.next = N_32路next
+ ,.subtract = N_32路subtract
+ ,.multiply = N_32路multiply
+ ,.divide = N_32路divide
+ ,.modulus = N_32路modulus
+ ,.shift_left = N_32路shift_left
+ ,.shift_right = N_32路shift_right
+ ,.arithmetic_shift_right = N_32路arithmetic_shift_right
+ ,.allocate_array = N_32路allocate_array
+ ,.allocate_array_zero = N_32路alloc_array_zero
+ ,.deallocate = N_32路deallocate
+};
+
+#endif
+
+#endif
+++ /dev/null
-/*
- N_32 - a processor native type
-
- For binary operations: a op b -> c
-
- To use N_32, first allocate a block of N_32. Do the arithmetic,
- if any results need be kept, copy them to another block. Then deallocate
- the block. Do not allocate numbers one at a time, or it would be slow.
-
-*/
-
-#ifndef IFACE
-#define N_32路IMPLEMENTATION
-#define IFACE
-#endif
-
-#ifndef N_32路IFACE
-#define N_32路IFACE
-
- //----------------------------------------
- // The instance data
- // no way to avoid adding this definition to the interface due to the use of inline functions
-
- typedef uint32_t Extent;
- typedef uint32_t Digit;;
-
- struct N_32 {
- Digit d0;
- };
-
- const N_32 N_32路zero;
- const N_32 N_32路one;
- const N_32 N_32路all_ones;
-
-
- //----------------------------------------
- // error status return values, and error handlers
- //
-
- typedef enum {
- N_32路Status路ok = 0
- ,N_32路Status路overflow = 1
- ,N_32路Status路accumulator_overflow = 2
- ,N_32路Status路carry = 3
- ,N_32路Status路borrow = 4
- ,N_32路Status路undefined_divide_by_zero = 5
- ,N_32路Status路undefined_modulus_zero = 6
- } N_32路Status;
-
- typedef enum {
- N_32路Order路lt = -1 // Less Than
- ,N_32路Order路eq = 0 // Equal
- ,N_32路Order路gt = 1 // Greater Than
- } N_32路Order;
-
- typedef N_32 *( *N_32路Allocate路MemoryFault )(Extent);
-
- //----------------------------------------
- // inline interface
- //
-
- // copy, convenience copy
-
- inline void N_32路copy(N_32 *destination ,N_32 *source){
- *destination = *source;
- }
-
- inline N_32 N_32路c(N_32 *source){
- return *source;
- }
-
- inline N_32 N_32路c_zero(void){
- return c(N_32路zero);
- }
-
- inline N_32 N_32路c_one(void){
- return c(N_32路one);
- }
-
- inline N_32 N_32路c_all_ones(void){
- return c(N_32路all_ones);
- }
-
-
- inline void N_32路set_to_zero(N_32 *instance){
- instance->d0 = 0;
- }
-
- inline void N_32路set_to_one(N_32 *instance){
- instance->d0 = 1;
- }
-
- // bit operations
-
- inline void N_32路and(N_32 *result ,N_32 *a ,N_32 *b){
- result->d0 = a->d0 & b->d0;
- }
-
- inline void N_32路or(N_32 *result ,N_32 *a ,N_32 *b){
- result->d0 = a->d0 | b->d0;
- }
-
- inline void N_32路complement(N_32 *result ,N_32 *a){
- result->d0 = ~a->d0;
- }
-
- inline void N_32路twos_complement(N_32 *result ,N_32 *a){
- result->d0 = ~a->d0 + 1;
- }
-
- inline bool N_32路lsb_is_set(N_32 *a){
- return a->d0 & 0x0000001;
- }
-
- inline bool N_32路msb_is_set(N_32 *a){
- return a->d0 & 0x8000000;
- }
-
- // for low precision Natural, and large number of summands for accumulate/add/sub, overflow could overflow and thus this op would fail
- inline N_32路Status N_32路accumulate(N_32 *overflow ,N_32 *accumulator ,...){
- va_list args;
- va_start(args ,accumulator);
-
- uint64_t *sum = &accumulator->d0;
- uint64_t *carry = &overflow->d0;
- N_32 *current;
-
- while( (current = va_arg(args ,N_32 *)) ){
- *sum += current->d0;
- if(*sum < current->d0){ // Overflow into carry
- (*carry)++;
- if(*carry == 0){
- va_end(args);
- return N_32路Status路accumulator_overflow;
- }
- }
- }
- va_end(args);
-
- if(*carry == 0) return N_32路Status路ok;
- return N_32路Status路OVERFLOW;
- }
-
- inline N_32路Order N_32路compare(N_32 *a ,N_32 *b){
- if(a->d0 < b->d0) return N_32路order路lt;
- if(a->d0 > b->d0) return N_32路order路gt;
- return N_32路order路eq;
- }
-
- inline bool N_32路lt(N_32 *a ,N_32 *b){
- return a->d0 < b->d0;
- }
-
- inline bool N_32路gt(N_32 *a ,N_32 *b){
- return a->d0 > b->d0;
- }
-
- inline bool N_32路eq(N_32 *a ,N_32 *b){
- return a->d0 == b->d0;
- }
-
- // arithmetic operations
-
- inline N_32路Status N_32路add(N_32 *sum ,N_32 *a ,N_32 *b){
- uint64_t result = (uint64_t)a->d0 + (uint64_t)b->d0;
- sum->d0 = (uint32_t)result;
- return (result >> 32) ? N_32路Status路carry : N_32路Status路ok;
- }
-
- inline N_32路Status N_32路next(N_32 *overflow ,N_32 *result ,N_32 *a){
- uint64_t sum = (uint64_t)a->d0 + (uint64_t)1;
- result->d0 = (uint32_t)sum;
- overflow->d0 = (uint32_t)(sum >> 32);
-
- if(overflow->d0 == 0) return N_32路status路ok;
- return N_32路status路overflow;
- }
-
- inline N_32路Status N_32路subtract(N_32 *difference ,N_32 *a ,N_32 *b){
- uint64_t diff = (uint64_t)a->d0 - (uint64_t)b->d0;
- difference->d0 = (uint32_t)diff;
- return (diff > a->d0) ? N_32路Status路borrow : N_32路Status路ok;
- }
-
- inline N_32路Status N_32路multiply(N_32 *overflow ,N_32 *result ,N_32 *a ,N_32 *b){
- uint64_t product = (uint64_t)a->d0 * (uint64_t)b->d0;
- result->d0 = (uint32_t)product;
- overflow->d0 = (uint32_t)(product >> 32);
-
- if(overflow->d0 == 0) return N_32路status路ok;
- return N_32路status路overflow;
- }
-
- inline N_32路Status N_32路divide(N_32 *remainder ,N_32 *quotient ,N_32 *a ,N_32 *b){
- if(b->d0 == 0) return N_32路Status路undefined_divide_by_zero;
-
- quotient->d0 = a->d0 / b->d0;
- remainder->d0 = a->d0 - (quotient->d0 * b->d0);
-
- return N_32路Status路ok;
- }
-
- inline N_32路Status N_32路modulus(N_32 *remainder ,N_32 *a ,N_32 *b){
- if(b->d0 == 0) return N_32路Status路undefined_modulus_zero;
- uint32_t quotient = a->d0 / b->d0;
- remainder->d0 = a->d0 - (quotient * b->d0);
- return N_32路Status路ok;
- }
-
- // shift
- inline void N_32路shift_left(Extent shift ,N_32 *sink ,N_32 *result ,N_32 *source){
- *sink = *source;
- result->d0 = source->d0 << shift;
- sink->d0 = source->d0 >> (32 - shift);
- }
-
- inline void N_32路shift_right(Extent shift ,N_32 *source ,N_32 *result ,N_32 *sink){
- *sink = *source;
- result->d0 = source->d0 >> shift;
- sink->d0 = source->d0 << (32 - shift);
- }
-
- inline void N_32路arithmetic_shift_right(Extent shift ,N_32 *result ,N_32 *sink){
- N_32 source;
- N_32 source = msb_is_set(result) ? N_32路all_ones : N_32路zero;
- N_32路shift_right(shift ,&source ,result ,sink);
- }
-
- //----------------------------------------
- // compiled interface
-
- typedef struct {
- N_32路Allocate allocate;
- N_32路Zero zero;
- N_32路One one;
- N_32路Deallocate deallocate;
- } N_32路Interface;
-
- extern const N_32路Interface N_32路interface;
-
-
-#endif
-
-#ifdef N_32路IMPLEMENTATION
-
- #include <stdarg.h>
- #include <stdlib.h>
-
- const N_32 N_32路zero = { .d0 = 0 };
- const N_32 N_32路one = { .d0 = 1 };
- const N_32 N_32路all_ones = { .d0 = ~(uint32_t)0 };
-
- // the allocate an array of N_32
- N_32 *N_32路allocate( Extent extent ,N_32 *(*memory_fault)(Extent) ){
- N_32 *instance = malloc((extent + 1) * sizeof(N_32) );
- if(!instance){
- return memory_fault ? memory_fault(extent) : NULL;
- }
- return instance;
- }
-
- N_32 *N_32路alloc_zero( Extent extent ,N_32 *(*memory_fault)(Extent) ){
- N_32 *instance = calloc( extent + 1 ,sizeof(N_32) );
- if(!instance){
- return memory_fault ? memory_fault(extent) : NULL;
- }
- return instance;
- }
-
- // initialize all with x
- N_32 *N_32路alloc_x(Extent extent ,N_32 *(*memory_fault)(Extent) ,N_32 *x){
- N_32 *instance = malloc((extent + 1) * sizeof(N_32));
- if(!instance){
- return memory_fault ? memory_fault(extent) : NULL;
- }
- N_32 *pt = instance;
- while( pt <= instance + extent ){
- *pt = *x;
- pt++;
- }
- return instance;
- }
-
- const N_32路Interface N_32路interface = {
- .allocate = N_32路allocate
- ,.allocate_zero = N_32路alloc_zero
- ,.allocate_all_x = N_32路alloc_x
- ,.deallocate = N_32路deallocate
- };
-
- void N_32路deallocate(N_32 *unencumbered){
- free(unencumbered);
- }
-
-#endif
+++ /dev/null
-/*
- A digit count followed by that many digits.
-
- Extent_Digit_Instance:
- - 'NN' stands for Natural Number representation.
- - 'Extent' refers to the maximum array index.
- - 'Digit' specifies that the representation involves digits.
- - 'Instance' differentiates this from the interface struct, ensuring clarity in alternative representations.
-*/
-
-#ifndef IFACE
-#define NN_Extent_Digit路IMPLEMENTATION
-#define IFACE
-#endif
-
-#ifndef NN_Extent_Digit路IFACE
-#define NN_Extent_Digit路IFACE
-
- typedef uint32_t Extent;
-
- // interface function signatures
- //
- typedef NN_Extent_Digit *(*NN_Extent_Digit路Copy路MemoryFault)
- (
- Extent extent
- );
-
- typedef NN_Extent_Digit *(*NN_Extent_Digit路Copy)
- (
- NN_Extent_Digit *original
- ,NN_Extent_Digit路Copy路MemoryFault memory_fault
- );
-
- typedef void (*NN_Extent_Digit路Accumulate)
- (
- NN_Extent_Digit *accumulator ,...
- );
-
- typedef NN_Extent_Digit *(*NN_Extent_Digit路Add)
- (
- NN_Extent_Digit *summand ,...
- );
-
- typedef NN_Extent_Digit *(*NN_Extent_Digit路Multiply)
- (
- NN_Extent_Digit *factor ,...
- );
-
- typedef NN_Extent_Digit *(*NN_Extent_Digit路Rotate_Right_Digit)
- (
- Extent count
- ,NN_Extent_Digit *a
- ,NN_Extent_Digit *b
- ,NN_Extent_Digit *c
- );
-
- typedef NN_Extent_Digit *(*NN_Extent_Digit路Rotate_Left_Digit)
- (
- Extent count
- ,NN_Extent_Digit *a
- ,NN_Extent_Digit *b
- ,NN_Extent_Digit *c
- );
-
- typedef NN_Extent_Digit *(*NN_Extent_Digit路Allocate路MemoryFault)
- (
- Extent extent
- );
-
- // interface struct definition
- //
- typedef struct {
- NN_Extent_Digit路Copy copy;
- NN_Extent_Digit路Accumulate accumulate;
- NN_Extent_Digit路Add add;
- NN_Extent_Digit路Multiply multiply;
- NN_Extent_Digit路Rotate_Right_Digit rotate_right_digit;
- NN_Extent_Digit路Rotate_Left_Digit rotate_left_digit;
- } NN_Extent_Digit;
-
- // an extent is a maximum array index
- NN_Extent_Digit *NN_Extent_Digit路allocate(Extent extent, NN_Extent_Digit路Allocate路MemoryFault memory_fault);
- void NN_Extent_Digit路deallocate(NN_Extent_Digit *unencumbered);
-
-#endif
-
-#ifdef NN_Extent_Digit路IMPLEMENTATION
-
- #include <stdarg.h>
- #include <stdlib.h>
- typedef uint32_t Digit;
-
- typedef struct {
- Extent extent;
- Digit a[];
- } Instance;
-
- NN_Extent_Digit *allocate(Extent extent, NN_Extent_Digit路Allocate路MemoryFault memory_fault){
- Extent allocation_size = sizeof(NN_Extent_Digit_Instance) + extent * sizeof(Digit) + sizeof(Digit);
- Instance *instance = malloc(allocation_size);
- if (!instance) {
- return memory_fault ? memory_fault(extent) : NULL;
- }
- instance->extent = extent;
-
- // nope-> need to allocate an interface signature struct and assign the method
- // function pointers to it. It will also need a field for holding the instance,
- // yes, declare a new interface struct that has an extra field on the bottom for
- // the instance pointer .. but then what of interface inheritance? hmmm. Perhaps
- // that is better done by composition anyway.
- return (NN_Extent_Digit *)instance;
- }
-
- void deallocate(NN_Extent_Digit *unencumbered){
- free(unencumbered);
- }
-
-#endif
--- /dev/null
+/*
+ A digit count followed by that many digits.
+
+ Extent_Digit_Instance:
+ - 'NN' stands for Natural Number representation.
+ - 'Extent' refers to the maximum array index.
+ - 'Digit' specifies that the representation involves digits.
+ - 'Instance' differentiates this from the interface struct, ensuring clarity in alternative representations.
+*/
+
+#ifndef IFACE
+#define NN_Extent_Digit路IMPLEMENTATION
+#define IFACE
+#endif
+
+#ifndef NN_Extent_Digit路IFACE
+#define NN_Extent_Digit路IFACE
+
+ typedef uint32_t Extent;
+
+ // interface function signatures
+ //
+ typedef NN_Extent_Digit *(*NN_Extent_Digit路Copy路MemoryFault)
+ (
+ Extent extent
+ );
+
+ typedef NN_Extent_Digit *(*NN_Extent_Digit路Copy)
+ (
+ NN_Extent_Digit *original
+ ,NN_Extent_Digit路Copy路MemoryFault memory_fault
+ );
+
+ typedef void (*NN_Extent_Digit路Accumulate)
+ (
+ NN_Extent_Digit *accumulator ,...
+ );
+
+ typedef NN_Extent_Digit *(*NN_Extent_Digit路Add)
+ (
+ NN_Extent_Digit *summand ,...
+ );
+
+ typedef NN_Extent_Digit *(*NN_Extent_Digit路Multiply)
+ (
+ NN_Extent_Digit *factor ,...
+ );
+
+ typedef NN_Extent_Digit *(*NN_Extent_Digit路Rotate_Right_Digit)
+ (
+ Extent count
+ ,NN_Extent_Digit *a
+ ,NN_Extent_Digit *b
+ ,NN_Extent_Digit *c
+ );
+
+ typedef NN_Extent_Digit *(*NN_Extent_Digit路Rotate_Left_Digit)
+ (
+ Extent count
+ ,NN_Extent_Digit *a
+ ,NN_Extent_Digit *b
+ ,NN_Extent_Digit *c
+ );
+
+ typedef NN_Extent_Digit *(*NN_Extent_Digit路Allocate路MemoryFault)
+ (
+ Extent extent
+ );
+
+ // interface struct definition
+ //
+ typedef struct {
+ NN_Extent_Digit路Copy copy;
+ NN_Extent_Digit路Accumulate accumulate;
+ NN_Extent_Digit路Add add;
+ NN_Extent_Digit路Multiply multiply;
+ NN_Extent_Digit路Rotate_Right_Digit rotate_right_digit;
+ NN_Extent_Digit路Rotate_Left_Digit rotate_left_digit;
+ } NN_Extent_Digit;
+
+ // an extent is a maximum array index
+ NN_Extent_Digit *NN_Extent_Digit路allocate(Extent extent, NN_Extent_Digit路Allocate路MemoryFault memory_fault);
+ void NN_Extent_Digit路deallocate(NN_Extent_Digit *unencumbered);
+
+#endif
+
+#ifdef NN_Extent_Digit路IMPLEMENTATION
+
+ #include <stdarg.h>
+ #include <stdlib.h>
+ typedef uint32_t Digit;
+
+ typedef struct {
+ Extent extent;
+ Digit a[];
+ } Instance;
+
+ NN_Extent_Digit *allocate(Extent extent, NN_Extent_Digit路Allocate路MemoryFault memory_fault){
+ Extent allocation_size = sizeof(NN_Extent_Digit_Instance) + extent * sizeof(Digit) + sizeof(Digit);
+ Instance *instance = malloc(allocation_size);
+ if (!instance) {
+ return memory_fault ? memory_fault(extent) : NULL;
+ }
+ instance->extent = extent;
+
+ // nope-> need to allocate an interface signature struct and assign the method
+ // function pointers to it. It will also need a field for holding the instance,
+ // yes, declare a new interface struct that has an extra field on the bottom for
+ // the instance pointer .. but then what of interface inheritance? hmmm. Perhaps
+ // that is better done by composition anyway.
+ return (NN_Extent_Digit *)instance;
+ }
+
+ void deallocate(NN_Extent_Digit *unencumbered){
+ free(unencumbered);
+ }
+
+#endif
--- /dev/null
+//----------------------------------------
+// Function Declarations
+
+void N_32_copy(N_32 *destination, N_32 *source);
+void N_32_bit_and(N_32 *result, N_32 *a, N_32 *b);
+void N_32_bit_or(N_32 *result, N_32 *a, N_32 *b);
+void N_32_bit_complement(N_32 *result, N_32 *a);
+N_32_Order N_32_compare(N_32 *a, N_32 *b);
+bool N_32_lt(N_32 *a, N_32 *b);
+bool N_32_gt(N_32 *a, N_32 *b);
+bool N_32_eq(N_32 *a, N_32 *b);
+N_32_Status N_32_add(N_32 *sum, N_32 *a, N_32 *b);
+N_32_Status N_32_subtract(N_32 *difference, N_32 *a, N_32 *b);
+N_32_Status N_32_multiply(N_32 *overflow, N_32 *result, N_32 *a, N_32 *b);
+N_32_Status N_32_divide(N_32 *remainder, N_32 *quotient, N_32 *a, N_32 *b);
+void N_32_shift_left(Extent shift, N_32 *sink, N_32 *result, N_32 *source);
+void N_32_shift_right(Extent shift, N_32 *source, N_32 *result, N_32 *sink);
+
+
+/*
+ N_32 - a processor native type
+
+ For binary operations: a op b -> c
+
+ To use N_32, first allocate a block of N_32. Do the arithmetic,
+ if any results need be kept, copy them to another block. Then deallocate
+ the block. Do not allocate numbers one at a time, or it would be slow.
+*/
+
+#ifndef IFACE
+#define N_32_IMPLEMENTATION
+#define IFACE
+#endif
+
+#ifndef N_32_IFACE
+#define N_32_IFACE
+
+#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 N_32 N_32;
+
+extern N_32 *N_32_zero;
+extern N_32 *N_32_one;
+extern N_32 *N_32_all_one_bit;
+extern N_32 *N_32_lsb;
+extern N_32 *N_32_msb;
+
+//----------------------------------------
+// Return Status
+
+typedef enum {
+ N_32_Status_ok = 0,
+ N_32_Status_overflow = 1,
+ N_32_Status_accumulator_overflow = 2,
+ N_32_Status_carry = 3,
+ N_32_Status_borrow = 4,
+ N_32_Status_undefined_divide_by_zero = 5,
+ N_32_Status_undefined_modulus_zero = 6
+} N_32_Status;
+
+typedef enum {
+ N_32_Order_lt = -1,
+ N_32_Order_eq = 0,
+ N_32_Order_gt = 1
+} N_32_Order;
+
+typedef N_32 *( *N_32_Allocate_MemoryFault )(Extent);
+
+//----------------------------------------
+// Interface
+
+typedef struct {
+ N_32 *( *allocate )(Extent, N_32_Allocate_MemoryFault);
+ void ( *deallocate )(N_32 *);
+ void ( *copy )(N_32 *, N_32 *);
+ void ( *bit_and )(N_32 *, N_32 *, N_32 *);
+ void ( *bit_or )(N_32 *, N_32 *, N_32 *);
+ void ( *bit_complement )(N_32 *, N_32 *);
+ N_32_Order ( *compare )(N_32 *, N_32 *);
+ bool ( *lt )(N_32 *, N_32 *);
+ bool ( *gt )(N_32 *, N_32 *);
+ bool ( *eq )(N_32 *, N_32 *);
+ N_32_Status ( *add )(N_32 *, N_32 *, N_32 *);
+ N_32_Status ( *subtract )(N_32 *, N_32 *, N_32 *);
+ N_32_Status ( *multiply )(N_32 *, N_32 *, N_32 *, N_32 *);
+ N_32_Status ( *divide )(N_32 *, N_32 *, N_32 *, N_32 *);
+ void ( *shift_left )(Extent, N_32 *, N_32 *, N_32 *);
+ void ( *shift_right )(Extent, N_32 *, N_32 *, N_32 *);
+} N_32_Interface;
+
+extern const N_32_Interface N_32_interface;
+
+#endif
+
+#ifdef N_32_IMPLEMENTATION
+
+#ifndef LOCAL
+
+struct{
+ Digit d0;
+} N_32;
+
+N_32 N_32_constant[4] = {
+ { .d0 = 0 },
+ { .d0 = 1 },
+ { .d0 = ~(uint32_t)0 },
+ { .d0 = 1 << 31 }
+};
+
+N_32 *N_32_zero = &N_32_constant[0];
+N_32 *N_32_one = &N_32_constant[1];
+N_32 *N_32_all_one_bit = &N_32_constant[2];
+N_32 *N_32_msb = &N_32_constant[3];
+N_32 *N_32_lsb = &N_32_constant[1];
+
+#endif
+
+#ifdef LOCAL
+
+struct{
+ Digit d0;
+} N_32;
+
+Local void N_32_copy(N_32 *destination, N_32 *source) {
+ *destination = *source;
+}
+
+Local void N_32_bit_and(N_32 *result, N_32 *a, N_32 *b) {
+ result->d0 = a->d0 & b->d0;
+}
+
+Local void N_32_bit_or(N_32 *result, N_32 *a, N_32 *b) {
+ result->d0 = a->d0 | b->d0;
+}
+
+Local void N_32_bit_complement(N_32 *result, N_32 *a) {
+ result->d0 = ~a->d0;
+}
+
+Local N_32_Order N_32_compare(N_32 *a, N_32 *b) {
+ if (a->d0 < b->d0) return N_32_Order_lt;
+ if (a->d0 > b->d0) return N_32_Order_gt;
+ return N_32_Order_eq;
+}
+
+Local void N_32_shift_left(Extent shift, N_32 *sink, N_32 *result, N_32 *source) {
+ *sink = *source;
+ result->d0 = source->d0 << shift;
+ sink->d0 = source->d0 >> (32 - shift);
+}
+
+Local void N_32_shift_right(Extent shift, N_32 *source, N_32 *result, N_32 *sink) {
+ *sink = *source;
+ result->d0 = source->d0 >> shift;
+ sink->d0 = source->d0 << (32 - shift);
+}
+
+Local const N_32_Interface N_32_interface = {
+ .copy = N_32_copy,
+ .bit_and = N_32_bit_and,
+ .bit_or = N_32_bit_or,
+ .bit_complement = N_32_bit_complement,
+ .compare = N_32_compare,
+ .shift_left = N_32_shift_left,
+ .shift_right = N_32_shift_right
+};
+
+#endif
+
+#endif
--- /dev/null
+/*
+ N_32 - a processor native type
+
+ For binary operations: a op b -> c
+
+ To use N_32, first allocate a block of N_32. Do the arithmetic,
+ if any results need be kept, copy them to another block. Then deallocate
+ the block. Do not allocate numbers one at a time, or it would be slow.
+
+*/
+
+#ifndef IFACE
+#define N_32路IMPLEMENTATION
+#define IFACE
+#endif
+
+#ifndef N_32路IFACE
+#define N_32路IFACE
+
+ //----------------------------------------
+ // The instance data
+ // no way to avoid adding this definition to the interface due to the use of inline functions
+
+ typedef uint32_t Extent;
+ typedef uint32_t Digit;;
+
+ struct N_32 {
+ Digit d0;
+ };
+
+ const N_32 N_32路zero;
+ const N_32 N_32路one;
+ const N_32 N_32路all_ones;
+
+
+ //----------------------------------------
+ // error status return values, and error handlers
+ //
+
+ typedef enum {
+ N_32路Status路ok = 0
+ ,N_32路Status路overflow = 1
+ ,N_32路Status路accumulator_overflow = 2
+ ,N_32路Status路carry = 3
+ ,N_32路Status路borrow = 4
+ ,N_32路Status路undefined_divide_by_zero = 5
+ ,N_32路Status路undefined_modulus_zero = 6
+ } N_32路Status;
+
+ typedef enum {
+ N_32路Order路lt = -1 // Less Than
+ ,N_32路Order路eq = 0 // Equal
+ ,N_32路Order路gt = 1 // Greater Than
+ } N_32路Order;
+
+ typedef N_32 *( *N_32路Allocate路MemoryFault )(Extent);
+
+ //----------------------------------------
+ // inline interface
+ //
+
+ // copy, convenience copy
+
+ inline void N_32路copy(N_32 *destination ,N_32 *source){
+ *destination = *source;
+ }
+
+ inline void N_32路set_to_zero(N_32 *instance){
+ instance->d0 = 0;
+ }
+
+ inline void N_32路set_to_one(N_32 *instance){
+ instance->d0 = 1;
+ }
+
+ // bit operations
+
+ inline void N_32路and(N_32 *result ,N_32 *a ,N_32 *b){
+ result->d0 = a->d0 & b->d0;
+ }
+
+ inline void N_32路or(N_32 *result ,N_32 *a ,N_32 *b){
+ result->d0 = a->d0 | b->d0;
+ }
+
+ inline void N_32路complement(N_32 *result ,N_32 *a){
+ result->d0 = ~a->d0;
+ }
+
+ inline void N_32路twos_complement(N_32 *result ,N_32 *a){
+ result->d0 = ~a->d0 + 1;
+ }
+
+ inline bool N_32路lsb_is_set(N_32 *a){
+ return a->d0 & 0x0000001;
+ }
+
+ inline bool N_32路msb_is_set(N_32 *a){
+ return a->d0 & 0x8000000;
+ }
+
+ // for low precision Natural, and large number of summands for accumulate/add/sub, overflow could overflow and thus this op would fail
+ inline N_32路Status N_32路accumulate(N_32 *overflow ,N_32 *accumulator ,...){
+ va_list args;
+ va_start(args ,accumulator);
+
+ uint64_t *sum = &accumulator->d0;
+ uint64_t *carry = &overflow->d0;
+ N_32 *current;
+
+ while( (current = va_arg(args ,N_32 *)) ){
+ *sum += current->d0;
+ if(*sum < current->d0){ // Overflow into carry
+ (*carry)++;
+ if(*carry == 0){
+ va_end(args);
+ return N_32路Status路accumulator_overflow;
+ }
+ }
+ }
+ va_end(args);
+
+ if(*carry == 0) return N_32路Status路ok;
+ return N_32路Status路OVERFLOW;
+ }
+
+ inline N_32路Order N_32路compare(N_32 *a ,N_32 *b){
+ if(a->d0 < b->d0) return N_32路order路lt;
+ if(a->d0 > b->d0) return N_32路order路gt;
+ return N_32路order路eq;
+ }
+
+ inline bool N_32路lt(N_32 *a ,N_32 *b){
+ return a->d0 < b->d0;
+ }
+
+ inline bool N_32路gt(N_32 *a ,N_32 *b){
+ return a->d0 > b->d0;
+ }
+
+ inline bool N_32路eq(N_32 *a ,N_32 *b){
+ return a->d0 == b->d0;
+ }
+
+ // arithmetic operations
+
+ inline N_32路Status N_32路add(N_32 *sum ,N_32 *a ,N_32 *b){
+ uint64_t result = (uint64_t)a->d0 + (uint64_t)b->d0;
+ sum->d0 = (uint32_t)result;
+ return (result >> 32) ? N_32路Status路carry : N_32路Status路ok;
+ }
+
+ inline N_32路Status N_32路next(N_32 *overflow ,N_32 *result ,N_32 *a){
+ uint64_t sum = (uint64_t)a->d0 + (uint64_t)1;
+ result->d0 = (uint32_t)sum;
+ overflow->d0 = (uint32_t)(sum >> 32);
+
+ if(overflow->d0 == 0) return N_32路status路ok;
+ return N_32路status路overflow;
+ }
+
+ inline N_32路Status N_32路subtract(N_32 *difference ,N_32 *a ,N_32 *b){
+ uint64_t diff = (uint64_t)a->d0 - (uint64_t)b->d0;
+ difference->d0 = (uint32_t)diff;
+ return (diff > a->d0) ? N_32路Status路borrow : N_32路Status路ok;
+ }
+
+ inline N_32路Status N_32路multiply(N_32 *overflow ,N_32 *result ,N_32 *a ,N_32 *b){
+ uint64_t product = (uint64_t)a->d0 * (uint64_t)b->d0;
+ result->d0 = (uint32_t)product;
+ overflow->d0 = (uint32_t)(product >> 32);
+
+ if(overflow->d0 == 0) return N_32路status路ok;
+ return N_32路status路overflow;
+ }
+
+ inline N_32路Status N_32路divide(N_32 *remainder ,N_32 *quotient ,N_32 *a ,N_32 *b){
+ if(b->d0 == 0) return N_32路Status路undefined_divide_by_zero;
+
+ quotient->d0 = a->d0 / b->d0;
+ remainder->d0 = a->d0 - (quotient->d0 * b->d0);
+
+ return N_32路Status路ok;
+ }
+
+ inline N_32路Status N_32路modulus(N_32 *remainder ,N_32 *a ,N_32 *b){
+ if(b->d0 == 0) return N_32路Status路undefined_modulus_zero;
+ uint32_t quotient = a->d0 / b->d0;
+ remainder->d0 = a->d0 - (quotient * b->d0);
+ return N_32路Status路ok;
+ }
+
+ // shift
+ inline void N_32路shift_left(Extent shift ,N_32 *sink ,N_32 *result ,N_32 *source){
+ *sink = *source;
+ result->d0 = source->d0 << shift;
+ sink->d0 = source->d0 >> (32 - shift);
+ }
+
+ inline void N_32路shift_right(Extent shift ,N_32 *source ,N_32 *result ,N_32 *sink){
+ *sink = *source;
+ result->d0 = source->d0 >> shift;
+ sink->d0 = source->d0 << (32 - shift);
+ }
+
+ inline void N_32路arithmetic_shift_right(Extent shift ,N_32 *result ,N_32 *sink){
+ N_32 source;
+ N_32 source = msb_is_set(result) ? N_32路all_ones : N_32路zero;
+ N_32路shift_right(shift ,&source ,result ,sink);
+ }
+
+ //----------------------------------------
+ // compiled interface
+
+ typedef struct {
+ N_32路Allocate allocate;
+ N_32路Zero zero;
+ N_32路One one;
+ N_32路Deallocate deallocate;
+ } N_32路Interface;
+
+ extern const N_32路Interface N_32路interface;
+
+
+#endif
+
+#ifdef N_32路IMPLEMENTATION
+
+ #include <stdarg.h>
+ #include <stdlib.h>
+
+ const N_32 N_32路zero = { .d0 = 0 };
+ const N_32 N_32路one = { .d0 = 1 };
+ const N_32 N_32路all_ones = { .d0 = ~(uint32_t)0 };
+
+ // the allocate an array of N_32
+ N_32 *N_32路allocate( Extent extent ,N_32 *(*memory_fault)(Extent) ){
+ N_32 *instance = malloc((extent + 1) * sizeof(N_32) );
+ if(!instance){
+ return memory_fault ? memory_fault(extent) : NULL;
+ }
+ return instance;
+ }
+
+ N_32 *N_32路alloc_zero( Extent extent ,N_32 *(*memory_fault)(Extent) ){
+ N_32 *instance = calloc( extent + 1 ,sizeof(N_32) );
+ if(!instance){
+ return memory_fault ? memory_fault(extent) : NULL;
+ }
+ return instance;
+ }
+
+ // initialize all with x
+ N_32 *N_32路alloc_x(Extent extent ,N_32 *(*memory_fault)(Extent) ,N_32 *x){
+ N_32 *instance = malloc((extent + 1) * sizeof(N_32));
+ if(!instance){
+ return memory_fault ? memory_fault(extent) : NULL;
+ }
+ N_32 *pt = instance;
+ while( pt <= instance + extent ){
+ *pt = *x;
+ pt++;
+ }
+ return instance;
+ }
+
+ const N_32路Interface N_32路interface = {
+ .allocate = N_32路allocate
+ ,.allocate_zero = N_32路alloc_zero
+ ,.allocate_all_x = N_32路alloc_x
+ ,.deallocate = N_32路deallocate
+ };
+
+ void N_32路deallocate(N_32 *unencumbered){
+ free(unencumbered);
+ }
+
+#endif