Path: blob/21.2-virgl/src/mapi/entry_ppc64le_tsd.h
4558 views
/*1* Mesa 3-D graphics library2*3* Copyright (C) 2017 Red Hat4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the "Software"),7* to deal in the Software without restriction, including without limitation8* the rights to use, copy, modify, merge, publish, distribute, sublicense,9* and/or sell copies of the Software, and to permit persons to whom the10* Software is furnished to do so, subject to the following conditions:11*12* The above copyright notice and this permission notice shall be included13* in all copies or substantial portions of the Software.14*15* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL18* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER19* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING20* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER21* DEALINGS IN THE SOFTWARE.22*23* Authors:24* Ben Crocker <[email protected]>25*/2627#ifdef HAVE_FUNC_ATTRIBUTE_VISIBILITY28#define HIDDEN __attribute__((visibility("hidden")))29#else30#define HIDDEN31#endif3233// NOTE: These must be powers of two:34#define PPC64LE_ENTRY_SIZE 25635#define PPC64LE_PAGE_ALIGN 6553636#if ((PPC64LE_ENTRY_SIZE & (PPC64LE_ENTRY_SIZE - 1)) != 0)37#error PPC64LE_ENTRY_SIZE must be a power of two!38#endif39#if ((PPC64LE_PAGE_ALIGN & (PPC64LE_PAGE_ALIGN - 1)) != 0)40#error PPC64LE_PAGE_ALIGN must be a power of two!41#endif4243__asm__(".text\n"44".balign " U_STRINGIFY(PPC64LE_ENTRY_SIZE) "\n"45"ppc64le_entry_start:");4647#define STUB_ASM_ENTRY(func) \48".globl " func "\n" \49".type " func ", @function\n" \50".balign " U_STRINGIFY(PPC64LE_ENTRY_SIZE) "\n" \51func ":\n\t" \52" addis 2, 12, .TOC.-" func "@ha\n\t" \53" addi 2, 2, .TOC.-" func "@l\n\t" \54" .localentry " func ", .-" func "\n\t"5556#define STUB_ASM_CODE(slot) \57" addis 11, 2, " ENTRY_CURRENT_TABLE "@got@ha\n\t" \58" ld 11, " ENTRY_CURRENT_TABLE "@got@l(11)\n\t" \59" ld 11, 0(11)\n\t" \60" cmpldi 11, 0\n\t" \61" beq 2000f\n" \62"1050:\n\t" \63" ld 12, " slot "*8(11)\n\t" \64" mtctr 12\n\t" \65" bctr\n" \66"2000:\n\t" \67" mflr 0\n\t" \68" std 0, 16(1)\n\t" \69" std 2, 40(1)\n\t" \70" stdu 1, -144(1)\n\t" \71" std 3, 56(1)\n\t" \72" std 4, 64(1)\n\t" \73" std 5, 72(1)\n\t" \74" std 6, 80(1)\n\t" \75" std 7, 88(1)\n\t" \76" std 8, 96(1)\n\t" \77" std 9, 104(1)\n\t" \78" std 10, 112(1)\n\t" \79" std 12, 128(1)\n\t" \80" addis 12, 2, " ENTRY_CURRENT_TABLE_GET "@got@ha\n\t" \81" ld 12, " ENTRY_CURRENT_TABLE_GET "@got@l(12)\n\t" \82" mtctr 12\n\t" \83" bctrl\n\t" \84" ld 2, 144+40(1)\n\t" \85" mr 11, 3\n\t" \86" ld 3, 56(1)\n\t" \87" ld 4, 64(1)\n\t" \88" ld 5, 72(1)\n\t" \89" ld 6, 80(1)\n\t" \90" ld 7, 88(1)\n\t" \91" ld 8, 96(1)\n\t" \92" ld 9, 104(1)\n\t" \93" ld 10, 112(1)\n\t" \94" ld 12, 128(1)\n\t" \95" addi 1, 1, 144\n\t" \96" ld 0, 16(1)\n\t" \97" mtlr 0\n\t" \98" b 1050b\n"99100#define MAPI_TMP_STUB_ASM_GCC101#include "mapi_tmp.h"102103#ifndef MAPI_MODE_BRIDGE104105#include <string.h>106#include "u_execmem.h"107108void109entry_patch_public(void)110{111}112113extern char114ppc64le_entry_start[] HIDDEN;115116mapi_func117entry_get_public(int slot)118{119return (mapi_func) (ppc64le_entry_start + slot * PPC64LE_ENTRY_SIZE);120}121122static const uint32_t code_templ[] = {123// This should be functionally the same code as would be generated from124// the STUB_ASM_CODE macro, but defined as a buffer.125// This is used to generate new dispatch stubs. Mesa will copy this126// data to the dispatch stub, and then it will patch the slot number and127// any addresses that it needs to.128// NOTE!!! NOTE!!! NOTE!!!129// This representation is correct for both little- and big-endian systems.130// However, more work needs to be done for big-endian Linux because it131// adheres to an older, AIX-compatible ABI that uses function descriptors.132// 1000:1330x7C0802A6, // <ENTRY+000>: mflr 01340xF8010010, // <ENTRY+004>: std 0, 16(1)1350xE96C0098, // <ENTRY+008>: ld 11, 9000f-1000b+0(12)1360xE96B0000, // <ENTRY+012>: ld 11, 0(11)1370x282B0000, // <ENTRY+016>: cmpldi 11, 01380x41820014, // <ENTRY+020>: beq 2000f139// 1050:1400xE80C00A8, // <ENTRY+024>: ld 0, 9000f-1000b+16(12)1410x7D8B002A, // <ENTRY+028>: ldx 12, 11, 01420x7D8903A6, // <ENTRY+032>: mtctr 121430x4E800420, // <ENTRY+036>: bctr144// 2000:1450xF8410028, // <ENTRY+040>: std 2, 40(1)1460xF821FF71, // <ENTRY+044>: stdu 1, -144(1)1470xF8610038, // <ENTRY+048>: std 3, 56(1)1480xF8810040, // <ENTRY+052>: std 4, 64(1)1490xF8A10048, // <ENTRY+056>: std 5, 72(1)1500xF8C10050, // <ENTRY+060>: std 6, 80(1)1510xF8E10058, // <ENTRY+064>: std 7, 88(1)1520xF9010060, // <ENTRY+068>: std 8, 96(1)1530xF9210068, // <ENTRY+072>: std 9, 104(1)1540xF9410070, // <ENTRY+076>: std 10, 112(1)1550xF9810080, // <ENTRY+080>: std 12, 128(1)1560xE98C00A0, // <ENTRY+084>: ld 12, 9000f-1000b+8(12)1570x7D8903A6, // <ENTRY+088>: mtctr 121580x4E800421, // <ENTRY+092>: bctrl1590x7C6B1B78, // <ENTRY+096>: mr 11, 31600xE8610038, // <ENTRY+100>: ld 3, 56(1)1610xE8810040, // <ENTRY+104>: ld 4, 64(1)1620xE8A10048, // <ENTRY+108>: ld 5, 72(1)1630xE8C10050, // <ENTRY+112>: ld 6, 80(1)1640xE8E10058, // <ENTRY+116>: ld 7, 88(1)1650xE9010060, // <ENTRY+120>: ld 8, 96(1)1660xE9210068, // <ENTRY+124>: ld 9, 104(1)1670xE9410070, // <ENTRY+128>: ld 10, 112(1)1680xE9810080, // <ENTRY+132>: ld 12, 128(1)1690x38210090, // <ENTRY+136>: addi 1, 1, 1441700xE8010010, // <ENTRY+140>: ld 0, 16(1)1710x7C0803A6, // <ENTRY+144>: mtlr 01720x4BFFFF84, // <ENTRY+148>: b 1050b173// 9000:1740, 0, // <ENTRY+152>: .quad ENTRY_CURRENT_TABLE1750, 0, // <ENTRY+160>: .quad ENTRY_CURRENT_TABLE_GET1760, 0 // <ENTRY+168>: .quad <slot>*8177};178static const uint64_t TEMPLATE_OFFSET_CURRENT_TABLE = sizeof(code_templ) - 3*8;179static const uint64_t TEMPLATE_OFFSET_CURRENT_TABLE_GET = sizeof(code_templ) - 2*8;180static const uint64_t TEMPLATE_OFFSET_SLOT = sizeof(code_templ) - 1*8;181182void183entry_patch(mapi_func entry, int slot)184{185char *code = (char *) entry;186*((uint64_t *) (code + TEMPLATE_OFFSET_CURRENT_TABLE)) = (uint64_t) ENTRY_CURRENT_TABLE;187*((uint64_t *) (code + TEMPLATE_OFFSET_CURRENT_TABLE_GET)) = (uint64_t) ENTRY_CURRENT_TABLE_GET;188*((uint64_t *) (code + TEMPLATE_OFFSET_SLOT)) = slot * sizeof(mapi_func);189}190191mapi_func192entry_generate(int slot)193{194char *code;195mapi_func entry;196197code = u_execmem_alloc(sizeof(code_templ));198if (!code)199return NULL;200201memcpy(code, code_templ, sizeof(code_templ));202203entry = (mapi_func) code;204entry_patch(entry, slot);205206return entry;207}208209#endif /* MAPI_MODE_BRIDGE */210211212