예제 #1
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)
예제 #2
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)
            ]