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)
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) ]