Exemplo n.º 1
0
 def reg_field_index(self, line: Line) -> RegisterFieldIndex:
     operand1, operand2 = line.split_operands()
     reg = Register(operand1)
     if not reg.is_valid():
         raise RegisterInvalidError
     field = self.field_index(operand2)
     return RegisterFieldIndex(line, reg, field)
Exemplo n.º 2
0
 def reg_branch(self, line: Line) -> RegisterBranch:
     operand1, operand2 = line.split_operands()
     reg = Register(operand1)
     if not reg.is_valid():
         raise RegisterInvalidError
     branch = self.get_branch(operand2)
     return RegisterBranch(line, reg, branch)
Exemplo n.º 3
0
 def aaget(self, node: KeyValue) -> str:
     address = self.vm.allocate()
     ecb_address = self.get_ecb_address("D1", "CE1CR")
     self.vm.set_value(address, ecb_address)
     reg = Register(node.get_value("BASEREG"))
     if reg.is_valid():
         self.regs.set_value(address, reg)
     return node.fall_down
Exemplo n.º 4
0
 def using(self, line: Line) -> None:
     operands = line.split_operands()
     if len(operands) != 2:
         raise UsingInvalidError
     base = Register(operands[1])
     if not base.is_valid():
         raise UsingInvalidError
     dsect_name = self.name if operands[0] == '*' else operands[0]
     self.set_using(dsect_name, base)
Exemplo n.º 5
0
 def branch_condition_reg(self, line: Line) -> BranchConditionRegister:
     operand1, operand2 = line.split_operands()
     mask = self.get_value(operand1)
     if not 0 <= mask <= BranchGeneric.MAX_VALUE:
         raise ConditionMaskError
     reg = Register(operand2)
     if not reg.is_valid():
         raise RegisterInvalidError
     return BranchConditionRegister(line, mask, reg)
Exemplo n.º 6
0
 def globz(self, line: Line) -> RegisterData:
     globc = self.key_value(line)
     reg = globc.get_value("REGR") or globc.get_value("REGS") or globc.get_value("REGC")
     base = Register(reg)
     if not base.is_valid():
         raise RegisterInvalidError(line)
     self.load_macro("GLOBAL", base=reg)
     line.command = "LHI"
     return RegisterData(line, base, config.GLOBAL)
Exemplo n.º 7
0
    def dbred(self, node: KeyValue) -> str:
        self._base_sw00sr()

        # Setup KEY1 Primary key
        pky = node.get_sub_value("KEY1", "PKY")
        if pky is not None:
            key = f"{self.seg.evaluate(pky):02X}"
        else:
            key = f"{self.seg.evaluate(node.get_sub_value('KEY1', 'S')):02X}"

        # Set up KEY2 to KEY6
        other_keys = dict()
        for key_number in range(2, 7):
            key_n = f"KEY{key_number}"
            if node.get_value(key_n) is None:
                break
            df_field_name = node.get_sub_value(key_n, "R")
            condition = node.get_sub_value(key_n, "C")
            sign = self.C[condition] if condition is not None else "=="
            field: FieldBaseDsp = node.get_sub_value(key_n, "S")
            if field is None:
                # TODO For M, D, L types
                raise DbredError
            base_address = self.regs.get_value(field.base)
            length = self.seg.lookup(df_field_name).length
            byte_array = self.vm.get_bytes(base_address + field.dsp, length)
            other_keys[df_field_name] = (f"{sign} {byte_array}", length)

        # Get the lrec
        ref_name = node.get_value("REF")
        item_number = 0 if node.get_value(
            "BEGIN") else self.tpfdf_ref[ref_name]
        item_number += 1
        lrec, item_number = Tpfdf.get_lrec(ref_name, key, item_number,
                                           other_keys)
        self.tpfdf_ref[ref_name] = item_number

        # Update error_code and REG=
        if lrec is None or self.is_error(node.label):
            error_code = self.seg.evaluate("#TPFDBER")
        else:
            error_code = self.seg.evaluate("#TPFDBOK")
            data_address = self.regs.R3 + self.seg.evaluate("SW00KL1")
            self.vm.set_bytes(lrec, data_address, len(lrec))
            reg = Register(node.get_value("REG"))
            if reg.is_valid():
                self.regs.set_value(data_address, reg)
        self.vm.set_byte(error_code,
                         self.regs.R3 + self.seg.evaluate("SW00RTN"))

        # ERROR=
        error_label = node.get_value("ERRORA")
        if error_label and self.is_error(node.label):
            return error_label

        return node.fall_down
Exemplo n.º 8
0
 def reg_data_field(self, line: Line) -> RegisterDataField:
     operand1, operand2, operand3 = line.split_operands()
     reg = Register(operand1)
     if not reg.is_valid():
         raise RegisterInvalidError
     data = self.get_value(operand2)
     if not 0 <= data <= RegisterDataField.MAX_VALUE:
         raise DataInvalidError
     field = self.field_base_dsp(operand3)
     return RegisterDataField(line, reg, data, field)
Exemplo n.º 9
0
 def _get_field_by_name(self, name: str) -> FieldBaseDsp:
     dsp = self.get_value(name)
     if self.is_based(name):
         possible_name = next(iter(re.split(r"[+*/-]", name)))
         # Field type of NAME+L'NAME or NAME
         base = self.get_base(self.lookup(
             possible_name).name) if name[0] != '*' else Register('R8')
         name = possible_name if name[0] != '*' else 'R8_AREA'
     else:
         base = Register('R0')
     return FieldBaseDsp(name, base, dsp)
Exemplo n.º 10
0
 def mhinf(self, node: KeyValue) -> str:
     if node.keys[0] != "ECB":
         raise MhinfExecutionError
     reg = Register(node.get_value("REG"))
     if not reg.is_valid():
         raise MhinfExecutionError
     option = node.get_value("INPTR")
     if option == "NAME":
         airline_code = self.vm.get_bytes(self.regs.get_value(reg), 2)
         self.set_partition(DataType("X", bytes=airline_code).decode)
     else:
         raise MhinfExecutionError
     return node.fall_down
Exemplo n.º 11
0
 def reg_data(self, line: Line) -> RegisterData:
     operand1, operand2 = line.split_operands()
     reg = Register(operand1)
     if not reg.is_valid():
         raise RegisterInvalidError
     data = self.get_value(operand2)
     max_unsigned_value = (1 << RegisterData.DATA_LENGTH) - 1
     min_signed_value = -1 << RegisterData.DATA_LENGTH - 1
     max_signed_value = (1 << RegisterData.DATA_LENGTH - 1) - 1
     if not min_signed_value <= data <= max_unsigned_value:
         raise DataInvalidError((line, data))
     if data > max_signed_value:
         data -= max_unsigned_value + 1  # Two"s complement negative number
     return RegisterData(line, reg, data)
Exemplo n.º 12
0
 def field_index(self, operand: str) -> FieldIndex:
     index = Register('R0')
     if operand.startswith('='):
         label_ref = self._literal(operand[1:])
         field = FieldBaseDsp(label_ref.label, self.get_base(self.name),
                              label_ref.dsp)
         return FieldIndex(field, index)
     operand1, operand2, operand3 = self.split_operand(operand)
     if not operand2 and not operand3:
         # Single label like EBW000
         field: FieldBaseDsp = self._get_field_by_name(name=operand1)
     elif not operand3:
         # Note: In TPF these types are with no base but with index register set.
         # In our tool we have flipped this. So there would be no index but the base would be present.
         if operand1.isdigit() or set("+-*").intersection(operand1):
             # Base_dsp 34(R5) or expression with base EBW008-EBW000(R9)
             field: FieldBaseDsp = self._get_field_by_base_dsp(
                 base=operand2, dsp=operand1)
         else:
             # Label with index EBW000(R14) or EBW000(R14,)
             field: FieldBaseDsp = self._get_field_by_name(name=operand1)
             index = Register(operand2)
             if not index.is_valid():
                 raise RegisterIndexInvalidError
     elif not operand2:
         # Base_dsp with no index 10(,R5)
         field: FieldBaseDsp = self._get_field_by_base_dsp(base=operand3,
                                                           dsp=operand1)
     else:
         # Base_dsp with index 10(R3,R5)
         field = self._get_field_by_base_dsp(base=operand3, dsp=operand1)
         index = Register(operand2)
         if not index.is_valid():
             raise RegisterIndexInvalidError
     return FieldIndex(field, index)
Exemplo n.º 13
0
 def _capture_output(self, output: Output,
                     last_node: InstructionType) -> None:
     output.messages = self.messages.copy()
     output.dumps.extend(self.dumps)
     output.last_line = last_node.label
     output.last_node = str(last_node)
     if output.debug:
         output.debug = self.debug.get_traces(hit=True)
         output.debug_missed = self.debug.get_traces(hit=False)
     for core in output.cores:
         macro_name = core.macro_name.upper()
         if macro_name in config.DEFAULT_MACROS:
             self._capture_core(core.field_data, macro_name,
                                config.DEFAULT_MACROS[macro_name])
         elif macro_name in macros:
             if not Register(core.base_reg).is_valid():
                 raise InvalidBaseRegError
             self._capture_core(core.field_data, macro_name,
                                self.regs.get_unsigned_value(core.base_reg))
     for reg in output.regs:
         output.regs[reg] = self.regs.get_value(reg)
     for reg in output.reg_pointers:
         try:
             output.reg_pointers[reg] = self.vm.get_bytes(
                 self.regs.get_unsigned_value(reg),
                 output.reg_pointers[reg]).hex().upper()
         except BaseAddressError:
             continue
     return
Exemplo n.º 14
0
 def index_to_label(self, field: FieldIndex) -> str:
     if field.index.reg == "R0":
         return field.name
     dsp = self.regs.get_address(field.index, field.dsp)
     label = self.seg.get_field_name(Register("R8"), dsp,
                                     config.INSTRUCTION_LEN_DEFAULT)
     return label
Exemplo n.º 15
0
 def branch_return(self, node: BranchConditionRegister) -> str:
     if node.mask & (1 << 3 - self.cc) != 0:
         value = self.regs.get_address(node.reg) - self.regs.R8
         label = self.seg.get_field_name(Register('R8'), value, 4)
     else:
         label = node.fall_down
     return label
Exemplo n.º 16
0
 def delete_reg(self, reg: str) -> bool:
     if not Register(reg).is_valid():
         return False
     if reg not in self.regs:
         return False
     del self.regs[reg]
     self.save()
     return True
Exemplo n.º 17
0
 def reg_label(self, line: Line) -> RegisterFieldIndex:
     reg_index: RegisterFieldIndex = self.reg_field_index(line)
     _, operand2 = line.split_operands()
     if operand2.startswith("*"):
         expression = line.label + operand2[1:]
         reg_index.field.dsp = self.get_value(expression)
         reg_index.field.base = Register("R8")
         reg_index.field.name = self.get_field_name(reg_index.field.base, reg_index.field.dsp, 4)
     return reg_index
Exemplo n.º 18
0
 def error_check(self, node: KeyValue) -> str:
     if self.is_error(node.label):
         field_name = node.get_value("FIELD")
         reg = Register(node.get_value("BASE"))
         address = self.regs.get_unsigned_value(reg) + self.seg.evaluate(
             field_name)
         byte_array = DataType("X",
                               input=node.get_value("XVALUE")).to_bytes()
         self.vm.set_bytes(byte_array, address, len(byte_array))
     return node.fall_down
Exemplo n.º 19
0
 def get_value(self, operand: str) -> int:
     if operand.isdigit():
         return int(operand)
     updated_operand = operand.upper()
     data_list = re.findall(r"[CXHFDBZPAY]D?'[^']+'", updated_operand)
     value_list = list()
     if data_list:
         updated_operand = re.sub(r"[CXHFDBZPAY]D?'[^']+'", "~", updated_operand)
         for data in data_list:
             value = DataType(data[0], input=data[2:-1]).value
             value_list.insert(0, value)
     exp_list = re.split(r"([+*()/-])", updated_operand)
     if len(exp_list) == 1:
         if exp_list[0] == "~":
             return value_list.pop()
         return self._location_counter if exp_list[0] == "*" else self.evaluate(exp_list[0])
     exp_list = [expression for expression in exp_list if expression]
     if len(exp_list) >= 2 and exp_list[0] == "-" and exp_list[1].isdigit():
         exp_list.pop(0)
         exp_list[0] = f"-{exp_list[0]}"
     exp_list = [(index, expression) for index, expression in enumerate(exp_list)]
     parenthesis = [indexed_expression for indexed_expression in exp_list if indexed_expression[1] in "()"]
     exp_list = [indexed_expression for indexed_expression in exp_list if indexed_expression[1] not in "()"]
     eval_list = list()
     for index, (position, expression) in enumerate(exp_list):
         if expression in ("-", "+", "/") or (expression == "*" and index % 2 == 1):
             eval_list.append((position, expression))
         else:
             if expression == "~":
                 value = value_list.pop()
             elif expression == "*":
                 value = self._location_counter
             elif expression.isdigit() or (expression[0] == "-" and expression[1:].isdigit()):
                 value = expression
             elif Register(expression).is_valid():
                 value = Register(expression).value
             else:
                 value = self.evaluate(expression)
             eval_list.append((position, str(value)))
     eval_list.extend(parenthesis)
     eval_list.sort(key=lambda item: item[0])
     eval_list = [expression for _, expression in eval_list]
     return int(eval("".join(eval_list)))
Exemplo n.º 20
0
 def create_regs(self, reg_dict: dict) -> bool:
     if 'regs' not in reg_dict:
         return False
     self.regs = dict()
     for reg in reg_dict['regs']:
         if not Register(reg).is_valid():
             return False
         self.regs[reg] = 0
     self.save()
     return True
Exemplo n.º 21
0
 def branch_on_count_register(self, node: RegisterRegister) -> str:
     dsp = self.regs.get_address(node.reg2)
     if dsp > 0:
         dsp -= self.regs.R8
     value = self.regs.get_value(node.reg1) - 1
     self.regs.set_value(value, node.reg1)
     if dsp == 0 or value == 0:
         label = node.fall_down
     else:
         label = self.seg.get_field_name(Register('R8'), dsp, 4)
     return label
Exemplo n.º 22
0
 def drop(self, line: Line) -> None:
     operands = line.split_operands()
     registers = [Register(operand) for operand in operands]
     if any(not register.is_valid() for register in registers):
         raise DropInvalidError(line)
     for drop_register in registers:
         self._using = {
             macro_name: register
             for macro_name, register in self._using.items()
             if register.reg != drop_register.reg
         }
Exemplo n.º 23
0
 def add_reg(self, reg_dict: dict) -> bool:
     if 'reg' not in reg_dict or not Register(reg_dict['reg']).is_valid():
         return False
     if 'value' not in reg_dict or not isinstance(reg_dict['value'], int):
         return False
     if len(reg_dict) != 2:
         return False
     if reg_dict['value'] < -0x80000000 or reg_dict['value'] > 0x7FFFFFFF:
         return False
     self.regs[reg_dict['reg']] = reg_dict['value']
     self.save()
     return True
Exemplo n.º 24
0
 def reg_reg(line: Line) -> RegisterRegister:
     operand1, operand2 = line.split_operands()
     reg1 = Register(operand1)
     reg2 = Register(operand2)
     if not reg1.is_valid() or not reg2.is_valid():
         raise RegisterInvalidError
     return RegisterRegister(line, reg1, reg2)
Exemplo n.º 25
0
 def _pd0_base(self, node: KeyValue) -> Optional[int]:
     workarea = node.get_value("WORKAREA")
     if workarea is None:
         raise Pd0BaseError
     if workarea[0] == "LEV":
         lev_parameter = workarea[1]
         level = lev_parameter[1] if len(
             lev_parameter
         ) == 2 and lev_parameter[0] == "D" else lev_parameter
         if not self._is_level_present(level):
             self._core_block(self.vm.allocate(), level)
         level = f"D{level}"
         level_address = self.get_ecb_address(level, "CE1CR")
         pd0_base = self.vm.get_value(level_address)
     elif workarea[0] == "REG":
         reg = Register(workarea[1])
         if not reg.is_valid():
             raise RegisterInvalidError
         pd0_base = self.regs.get_value(reg)
     else:
         raise Pd0BaseError
     return pd0_base
Exemplo n.º 26
0
 def pnrcc(self, node: KeyValue) -> str:
     action = node.get_value("ACTION")
     reg = Register(node.get_value("REG"))
     if not reg.is_valid():
         raise RegisterInvalidError
     pnrcm_base = self.regs.get_value(reg)
     self.seg.load_macro("PNRCM")
     if self.is_error(node.label):
         error_code = self.seg.evaluate("#PM1ER5")
         self.vm.set_value(error_code,
                           pnrcm_base + self.seg.evaluate("PM1ERR"), 1)
         return node.fall_down
     if action in ["CRLON"]:
         pnr_locator_bytes = self.vm.get_bytes(
             pnrcm_base + self.seg.evaluate("PM1LOC"), 6)
         pnr_locator = DataType("X", bytes=pnr_locator_bytes).decode
         ordinal = PnrLocator.to_ordinal(pnr_locator)
         self.vm.set_value(ordinal,
                           pnrcm_base + self.seg.evaluate("PM1ORN"))
         self.vm.set_value(ordinal,
                           pnrcm_base + self.seg.evaluate("PM1FAD"))
     return node.fall_down
Exemplo n.º 27
0
 def reg_reg_field(self, line: Line) -> RegisterRegisterField:
     operand1, operand2, operand3 = line.split_operands()
     reg1 = Register(operand1)
     reg2 = Register(operand2)
     if not reg1.is_valid() or not reg2.is_valid():
         raise RegisterInvalidError
     field = self.field_base_dsp(operand3)
     return RegisterRegisterField(line, reg1, reg2, field)
Exemplo n.º 28
0
 def reg_reg_branch(self, line: Line) -> RegisterRegisterBranch:
     operand1, operand2, operand3 = line.split_operands()
     reg1 = Register(operand1)
     reg2 = Register(operand2)
     if not reg1.is_valid() or not reg2.is_valid():
         raise RegisterInvalidError
     branch = self.get_branch(operand3)
     return RegisterRegisterBranch(line, reg1, reg2, branch)
Exemplo n.º 29
0
    def heapa(self, node: KeyValue) -> str:
        # REG, REF and SREF
        reg = Register(node.get_value("REG"))
        ref = node.get_value("REF")
        if ref is None:
            sref = node.get_value("SREF")
            if sref is None:
                raise HeapaExecutionError
            ref_bytes = self.seg.get_constant_bytes(sref, 8)
            ref = DataType("X", bytes=ref_bytes).decode

        # ERROR= for forced errors
        error_label = node.get_value("ERROR")
        if error_label and self.is_error(node.label):
            if reg.is_valid():
                self.regs.set_value(0, reg)
            return error_label

        # HEAPA / CFCMA / EHEAPA command types
        command = node.keys[0]
        heap = self.heap["new"] if node.command == "EHEAPA" else self.heap[
            "old"]
        if command == "ALLOCATE":
            address = self.vm.allocate()
            heap[ref] = address
            if reg.is_valid():
                self.regs.set_value(address, reg)
        elif command == "LOADADD":
            address = heap[ref] if ref in heap else 0
            if reg.is_valid():
                self.regs.set_value(address, reg)
            if address == 0 and error_label:
                return error_label
        elif command == "FREE":
            heap.pop(ref, None)
        else:
            raise HeapaExecutionError
        return node.fall_down
Exemplo n.º 30
0
 def _get_field_by_base_dsp(self,
                            base: str,
                            dsp: str,
                            length: Optional[int] = None) -> FieldBaseDsp:
     # Set base register
     base = Register(base)
     if not base.is_valid():
         raise RegisterInvalidError
     # Set displacement
     dsp = self.get_value(dsp)
     if not 0 <= dsp <= 4095:
         raise FieldDspInvalidError
     # Set name
     name = base.reg + '_AREA'
     return FieldBaseDsp(name, base, dsp)