m = Module()
comb = m.d.comb
+ # check if op is 32-bit, and get sign bit from operand a
is_32bit = Signal(reset_less=True)
- comb += is_32bit.eq(self.i.ctx.op.is_32bit)
sign_bit = Signal(reset_less=True)
+ comb += is_32bit.eq(self.i.ctx.op.is_32bit)
comb += sign_bit.eq(Mux(is_32bit, self.i.a[31], self.i.a[63]))
- add_output = Signal(self.i.a.width + 1, reset_less=True)
- comb += add_output.eq(self.i.a + self.i.b + self.i.carry_in)
-
# Signals for rotates and shifts
rotl_out = Signal.like(self.i.a)
mask = Signal.like(self.i.a)
comb += rotl_out.eq(Cat(rotl32.o, Repl(0, 32)))
with m.Else():
comb += rotl_out.eq(rotl.o)
-
+ ##########################
+ # main switch-statement for handling arithmetic and logic operations
with m.Switch(self.i.ctx.op.insn_type):
+ #### add ####
with m.Case(InternalOp.OP_ADD):
- comb += self.o.o.eq(add_output[0:64])
- comb += self.o.carry_out.eq(add_output[64])
+ # little trick: do the add using only one add (not 2)
+ add_a = Signal(self.i.a.width + 2, reset_less=True)
+ add_b = Signal(self.i.a.width + 2, reset_less=True)
+ add_output = Signal(self.i.a.width + 2, reset_less=True)
+ # in bit 0, 1+carry_in creates carry into bit 1 and above
+ comb += add_a.eq(Cat(self.i.carry_in, a, Const(0, 1)))
+ comb += add_b.eq(Cat(Const(1, 1), b, Const(0, 1)))
+ comb += add_output.eq(a + b)
+ # bit 0 is not part of the result, top bit is the carry-out
+ comb += self.o.o.eq(add_output[1:-1])
+ comb += self.o.carry_out.eq(add_output[-1])
+
+ #### and ####
with m.Case(InternalOp.OP_AND):
comb += self.o.o.eq(self.i.a & self.i.b)
+
+ #### or ####
with m.Case(InternalOp.OP_OR):
comb += self.o.o.eq(self.i.a | self.i.b)
+
+ #### xor ####
with m.Case(InternalOp.OP_XOR):
comb += self.o.o.eq(self.i.a ^ self.i.b)
+
+ #### shift left ####
with m.Case(InternalOp.OP_SHL):
comb += maskgen.mb.eq(Mux(is_32bit, 32, 0))
comb += maskgen.me.eq(63-self.i.b[0:6])
with m.Else():
comb += mask.eq(maskgen.o)
comb += self.o.o.eq(rotl_out & mask)
+
+ #### shift right ####
with m.Case(InternalOp.OP_SHR):
comb += maskgen.mb.eq(Mux(is_32bit, 32, 0) + self.i.b[0:6])
comb += maskgen.me.eq(63)
with m.Else():
comb += mask.eq(maskgen.o)
with m.If(self.i.ctx.op.is_signed):
- comb += self.o.o.eq(rotl_out & mask |
- Mux(sign_bit, ~mask, 0))
- comb += self.o.carry_out.eq(sign_bit & ((rotl_out & mask) != 0))
+ out = rotl_out & mask | Mux(sign_bit, ~mask, 0))
+ cout = sign_bit & ((rotl_out & mask) != 0))
+ comb += self.o.o.eq(out)
+ comb += self.o.carry_out.eq(cout)
with m.Else():
comb += self.o.o.eq(rotl_out & mask)