+ switch (r_type)
+ {
+ case elfcpp::R_POWERPC_TPREL16_HA:
+ if (target->tprel_opt())
+ {
+ section_size_type slen;
+ const unsigned char* view = NULL;
+ view = ppc_object->section_contents(data_shndx, &slen, false);
+ section_size_type off
+ = convert_to_section_size_type(reloc.get_r_offset()) & -4;
+ if (off < slen)
+ {
+ uint32_t insn = elfcpp::Swap<32, big_endian>::readval(view + off);
+ if ((insn & ((0x3fu << 26) | 0x1f << 16))
+ != ((15u << 26) | ((size == 32 ? 2 : 13) << 16)))
+ target->set_tprel_opt(false);
+ }
+ }
+ break;
+
+ case elfcpp::R_PPC64_TPREL16_HIGH:
+ case elfcpp::R_PPC64_TPREL16_HIGHA:
+ case elfcpp::R_PPC64_TPREL16_HIGHER:
+ case elfcpp::R_PPC64_TPREL16_HIGHERA:
+ case elfcpp::R_PPC64_TPREL16_HIGHEST:
+ case elfcpp::R_PPC64_TPREL16_HIGHESTA:
+ if (size != 64)
+ break;
+ // Fall through.
+ case elfcpp::R_POWERPC_TPREL16_HI:
+ target->set_tprel_opt(false);
+ break;
+ default:
+ break;
+ }
+