106c3fb27SDimitry Andric //===----- ppc64.cpp - Generic JITLink ppc64 edge kinds, utilities ------===// 206c3fb27SDimitry Andric // 306c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 406c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 506c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 606c3fb27SDimitry Andric // 706c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 806c3fb27SDimitry Andric // 906c3fb27SDimitry Andric // Generic utilities for graphs representing 64-bit PowerPC objects. 1006c3fb27SDimitry Andric // 1106c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 1206c3fb27SDimitry Andric 1306c3fb27SDimitry Andric #include "llvm/ExecutionEngine/JITLink/ppc64.h" 1406c3fb27SDimitry Andric 1506c3fb27SDimitry Andric #define DEBUG_TYPE "jitlink" 1606c3fb27SDimitry Andric 1706c3fb27SDimitry Andric namespace llvm::jitlink::ppc64 { 1806c3fb27SDimitry Andric 1906c3fb27SDimitry Andric const char NullPointerContent[8] = {0x00, 0x00, 0x00, 0x00, 2006c3fb27SDimitry Andric 0x00, 0x00, 0x00, 0x00}; 2106c3fb27SDimitry Andric 2206c3fb27SDimitry Andric const char PointerJumpStubContent_little[20] = { 2306c3fb27SDimitry Andric 0x18, 0x00, 0x41, (char)0xf8, // std r2, 24(r1) 2406c3fb27SDimitry Andric 0x00, 0x00, (char)0x82, 0x3d, // addis r12, r2, OffHa 2506c3fb27SDimitry Andric 0x00, 0x00, (char)0x8c, (char)0xe9, // ld r12, OffLo(r12) 2606c3fb27SDimitry Andric (char)0xa6, 0x03, (char)0x89, 0x7d, // mtctr r12 2706c3fb27SDimitry Andric 0x20, 0x04, (char)0x80, 0x4e, // bctr 2806c3fb27SDimitry Andric }; 2906c3fb27SDimitry Andric 3006c3fb27SDimitry Andric const char PointerJumpStubContent_big[20] = { 3106c3fb27SDimitry Andric (char)0xf8, 0x41, 0x00, 0x18, // std r2, 24(r1) 3206c3fb27SDimitry Andric 0x3d, (char)0x82, 0x00, 0x00, // addis r12, r2, OffHa 3306c3fb27SDimitry Andric (char)0xe9, (char)0x8c, 0x00, 0x00, // ld r12, OffLo(r12) 3406c3fb27SDimitry Andric 0x7d, (char)0x89, 0x03, (char)0xa6, // mtctr r12 3506c3fb27SDimitry Andric 0x4e, (char)0x80, 0x04, 0x20, // bctr 3606c3fb27SDimitry Andric }; 3706c3fb27SDimitry Andric 3806c3fb27SDimitry Andric // TODO: We can use prefixed instructions if LLJIT is running on power10. 3906c3fb27SDimitry Andric const char PointerJumpStubNoTOCContent_little[32] = { 4006c3fb27SDimitry Andric (char)0xa6, 0x02, (char)0x88, 0x7d, // mflr 12 4106c3fb27SDimitry Andric 0x05, (char)0x00, (char)0x9f, 0x42, // bcl 20,31,.+4 4206c3fb27SDimitry Andric (char)0xa6, 0x02, 0x68, 0x7d, // mflr 11 4306c3fb27SDimitry Andric (char)0xa6, 0x03, (char)0x88, 0x7d, // mtlr 12 4406c3fb27SDimitry Andric 0x00, 0x00, (char)0x8b, 0x3d, // addis 12,11,OffHa 4506c3fb27SDimitry Andric 0x00, 0x00, (char)0x8c, (char)0xe9, // ld 12, OffLo(12) 4606c3fb27SDimitry Andric (char)0xa6, 0x03, (char)0x89, 0x7d, // mtctr 12 4706c3fb27SDimitry Andric 0x20, 0x04, (char)0x80, 0x4e, // bctr 4806c3fb27SDimitry Andric }; 4906c3fb27SDimitry Andric 5006c3fb27SDimitry Andric const char PointerJumpStubNoTOCContent_big[32] = { 5106c3fb27SDimitry Andric 0x7d, (char)0x88, 0x02, (char)0xa6, // mflr 12 5206c3fb27SDimitry Andric 0x42, (char)0x9f, 0x00, 0x05, // bcl 20,31,.+4 5306c3fb27SDimitry Andric 0x7d, 0x68, 0x02, (char)0xa6, // mflr 11 5406c3fb27SDimitry Andric 0x7d, (char)0x88, 0x03, (char)0xa6, // mtlr 12 5506c3fb27SDimitry Andric 0x3d, (char)0x8b, 0x00, 0x00, // addis 12,11,OffHa 5606c3fb27SDimitry Andric (char)0xe9, (char)0x8c, 0x00, 0x00, // ld 12, OffLo(12) 5706c3fb27SDimitry Andric 0x7d, (char)0x89, 0x03, (char)0xa6, // mtctr 12 5806c3fb27SDimitry Andric 0x4e, (char)0x80, 0x04, 0x20, // bctr 5906c3fb27SDimitry Andric }; 6006c3fb27SDimitry Andric 6106c3fb27SDimitry Andric const char *getEdgeKindName(Edge::Kind K) { 6206c3fb27SDimitry Andric switch (K) { 6306c3fb27SDimitry Andric case Pointer64: 6406c3fb27SDimitry Andric return "Pointer64"; 6506c3fb27SDimitry Andric case Pointer32: 6606c3fb27SDimitry Andric return "Pointer32"; 67*5f757f3fSDimitry Andric case Pointer16: 68*5f757f3fSDimitry Andric return "Pointer16"; 69*5f757f3fSDimitry Andric case Pointer16DS: 70*5f757f3fSDimitry Andric return "Pointer16DS"; 71*5f757f3fSDimitry Andric case Pointer16HA: 72*5f757f3fSDimitry Andric return "Pointer16HA"; 73*5f757f3fSDimitry Andric case Pointer16HI: 74*5f757f3fSDimitry Andric return "Pointer16HI"; 75*5f757f3fSDimitry Andric case Pointer16HIGH: 76*5f757f3fSDimitry Andric return "Pointer16HIGH"; 77*5f757f3fSDimitry Andric case Pointer16HIGHA: 78*5f757f3fSDimitry Andric return "Pointer16HIGHA"; 79*5f757f3fSDimitry Andric case Pointer16HIGHER: 80*5f757f3fSDimitry Andric return "Pointer16HIGHER"; 81*5f757f3fSDimitry Andric case Pointer16HIGHERA: 82*5f757f3fSDimitry Andric return "Pointer16HIGHERA"; 83*5f757f3fSDimitry Andric case Pointer16HIGHEST: 84*5f757f3fSDimitry Andric return "Pointer16HIGHEST"; 85*5f757f3fSDimitry Andric case Pointer16HIGHESTA: 86*5f757f3fSDimitry Andric return "Pointer16HIGHESTA"; 87*5f757f3fSDimitry Andric case Pointer16LO: 88*5f757f3fSDimitry Andric return "Pointer16LO"; 89*5f757f3fSDimitry Andric case Pointer16LODS: 90*5f757f3fSDimitry Andric return "Pointer16LODS"; 91*5f757f3fSDimitry Andric case Pointer14: 92*5f757f3fSDimitry Andric return "Pointer14"; 9306c3fb27SDimitry Andric case Delta64: 9406c3fb27SDimitry Andric return "Delta64"; 95*5f757f3fSDimitry Andric case Delta34: 96*5f757f3fSDimitry Andric return "Delta34"; 9706c3fb27SDimitry Andric case Delta32: 9806c3fb27SDimitry Andric return "Delta32"; 9906c3fb27SDimitry Andric case NegDelta32: 10006c3fb27SDimitry Andric return "NegDelta32"; 10106c3fb27SDimitry Andric case Delta16: 10206c3fb27SDimitry Andric return "Delta16"; 10306c3fb27SDimitry Andric case Delta16HA: 10406c3fb27SDimitry Andric return "Delta16HA"; 105*5f757f3fSDimitry Andric case Delta16HI: 106*5f757f3fSDimitry Andric return "Delta16HI"; 10706c3fb27SDimitry Andric case Delta16LO: 10806c3fb27SDimitry Andric return "Delta16LO"; 109*5f757f3fSDimitry Andric case TOC: 110*5f757f3fSDimitry Andric return "TOC"; 111*5f757f3fSDimitry Andric case TOCDelta16: 112*5f757f3fSDimitry Andric return "TOCDelta16"; 11306c3fb27SDimitry Andric case TOCDelta16DS: 11406c3fb27SDimitry Andric return "TOCDelta16DS"; 115*5f757f3fSDimitry Andric case TOCDelta16HA: 116*5f757f3fSDimitry Andric return "TOCDelta16HA"; 117*5f757f3fSDimitry Andric case TOCDelta16HI: 118*5f757f3fSDimitry Andric return "TOCDelta16HI"; 119*5f757f3fSDimitry Andric case TOCDelta16LO: 120*5f757f3fSDimitry Andric return "TOCDelta16LO"; 12106c3fb27SDimitry Andric case TOCDelta16LODS: 12206c3fb27SDimitry Andric return "TOCDelta16LODS"; 123*5f757f3fSDimitry Andric case RequestGOTAndTransformToDelta34: 124*5f757f3fSDimitry Andric return "RequestGOTAndTransformToDelta34"; 12506c3fb27SDimitry Andric case CallBranchDelta: 12606c3fb27SDimitry Andric return "CallBranchDelta"; 12706c3fb27SDimitry Andric case CallBranchDeltaRestoreTOC: 12806c3fb27SDimitry Andric return "CallBranchDeltaRestoreTOC"; 129*5f757f3fSDimitry Andric case RequestCall: 130*5f757f3fSDimitry Andric return "RequestCall"; 131*5f757f3fSDimitry Andric case RequestCallNoTOC: 132*5f757f3fSDimitry Andric return "RequestCallNoTOC"; 133*5f757f3fSDimitry Andric case RequestTLSDescInGOTAndTransformToTOCDelta16HA: 134*5f757f3fSDimitry Andric return "RequestTLSDescInGOTAndTransformToTOCDelta16HA"; 135*5f757f3fSDimitry Andric case RequestTLSDescInGOTAndTransformToTOCDelta16LO: 136*5f757f3fSDimitry Andric return "RequestTLSDescInGOTAndTransformToTOCDelta16LO"; 137*5f757f3fSDimitry Andric case RequestTLSDescInGOTAndTransformToDelta34: 138*5f757f3fSDimitry Andric return "RequestTLSDescInGOTAndTransformToDelta34"; 13906c3fb27SDimitry Andric default: 14006c3fb27SDimitry Andric return getGenericEdgeKindName(static_cast<Edge::Kind>(K)); 14106c3fb27SDimitry Andric } 14206c3fb27SDimitry Andric } 14306c3fb27SDimitry Andric 14406c3fb27SDimitry Andric } // end namespace llvm::jitlink::ppc64 145