Exemple #1
0
    def get_types(self, hwmode):
        tys = []
        for ty in self.ty_infos:
            if isinstance(ty, ValueTypeByHWMode):
                tys.append(MachineValueType(ty.get_type(hwmode)))
            else:
                assert (isinstance(ty, ValueType))
                tys.append(MachineValueType(ty))

        return tys
Exemple #2
0
    def __init__(self, value_type, **props):
        from codegen.types import MachineValueType

        self.value_type = MachineValueType(value_type)
        self.props = dict(props)

        self.matcher = ValueTypeMatcher(self.value_type, None, [])
Exemple #3
0
def glued_node_iter(node):
    from codegen.types import MachineValueType, ValueType

    glue_ty = MachineValueType(ValueType.GLUE)
    yield node
    while len(node.operands) > 0 and node.operands[-1].ty == glue_ty:
        node = node.operands[-1].node
        yield node
Exemple #4
0
def construct(inst, node, dag: Dag, result: MatcherResult):
    from codegen.types import ValueType, MachineValueType
    from codegen.spec import MachineRegisterDef
    from codegen.dag import DagValue

    dic = result.values_as_dict

    ops = []
    for name, opnd in inst.ins.items():
        ops.extend(opnd.apply(dic[name].value, dag))

    operands = list(node.operands)

    # Capture chain
    chain = None

    operand_idx = 0
    if operand_idx < len(operands) and operands[
            operand_idx].ty.value_type == ValueType.OTHER:
        chain = operands[operand_idx]
        operand_idx += 1

    stack = []
    if chain is None:
        stack.append(node)

    while len(stack) > 0:
        parent_node = stack.pop()

        if len(parent_node.operands) == 0:
            break

        if parent_node.operands[0].ty.value_type == ValueType.OTHER:
            chain = parent_node.operands[0]
            break

        for operand in parent_node.operands:
            stack.append(operand.node)

    if not chain:
        chain = dag.entry

    glue = None

    if len(operands) > 0 and operands[-1].ty.value_type == ValueType.GLUE:
        glue = node.operands[-1]
        operands.pop()

    for reg in inst.uses:
        assert (isinstance(reg, MachineRegisterDef))
        if not reg in dic:
            continue

        operand = dic[reg].value

        if not operand:
            continue

        reg_node = DagValue(dag.add_target_register_node(operand.ty, reg), 0)

        copy_to_reg_ops = [chain, reg_node, operand]
        if glue:
            copy_to_reg_ops.append(glue)

        chain = DagValue(
            dag.add_node(VirtualDagOps.COPY_TO_REG, [
                MachineValueType(ValueType.OTHER),
                MachineValueType(ValueType.GLUE)
            ], *copy_to_reg_ops), 0)

        glue = chain.get_value(1)

    operand_idx += len(ops)

    while operand_idx < len(operands):
        operand = operands[operand_idx]
        operand_idx += 1

        if operand == glue:
            continue

        ops.append(operand)

    if chain:
        ops.append(chain)

    if glue:
        ops.append(glue)

    return dag.add_machine_dag_node(inst, node.value_types, *ops)
Exemple #5
0
    def match(self, node, values, idx, dag):
        from codegen.types import ValueType, MachineValueType
        from codegen.spec import MachineRegisterDef
        from codegen.mir import MachineRegister
        from codegen.dag import VirtualDagOps, DagValue, StoreDagNode, LoadDagNode

        if idx >= len(values):
            return idx, None

        value = values[idx]

        node = value.node

        # Check opcode
        _, res = self.opcode.match(None, [value], 0, dag)
        if not res:
            return idx, None

        mem_vt = self.props["mem_vt"] if "mem_vt" in self.props else None
        if mem_vt:
            assert (isinstance(node, (StoreDagNode, LoadDagNode)))

            if node.mem_operand.size != MachineValueType(
                    mem_vt).get_size_in_byte():
                return idx, None

        # Check operands
        operand_idx = 0

        # Capture chain
        chain = None
        if operand_idx < len(node.operands) and node.operands[
                operand_idx].ty.value_type == ValueType.OTHER:
            chain = node.operands[operand_idx]
            operand_idx += 1

        match_results = []
        for matcher in self.operands:
            operand_idx, res = matcher.match(node, node.operands, operand_idx,
                                             dag)

            if not res:
                return idx, None

            match_results.append(res)

            for sub_value in res.sub_values:
                match_results.append(sub_value)

        # while operand_idx < len(node.operands) and node.operands[operand_idx].node.opcode == VirtualDagOps.UNDEF:
        #     operand_idx += 1

        # if operand_idx != len(node.operands):
        #     return None

        # Check values
        value_idx = 0
        node_values = [DagValue(node, i) for i in range(len(node.value_types))]

        for matcher in self.values:
            _, res = matcher.match(node, node_values, value_idx, dag)
            if not res:
                return idx, None

            match_results.append(res)

            for sub_value in res.sub_values:
                match_results.append(sub_value)

        return idx + 1, MatcherResult(None, None, match_results)
Exemple #6
0
    def get_register_count(self, vt):
        if vt in [MachineValueType(e) for e in ValueType]:
            return 1

        raise NotImplementedError()
Exemple #7
0
        def construct(self, node, dag, result):
            from codegen.dag import DagValue

            ops = []
            for operand, operand_name in zip(self.operands, self.opcode.ins):
                ops.extend(operand.construct(node, dag, result))

            inst = self.opcode

            # Capture chain
            chain = None
            operand_idx = 0
            if operand_idx < len(node.operands) and node.operands[
                    operand_idx].ty.value_type == ValueType.OTHER:
                chain = node.operands[operand_idx]
                operand_idx += 1

            stack = []
            if chain is None:
                stack.append(node)

            while len(stack) > 0:
                parent_node = stack.pop()

                if len(parent_node.operands) == 0:
                    break

                if parent_node.operands[0].ty.value_type == ValueType.OTHER:
                    chain = parent_node.operands[0]
                    break

                for operand in parent_node.operands:
                    stack.append(operand.node)

            if not chain:
                chain = dag.entry

            glue = None
            for reg in inst.uses:
                assert (isinstance(reg, MachineRegisterDef))
                operand = dic[reg].value

                if not operand:
                    continue

                reg_node = DagValue(
                    dag.add_target_register_node(operand.ty, reg), 0)

                chain = DagValue(
                    dag.add_node(VirtualDagOps.COPY_TO_REG, [
                        MachineValueType(ValueType.OTHER),
                        MachineValueType(ValueType.GLUE)
                    ], chain, reg_node, operand), 0)

                glue = chain.get_value(1)

            if len(node.operands
                   ) > 0 and node.operands[-1].ty.value_type == ValueType.GLUE:
                glue = node.operands[-1]

            if chain:
                ops.append(chain)

            if glue:
                ops.append(glue)

            return [
                DagValue(
                    dag.add_machine_dag_node(inst, node.value_types, *ops), 0)
            ]