typedef long long type;
typedef unsigned long long utype;

#define TEST(name, op) \
  void op_##name(type *left, type *right, type *result) { op; }

TEST(add, *result = *left + *right)
TEST(sub, *result = *left - *right)
TEST(mul, *result = *left * *right)
TEST(div, *result = *left / *right)
TEST(mod, *result = *left % *right)
TEST(inc, *result = ++(*left))
TEST(dec, *result = --(*left))
TEST(neg, *result = -*left)
TEST(lshiftc, *result = *left << 5)
TEST(rshiftc, *result = *left >> 5)
TEST(lshift, *result = *left << *right)
TEST(rshift, *result = *left >> *right)
TEST(urshiftc, *result = (utype)*left >> 5)
TEST(urshift, *result = (utype)*left >> *right)
TEST(not, *result = !*left)
TEST(bitnot, *result = ~*left)
TEST(and, *result = *left & *right)
TEST(or, *result = *left | *right)
TEST(xor, *result = *left ^ *right)
TEST(assign, *result = *left)
TEST(const1, *result = 0 - *left)
TEST(const2, *result = *left + 0x100000001LL)
TEST(const3, *result = *left + 0xFFFFFFFFFFFFFFFFLL)

/* Bad:
   mul - can't directly, tops out at 32 bit
   div - none
   mod - none
   inc is a add 1 from constant pool
   dec is a add -1 from constant pool
   neg - tops out at 32 bit
   lshiftc
   {u}rshiftc
   lshift
   {u}rshift
   not
   bitnot
   add doesn't recognise replicated constants
   vshr, reg doesn't exist but can be done through vshl, -shift
*/
