Skip to content

Instantly share code, notes, and snippets.

@notfoundry
Created September 9, 2020 03:05
Show Gist options
  • Select an option

  • Save notfoundry/aa927a9ef07a3a5990b08c5e78b0b492 to your computer and use it in GitHub Desktop.

Select an option

Save notfoundry/aa927a9ef07a3a5990b08c5e78b0b492 to your computer and use it in GitHub Desktop.
4-bit ALU metaprogrammed in C11's _Generic
const static struct _0 {} _0;
const static struct _1 {} _1;
#define G7_SPLICE(expr) __typeof__(expr)
#define G7_STRUCT(...) (struct { __VA_ARGS__ } ){}
#define G7_NAND(a, b) \
_Generic(a, \
struct _0: _1, \
struct _1: \
_Generic(b, struct _0: _1, struct _1: _0))
#define G7_NOT(a) G7_NAND(a,a)
#define G7_AND(a, b) G7_NOT(G7_NAND(a, b))
#define G7_OR(a, b) G7_NAND(G7_NOT(a), G7_NOT(b))
#define G7_NOR(a, b) G7_NOT(G7_OR(a, b))
#define G7_XOR(a, b) G7_NAND(G7_NAND(a, G7_NAND(a, b)), G7_NAND(G7_NAND(a, b), b))
#define G7_XNOR(a, b) G7_NOT(G7_XOR(a, b))
#define G7_MUX_2_1(a, b, s) G7_NAND(G7_NAND(a, G7_NOT(s)), G7_NAND(b, s))
#define G7_HALF_ADD_2_1(a, b) \
G7_STRUCT( \
G7_SPLICE(G7_XOR(a, b)) sum; \
G7_SPLICE(G7_AND(a, b)) carry; \
)
#define G7_FULL_ADD_2_1(a, b, c) \
G7_STRUCT( \
G7_SPLICE( \
G7_HALF_ADD_2_1(c, G7_HALF_ADD_2_1(a, b).sum).sum \
) sum; \
G7_SPLICE( \
G7_OR( \
G7_HALF_ADD_2_1(a, b).carry, \
G7_HALF_ADD_2_1(c, G7_HALF_ADD_2_1(a, b).sum).carry \
) \
) carry; \
)
#define G7_FULL_ADD_8_4(x3, x2, x1, x0, y3, y2, y1, y0, c) \
G7_STRUCT( \
G7_SPLICE( \
G7_FULL_ADD_2_1(x0, y0, c).sum \
) s0; \
G7_SPLICE( \
G7_FULL_ADD_2_1(x1, y1, \
G7_FULL_ADD_2_1(x0, y0, c).carry).sum \
) s1; \
G7_SPLICE( \
G7_FULL_ADD_2_1(x2, y2, \
G7_FULL_ADD_2_1(x1, y1, \
G7_FULL_ADD_2_1(x0, y0, c).carry).carry).sum \
) s2; \
G7_SPLICE( \
G7_FULL_ADD_2_1(x3, y3, \
G7_FULL_ADD_2_1(x2, y2, \
G7_FULL_ADD_2_1(x1, y1, \
G7_FULL_ADD_2_1(x0, y0, c).carry).carry).carry).sum \
) s3; \
G7_SPLICE( \
G7_FULL_ADD_2_1(x3, y3, \
G7_FULL_ADD_2_1(x2, y2, \
G7_FULL_ADD_2_1(x1, y1, \
G7_FULL_ADD_2_1(x0, y0, c).carry).carry).carry).carry \
) c; \
)
#define G7_TO_INT_1(x) _Generic(x, struct _0: 0, struct _1: 1)
#define G7_TO_INT_4(x3, x2, x1, x0) \
_Generic(x3, struct _0: 0, struct _1: 8) \
+ _Generic(x2, struct _0: 0, struct _1: 4) \
+ _Generic(x1, struct _0: 0, struct _1: 2) \
+ _Generic(x0, struct _0: 0, struct _1: 1)
#define sum G7_FULL_ADD_8_4( \
_0, _0, _1, _0, \
_0, _0, _1, _0, \
_0 \
)
_Static_assert(G7_TO_INT_4(sum.s3, sum.s2, sum.s1, sum.s0) == 4, "wtf");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment