Converts generic register references (such as $t0, $t1, etc), immediate values, and jump addresses
        to their binary equivalents.

def resolve_operands(self, encoding_map, operation, pc):
        """
        Converts generic register references (such as $t0, $t1, etc), immediate values, and jump addresses
        to their binary equivalents.
        """
        convert = Encoder.to_binary
        branch_replace = False
        jump_replace = False

        for operand, value in encoding_map.iteritems():
            if (operand == 'rs' or operand == 'rt' or operand == 'rd'):
                encoding_map[operand] = MIPS.registers[value]

            elif (operand == 'imm'):
                encoding_map[operand] = convert(int(value), MIPS.IMMEDIATE_SIZE)

            elif (operand == 'addr'):
                encoding_map[operand] = convert(int(value), MIPS.ADDRESS_SIZE)

            elif (operand == 'shamt'):
                encoding_map[operand] = convert(int(value), MIPS.SHAMT_SIZE)

            elif (operand == 'label'):
                label = encoding_map[operand]
                hit, index = self.label_cache.query(label)

                if not hit:
                    raise RuntimeError('No address found for label: {}'.format(label))

                if ((operation == 'beq') or (operation == 'bne')):
                    # Calculate the relative instruction offset. The MIPS ISA uses
                    # PC + 4 + (branch offset) to resolve branch targets.
                    if index > pc:
                        encoding_map[operand] = convert(index - pc - 1, MIPS.IMMEDIATE_SIZE)
                    elif index < pc:
                        encoding_map[operand] = convert((pc + 1) - index, MIPS.IMMEDIATE_SIZE)
                    else:
                        # Not sure why a branch would resolve to itself, but ok
                        # (PC + 4) - 4 = 
                        encoding_map[operand] = convert(-1, MIPS.IMMEDIATE_SIZE)

                    branch_replace = True

                elif ((operation == 'j') or (operation == 'jal')):
                    # Jump addresses are absolute
                    encoding_map[operand] = convert(index, MIPS.ADDRESS_SIZE)
                    jump_replace = True

        # Need to convert references to 'label' back to references the instruction
        # encoding string recognizes, otherwise we end up with the default value (zero)
        # This doesn't feel very clean, but working on a fix.
        if branch_replace:
            encoding_map['imm'] = encoding_map['label']
        elif jump_replace:
            encoding_map['addr'] = encoding_map['label']