.decl A(x:number)
A(11).
A(4711).
A(121233).
A(1234).
A(-1).
A(-100).

.decl r_band(x:number, y:number, z:number)
.output r_band()
r_band(x band y, x, y) :- A(x), A(y).

.decl r_bxor(x:number, y:number, z:number)
.output r_bxor()
r_bxor(x bxor y, x, y) :- A(x), A(y).

.decl r_bor(x:number, y:number, z:number)
.output r_bor()
r_bor(x bor y, x, y) :- A(x), A(y).

.decl r_bnot(x:number, y:number)
.output r_bnot()
r_bnot(bnot x, x) :- A(x).


.decl B0(x:number)
B0(-10).
B0(-1).
B0(0).
B0(1).
B0(10).

.decl B1(x:number)
B1(-64).
B1(-48).
B1(-32).
B1(-16).
B1(-6).
B1(-3).
B1(-2).
B1(-1).
B1(0).
B1(1).
B1(3).
B1(6).
B1(16).
B1(31).


#define LO_32 ((0x7FFFFFFF bshl 1) + 1)
#define SIGN_BIT (0x40000000 bshl 1)

#if RAM_DOMAIN_SIZE == 32
    #define as32bit(op, x, y, out) out = x op y
#elif RAM_DOMAIN_SIZE == 64
    // HACK:  Do some gymnastics to pretend we're just working with 32 bits
    // FIXME: We'll eventually need separate test cases for 32 vs 64 bits ram domain
    #define HI_32 (LO_32 bshl 32)
    #define as32bit(op, x, y, out) \
        t = (x op (y band 0x1f)) band LO_32, (0 != t band SIGN_BIT, out = t bor HI_32; 0 = t band SIGN_BIT, out = t)
#endif


.decl r_shift_L(x:number, y:number, z:number)
.output r_shift_L()
r_shift_L(x, y, z) :- as32bit(bshl, x, y, z), B0(x), B1(y).

.decl r_shift_R(x:number, y:number, z:number)
.output r_shift_R()
r_shift_R(x, y, z) :- as32bit(bshr, x, y, z), B0(x), B1(y).

.decl r_shift_R_unsigned(x:number, y:number, z:number)
.output r_shift_R_unsigned()
r_shift_R_unsigned(x, y, z) :- as32bit(bshru, (x band LO_32), y, z), B0(x), B1(y).

