dut_sig = getattr(dut.o.ctx.op, name)
comb += Assert(dut_sig == rec_sig)
- with m.If(rec.invert_a):
- comb += Assert(dut.o.a == ~a)
- with m.Else():
- comb += Assert(dut.o.a == a)
+ with m.If(rec.insn_type != InternalOp.OP_CMP):
+ with m.If(rec.invert_a):
+ comb += Assert(dut.o.a == ~a)
+ with m.Else():
+ comb += Assert(dut.o.a == a)
- with m.If(rec.imm_data.imm_ok &
- ~(rec.insn_type == InternalOp.OP_RLC)):
- comb += Assert(dut.o.b == rec.imm_data.imm)
- with m.Else():
comb += Assert(dut.o.b == b)
+ with m.Else():
+ with m.If(rec.invert_a):
+ comb += Assert(dut.o.a == ~b)
+ with m.Else():
+ comb += Assert(dut.o.a == b)
+
+ comb += Assert(dut.o.b == a)
+
+
# operand a to be as-is or inverted
a = Signal.like(self.i.a)
- with m.If(self.i.ctx.op.invert_a):
- comb += a.eq(~self.i.a)
+ with m.If(self.i.ctx.op.insn_type != InternalOp.OP_CMP):
+ with m.If(self.i.ctx.op.invert_a):
+ comb += a.eq(~self.i.a)
+ with m.Else():
+ comb += a.eq(self.i.a)
+
+ comb += self.o.a.eq(a)
+ comb += self.o.b.eq(self.i.b)
with m.Else():
- comb += a.eq(self.i.a)
+ with m.If(self.i.ctx.op.invert_a):
+ comb += self.o.a.eq(~self.i.b)
+ with m.Else():
+ comb += self.o.a.eq(self.i.b)
- comb += self.o.a.eq(a)
+ comb += self.o.b.eq(self.i.a)
- ##### operand B #####
-
- # TODO: see https://bugs.libre-soc.org/show_bug.cgi?id=305#c43
- # remove this, just do self.o.b.eq(self.i.b) and move the
- # immediate-detection into set_alu_inputs in the unit test
- # If there's an immediate, set the B operand to that
- comb += self.o.b.eq(self.i.b)
##### carry-in #####
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]))
+
+
+ # 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)
+ with m.If((self.i.ctx.op.insn_type == InternalOp.OP_ADD) |
+ (self.i.ctx.op.insn_type == InternalOp.OP_CMP)):
+ # in bit 0, 1+carry_in creates carry into bit 1 and above
+ comb += add_a.eq(Cat(self.i.carry_in, self.i.a, Const(0, 1)))
+ comb += add_b.eq(Cat(Const(1, 1), self.i.b, Const(0, 1)))
+ comb += add_output.eq(add_a + add_b)
+
##########################
# main switch-statement for handling arithmetic operations
with m.Switch(self.i.ctx.op.insn_type):
#### CMP, CMPL ####
- # TODO with m.Case(InternalOp.OP_CMP):
+ with m.Case(InternalOp.OP_CMP):
+ comb += o.eq(add_output[1:-1])
#### add ####
with m.Case(InternalOp.OP_ADD):
- # 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, self.i.a, Const(0, 1)))
- comb += add_b.eq(Cat(Const(1, 1), self.i.b, Const(0, 1)))
- comb += add_output.eq(add_a + add_b)
# bit 0 is not part of the result, top bit is the carry-out
comb += o.eq(add_output[1:-1])
comb += carry_out.eq(add_output[-1])
from soc.decoder.isa.caller import ISACaller, special_sprs
from soc.decoder.power_decoder import (create_pdecode)
from soc.decoder.power_decoder2 import (PowerDecode2)
-from soc.decoder.power_enums import (XER_bits, Function)
+from soc.decoder.power_enums import (XER_bits, Function, InternalOp)
from soc.decoder.selectable_int import SelectableInt
from soc.simulator.program import Program
from soc.decoder.isa.all import ISA
yield alu.p.data_i.carry_in.eq(carry)
so = 1 if sim.spr['XER'][XER_bits['SO']] else 0
yield alu.p.data_i.so.eq(so)
-
+
# This test bench is a bit different than is usual. Initially when I
# was writing it, I had all of the tests call a function to create a
self.run_tst_program(Program(lst), initial_regs, initial_sprs)
def test_cmp(self):
- lst = ["cmp cr2, 1, 6, 7"]
+ lst = ["subf. 1, 6, 7",
+ "cmp cr2, 1, 6, 7"]
initial_regs = [0] * 32
- initial_regs[6] = random.randint(0, (1<<64)-1)
- initial_regs[7] = random.randint(0, (1<<64)-1)
+ initial_regs[6] = 0x10
+ initial_regs[7] = 0x05
self.run_tst_program(Program(lst), initial_regs, {})
def test_extsb(self):
self.assertEqual(fn_unit, Function.ALU.value)
yield from set_alu_inputs(alu, pdecode2, simulator)
yield from set_extra_alu_inputs(alu, pdecode2, simulator)
- yield
+ yield
opname = code.split(' ')[0]
yield from simulator.call(opname)
index = simulator.pc.CIA.value//4
cr_actual = yield alu.n.data_o.cr0
self.assertEqual(cr_expected, cr_actual)
+ op = yield dec2.e.insn_type
+ if op == InternalOp.OP_CMP.value:
+ bf = yield dec2.dec.BF
+ cr_actual = yield alu.n.data_o.cr0
+ cr_expected = sim.crl[bf].get_range().value
+ self.assertEqual(cr_expected, cr_actual)
+
+
if __name__ == "__main__":
unittest.main(exit=False)