xref: /freebsd-src/contrib/llvm-project/llvm/lib/ExecutionEngine/JITLink/ppc64.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
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