Loongson MMI: Merge with MIPS64/add auto-detection
Modern Loongson processors are MIPS64-compatible, and MMI instructions
are now supported in the mainline of GCC. Thus, this commit adds
compile-time and run-time auto-detection of MMI instructions and moves
the MMI SIMD extensions for libjpeg-turbo from simd/loongson/ to
simd/mips64/. That will allow MMI and MSA instructions to co-exist
in the same build once #377 has been integrated.
Based on:
82953ddd61
Closes #383
This commit is contained in:
@@ -314,15 +314,35 @@ if(CMAKE_POSITION_INDEPENDENT_CODE OR ENABLE_SHARED)
|
||||
endif()
|
||||
|
||||
###############################################################################
|
||||
# Loongson (Intrinsics)
|
||||
# MIPS64 (Intrinsics)
|
||||
###############################################################################
|
||||
|
||||
elseif(CPU_TYPE STREQUAL "loongson")
|
||||
elseif(CPU_TYPE STREQUAL "loongson" OR CPU_TYPE MATCHES "mips64*")
|
||||
|
||||
set(SIMD_SOURCES loongson/jccolor-mmi.c loongson/jcgray-mmi.c
|
||||
loongson/jcsample-mmi.c loongson/jdcolor-mmi.c loongson/jdsample-mmi.c
|
||||
loongson/jdmerge-mmi.c loongson/jfdctfst-mmi.c loongson/jfdctint-mmi.c
|
||||
loongson/jidctfst-mmi.c loongson/jidctint-mmi.c loongson/jquanti-mmi.c)
|
||||
set(CMAKE_REQUIRED_FLAGS -Wa,-mloongson-mmi,-mloongson-ext)
|
||||
|
||||
check_c_source_compiles("
|
||||
int main(void) {
|
||||
int c = 0, a = 0, b = 0;
|
||||
asm (
|
||||
\"paddb %0, %1, %2\"
|
||||
: \"=f\" (c)
|
||||
: \"f\" (a), \"f\" (b)
|
||||
);
|
||||
return c;
|
||||
}" HAVE_MMI)
|
||||
|
||||
unset(CMAKE_REQUIRED_FLAGS)
|
||||
|
||||
if(NOT HAVE_MMI)
|
||||
simd_fail("SIMD extensions not available for this CPU")
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(SIMD_SOURCES mips64/jccolor-mmi.c mips64/jcgray-mmi.c mips64/jcsample-mmi.c
|
||||
mips64/jdcolor-mmi.c mips64/jdmerge-mmi.c mips64/jdsample-mmi.c
|
||||
mips64/jfdctfst-mmi.c mips64/jfdctint-mmi.c mips64/jidctfst-mmi.c
|
||||
mips64/jidctint-mmi.c mips64/jquanti-mmi.c)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
foreach(file ${SIMD_SOURCES})
|
||||
@@ -330,8 +350,12 @@ if(CMAKE_COMPILER_IS_GNUCC)
|
||||
" -fno-strict-aliasing")
|
||||
endforeach()
|
||||
endif()
|
||||
foreach(file ${SIMD_SOURCES})
|
||||
set_property(SOURCE ${file} APPEND_STRING PROPERTY COMPILE_FLAGS
|
||||
" -Wa,-mloongson-mmi,-mloongson-ext")
|
||||
endforeach()
|
||||
|
||||
add_library(simd OBJECT ${SIMD_SOURCES} loongson/jsimd.c)
|
||||
add_library(simd OBJECT ${SIMD_SOURCES} mips64/jsimd.c)
|
||||
|
||||
if(CMAKE_POSITION_INDEPENDENT_CODE OR ENABLE_SHARED)
|
||||
set_target_properties(simd PROPERTIES POSITION_INDEPENDENT_CODE 1)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* jsimd_loongson.c
|
||||
* jsimd_mips64.c
|
||||
*
|
||||
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
* Copyright (C) 2009-2011, 2014, 2016, 2018, D. R. Commander.
|
||||
@@ -13,7 +13,7 @@
|
||||
*
|
||||
* This file contains the interface between the "normal" portions
|
||||
* of the library and the SIMD implementations when running on a
|
||||
* Loongson architecture.
|
||||
* 64-bit MIPS architecture.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
@@ -24,8 +24,76 @@
|
||||
#include "../../jsimddct.h"
|
||||
#include "../jsimd.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
static unsigned int simd_support = ~0;
|
||||
|
||||
#if defined(__linux__)
|
||||
|
||||
#define SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT (1024 * 1024)
|
||||
|
||||
LOCAL(int)
|
||||
check_feature(char *buffer, char *feature)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if (*feature == 0)
|
||||
return 0;
|
||||
if (strncmp(buffer, "ASEs implemented", 16) != 0)
|
||||
return 0;
|
||||
buffer += 16;
|
||||
while (isspace(*buffer))
|
||||
buffer++;
|
||||
|
||||
/* Check if 'feature' is present in the buffer as a separate word */
|
||||
while ((p = strstr(buffer, feature))) {
|
||||
if (p > buffer && !isspace(*(p - 1))) {
|
||||
buffer++;
|
||||
continue;
|
||||
}
|
||||
p += strlen(feature);
|
||||
if (*p != 0 && !isspace(*p)) {
|
||||
buffer++;
|
||||
continue;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
LOCAL(int)
|
||||
parse_proc_cpuinfo(int bufsize)
|
||||
{
|
||||
char *buffer = (char *)malloc(bufsize);
|
||||
FILE *fd;
|
||||
|
||||
simd_support = 0;
|
||||
|
||||
if (!buffer)
|
||||
return 0;
|
||||
|
||||
fd = fopen("/proc/cpuinfo", "r");
|
||||
if (fd) {
|
||||
while (fgets(buffer, bufsize, fd)) {
|
||||
if (!strchr(buffer, '\n') && !feof(fd)) {
|
||||
/* "impossible" happened - insufficient size of the buffer! */
|
||||
fclose(fd);
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
if (check_feature(buffer, "loongson-mmi"))
|
||||
simd_support |= JSIMD_MMI;
|
||||
}
|
||||
fclose(fd);
|
||||
}
|
||||
free(buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check what SIMD accelerations are supported.
|
||||
*
|
||||
@@ -37,14 +105,32 @@ init_simd(void)
|
||||
#ifndef NO_GETENV
|
||||
char *env = NULL;
|
||||
#endif
|
||||
#if defined(__linux__)
|
||||
int bufsize = 1024; /* an initial guess for the line buffer size limit */
|
||||
#endif
|
||||
|
||||
if (simd_support != ~0U)
|
||||
return;
|
||||
|
||||
simd_support = 0;
|
||||
|
||||
#if defined(__linux__)
|
||||
while (!parse_proc_cpuinfo(bufsize)) {
|
||||
bufsize *= 2;
|
||||
if (bufsize > SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT)
|
||||
break;
|
||||
}
|
||||
#elif defined(__mips_loongson_vector_rev)
|
||||
/* Only enable MMI by default on non-Linux platforms when the compiler flags
|
||||
* support it. */
|
||||
simd_support |= JSIMD_MMI;
|
||||
#endif
|
||||
|
||||
#ifndef NO_GETENV
|
||||
/* Force different settings through environment variables */
|
||||
env = getenv("JSIMD_FORCEMMI");
|
||||
if ((env != NULL) && (strcmp(env, "1") == 0))
|
||||
simd_support = JSIMD_MMI;
|
||||
env = getenv("JSIMD_FORCENONE");
|
||||
if ((env != NULL) && (strcmp(env, "1") == 0))
|
||||
simd_support = 0;
|
||||
Reference in New Issue
Block a user