OSDN Git Service

[PPC64] Support "symbol@high" and "symbol@higha" symbol modifers.
authorSean Fertile <sfertile@ca.ibm.com>
Fri, 15 Jun 2018 19:47:11 +0000 (19:47 +0000)
committerSean Fertile <sfertile@ca.ibm.com>
Fri, 15 Jun 2018 19:47:11 +0000 (19:47 +0000)
Add support for the "@high" and "@higha" symbol modifiers in powerpc64 assembly.
The modifiers represent accessing the segment consiting of bits 16-31 of a
64-bit address/offset.

Differential Revision: https://reviews.llvm.org/D47729

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@334855 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def
include/llvm/MC/MCExpr.h
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
lib/MC/MCExpr.cpp
lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp
lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h
test/MC/PowerPC/ppc64-fixup-apply.s
test/MC/PowerPC/ppc64-fixups.s

index d2dbc79..4677f6d 100644 (file)
@@ -89,6 +89,8 @@
 #undef R_PPC64_DTPREL16_HIGHESTA
 #undef R_PPC64_TLSGD
 #undef R_PPC64_TLSLD
+#undef R_PPC64_ADDR16_HIGH
+#undef R_PPC64_ADDR16_HIGHA
 #undef R_PPC64_IRELATIVE
 #undef R_PPC64_REL16
 #undef R_PPC64_REL16_LO
@@ -176,6 +178,8 @@ ELF_RELOC(R_PPC64_DTPREL16_HIGHEST,     105)
 ELF_RELOC(R_PPC64_DTPREL16_HIGHESTA,    106)
 ELF_RELOC(R_PPC64_TLSGD,                107)
 ELF_RELOC(R_PPC64_TLSLD,                108)
+ELF_RELOC(R_PPC64_ADDR16_HIGH,          110)
+ELF_RELOC(R_PPC64_ADDR16_HIGHA,         111)
 ELF_RELOC(R_PPC64_IRELATIVE,            248)
 ELF_RELOC(R_PPC64_REL16,                249)
 ELF_RELOC(R_PPC64_REL16_LO,             250)
index d746496..6985449 100644 (file)
@@ -218,6 +218,8 @@ public:
     VK_PPC_LO,             // symbol@l
     VK_PPC_HI,             // symbol@h
     VK_PPC_HA,             // symbol@ha
+    VK_PPC_HIGH,           // symbol@high
+    VK_PPC_HIGHA,          // symbol@higha
     VK_PPC_HIGHER,         // symbol@higher
     VK_PPC_HIGHERA,        // symbol@highera
     VK_PPC_HIGHEST,        // symbol@highest
index e15fd0b..91fd129 100644 (file)
@@ -723,9 +723,11 @@ void RuntimeDyldELF::resolvePPC64Relocation(const SectionEntry &Section,
     writeInt16BE(LocalAddress, applyPPClo(Value + Addend) & ~3);
     break;
   case ELF::R_PPC64_ADDR16_HI:
+  case ELF::R_PPC64_ADDR16_HIGH:
     writeInt16BE(LocalAddress, applyPPChi(Value + Addend));
     break;
   case ELF::R_PPC64_ADDR16_HA:
+  case ELF::R_PPC64_ADDR16_HIGHA:
     writeInt16BE(LocalAddress, applyPPCha(Value + Addend));
     break;
   case ELF::R_PPC64_ADDR16_HIGHER:
index f2d078b..c4e8fb6 100644 (file)
@@ -239,6 +239,8 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
   case VK_PPC_LO: return "l";
   case VK_PPC_HI: return "h";
   case VK_PPC_HA: return "ha";
+  case VK_PPC_HIGH: return "high";
+  case VK_PPC_HIGHA: return "higha";
   case VK_PPC_HIGHER: return "higher";
   case VK_PPC_HIGHERA: return "highera";
   case VK_PPC_HIGHEST: return "highest";
@@ -343,6 +345,8 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
     .Case("l", VK_PPC_LO)
     .Case("h", VK_PPC_HI)
     .Case("ha", VK_PPC_HA)
+    .Case("high", VK_PPC_HIGH)
+    .Case("higha", VK_PPC_HIGHA)
     .Case("higher", VK_PPC_HIGHER)
     .Case("highera", VK_PPC_HIGHERA)
     .Case("highest", VK_PPC_HIGHEST)
index d6db354..581ca1a 100644 (file)
@@ -1394,6 +1394,12 @@ ExtractModifierFromExpr(const MCExpr *E,
     case MCSymbolRefExpr::VK_PPC_HA:
       Variant = PPCMCExpr::VK_PPC_HA;
       break;
+    case MCSymbolRefExpr::VK_PPC_HIGH:
+      Variant = PPCMCExpr::VK_PPC_HIGH;
+      break;
+    case MCSymbolRefExpr::VK_PPC_HIGHA:
+      Variant = PPCMCExpr::VK_PPC_HIGHA;
+      break;
     case MCSymbolRefExpr::VK_PPC_HIGHER:
       Variant = PPCMCExpr::VK_PPC_HIGHER;
       break;
@@ -1973,6 +1979,10 @@ PPCAsmParser::applyModifierToExpr(const MCExpr *E,
     return PPCMCExpr::create(PPCMCExpr::VK_PPC_HI, E, false, Ctx);
   case MCSymbolRefExpr::VK_PPC_HA:
     return PPCMCExpr::create(PPCMCExpr::VK_PPC_HA, E, false, Ctx);
+  case MCSymbolRefExpr::VK_PPC_HIGH:
+    return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGH, E, false, Ctx);
+  case MCSymbolRefExpr::VK_PPC_HIGHA:
+    return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHA, E, false, Ctx);
   case MCSymbolRefExpr::VK_PPC_HIGHER:
     return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHER, E, false, Ctx);
   case MCSymbolRefExpr::VK_PPC_HIGHERA:
index 52bf514..7315a73 100644 (file)
@@ -55,6 +55,10 @@ static MCSymbolRefExpr::VariantKind getAccessVariant(const MCValue &Target,
     return MCSymbolRefExpr::VK_PPC_HI;
   case PPCMCExpr::VK_PPC_HA:
     return MCSymbolRefExpr::VK_PPC_HA;
+  case PPCMCExpr::VK_PPC_HIGH:
+    return MCSymbolRefExpr::VK_PPC_HIGH;
+  case PPCMCExpr::VK_PPC_HIGHA:
+    return MCSymbolRefExpr::VK_PPC_HIGHA;
   case PPCMCExpr::VK_PPC_HIGHERA:
     return MCSymbolRefExpr::VK_PPC_HIGHERA;
   case PPCMCExpr::VK_PPC_HIGHER:
@@ -151,6 +155,12 @@ unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
       case MCSymbolRefExpr::VK_PPC_HA:
         Type = ELF::R_PPC_ADDR16_HA;
         break;
+      case MCSymbolRefExpr::VK_PPC_HIGH:
+        Type = ELF::R_PPC64_ADDR16_HIGH;
+        break;
+      case MCSymbolRefExpr::VK_PPC_HIGHA:
+        Type = ELF::R_PPC64_ADDR16_HIGHA;
+        break;
       case MCSymbolRefExpr::VK_PPC_HIGHER:
         Type = ELF::R_PPC64_ADDR16_HIGHER;
         break;
index 54f6643..32e6a0b 100644 (file)
@@ -44,6 +44,8 @@ void PPCMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
     case VK_PPC_LO: OS << "@l"; break;
     case VK_PPC_HI: OS << "@h"; break;
     case VK_PPC_HA: OS << "@ha"; break;
+    case VK_PPC_HIGH: OS << "@high"; break;
+    case VK_PPC_HIGHA: OS << "@higha"; break;
     case VK_PPC_HIGHER: OS << "@higher"; break;
     case VK_PPC_HIGHERA: OS << "@highera"; break;
     case VK_PPC_HIGHEST: OS << "@highest"; break;
@@ -75,6 +77,10 @@ PPCMCExpr::evaluateAsInt64(int64_t Value) const {
       return (Value >> 16) & 0xffff;
     case VK_PPC_HA:
       return ((Value + 0x8000) >> 16) & 0xffff;
+    case VK_PPC_HIGH:
+      return (Value >> 16) & 0xffff;
+    case VK_PPC_HIGHA:
+      return ((Value + 0x8000) >> 16) & 0xffff;
     case VK_PPC_HIGHER:
       return (Value >> 32) & 0xffff;
     case VK_PPC_HIGHERA:
@@ -125,6 +131,12 @@ PPCMCExpr::evaluateAsRelocatableImpl(MCValue &Res,
       case VK_PPC_HA:
         Modifier = MCSymbolRefExpr::VK_PPC_HA;
         break;
+      case VK_PPC_HIGH:
+        Modifier = MCSymbolRefExpr::VK_PPC_HIGH;
+        break;
+      case VK_PPC_HIGHA:
+        Modifier = MCSymbolRefExpr::VK_PPC_HIGHA;
+        break;
       case VK_PPC_HIGHERA:
         Modifier = MCSymbolRefExpr::VK_PPC_HIGHERA;
         break;
index d42a111..8bb4791 100644 (file)
@@ -23,6 +23,8 @@ public:
     VK_PPC_LO,
     VK_PPC_HI,
     VK_PPC_HA,
+    VK_PPC_HIGH,
+    VK_PPC_HIGHA,
     VK_PPC_HIGHER,
     VK_PPC_HIGHERA,
     VK_PPC_HIGHEST,
index c3b7d06..d16c9f2 100644 (file)
@@ -40,6 +40,9 @@ addis 1, 1, 1b-2f@ha
 addi 1, 1, target6@h
 addis 1, 1, target6@h
 
+addi  1, 1, target6@high
+addis 1, 1, target6@higha
+
 .set target6, 0x4321fedc
 
 addi 1, 1, target7@higher
@@ -70,7 +73,7 @@ addis 1, 1, target7@highesta
 # CHECK-NEXT:    ]
 # CHECK-NEXT:    Address: 0x0
 # CHECK-NEXT:    Offset:
-# CHECK-NEXT:    Size: 72
+# CHECK-NEXT:    Size: 80
 # CHECK-NEXT:    Link: 0
 # CHECK-NEXT:    Info: 0
 # CHECK-NEXT:    AddressAlignment: 4
@@ -82,10 +85,10 @@ addis 1, 1, target7@highesta
 # CHECK-LE-NEXT:   0010: 44442138 1111213C 01802138 0110213C
 # CHECK-BE-NEXT:   0020: 60218001 64211001 38210008 3C210000
 # CHECK-LE-NEXT:   0020: 01802160 01102164 08002138 0000213C
-# CHECK-BE-NEXT:   0030: 38214321 3C214321 3821FFFF 3C211234
-# CHECK-LE-NEXT:   0030: 21432138 2143213C FFFF2138 3412213C
-# CHECK-BE-NEXT:   0040: 38210000 3C211235
-# CHECK-LE-NEXT:   0040: 00002138 3512213C
+# CHECK-BE-NEXT:   0030: 38214321 3C214321 38214321 3C214322
+# CHECK-LE-NEXT:   0030: 21432138 2143213C 21432138 2243213C
+# CHECK-BE-NEXT:   0040: 3821FFFF 3C211234 38210000 3C211235
+# CHECK-LE-NEXT:   0040: FFFF2138 3412213C 00002138 3512213C
 # CHECK-NEXT:    )
 # CHECK-NEXT:  }
 
index 0b8375b..c3412b0 100644 (file)
 # CHECK-LE-REL:                             0x{{[0-9A-F]*[048C]}} R_PPC64_ADDR16_HA target 0x0
             addis 3, 3, target@ha
 
+# CHECK-BE: addis 3, 3, target@higha        # encoding: [0x3c,0x63,A,A]
+# CHECK-LE: addis 3, 3, target@higha        # encoding: [A,A,0x63,0x3c]
+# CHECK-BE-NEXT:                            #   fixup A - offset: 2, value: target@higha, kind: fixup_ppc_half16
+# CHECK-LE-NEXT:                            #   fixup A - offset: 0, value: target@higha, kind: fixup_ppc_half16
+# CHECK-BE-REL:                             0x{{[0-9A-F]*[26AE]}} R_PPC64_ADDR16_HIGHA target 0x0
+# CHECK-LE-REL:                             0x{{[0-9A-F]*[048C]}} R_PPC64_ADDR16_HIGHA target 0x0
+
+            addis 3, 3, target@higha
+
 # CHECK-BE: lis 3, target@ha                # encoding: [0x3c,0x60,A,A]
 # CHECK-LE: lis 3, target@ha                # encoding: [A,A,0x60,0x3c]
 # CHECK-BE-NEXT:                            #   fixup A - offset: 2, value: target@ha, kind: fixup_ppc_half16
@@ -217,6 +226,14 @@ base:
 # CHECK-LE-REL:                             0x{{[0-9A-F]*[048C]}} R_PPC64_ADDR16_HI target 0x0
             oris 3, 3, target@h
 
+# CHECK-BE:  oris 3, 3, target@high         # encoding: [0x64,0x63,A,A]
+# CHECK-LE:  oris 3, 3, target@high         # encoding: [A,A,0x63,0x64]
+# CHECK-BE-NEXT:                            #   fixup A - offset: 2, value: target@high, kind: fixup_ppc_half16
+# CHECK-LE-NEXT:                            #   fixup A - offset: 0, value: target@high, kind: fixup_ppc_half16
+# CHECK-BE-REL:                             0x{{[0-9A-F]*[26AE]}} R_PPC64_ADDR16_HIGH target 0x0
+# CHECK-LE-REL:                             0x{{[0-9A-F]*[048C]}} R_PPC64_ADDR16_HIGH target 0x0
+            oris 3, 3, target@high
+
 # CHECK-BE: ld 1, target@toc(2)             # encoding: [0xe8,0x22,A,0bAAAAAA00]
 # CHECK-LE: ld 1, target@toc(2)             # encoding: [0bAAAAAA00,A,0x22,0xe8]
 # CHECK-BE-NEXT:                            #   fixup A - offset: 2, value: target@toc, kind: fixup_ppc_half16ds