comb += o.eq(Cat(self.i.a[0:16], Repl(self.i.a[15], 64-16)))
with m.If(self.i.ctx.op.data_len == 4):
comb += o.eq(Cat(self.i.a[0:32], Repl(self.i.a[31], 64-32)))
+ with m.Case(InternalOp.OP_CMPEQB):
+ eqs = Signal(8, reset_less=True)
+ src1 = Signal(8, reset_less=True)
+ comb += src1.eq(self.i.a[0:8])
+ for i in range(8):
+ comb += eqs[i].eq(src1 == self.i.b[8*i:8*(i+1)])
+ comb += self.o.cr0.eq(Cat(Const(0, 2), eqs.any(), Const(0, 1)))
+
+
###### sticky overflow and context, both pass-through #####
# TODO: if o[63] is XORed with "operand == OP_CMP"
# that can be used as a test
# see https://bugs.libre-soc.org/show_bug.cgi?id=305#c60
+
comb += is_cmp.eq(self.i.ctx.op.insn_type == InternalOp.OP_CMP)
comb += msb_test.eq(o[-1] ^ is_cmp)
comb += is_zero.eq(o == 0)
comb += so.eq(self.i.so | self.i.ov)
comb += self.o.o.eq(o)
- comb += self.o.cr0.eq(Cat(so, is_zero, is_positive, is_negative))
+ with m.If(self.i.ctx.op.insn_type != InternalOp.OP_CMPEQB):
+ comb += self.o.cr0.eq(Cat(so, is_zero, is_positive, is_negative))
+ with m.Else():
+ comb += self.o.cr0.eq(self.i.cr0)
+
comb += self.o.so.eq(so)
comb += self.o.ctx.eq(self.i.ctx)
initial_regs[1] = random.randint(0, (1<<64)-1)
self.run_tst_program(Program(lst), initial_regs)
+ def test_cmpeqb(self):
+ lst = ["cmpeqb cr0, 1, 2"]
+ for i in range(20):
+ initial_regs = [0] * 32
+ initial_regs[1] = i
+ initial_regs[2] = 0x01030507090b0d0f11
+ self.run_tst_program(Program(lst), initial_regs, {})
+
def test_ilang(self):
rec = CompALUOpSubset()
self.assertEqual(cr_expected, cr_actual, code)
op = yield dec2.e.insn_type
- if op == InternalOp.OP_CMP.value:
+ if op == InternalOp.OP_CMP.value or \
+ op == InternalOp.OP_CMPEQB.value:
bf = yield dec2.dec.BF
cr_actual = yield alu.n.data_o.cr0
cr_expected = sim.crl[bf].get_range().value