예제 #1
0
def match_addrmode5(node, values, idx, dag: Dag):
    from codegen.dag import VirtualDagOps, DagValue
    from codegen.types import ValueType

    value = values[idx]

    if value.node.opcode == VirtualDagOps.FRAME_INDEX:
        index = value.node.index
        base = DagValue(
            dag.add_frame_index_node(value.ty, index, True), 0)
        offset = DagValue(dag.add_target_constant_node(
            value.ty, 0), 0)

        return idx + 1, [base, offset]

    if value.node.opcode == VirtualDagOps.ADD:
        value1 = value.node.operands[0]
        value2 = value.node.operands[1]

        if value1.node.opcode == VirtualDagOps.CONSTANT:
            base = value2

            assert(value1.node.value.value % 4 == 0)
            offset = DagValue(dag.add_target_constant_node(
                value1.ty, ConstantInt(value1.node.value.value >> 2, value1.node.value.ty)), 0)

            return idx + 1, [base, offset]
        elif value2.node.opcode == VirtualDagOps.CONSTANT:
            base = value1

            assert(value2.node.value.value % 4 == 0)
            offset = DagValue(dag.add_target_constant_node(
                value2.ty, ConstantInt(value2.node.value.value >> 2, value2.node.value.ty)), 0)

            return idx + 1, [base, offset]

    if value.node.opcode == VirtualDagOps.SUB:
        if value2.node.opcode == VirtualDagOps.CONSTANT:
            raise NotImplementedError()

    # if value.node.opcode == ARMDagOps.WRAPPER:
    #     base = value.node.operands[0]
    #     offset = DagValue(dag.add_target_constant_node(
    #         value.ty, 0), 0)

    #     return idx + 1, MatcherResult([base, offset])

    # only base.
    base = value

    assert(base.node.opcode != VirtualDagOps.TARGET_CONSTANT)

    offset = DagValue(dag.add_target_constant_node(
        value.ty, 0), 0)

    return idx + 1, [base, offset]
예제 #2
0
def get_legalized_op(operand, legalized):
    from codegen.dag import DagValue

    if operand.node not in legalized:
        return operand

    legalized_node = legalized[operand.node]

    if isinstance(legalized_node, (list, tuple)):
        return [DagValue(n, operand.index) for n in legalized_node]

    return DagValue(legalized_node, operand.index)
예제 #3
0
    def apply_value(self, value, dag):
        from codegen.dag import VirtualDagOps, DagValue

        if value.node.opcode == VirtualDagOps.CONSTANT:
            value = DagValue(
                dag.add_target_constant_node(value.ty, value.node.value), 0)

        if value.node.opcode == VirtualDagOps.FRAME_INDEX:
            value = DagValue(
                dag.add_frame_index_node(value.ty, value.node.index, True), 0)

        return value
예제 #4
0
            def construct(self, node, dag, result):
                from codegen.dag import DagValue

                return [
                    DagValue(
                        dag.add_target_constant_node(node.value_types[0],
                                                     self.value), 0)
                ]
예제 #5
0
    def match(self, node, dag):
        from codegen.types import ValueType
        from codegen.spec import MachineRegisterDef
        from codegen.mir import MachineRegister
        from codegen.dag import VirtualDagOps, DagValue

        value = DagValue(node, 0)

        return self.pattern.match(None, [value], 0, dag)
예제 #6
0
            def construct(self, node, dag, result):
                from codegen.dag import DagValue
                from codegen.mir import MachineRegister

                return [
                    DagValue(
                        dag.add_register_node(node.value_types[0],
                                              MachineRegister(self.reg)), 0)
                ]
예제 #7
0
def match_addrmode6(node, values, idx, dag: Dag):
    from codegen.dag import VirtualDagOps, DagValue
    from codegen.types import ValueType

    value = values[idx]

    addr = value

    align = DagValue(dag.add_target_constant_node(
        value.ty, 1), 0)  # TODO: Need alignment information

    return idx + 1, [addr, align]
예제 #8
0
def match_fi_addr(node, values, idx, dag):
    from codegen.dag import VirtualDagOps, DagValue
    from codegen.types import ValueType

    value = values[idx]

    if value.node.opcode == VirtualDagOps.FRAME_INDEX:
        index = value.node.index
        fi = DagValue(dag.add_frame_index_node(value.ty, index, True), 0)

        return idx + 1, fi

    return idx, None
예제 #9
0
def match_imm0_65535(node, values, idx, dag):
    from codegen.dag import VirtualDagOps
    from codegen.types import ValueType

    value = values[idx]
    if value.node.opcode not in [VirtualDagOps.CONSTANT, VirtualDagOps.TARGET_CONSTANT]:
        return idx, None

    if not in_bits_unsigned(value.node.value.value, 16):
        return idx, None

    target_value = DagValue(dag.add_target_constant_node(
        value.ty, value.node.value), 0)

    return idx + 1, target_value
예제 #10
0
def match_mod_imm(node, values, idx, dag):
    from codegen.dag import VirtualDagOps
    from codegen.types import ValueType

    value = values[idx]
    if value.node.opcode not in [VirtualDagOps.CONSTANT, VirtualDagOps.TARGET_CONSTANT]:
        return idx, None

    constant = value.node.value.value
    if get_mod_imm(constant) != -1:
        target_value = DagValue(dag.add_target_constant_node(
            value.ty, constant), 0)

        return idx + 1, target_value

    return idx, None
예제 #11
0
    def construct(self, node, dag: Dag, result: MatcherResult):
        operands = []
        for operand in self.operands:
            value = operand.construct(node, dag, result)
            operands.extend(value)

        assert (len(operands) == 1)

        base_node = operands[0].node

        from codegen.dag import DagNode, DagValue

        if isinstance(base_node, DagNode):
            return [DagValue(base_node, 0)]
            # return [DagValue(dag.add_node(base_node.opcode, [self.value_type], *base_node.operands), 0)]
        else:
            raise NotImplementedError()
예제 #12
0
def match_imm_shifter_operand(node, values, idx, dag):
    from codegen.dag import VirtualDagOps
    from codegen.types import ValueType

    value = values[idx]

    opc = get_shift_opcode(value.node.opcode)
    if opc == 0:
        return idx, None

    rhs = value.node.operands[1]
    if rhs.node.opcode not in [VirtualDagOps.CONSTANT, VirtualDagOps.TARGET_CONSTANT]:
        return idx, None

    rhs_val = rhs.node.value.value

    base = value.node.operands[0]
    opc = DagValue(dag.add_target_constant_node(
        value.ty, opc | (rhs_val << 3)), 0)

    return idx + 1, [base, opc]
예제 #13
0
FMV_D_X = def_inst_node_(RISCVMachineOps.FMV_D_X)
FMV_X_D = def_inst_node_(RISCVMachineOps.FMV_X_D)

MUL = def_inst_node_(RISCVMachineOps.MUL)
DIV = def_inst_node_(RISCVMachineOps.DIV)
DIVU = def_inst_node_(RISCVMachineOps.DIVU)
REM = def_inst_node_(RISCVMachineOps.REM)
REMU = def_inst_node_(RISCVMachineOps.REMU)

from codegen.dag import DagValue

HI20 = def_node_xform_(
    I32Imm, lambda value, dag: DagValue(
        dag.add_target_constant_node(
            value.node.value_types[0],
            ConstantInt((value.node.value.value & 0xFFFFFFFF) >> 12, value.node
                        .value.ty)), 0))


def get_bits_sext(value, bits):
    minus = value < 0
    value = abs(value)

    value = value & ((1 << bits) - 1)

    if minus:
        value = -value

    return value
예제 #14
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)
            ]
예제 #15
0
    def match(self, node, values, idx, dag):
        from codegen.dag import DagValue

        return self.matcher.match(None, [DagValue(node, 0)], 0, dag)
예제 #16
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)
예제 #17
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)