From: Michael Nolan Date: Mon, 23 Mar 2020 18:40:22 +0000 (-0400) Subject: Properly sign extend immediates X-Git-Tag: div_pipeline~1643 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a75390408a10cfb78b745a5882f58ee9df3be39e;p=soc.git Properly sign extend immediates --- diff --git a/src/soc/decoder/power_decoder2.py b/src/soc/decoder/power_decoder2.py index 08c9f44d..27b520c0 100644 --- a/src/soc/decoder/power_decoder2.py +++ b/src/soc/decoder/power_decoder2.py @@ -3,7 +3,7 @@ based on Anton Blanchard microwatt decode2.vhdl """ -from nmigen import Module, Elaboratable, Signal, Mux, Const +from nmigen import Module, Elaboratable, Signal, Mux, Const, Cat, Repl from nmigen.cli import rtlil from soc.decoder.power_decoder import create_pdecode @@ -91,6 +91,13 @@ class DecodeB(Elaboratable): self.imm_out = Data(64, "imm_b") self.spr_out = Data(10, "spr_b") + def exts(self, exts_data, width, fullwidth): + exts_data = exts_data[0:width] + topbit = exts_data[-1] + signbits = Repl(topbit, fullwidth-width) + return Cat(exts_data, signbits) + + def elaborate(self, platform): m = Module() comb = m.d.comb @@ -104,13 +111,16 @@ class DecodeB(Elaboratable): comb += self.imm_out.data.eq(self.dec.UI[0:-1]) comb += self.imm_out.ok.eq(1) with m.Case(In2Sel.CONST_SI): # TODO: sign-extend here? - comb += self.imm_out.data.eq(self.dec.SI[0:-1]) + comb += self.imm_out.data.eq( + self.exts(self.dec.SI[0:-1], 16, 64)) comb += self.imm_out.ok.eq(1) with m.Case(In2Sel.CONST_UI_HI): comb += self.imm_out.data.eq(self.dec.UI[0:-1]<<16) comb += self.imm_out.ok.eq(1) with m.Case(In2Sel.CONST_SI_HI): # TODO: sign-extend here? comb += self.imm_out.data.eq(self.dec.SI[0:-1]<<16) + comb += self.imm_out.data.eq( + self.exts(self.dec.SI[0:-1] << 16, 32, 64)) comb += self.imm_out.ok.eq(1) with m.Case(In2Sel.CONST_LI): comb += self.imm_out.data.eq(self.dec.LI[0:-1]<<2) diff --git a/src/soc/decoder/test/test_decoder_gas.py b/src/soc/decoder/test/test_decoder_gas.py index 4ed591e6..0003e2e6 100644 --- a/src/soc/decoder/test/test_decoder_gas.py +++ b/src/soc/decoder/test/test_decoder_gas.py @@ -17,6 +17,23 @@ class Register: def __init__(self, num): self.num = num +class Checker: + def __init__(self): + self.imm = 0 + + def get_imm(self, in2_sel): + if in2_sel == In2Sel.CONST_UI.value: + return self.imm & 0xffff + if in2_sel == In2Sel.CONST_UI_HI.value: + return (self.imm & 0xffff) << 16 + if in2_sel == In2Sel.CONST_SI.value: + sign_bit = 1 << 15 + return (self.imm & (sign_bit-1)) - (self.imm & sign_bit) + if in2_sel == In2Sel.CONST_SI_HI.value: + imm = self.imm << 16 + sign_bit = 1 << 31 + return (imm & (sign_bit-1)) - (imm & sign_bit) + class RegRegOp: def __init__(self): @@ -70,8 +87,9 @@ class RegRegOp: assert(rc == 0) -class RegImmOp: +class RegImmOp(Checker): def __init__(self): + super().__init__() self.ops = { "addi": InternalOp.OP_ADD, "addis": InternalOp.OP_ADD, @@ -106,10 +124,9 @@ class RegImmOp: imm = yield pdecode2.e.imm_data.data in2_sel = yield pdecode2.dec.op.in2_sel - if in2_sel in [In2Sel.CONST_SI_HI.value, In2Sel.CONST_UI_HI.value]: - assert(imm == (self.imm << 16)) - else: - assert(imm == self.imm) + imm_expected = self.get_imm(in2_sel) + msg = "imm: got {:x}, expected {:x}".format(imm, imm_expected) + assert imm == imm_expected, msg rc = yield pdecode2.e.rc.data if '.' in self.opcodestr: @@ -118,8 +135,9 @@ class RegImmOp: assert(rc == 0) -class LdStOp: +class LdStOp(Checker): def __init__(self): + super().__init__() self.ops = { "lwz": InternalOp.OP_LOAD, "stw": InternalOp.OP_STORE, @@ -154,7 +172,8 @@ class LdStOp: assert(r2sel == self.r2.num) imm = yield pdecode2.e.imm_data.data - assert(imm == self.imm) + in2_sel = yield pdecode2.dec.op.in2_sel + assert(imm == self.get_imm(in2_sel)) update = yield pdecode2.e.update if "u" in self.opcodestr: