Beispiel #1
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)
Beispiel #2
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)
Beispiel #3
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)
Beispiel #4
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)
Beispiel #5
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)
Beispiel #6
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
Beispiel #7
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
Beispiel #8
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
Beispiel #9
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)
Beispiel #10
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)
Beispiel #11
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
Beispiel #12
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
Beispiel #13
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)
Beispiel #14
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
Beispiel #15
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)
Beispiel #16
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)
Beispiel #17
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
Beispiel #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
Beispiel #19
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
Beispiel #20
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)
Beispiel #21
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)))
Beispiel #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
         }
Beispiel #23
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
Beispiel #24
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
Beispiel #25
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
Beispiel #26
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)
Beispiel #27
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)
Beispiel #28
0
 def datas(self, line: Line) -> None:
     operands = line.split_operands()
     if len(operands) < 3:
         raise UsingInvalidError
     if not Register(operands[0]).is_valid():
         raise UsingInvalidError
     suffix: Optional[str] = operands[1] if operands[1] else None
     for operand in operands[2:]:
         if operand not in macros:
             raise UsingInvalidError(line)
         self.load_macro(operand,
                         base=operands[0],
                         suffix=suffix,
                         override=False)
     return
Beispiel #29
0
 def assemble(self) -> None:
     if self.nodes:
         return
     # Default processing
     self.set_using(self.name, Register("R8"))
     self.load_macro("EB0EB", base="R9")
     # Get the data from line after removing CVS and empty lines.
     file_lines = File.open(self.file_name)
     # Create a list of Line objects
     lines = Line.from_file(file_lines)
     # First pass - Build Symbol Table and generate constants.
     self._build_symbol_table(lines)
     # Update index of each line
     lines = self._update_index(lines)
     # Generate constants
     self._generate_constants()
     # Second pass - Assemble instructions and populates nodes.
     self._assemble_instructions(lines)
     return
Beispiel #30
0
 def create_field_byte(self,
                       macro_name: str,
                       field_dict: dict,
                       persistence=True) -> dict:
     if not Core.validate_field_dict(macro_name, field_dict):
         return dict()
     if set(field_dict) != {'field', 'length', 'base_reg'}:
         return dict()
     if not isinstance(field_dict['length'],
                       int) or field_dict['length'] < 0:
         return dict()
     if field_dict['base_reg'] and not Register(
             field_dict['base_reg']).is_valid():
         return dict()
     core_dict = {
         'macro_name': macro_name,
         'base_reg': field_dict['base_reg']
     }
     field_dict = field_dict.copy()
     del field_dict['base_reg']
     core_dict['base_reg'] = core_dict[
         'base_reg'] if core_dict['base_reg'] != 'R0' else str()
     if not core_dict[
             'base_reg'] and macro_name not in config.DEFAULT_MACROS:
         return dict()
     if core_dict['base_reg'] and macro_name in config.DEFAULT_MACROS:
         return dict()
     field_dict['length'] = field_dict['length'] if 'length' in field_dict and field_dict['length'] \
         else macros[macro_name].evaluate(f"L'{field_dict['field']}")
     core = next((core for core in self.cores
                  if core.macro_name == core_dict['macro_name']), None)
     if core:
         core.base_reg = core_dict['base_reg']
     else:
         core: Core = Core.create_from_dict(
             core_dict) if persistence else Core.dict_to_doc(core_dict)
         self.cores.append(core)
         if persistence:
             self.save()
     field_byte = core.create_field_byte(field_dict, persistence)
     return field_byte