private void processHI16Relocation(MIPS_ElfRelocationContext elfRelocationContext,
			MIPS_DeferredRelocation hi16reloc, long lo16Addend) {

		long newValue;
		if (hi16reloc.isGpDisp) {

			newValue = (int) elfRelocationContext.getGPValue();
			if (newValue == -1) {
				markAsError(elfRelocationContext.getProgram(), hi16reloc.relocAddr,
					hi16reloc.relocType, hi16reloc.elfSymbol.getNameAsString(),
					hi16reloc.elfSymbol.getSymbolTableIndex(),
					"Failed to perform GP-based relocation", elfRelocationContext.getLog());
				return;
			}
			if (hi16reloc.relocType == MIPS_ElfRelocationType.R_MIPS16_HI16) {
				newValue -= (hi16reloc.relocAddr.getOffset() + 4) & ~0x3;
			}
			else {
				newValue -= hi16reloc.relocAddr.getOffset();
			}
		}
		else {
			newValue = (int) elfRelocationContext.getSymbolValue(hi16reloc.elfSymbol);
		}
// FIXME: should always use hi16reloc.addend - figure out at time of deferral
		long addend;
		if (elfRelocationContext.extractAddend()) {
			addend = ((hi16reloc.oldValueL & 0xffff) << 16) + lo16Addend;
		}
		else {
			addend = hi16reloc.addendL;
		}

		newValue = (newValue + addend + 0x8000) >> 16;
		newValue = (hi16reloc.oldValueL & ~0xffff) | (newValue & 0xffff);
		Memory memory = elfRelocationContext.getProgram().getMemory();
		try {
			memory.setInt(hi16reloc.relocAddr,
				shuffle((int) newValue, hi16reloc.relocType, elfRelocationContext));
		}
		catch (MemoryAccessException e) {
			// Unexpected since we did a previous getInt without failure
			throw new AssertException(e);
		}
	}
Complete HI16 relocation (R_MIPS_HI16, R_MIPS16_HI16, R_MICROMIPS_HI16) using
specified LO16 relocation data
@param elfRelocationContext
@param hi16reloc
@param lo16Addend
@return true if successful or false if unsupported
Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationHandler.java