// document.
static uint16_t lo(uint64_t v) { return v; }
static uint16_t hi(uint64_t v) { return v >> 16; }
-static uint16_t ha(uint64_t v) { return (v + 0x8000) >> 16; }
+static uint64_t ha(uint64_t v) { return (v + 0x8000) >> 16; }
static uint16_t higher(uint64_t v) { return v >> 32; }
static uint16_t highera(uint64_t v) { return (v + 0x8000) >> 32; }
static uint16_t highest(uint64_t v) { return v >> 48; }
case R_PPC64_TPREL16_HA:
if (config->tocOptimize && shouldTocOptimize && ha(val) == 0)
writeFromHalf16(loc, NOP);
- else
+ else {
+ checkInt(loc, val + 0x8000, 32, rel);
write16(loc, ha(val));
+ }
break;
case R_PPC64_ADDR16_HI:
case R_PPC64_REL16_HI:
case R_PPC64_TPREL16_HI:
+ checkInt(loc, val, 32, rel);
write16(loc, hi(val));
break;
case R_PPC64_ADDR16_HIGHER:
--- /dev/null
+# REQUIRES: ppc
+# RUN: llvm-mc -filetype=obj -triple=ppc64le --defsym HI=1 %s -o %thi.o
+# RUN: ld.lld %thi.o --defsym=a=0x7fffffff -o /dev/null
+# RUN: not ld.lld %thi.o --defsym=a=0x80000000 -o /dev/null
+# RUN: ld.lld %thi.o --defsym=a=0xffffffff80000000 -o /dev/null
+# RUN: not ld.lld %thi.o --defsym=a=0xffffffff7fffffff -o /dev/null
+
+# RUN: llvm-mc -filetype=obj -triple=ppc64le --defsym HA=1 %s -o %tha.o
+# RUN: ld.lld %tha.o --defsym=a=0x7fff7fff -o /dev/null
+# RUN: not ld.lld %tha.o --defsym=a=0x7fff8000 -o /dev/null
+# RUN: ld.lld %tha.o --defsym=a=0xffffffff7fff8000 -o /dev/null
+# RUN: not ld.lld %tha.o --defsym=a=0xffffffff7fff7fff -o /dev/null
+
+.ifdef HI
+lis 4, a@h # R_PPC64_ADDR16_HI
+.endif
+
+.ifdef HA
+lis 4, a@ha # R_PPC64_ADDR16_HA
+.endif