Skip to content

Commit

Permalink
Loongson MMI: Merge with MIPS64/add auto-detection
Browse files Browse the repository at this point in the history
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:
FlyGoat/libjpeg-turbo@82953dd

Closes #383
  • Loading branch information
dcommander committed Dec 17, 2019
1 parent 52fef34 commit 81b8c0e
Show file tree
Hide file tree
Showing 20 changed files with 119 additions and 9 deletions.
38 changes: 31 additions & 7 deletions simd/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -314,24 +314,48 @@ 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})
set_property(SOURCE ${file} APPEND_STRING PROPERTY COMPILE_FLAGS
" -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)
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
90 changes: 88 additions & 2 deletions simd/loongson/jsimd.c → simd/mips64/jsimd.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* jsimd_loongson.c
* jsimd_mips64.c
*
* Copyright 2009 Pierre Ossman <[email protected]> for Cendio AB
* Copyright (C) 2009-2011, 2014, 2016, 2018, D. R. Commander.
Expand All @@ -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
Expand All @@ -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.
*
Expand All @@ -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;
Expand Down
File renamed without changes.
File renamed without changes.

0 comments on commit 81b8c0e

Please sign in to comment.