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
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, [])
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
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 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)
def get_register_count(self, vt): if vt in [MachineValueType(e) for e in ValueType]: return 1 raise NotImplementedError()
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) ]