Merge branch 'master' into 'master'
Add support for loongarch64. See merge request glvnd/libglvnd!271
This commit is contained in:
commit
9215f347d2
13
configure.ac
13
configure.ac
|
@ -165,6 +165,10 @@ if test "x$enable_asm" = xyes; then
|
|||
#endif
|
||||
])],
|
||||
[asm_arch=ppc64],[])
|
||||
;;
|
||||
loongarch64)
|
||||
asm_arch=loongarch64
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$asm_arch" in
|
||||
|
@ -188,6 +192,10 @@ if test "x$enable_asm" = xyes; then
|
|||
DEFINES="$DEFINES -DUSE_PPC64_ASM"
|
||||
AC_MSG_RESULT([yes, ppc64])
|
||||
;;
|
||||
loongarch64)
|
||||
DEFINES="$DEFINES -DUSE_LOONGARCH64_ASM"
|
||||
AC_MSG_RESULT([yes, loongarch64])
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT([no, platform '$host_cpu' not supported])
|
||||
;;
|
||||
|
@ -264,6 +272,10 @@ xaarch64)
|
|||
# For aarch64, only the TSD stubs have been implemented yet.
|
||||
gldispatch_entry_type=aarch64_tsd
|
||||
;;
|
||||
xloongarch64)
|
||||
# For loongarch64, only the TSD stubs have been implemented yet.
|
||||
gldispatch_entry_type=loongarch64_tsd
|
||||
;;
|
||||
*)
|
||||
# The C stubs will work with either TLS or TSD.
|
||||
gldispatch_entry_type=pure_c
|
||||
|
@ -313,6 +325,7 @@ AM_CONDITIONAL([GLDISPATCH_TYPE_PPC64_TLS], [test "x$gldispatch_entry_type" = "x
|
|||
AM_CONDITIONAL([GLDISPATCH_TYPE_PPC64_TSD], [test "x$gldispatch_entry_type" = "xppc64_tsd"])
|
||||
AM_CONDITIONAL([GLDISPATCH_TYPE_ARMV7_TSD], [test "x$gldispatch_entry_type" = "xarmv7_tsd"])
|
||||
AM_CONDITIONAL([GLDISPATCH_TYPE_AARCH64_TSD], [test "x$gldispatch_entry_type" = "xaarch64_tsd"])
|
||||
AM_CONDITIONAL([GLDISPATCH_TYPE_LOONGARCH64_TSD], [test "x$gldispatch_entry_type" = "xloongarch64_tsd"])
|
||||
AM_CONDITIONAL([GLDISPATCH_TYPE_PURE_C], [test "x$gldispatch_entry_type" = "xpure_c"])
|
||||
|
||||
AS_IF([test "x$gldispatch_entry_type" != "xpure_c"],
|
||||
|
|
|
@ -99,6 +99,11 @@ enum {
|
|||
* Used for stubs on PPC64LE systems. Same as PPC64, for compatibility.
|
||||
*/
|
||||
__GLDISPATCH_STUB_PPC64LE = __GLDISPATCH_STUB_PPC64,
|
||||
|
||||
/*!
|
||||
* Used for stubs on LOONGARCH/loongarch64.
|
||||
*/
|
||||
__GLDISPATCH_STUB_LOONGARCH64,
|
||||
};
|
||||
|
||||
/*!
|
||||
|
|
|
@ -108,6 +108,16 @@ extern char glx_entrypoint_end[];
|
|||
"mtctr 12\n" \
|
||||
"bctr\n"
|
||||
|
||||
#elif defined(USE_LOONGARCH64_ASM)
|
||||
|
||||
#define STUB_SIZE 32
|
||||
#define STUB_ASM_ARCH(slot) \
|
||||
"la.global $t0,entrypointFunctions\n" \
|
||||
"li.d $t1," slot "*8\r\n" \
|
||||
"add.d $t0, $t0,$t1\r\n" \
|
||||
"ld.d $t0, $t0,0\n" \
|
||||
"jirl $r0, $t0,0\n"
|
||||
|
||||
#else
|
||||
#error "Can't happen -- not implemented"
|
||||
#endif
|
||||
|
|
|
@ -124,6 +124,11 @@ static void InvalidateCache(void)
|
|||
}
|
||||
__asm__ __volatile__("isync");
|
||||
}
|
||||
#elif defined(USE_LOONGARCH64_ASM)
|
||||
static void InvalidateCache(void)
|
||||
{
|
||||
__builtin___clear_cache(public_entry_start, public_entry_end);
|
||||
}
|
||||
#else
|
||||
static void InvalidateCache(void)
|
||||
{
|
||||
|
|
|
@ -50,6 +50,12 @@ MAPI_GLDISPATCH_ENTRY_FILES += entry_simple_asm.c
|
|||
MAPI_GLDISPATCH_ENTRY_FILES += entry_common.c
|
||||
endif
|
||||
|
||||
if GLDISPATCH_TYPE_LOONGARCH64_TSD
|
||||
MAPI_GLDISPATCH_ENTRY_FILES = entry_loongarch64_tsd.c
|
||||
MAPI_GLDISPATCH_ENTRY_FILES += entry_simple_asm.c
|
||||
MAPI_GLDISPATCH_ENTRY_FILES += entry_common.c
|
||||
endif
|
||||
|
||||
if GLDISPATCH_TYPE_PURE_C
|
||||
MAPI_GLDISPATCH_ENTRY_FILES = entry_pure_c.c
|
||||
endif
|
||||
|
|
121
src/GLdispatch/vnd-glapi/entry_loongarch64_tsd.c
Normal file
121
src/GLdispatch/vnd-glapi/entry_loongarch64_tsd.c
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright (c) 2016, NVIDIA CORPORATION.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and/or associated documentation files (the
|
||||
* "Materials"), to deal in the Materials without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
* permit persons to whom the Materials are furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* unaltered in all copies or substantial portions of the Materials.
|
||||
* Any additions, deletions, or changes to the original source files
|
||||
* must be clearly indicated in accompanying documentation.
|
||||
*
|
||||
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
#include "entry.h"
|
||||
#include "entry_common.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "glapi.h"
|
||||
#include "u_macros.h"
|
||||
#include "u_current.h"
|
||||
#include "utils_misc.h"
|
||||
#include "glvnd/GLdispatchABI.h"
|
||||
|
||||
/*
|
||||
* The size of each dispatch stub.
|
||||
*/
|
||||
#define ENTRY_STUB_ALIGN 256
|
||||
#if !defined(GLDISPATCH_PAGE_SIZE)
|
||||
// Note that on loongarch64, the page size is 16K.
|
||||
#define GLDISPATCH_PAGE_SIZE 16384
|
||||
#endif
|
||||
|
||||
#define STUB_ASM_ENTRY(func) \
|
||||
".balign " U_STRINGIFY(ENTRY_STUB_ALIGN) "\n\t" \
|
||||
".global " func "\n\t" \
|
||||
".type " func ", %function\n\t" \
|
||||
func ":\n\t"
|
||||
|
||||
/*
|
||||
* Looks up the current dispatch table, finds the stub address at the given slot
|
||||
* then jumps to it.
|
||||
*
|
||||
* First tries to find a dispatch table in _glapi_Current[GLAPI_CURRENT_DISPATCH],
|
||||
* if not found then it jumps to the 'lookup_dispatch' and calls
|
||||
* _glapi_get_current() then jumps back to the 'found_dispatch' label.
|
||||
*
|
||||
* The 'found_dispatch' section computes the correct offset in the dispatch
|
||||
* table then does a branch without link to the function address.
|
||||
*/
|
||||
#define STUB_ASM_CODE(slot) \
|
||||
"addi.d $sp, $sp, -16\n\t" \
|
||||
"st.d $a1, $sp, 0\n\t" \
|
||||
"st.d $a0, $sp, 8\n\t" \
|
||||
"la.global $a0,_glapi_Current\n\t" \
|
||||
"ld.d $a0, $a0,0\n\t" \
|
||||
"beqz $a0, 10f\n\t" \
|
||||
"11:\n\t" /* found dispatch */ \
|
||||
"la.local $a1, 3f\n\t" \
|
||||
"ld.d $a1, $a1,0\n\t" \
|
||||
"ldx.d $t1, $a0, $a1\n\t" \
|
||||
"ld.d $a1, $sp, 0\n\t" \
|
||||
"ld.d $a0, $sp, 8\n\t" \
|
||||
"addi.d $sp, $sp, 16\n\t" \
|
||||
"jirl $r0,$t1,0\n\t" \
|
||||
"10:\n\t" /* lookup dispatch */ \
|
||||
"addi.d $sp, $sp, -8*8\n\t" \
|
||||
"st.d $ra, $sp, 0\n\t" \
|
||||
"st.d $a7, $sp, 8\n\t" \
|
||||
"st.d $a6, $sp, 16\n\t" \
|
||||
"st.d $a5, $sp, 24\n\t" \
|
||||
"st.d $a4, $sp, 32\n\t" \
|
||||
"st.d $a3, $sp, 40\n\t" \
|
||||
"st.d $a2, $sp, 48\n\t" \
|
||||
"la.global $a0,_glapi_get_current\n\t" \
|
||||
"jirl $ra, $a0,0\n\t" \
|
||||
"ld.d $ra, $sp, 0\n\t" \
|
||||
"ld.d $a7, $sp, 8\n\t" \
|
||||
"ld.d $a6, $sp, 16\n\t" \
|
||||
"ld.d $a5, $sp, 24\n\t" \
|
||||
"ld.d $a4, $sp, 32\n\t" \
|
||||
"ld.d $a3, $sp, 40\n\t" \
|
||||
"ld.d $a2, $sp, 48\n\t" \
|
||||
"addi.d $sp, $sp, 8*8\n\t" \
|
||||
"b 11b\n\t" \
|
||||
"3:\n\t" \
|
||||
".dword " slot " * 8\n\t" /* size of (void *) */
|
||||
|
||||
__asm__(".section wtext,\"ax\"\n"
|
||||
".balign " U_STRINGIFY(GLDISPATCH_PAGE_SIZE) "\n"
|
||||
".globl public_entry_start\n"
|
||||
".hidden public_entry_start\n"
|
||||
"public_entry_start:\n");
|
||||
|
||||
#define MAPI_TMP_STUB_ASM_GCC
|
||||
#include "mapi_tmp.h"
|
||||
|
||||
__asm__(".balign " U_STRINGIFY(GLDISPATCH_PAGE_SIZE) "\n"
|
||||
".globl public_entry_end\n"
|
||||
".hidden public_entry_end\n"
|
||||
"public_entry_end:\n"
|
||||
".text\n\t");
|
||||
|
||||
const int entry_type = __GLDISPATCH_STUB_LOONGARCH64;
|
||||
const int entry_stub_size = ENTRY_STUB_ALIGN;
|
||||
|
|
@ -54,6 +54,8 @@ else
|
|||
_entry_files += 'entry_ppc64_tls.c'
|
||||
elif gl_dispatch_type == 'ppc64_tsd'
|
||||
_entry_files += 'entry_ppc64_tsd.c'
|
||||
elif gl_dispatch_type == 'loongarch64_tsd'
|
||||
_entry_files += 'entry_loongarch64_tsd.c'
|
||||
else
|
||||
error('No matching ASM file for @0@'.format(gl_dispatch_type))
|
||||
endif
|
||||
|
|
|
@ -238,6 +238,36 @@ static void patch_ppc64(char *writeEntry, const char *execEntry,
|
|||
#endif
|
||||
}
|
||||
|
||||
static void patch_loongarch64(char *writeEntry, const char *execEntry,
|
||||
int stubSize, void *incrementPtr)
|
||||
{
|
||||
#if defined(__loongarch64)
|
||||
const uint32_t tmpl[] = {
|
||||
0x1c000004, // pcaddu12i $r4,0
|
||||
0x02c07084, // addi.d $r4,$r4,28(0x1c)
|
||||
0x28c00084, // ld.d $r4,$r4,0
|
||||
0x28c00085, // ld.d $r5,$r4,0
|
||||
0x02c004a5, // addi.d $r5,$r5,1(0x1)
|
||||
0x29c00085, // st.d $r5,$r4,0
|
||||
0x4c000020, // jirl $r0,$r1,0
|
||||
// 1:
|
||||
0x00000000,0x00000000,
|
||||
};
|
||||
|
||||
static const int offsetAddr = sizeof(tmpl) - 8;
|
||||
|
||||
if (stubSize < sizeof(tmpl)) {
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(writeEntry, tmpl, sizeof(tmpl));
|
||||
*((uint64_t *)(writeEntry + offsetAddr)) = (uint64_t) incrementPtr;
|
||||
|
||||
__builtin___clear_cache((char *) execEntry, (char *) (execEntry + sizeof(tmpl)));
|
||||
#else
|
||||
assert(0); // Should not be calling this
|
||||
#endif
|
||||
}
|
||||
|
||||
GLboolean dummyCheckPatchSupported(int type, int stubSize)
|
||||
{
|
||||
|
@ -249,6 +279,7 @@ GLboolean dummyCheckPatchSupported(int type, int stubSize)
|
|||
case __GLDISPATCH_STUB_AARCH64:
|
||||
case __GLDISPATCH_STUB_X32:
|
||||
case __GLDISPATCH_STUB_PPC64:
|
||||
case __GLDISPATCH_STUB_LOONGARCH64:
|
||||
return GL_TRUE;
|
||||
default:
|
||||
return GL_FALSE;
|
||||
|
@ -287,6 +318,9 @@ GLboolean dummyPatchFunction(int type, int stubSize,
|
|||
case __GLDISPATCH_STUB_PPC64:
|
||||
patch_ppc64(writeAddr, execAddr, stubSize, incrementPtr);
|
||||
break;
|
||||
case __GLDISPATCH_STUB_LOONGARCH64:
|
||||
patch_loongarch64(writeAddr, execAddr, stubSize, incrementPtr);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue