fix elwidth overrides when sw=8
[openpower-isa.git] / src / openpower / decoder / isa / caller.py
index 205ae88808ab7ecf7c23e89eeb35fdf1322cbb32..9a8c24817c27f77ea51003ab2ecd1af39e271a93 100644 (file)
@@ -18,6 +18,7 @@ from copy import deepcopy
 from functools import wraps
 import os
 import sys
+from elftools.elf.elffile import ELFFile  # for isinstance
 
 from nmigen.sim import Settle
 import openpower.syscalls
@@ -25,7 +26,7 @@ from openpower.consts import (MSRb, PIb,  # big-endian (PowerISA versions)
                               SVP64CROffs, SVP64MODEb)
 from openpower.decoder.helpers import (ISACallerHelper, ISAFPHelpers, exts,
                                        gtu, undefined, copy_assign_rhs)
-from openpower.decoder.isa.mem import Mem, MemMMap, MemException
+from openpower.decoder.isa.mem import Mem, MemMMap, MemException, LoadedELF
 from openpower.decoder.isa.radixmmu import RADIX
 from openpower.decoder.isa.svshape import SVSHAPE
 from openpower.decoder.isa.svstate import SVP64State
@@ -1193,7 +1194,8 @@ class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop):
                  initial_fpscr=0,
                  insnlog=None,
                  use_mmap_mem=False,
-                 use_syscall_emu=False):
+                 use_syscall_emu=False,
+                 emulating_mmap=False):
         if use_syscall_emu:
             self.syscall = SyscallEmulator(isacaller=self)
             if not use_mmap_mem:
@@ -1202,6 +1204,16 @@ class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop):
         else:
             self.syscall = None
 
+        # we will eventually be able to load ELF files without use_syscall_emu
+        # (e.g. the linux kernel), so do it in a separate if block
+        if isinstance(initial_insns, ELFFile):
+            if not use_mmap_mem:
+                log("forcing use_mmap_mem due to loading an ELF file")
+                use_mmap_mem = True
+            if not emulating_mmap:
+                log("forcing emulating_mmap due to loading an ELF file")
+                emulating_mmap = True
+
         # trace log file for model output. if None do nothing
         self.insnlog = insnlog
         self.insnlog_is_file = hasattr(insnlog, "write")
@@ -1272,9 +1284,15 @@ class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop):
         if use_mmap_mem:
             self.mem = MemMMap(row_bytes=8,
                                initial_mem=initial_mem,
-                               misaligned_ok=True)
+                               misaligned_ok=True,
+                               emulating_mmap=emulating_mmap)
             self.imem = self.mem
-            self.mem.initialize(row_bytes=4, initial_mem=initial_insns)
+            lelf = self.mem.initialize(row_bytes=4, initial_mem=initial_insns)
+            if isinstance(lelf, LoadedELF):  # stuff parsed from ELF
+                initial_pc = lelf.pc
+                for k, v in lelf.gprs.items():
+                    self.gpr[k] = SelectableInt(v, 64)
+                initial_fpscr = lelf.fpscr
             self.mem.log_fancy(kind=LogType.InstrInOuts)
         else:
             self.mem = Mem(row_bytes=8, initial_mem=initial_mem,
@@ -2070,7 +2088,7 @@ class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop):
                        "brh", "brw", "brd",
                        'setvl', 'svindex', 'svremap', 'svstep',
                        'svshape', 'svshape2',
-                       'ternlogi', 'bmask', 'cprop',
+                       'ternlogi', 'bmask', 'cprop', 'gbbd',
                        'absdu', 'absds', 'absdacs', 'absdacu', 'avgadd',
                        'fmvis', 'fishmv', 'pcdec', "maddedu", "divmod2du",
                        "dsld", "dsrd", "maddedus",
@@ -2086,6 +2104,11 @@ class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop):
             illegal = False
             ins_name = dotstrp
 
+        # match against instructions treated as nop, see nop below
+        if asmop.startswith("dcbt"):
+            illegal = False
+            ins_name = "nop"
+
         # branch-conditional redirects to sv.bc
         if asmop.startswith('bc') and self.is_svp64_mode:
             ins_name = 'sv.%s' % ins_name
@@ -2131,7 +2154,7 @@ class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop):
             ew_src = 8 << (3-int(ew_src))  # convert to bitlength
             ew_dst = 8 << (3-int(ew_dst))  # convert to bitlength
             xlen = max(ew_src, ew_dst)
-            log("elwdith", ew_src, ew_dst)
+            log("elwidth", ew_src, ew_dst)
         log("XLEN:", self.is_svp64_mode, xlen)
 
         # look up instruction in ISA.instrs, prepare namespace
@@ -2227,7 +2250,7 @@ class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop):
             elif name in spr_byname:
                 inputs[name] = self.spr[name]
             else:
-                regval = (yield from self.get_input(name, ew_src))
+                regval = (yield from self.get_input(name, ew_src, xlen))
                 log("regval name", name, regval)
                 inputs[name] = regval
 
@@ -2527,7 +2550,7 @@ class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop):
             else:
                 self.namespace['D'] = imm
 
-    def get_input(self, name, ew_src):
+    def get_input(self, name, ew_src, xlen):
         # using PowerDecoder2, first, find the decoder index.
         # (mapping name RA RB RC RS to in1, in2, in3)
         regnum, is_vec = yield from get_idx_in(self.dec2, name, True)
@@ -2554,14 +2577,17 @@ class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop):
         if not self.is_svp64_mode or not self.pred_src_zero:
             log('reading reg %s %s' % (name, str(regnum)), is_vec)
             if name in fregs:
-                reg_val = SelectableInt(self.fpr(base, is_vec, offs, ew_src))
-                log("read reg %d/%d: 0x%x" % (base, offs, reg_val.value),
-                    kind=LogType.InstrInOuts)
+                fval = self.fpr(base, is_vec, offs, ew_src)
+                reg_val = SelectableInt(fval)
+                assert ew_src == XLEN, "TODO fix elwidth conversion"
                 self.trace("r:FPR:%d:%d:%d " % (base, offs, ew_src))
+                log("read fp reg %d/%d: 0x%x" % (base, offs, reg_val.value),
+                    kind=LogType.InstrInOuts)
             elif name is not None:
-                reg_val = SelectableInt(self.gpr(base, is_vec, offs, ew_src))
+                gval = self.gpr(base, is_vec, offs, ew_src)
+                reg_val = SelectableInt(gval.value, bits=xlen)
                 self.trace("r:GPR:%d:%d:%d " % (base, offs, ew_src))
-                log("read reg %d/%d: 0x%x" % (base, offs, reg_val.value),
+                log("read int reg %d/%d: 0x%x" % (base, offs, reg_val.value),
                     kind=LogType.InstrInOuts)
         else:
             log('zero input reg %s %s' % (name, str(regnum)), is_vec)