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
getEdgeKindName(Edge::Kind K)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