예제 #1
0
    def get_direct_init(self, key, defaultvalue):
        """ Get the *value* for *key* """
        if self.direct_initialization_support:

            if isinstance(key, str):
                keys = self.target.registers.values()
                keys = [lkey for lkey in keys if lkey.name == key]
                if len(keys) != 1:
                    raise MicroprobeCodeGenerationError(
                        "Unable to find the direct initialization value"
                        " name: %s" % key)
                key = keys[0]

            if key in self._direct_init_dict:
                return self._direct_init_dict[key]

            if defaultvalue is not None:
                return defaultvalue

            raise MicroprobeCodeGenerationError(
                "Unable to find the direct initialization value")

        else:
            raise MicroprobeCodeGenerationError(
                "Direct intialization function called but not supported")
예제 #2
0
파일: var.py 프로젝트: IBM/microprobe
    def __init__(self, name, vartype, align=1, value=None, address=None):
        """

        :param name:
        :param vartype:
        :param align:  (Default value = 16)
        :param value:  (Default value = None)

        """
        super(VariableSingle, self).__init__()
        self._name = name
        self._type = vartype.lower()
        self._align = align
        self._value = value
        self._address = address

        if align is not None:
            if align <= 0:
                raise MicroprobeCodeGenerationError(
                    "Alignment should be > 0 in definition of "
                    "variable: '%s'" % name)
            val = math.log(align, 2)
            if val != int(val):
                raise MicroprobeCodeGenerationError(
                    "Alignment should be power of 2 in definition of "
                    "variable: '%s'" % name)
예제 #3
0
파일: isa.py 프로젝트: IBM/microprobe
    def get_register_for_address_arithmetic(self, context):
        """

        :param context:

        """
        reg = [
            reg
            for reg in self._address_registers
            if reg not in context.reserved_registers
            and int(reg.codification) >= 8 and int(reg.codification) <= 15
        ]

        reg += [
            reg
            for reg in self._address_registers
            if reg not in context.reserved_registers
            and int(reg.codification) < 8 and int(reg.codification) > 15
        ]

        if len(reg) == 0:
            raise MicroprobeCodeGenerationError(
                "No free registers available. "
                "Change your policy."
            )

        return reg[0]
예제 #4
0
    def __init__(self, instrs, prepend=None, allow_registers=None):
        """

        :param instrs:

        """
        super(SetInstructionTypeBySequencePass, self).__init__()

        for instr in instrs:
            if not isinstance(instr, InstructionType):
                raise MicroprobeCodeGenerationError(
                    "Invalid sequence definition. '%s' is not an instruction"
                    " type " % instr)

        self._sequence = instrs
        self._func = getnextf(itertools.cycle(instrs))
        self._description = "Repeat the instruction sequence '%s'" % \
            ([instruction.name for instruction in self._sequence])

        if prepend is None:
            prepend = []

        self._prepend = prepend
        self._aregs = []
        if allow_registers is not None:
            self._aregs = allow_registers
예제 #5
0
 def register_direct_init(self, dummy_key, dummy_value):
     """ Initialize *key* with the value *value* """
     if self.direct_initialization_support:
         raise NotImplementedError
     else:
         raise MicroprobeCodeGenerationError(
             "Direct intialization function called but not supported")
예제 #6
0
    def __add__(self, other):
        """

        :param other:

        """

        if isinstance(other, self.__class__):

            if self.base_address != other.base_address:
                raise MicroprobeCodeGenerationError(
                    "I can not add '%s' "
                    "and '%s'" % (self, other)
                )

            return self.__class__(
                self.base_address, self.displacement + other.displacement
            )

        elif isinstance(other, int):

            return self.__class__(self.base_address, self.displacement + other)

        else:
            raise NotImplementedError
예제 #7
0
    def representation(self, value):
        """

        :param value:

        """
        assert isinstance(value, tuple(list(six.integer_types) + [Address]))
        if isinstance(value, six.integer_types):
            # print(value, self._shift)
            # assert value % (self._shift + 1) == 0
            return _format_integer(self, value)
        else:
            base_address = value.base_address
            displacement = value.displacement

            if isinstance(base_address, Variable):
                str_value = base_address.name
            elif isinstance(base_address, str):
                str_value = base_address
            else:
                raise MicroprobeCodeGenerationError(
                    "Unable to generate the string representation of '%s'"
                    " with value: '%s'" % (self, value))

            if displacement > 0:
                str_value = "%s+0x%x" % (str_value, displacement)
            elif displacement < 0:
                str_value = "%s-0x%x" % (str_value, abs(displacement))

            return str_value
예제 #8
0
    def __mod__(self, other):
        """

        :param other:

        """

        if isinstance(other, self.__class__):

            if self.base_address != other.base_address:
                raise MicroprobeCodeGenerationError("I can not compute the "
                                                    "module '%s' and '%s'" %
                                                    (self, other))

            return self.__class__(self.base_address,
                                  self.displacement + other.displacement)

        elif isinstance(other, six.integer_types):

            if isinstance(self._base_address, six.integer_types):
                return (self._base_address + self.displacement) % other

            return self.displacement % other

        else:
            raise NotImplementedError
예제 #9
0
 def set_current_thread(self, idx):
     """ """
     self._current_thread = idx
     if not 1 <= idx <= self._threads + 1:
         raise MicroprobeCodeGenerationError(
             "Unknown thread id: %d (min: 1, max: %d)" %
             (idx, self._threads + 1))
예제 #10
0
파일: var.py 프로젝트: IBM/microprobe
    def __init__(self,
                 name,
                 vartype,
                 size,
                 align=None,
                 value=None,
                 address=None):
        """

        :param name:
        :param vartype:
        :param size:
        :param align:  (Default value = 16)
        :param value:  (Default value = None)

        """
        super(VariableArray, self).__init__()
        self._name = name
        self._type = vartype.lower()
        self._align = align
        self._value = value
        self._address = address
        self._elems = size

        if self._elems < 1:
            raise MicroprobeCodeGenerationError(
                "Array size should be greater than 0 in definition of "
                "variable: '%s'" % name)

        if align == 0:
            align = None

        if align is not None:
            val = math.log(align, 2)
            if val != int(val):
                raise MicroprobeCodeGenerationError(
                    "Alignment should be power of 2 in definition of "
                    "variable: '%s'" % name)

        if align is not None and address is not None:
            if not address.check_alignment(align):
                raise MicroprobeCodeGenerationError(
                    "Alignment requirements do not match address in definition"
                    " of variable: '%s'" % name)
예제 #11
0
    def set_register(self, reg, value, context):
        """

        :param reg:
        :param value:
        :param context:

        """
        raise MicroprobeCodeGenerationError("Unable to set register '%s' to "
                                            " value '%d'." % (reg.name, value))
예제 #12
0
    def __call__(self, building_block, target):

        for register_name in self._register_names:
            try:
                register = target.registers[register_name]
            except KeyError:
                raise MicroprobeCodeGenerationError(
                    "Unknown register '%s'. Known registers: %s" %
                    (register_name, list(target.registers.keys())))
            building_block.context.add_reserved_registers([register])
예제 #13
0
    def __call__(self, building_block, target):
        """

        :param building_block:
        :param target:

        """

        reg = [
            reg for reg in target.registers.values()
            if reg.name == self._register_name
        ][0]

        value = self._value

        if (reg in building_block.context.reserved_registers
                and self._reserve):
            raise MicroprobeCodeGenerationError("Register '%s' already"
                                                " reserved" % str(reg))

        if reg in target.control_registers and self._force_control is False:
            raise MicroprobeCodeGenerationError(
                "Register '%s' in Target definition control"
                " registers" % str(reg))

        if callable(value):
            value = value()

        if reg.used_for_float_arithmetic:
            value = ieee_float_to_int64(float(value))

        if (target.wrapper.direct_initialization_support
                and not self._force_code):
            target.wrapper.register_direct_init(reg, value)
        else:
            building_block.add_init(
                target.set_register(reg, value, building_block.context))

        building_block.context.set_register_value(reg, value)

        if (self._reserve is not False
                and reg not in building_block.context.reserved_registers):
            building_block.context.add_reserved_registers([reg])
예제 #14
0
파일: var.py 프로젝트: IBM/microprobe
    def size(self):
        """Variable size in bytes (::class:`~.int`)."""

        if self._type in VAR_TYPE_LEN_DICT:
            return VAR_TYPE_LEN_DICT[self._type] * self._elems
        elif "*" in self._type:
            # TODO: Assuming a 64 bits address size
            return 8 * self._elems
        else:
            raise MicroprobeCodeGenerationError(
                "Unable to compute the size of type '%s' in definition "
                "of variable '%s'" % (self._type, self._name))
예제 #15
0
    def __init__(self, target, wrapper, **kwargs):
        """Create a Synthesizer object.

        :param target: Benchmark target
        :type target: :class:`~.Target`
        :param wrapper: Wrapper object defining the output format
        :type wrapper: :class:`~.Wrapper`
        :param value: Default immediate value used for non-initialized
                      immediates (Default: random)
        :type value: :class:`~.int`
        :param no_scratch: Disable automatic declaration of scratch variables
                           required for code generation support
                           (Default: False)
        :type no_scratch: :class:`~.bool`
        :param extra_raw: List of extra raw strings to be embedded in the final
                          output
        :type extra_raw: :class:`~.list` of elements containing a ``name`` and
                         a ``value`` attributes (Default: [])
        :return: A Synthesizer instance
        :rtype: :class:`~.Synthesizer`
        """
        self._target = target

        # Extra arguments
        self._no_scratch = kwargs.get("no_scratch", False)
        self._raw = kwargs.get("extra_raw", {})
        self._immediate = kwargs.get("value", "random")
        self._threads = kwargs.get("threads", 1)

        self._passes = {}
        for idx in range(1, self._threads + 1):
            self._passes[idx] = []

        self._current_thread = 1

        if isinstance(wrapper, list):
            if len(wrapper) != self._threads:
                raise MicroprobeCodeGenerationError(
                    "Number of wrappers provided (%d) is different from "
                    "number of threads (%d) specified in the Synthesizer" %
                    (len(wrapper), self._threads)
                )
            self._wrappers = wrapper
        else:
            self._wrappers = [wrapper]
            for dummy in range(1, self._threads):
                new_wrapper = copy.deepcopy(wrapper)
                self._wrappers.append(new_wrapper)

        for wrapper in self._wrappers:
            wrapper.set_target(target)
예제 #16
0
파일: __init__.py 프로젝트: IBM/microprobe
    def __call__(self, building_block, target):
        """

        :param building_block:
        :param dummy_target:

        """

        loopvar = None
        for var in building_block.registered_global_vars():
            if var.name == self._varname:
                loopvar = var
                break

        if loopvar is None:
            raise MicroprobeCodeGenerationError(
                "AddOne pass var '%s' not declared" % self._varname)

        context = building_block.context

        areg = target.get_register_for_address_arithmetic(context)
        context.add_reserved_registers([areg])

        # Reset register to zero
        instrs = target.set_register(areg, 0, context)

        for instr in instrs:
            instr.add_comment("Loop counter init")

        building_block.add_init(instrs)

        instrs = target.add_to_register(areg, 1)

        try:
            instrs += target.store_integer(areg, loopvar.address, 64, context)
        except MicroprobeCodeGenerationError:
            areg = target.scratch_registers[0]
            instrs += target.set_register_to_address(
                areg,
                loopvar.address,
                context,
            )
            context.set_register_value(areg, loopvar.address)
            instrs += target.store_integer(areg, loopvar.address, 64, context)

        for instr in instrs:
            instr.add_comment("Loop update")

        building_block.add_fini(instrs)

        return []
예제 #17
0
    def __call__(self, building_block, target):
        """

        :param building_block:
        :param target:

        """

        replaced = False

        if self._every == 0:
            return

        count = 0
        for bbl in building_block.cfg.bbls:
            for instr in bbl.instrs:

                if instr.architecture_type == self._instr1:
                    count = count + 1

                    if (count % self._every) != 0:
                        continue

                    replaced = True
                    instr.set_arch_type(self._instr2)

                    # reserve implicit operands (if they are not already
                    # reserved) and add them as allowed
                    for operand_descriptor in instr.implicit_operands:
                        register = list(operand_descriptor.type.values())[0]
                        instr.add_allow_register(register)

                        if operand_descriptor.is_output and register not \
                                in building_block.context.reserved_registers \
                                and register not in target.control_registers:
                            building_block.context.add_reserved_registers(
                                [register])

                    context_fix_functions = instr.check_context(
                        building_block.context)
                    for context_fix_function in context_fix_functions:
                        try:
                            context_fix_function(target, building_block)
                        except MicroprobeUncheckableEnvironmentWarning as wue:
                            building_block.add_warning(str(wue))

        if not replaced:
            raise MicroprobeCodeGenerationError(
                "Unable to replace %s by %s every %d times" %
                (self._instr1.name, self._instr2.name, self._every))
예제 #18
0
    def add_pass(self, synth_pass, thread_idx=None):
        """Add a pass to the benchmark synthesizer.

        :param synth_pass: New pass to add.
        :type synth_pass: :class:`~.Pass`
        """

        if thread_idx is None:
            self._passes[self._current_thread].append(synth_pass)
        else:
            if not 1 <= thread_idx <= self._threads + 1:
                raise MicroprobeCodeGenerationError(
                    "Unknown thread id: %d (min: 1, max: %d)" %
                    (thread_idx, self._threads + 1))
            self._passes[thread_idx].append(synth_pass)
예제 #19
0
    def __call__(self, building_block, target):
        """

        :param building_block:
        :param target:

        """

        instructions_def = interpret_asm(self._asm, target,
                                         building_block.labels)

        instructions = []
        for definition in instructions_def:
            instruction = microprobe.code.ins.Instruction()
            instruction_set_def_properties(instruction,
                                           definition,
                                           building_block=building_block,
                                           target=target,
                                           allowed_registers=self._aregs)
            instructions.append(instruction)

        if self._index < 0:
            building_block.add_instructions(
                instructions, after=building_block.cfg.bbls[-1].instrs[-1])
        elif self._index == 0:
            building_block.add_instructions(
                instructions, before=building_block.cfg.bbls[0].instrs[0])
        else:
            cindex = 0
            ains = None
            instr = None
            for bbl in building_block.cfg.bbls:
                for instr in bbl.instrs:
                    cindex = cindex + 1

                if instr is None:
                    raise MicroprobeCodeGenerationError(
                        "Empty basic block found")

                if cindex == self._index:
                    ains = instr

                    building_block.add_instructions(instructions, after=ains)

                    return

            building_block.add_instructions(
                instructions, after=building_block.cfg.bbls[-1].instrs[-1])
예제 #20
0
    def set_valid_values(self, values):
        """

        :param values:

        """
        if len(values) == 0:
            raise MicroprobeCodeGenerationError(
                "Setting an operand without any valid value. Please check "
                "the definition files. Previous value: '%s'. New values: '%s'"
                "." % (list(self.values()), values))

        for value in values:
            assert value in list(self.values())

        self._computed_values = values
        self._const = len(values) == 1
예제 #21
0
    def add_instructions(self, instrs, after=None, before=None):
        """Adds the given instruction to the building block.

        Adds the given instructions right after the specified instruction and
        before the specified one. If the condition can not be fulfilled an
        specification exception is raised.

        :param instrs: Instruction to add
        :type instrs: :class:`~.list` of :class:`~.Instruction`
        :param after: Instruction after which to add the new instruction
                      (Default value = None)
        :type after: :class:`~.Instruction`
        :param before: Instruction before which to add the new instruction
                       (Default value = None)
        :type before: :class:`~.Instruction`

        """

        if after is None and before is None:
            bbl = self.cfg.last_bbl()
            bbl.insert_instr(instrs)

        elif after is not None and before is None:
            idx_after = self.cfg.index(after)
            bbl = self.cfg.get_bbl(idx_after)
            bbl.insert_instr(instrs, after=after)

        elif after is None and before is not None:
            idx_before = self.cfg.index(before)
            bbl = self.cfg.get_bbl(idx_before)
            bbl.insert_instr(instrs, before=before)

        elif after is not None and before is not None:
            idx_before = self.cfg.index(before)
            idx_after = self.cfg.index(after)

            if idx_before < idx_after:
                bbl = self.cfg.get_bbl(idx_before)
                bbl.insert_instr(instrs)
            elif idx_before == idx_after:
                bbl = self.cfg.get_bbl(idx_before)
                bbl.insert_instr(instrs, after=after, before=before)
            else:
                raise MicroprobeCodeGenerationError(
                    "Attempt to inserst instruction in a position that it is"
                    " not possible")
예제 #22
0
    def codification(self, value):
        """

        :param value:

        """

        if isinstance(value, six.integer_types):
            return str(value >> self._shift)
        elif isinstance(value, Address):
            raise MicroprobeCodeGenerationError("Unable to codify the"
                                                " symbolic address: %s ."
                                                " Consider to add a pass to"
                                                " translate them to actual "
                                                "values " % value)
        else:
            raise NotImplementedError
예제 #23
0
    def get_register_for_address_arithmetic(self, context):
        """

        :param context:

        """
        reg = [
            reg for reg in self._address_registers
            if reg not in context.reserved_registers
        ]

        if len(reg) == 0:
            raise MicroprobeCodeGenerationError("No free registers available. "
                                                "Change your policy.")

        # REG0 tends to have special meaning and it is usually at the
        # beginning, move it
        reg = reg[1:] + [reg[0]]
        return reg[0]
예제 #24
0
    def get_context(self, variable=None, tmpl_path=None):
        """ """

        if variable is None:
            variable = self.context_var

        if variable.size < self.context_var.size:
            raise MicroprobeCodeGenerationError(
                "Variable '%s' is too small to save the target context")

        asm = open(os.path.join(tmpl_path, "getcontext.S")).readlines()

        if len(asm) == 0:
            return []

        reg = self._scratch_registers[0]
        instrs = self.set_register_to_address(reg, variable.address, Context())

        return instrs + \
            microprobe.code.ins.instructions_from_asm(asm, self.target)
예제 #25
0
파일: bbl.py 프로젝트: IBM/microprobe
    def reset_instruction(self, instr, new_instr):
        """Resets the instruction within a basic block by another instruction.

        Resets the instruction within a basic block by another instruction.
        If the instruction is not found, an exception is raised.

        :param instr: Instruction to replace
        :type instr: :class:`~.Instruction`
        :param new_instr: New instruction
        :type new_instr: :class:`~.Instruction`
        :raise microprobe.exceptions.MicroprobeCodeGenerationError: if the
            instruction is not found in the basic block

        """

        idx = self._index(instr)
        if idx < 0:
            raise MicroprobeCodeGenerationError("Instruction not found "
                                                "in the basic block")
        self._instrs[idx] = new_instr
예제 #26
0
    def __rsub__(self, other):
        """

        :param other:

        """

        if isinstance(other, (Address, InstructionAddress)):

            if self.base_address != other.base_address:
                raise MicroprobeCodeGenerationError("I can not sub '%s' "
                                                    "and '%s'" % (self, other))

            return other.displacement - self.displacement

        elif isinstance(other, six.integer_types):
            return self.__class__(self.base_address, self.displacement - other)
        else:
            raise NotImplementedError(
                "Substraction not implemented for %s and %s "
                "objects" % (self.__class__, other.__class__))
예제 #27
0
    def __sub__(self, other):
        """

        :param other:

        """

        if isinstance(other, self.__class__):

            if self.base_address != other.base_address:
                raise MicroprobeCodeGenerationError("I can not sub '%s' "
                                                    "and '%s'" % (self, other))

            return self.displacement - other.displacement

        elif isinstance(other, six.integer_types):
            return self.__class__(self.base_address, self.displacement - other)

        else:
            LOG.critical("%s != %s", self, other)
            LOG.critical("%s != %s", type(self), type(other))
            raise NotImplementedError
예제 #28
0
    def __rsub__(self, other):
        """

        :param other:

        """

        if isinstance(other, (Address, InstructionAddress)):

            if self.base_address != other.base_address:
                raise MicroprobeCodeGenerationError(
                    "I can not sub '%s' "
                    "and '%s'" % (self, other)
                )

            return other.displacement - self.displacement

        elif isinstance(other, int):
            return self.__class__(self.base_address, self.displacement - other)

        else:
            print(self.__class__, other.__class__)
            raise NotImplementedError
예제 #29
0
    def _wrap_thread(self, bench, thread_id):
        """Wrap a thread in benchmark.

        This function wraps a thread using the synthesizer wrapper. The
        wrapping process is the process of converting the internal
        representation of the benchmark to the actual string that is written
        to a file, adding the necessary prologue and epilogue bytes of
        data.

        :param bench: Benchmark to wrap.
        :type bench: :class:`~.Benchmark`
        :param thread_id: Thread to wrap
        :type thread_id : :class:`~.int`
        :return: A string representation of the benchmark
        :rtype: :class:`~.str`
        """

        bench.set_current_thread(thread_id)
        self.set_current_thread(thread_id)

        thread_str = []
        thread_str.append(self.wrapper.start_main())

        if 'CODE_HEADER' in self._raw:
            thread_str.append("\n" + self._raw['CODE_HEADER'] + "\n")

        for var in bench.registered_global_vars():
            if var.value is None:
                thread_str.append(
                    self.wrapper.init_global_var(
                        var, self._immediate
                    )
                )

        thread_str.append(self.wrapper.post_var())

        # TODO: This is hardcoded and assumes a loop always. Needs to be more
        # generic: pass a building block to a wrapper and it automatically
        # returns the required string

        for instr in bench.init:
            thread_str.append(self.wrapper.wrap_ins(instr))

        code_str = []
        first = True
        instr = None
        for bbl in bench.cfg.bbls:
            for instr in bbl.instrs:
                if first is True:
                    first = False
                    if bench.init:
                        code_str.append(
                            self.wrapper.start_loop(
                                instr, bench.init[0]
                            )
                        )
                    else:
                        code_str.append(self.wrapper.start_loop(instr, instr))
                code_str.append(self.wrapper.wrap_ins(instr))

        if instr is None:
            raise MicroprobeCodeGenerationError(
                "No instructions found in benchmark"
            )

        thread_str.extend(code_str)

        for instr in bench.fini:
            thread_str.append(self.wrapper.wrap_ins(instr))

        last_instr = instr
        thread_str.append(self.wrapper.end_loop(last_instr))

        if 'CODE_FOOTER' in self._raw:
            thread_str.append("\n" + self._raw['CODE_FOOTER'] + "\n")

        thread_str.append(self.wrapper.end_main())

        return thread_str
예제 #30
0
    def set_register_to_address(self,
                                register,
                                address,
                                context,
                                force_absolute=False,
                                force_relative=False):
        instrs = []

        assert address is not None

        LOG.debug("Begin setting '%s' to address '%s'", register, address)

        if isinstance(address.base_address, Variable):

            LOG.debug("Base address is a Variable: %s", address.base_address)
            closest = context.get_closest_address_value(address)

            if context.register_has_value(address):

                present_reg = context.registers_get_value(address)[0]
                displacement = 0
                LOG.debug("Address already in register '%s'", present_reg)

            elif closest is not None:

                present_reg, taddress = closest
                displacement = address.displacement - taddress.displacement
                LOG.debug("Closest value '%s' found in '%s'", taddress,
                          present_reg)
                LOG.debug("Displacement needed: %s", displacement)

            elif context.register_has_value(
                    Address(base_address=address.base_address)):

                present_reg = context.registers_get_value(
                    Address(base_address=address.base_address))[0]
                displacement = address.displacement
                LOG.debug("Base address '%s' found in '%s'", taddress,
                          present_reg)
                LOG.debug("Displacement needed: %s", displacement)

            else:

                present_reg = None
                displacement = None

            LOG.debug("Present_reg: %s", present_reg)
            LOG.debug("Displacement: %s", displacement)

            if present_reg is not None:

                if displacement != 0 and abs(displacement) < (2**15):

                    addi_ins = self.new_instruction("ADDI_V0")
                    addi_ins.set_operands(
                        [register, present_reg, displacement])
                    instrs.append(addi_ins)

                    LOG.debug("Computing directly from context (short)")

                    return instrs

                if present_reg != register:
                    or_ins = self.new_instruction("OR_V0")
                    or_ins.set_operands([present_reg, register, present_reg])
                    instrs.append(or_ins)

                if displacement != 0:
                    instrs += self.add_to_register(register, displacement)

                LOG.debug("Computing directly from context (long)")

                return instrs

        if context.symbolic and not force_absolute and not force_relative:

            # TODO: This should be a call to the environment object because
            # the implementation depends on the environment

            # Base address can be an instruction label (str) or
            # a Variable instance
            basename = address.base_address
            if not isinstance(address.base_address, str):
                basename = address.base_address.name

            lis_ins = self.new_instruction("ADDIS_V1")
            lis_ins.operands()[0].set_value(register)
            lis_ins.operands()[1].set_value(0)
            lis_ins.operands()[2].set_value("%s@highest" % basename,
                                            check=False)

            instrs.append(lis_ins)

            ori_ins = self.new_instruction("ORI_V0")
            ori_ins.operands()[0].set_value(register)
            ori_ins.operands()[1].set_value(register)
            ori_ins.operands()[2].set_value("%s@higher" % basename,
                                            check=False)
            instrs.append(ori_ins)

            rldicr_ins = self.new_instruction("RLDICR_V0")
            rldicr_ins.set_operands([register, register, 32, 31])
            instrs.append(rldicr_ins)

            oris_ins = self.new_instruction("ORIS_V0")
            oris_ins.operands()[0].set_value(register)
            oris_ins.operands()[1].set_value(register)
            oris_ins.operands()[2].set_value("%s@h" % basename, check=False)
            instrs.append(oris_ins)

            ori_ins = self.new_instruction("ORI_V0")
            ori_ins.operands()[0].set_value(register)
            ori_ins.operands()[1].set_value(register)
            ori_ins.operands()[2].set_value("%s@l" % basename, check=False)
            instrs.append(ori_ins)

            if address.displacement != 0:
                instrs += self.add_to_register(register, address.displacement)

            LOG.debug("End Loading symbolic reference")

            return instrs

        LOG.debug("Context not symbolic")

        base_address = address.base_address
        displacement = address.displacement

        LOG.debug("Base_address: %s", base_address)
        LOG.debug("Displacement: %s", displacement)

        if isinstance(base_address, Variable):
            LOG.debug("Get absolute address")
            displacement += base_address.address.displacement
            base_address = base_address.address.base_address

        LOG.debug("Base_address 2: %s", base_address)
        LOG.debug("Displacement 2: %s", displacement)

        if isinstance(base_address, str):

            if base_address == "data":
                base_address = Address(base_address=base_address)
            elif base_address == "code":
                base_address = InstructionAddress(base_address=base_address)

        source_register = None
        if context.register_has_value(base_address):
            source_register = context.registers_get_value(base_address)[0]
        else:

            for reg, value in context.register_values.items():
                if not isinstance(value, Address):
                    continue

                if (Address(base_address=value.base_address) ==
                        base_address.base_address):

                    source_register = reg
                    displacement += base_address.displacement
                    base_address = Address(
                        base_address=base_address.base_address)
                    break

                if value.base_address == base_address.base_address:
                    source_register = reg
                    displacement += base_address.displacement
                    base_address = Address(
                        base_address=base_address.base_address)
                    break

        if source_register is None or displacement >= (2**31):
            # Not source register found
            if base_address.base_address == "data":
                value = context.data_segment
            elif base_address.base_address == "code":
                value = context.code_segment
            else:
                LOG.debug(context.dump())
                raise MicroprobeCodeGenerationError(
                    "Unable to generate "
                    "the base address: '%s'"
                    " for target address: '%s'." % (base_address, address))

            if abs(displacement) >= (2**31):
                value = value + displacement
                displacement = 0

            assert (value is not None)

            instrs += self.set_register(register, value, context)

        if source_register is not None and source_register != register:
            or_ins = self.new_instruction("OR_V0")
            or_ins.set_operands([source_register, register, source_register])
            instrs.append(or_ins)

        if displacement != 0:
            instrs += self.add_to_register(register, displacement)

        LOG.debug("End address generation")
        return instrs