Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions common/sse2simde.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Provide the SSE intrinsics API on non-x86 / non-ARM targets
// (e.g. RISC-V) via SIMDe (SIMD Everywhere, https://github.com/simd-everywhere/simde).
//
// This is the counterpart of sse2neon.h for ARM: code written against
// <xmmintrin.h>/<emmintrin.h> keeps working, and SIMDe maps it to the
// native vector extension where it can (RVV on RISC-V) or to portable C.
//
// Requires the SIMDe headers (Debian/Ubuntu: libsimde-dev, Fedora: simde-devel).
//
//===========================================================================//
#ifndef SSE2SIMDE_H
#define SSE2SIMDE_H

#ifndef SIMDE_ENABLE_NATIVE_ALIASES
#define SIMDE_ENABLE_NATIVE_ALIASES
#endif

#include <simde/x86/sse4.1.h>

#endif // SSE2SIMDE_H
12 changes: 7 additions & 5 deletions mathlib/sse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include "mathlib/vector.h"
#if defined(__arm__) || defined(__aarch64__)
#include "sse2neon.h"
#elif defined(__riscv)
#include "sse2simde.h"
#endif

#include "sse.h"
Expand Down Expand Up @@ -180,7 +182,7 @@ float _SSE_RSqrtFast(float x)
Assert( s_bMathlibInitialized );

float rroot;
#if defined(__arm__) || defined(__aarch64__)
#if defined(__arm__) || defined(__aarch64__) || defined(__riscv)
rroot = _SSE_RSqrtAccurate(x);
#elif _WIN32
_asm
Expand Down Expand Up @@ -217,7 +219,7 @@ float FASTCALL _SSE_VectorNormalize (Vector& vec)
// be much of a performance win, considering you will very likely miss 3 branch predicts in a row.
if ( v[0] || v[1] || v[2] )
{
#if defined(__arm__) || defined(__aarch64__)
#if defined(__arm__) || defined(__aarch64__) || defined(__riscv)
float rsqrt = _SSE_RSqrtAccurate( v[0] * v[0] + v[1] * v[1] + v[2] * v[2] );
r[0] = v[0] * rsqrt;
r[1] = v[1] * rsqrt;
Expand Down Expand Up @@ -296,7 +298,7 @@ void FASTCALL _SSE_VectorNormalizeFast (Vector& vec)
float _SSE_InvRSquared(const float* v)
{
float inv_r2 = 1.f;
#if defined(__arm__) || defined(__aarch64__)
#if defined(__arm__) || defined(__aarch64__) || defined(__riscv)
return _SSE_RSqrtAccurate( FLT_EPSILON + v[0] * v[0] + v[1] * v[1] + v[2] * v[2] );
#elif _WIN32
_asm { // Intel SSE only routine
Expand Down Expand Up @@ -391,7 +393,7 @@ typedef __m64 v2si; // vector of 2 int (mmx)

void _SSE_SinCos(float x, float* s, float* c)
{
#if defined(__arm__) || defined(__aarch64__)
#if defined(__arm__) || defined(__aarch64__) || defined(__riscv)
#if defined( OSX )
__sincosf(x, s, c);
#elif defined( POSIX )
Expand Down Expand Up @@ -607,7 +609,7 @@ void _SSE_SinCos(float x, float* s, float* c)

float _SSE_cos( float x )
{
#if defined(__arm__) || defined(__aarch64__)
#if defined(__arm__) || defined(__aarch64__) || defined(__riscv)
return cos(x);
#elif _WIN32
float temp;
Expand Down
6 changes: 3 additions & 3 deletions public/materialsystem/imesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -1152,7 +1152,7 @@ inline void CVertexBuilder::FastAdvanceNVertices( int n )
//-----------------------------------------------------------------------------
inline void CVertexBuilder::FastVertex( const ModelVertexDX7_t &vertex )
{
#if defined(__arm__) || defined(__aarch64__) || defined(PLATFORM_WINDOWS_PC64)
#if defined(__arm__) || defined(__aarch64__) || defined(__riscv) || defined(PLATFORM_WINDOWS_PC64)
FastVertexSSE( vertex );
#else
Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // FIXME: support compressed verts if needed
Expand Down Expand Up @@ -1309,7 +1309,7 @@ inline void CVertexBuilder::Fast4VerticesSSE(
movntps [edi + 80+96], xmm5

}
#elif defined(__arm__) || defined(PLATFORM_WINDOWS_PC64)
#elif defined(__arm__) || defined(__riscv) || defined(PLATFORM_WINDOWS_PC64)
const void *pReadA = &vtx_a;
const void *pReadB = &vtx_b;
const void *pReadC = &vtx_c;
Expand Down Expand Up @@ -1354,7 +1354,7 @@ inline void CVertexBuilder::Fast4VerticesSSE(

inline void CVertexBuilder::FastVertex( const ModelVertexDX8_t &vertex )
{
#if defined(__arm__) || defined(__aarch64__) || defined(PLATFORM_WINDOWS_PC64)
#if defined(__arm__) || defined(__aarch64__) || defined(__riscv) || defined(PLATFORM_WINDOWS_PC64)
FastVertexSSE( vertex );
#else
Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // FIXME: support compressed verts if needed
Expand Down
4 changes: 4 additions & 0 deletions public/mathlib/mathlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -1203,6 +1203,8 @@ FORCEINLINE int RoundFloatToInt(float f)
return pResult[1];
#elif defined (__arm__) || defined (__aarch64__)
return (int)(f + 0.5f);
#elif defined( PLATFORM_RISCV64 )
return (int)lrintf( f ); // round to nearest (even), like cvtss2si on x86
#else
#error Unknown architecture
#endif
Expand Down Expand Up @@ -1235,6 +1237,8 @@ FORCEINLINE unsigned long RoundFloatToUnsignedLong(float f)
#else // !X360
#if defined(__arm__) || defined(__aarch64__)
return (unsigned long)(f + 0.5f);
#elif defined( PLATFORM_RISCV64 )
return (unsigned long)llrintf( f );
#elif defined( PLATFORM_WINDOWS_PC64 )
uint nRet = ( uint ) f;
if ( nRet & 1 )
Expand Down
2 changes: 2 additions & 0 deletions public/mathlib/ssemath.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include <xboxmath.h>
#elif defined(__arm__) || defined(__aarch64__)
#include "sse2neon.h"
#elif defined(__riscv)
#include "sse2simde.h"
#else
#include <xmmintrin.h>
#endif
Expand Down
2 changes: 2 additions & 0 deletions public/mathlib/vector4d.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@

#if defined (__arm__) || defined(__aarch64__)
#include "sse2neon.h"
#elif defined(__riscv)
#include "sse2simde.h"
#endif

// forward declarations
Expand Down
2 changes: 1 addition & 1 deletion public/saverestoretypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ inline const char *CSaveRestoreSegment::StringFromSymbol( int token )
/// compilers. Either way, there's no portable intrinsic.

// Newer GCC versions provide this in this header, older did by default.
#if !defined( _rotr ) && defined( COMPILER_GCC ) && !defined( __arm__ ) && !defined( __aarch64__ )
#if !defined( _rotr ) && defined( COMPILER_GCC ) && !defined( __arm__ ) && !defined( __aarch64__ ) && !defined( __riscv )
#include <x86intrin.h>
#endif

Expand Down
2 changes: 1 addition & 1 deletion public/steam/steamtypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ typedef unsigned char uint8;
#define POSIX 1
#endif

#if defined(__x86_64__) || defined(_WIN64) || defined(__aarch64__)
#if defined(__x86_64__) || defined(_WIN64) || defined(__aarch64__) || (defined(__riscv) && __riscv_xlen == 64)
#define X64BITS
#endif

Expand Down
14 changes: 9 additions & 5 deletions public/tier0/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
#ifndef PLATFORM_H
#define PLATFORM_H

#if defined(__x86_64__) || defined(_WIN64) || defined(__aarch64__)
#if defined(__riscv) && (__riscv_xlen == 64)
#define PLATFORM_RISCV64 1
#endif

#if defined(__x86_64__) || defined(_WIN64) || defined(__aarch64__) || defined(PLATFORM_RISCV64)
#define PLATFORM_64BITS 1
#endif

Expand Down Expand Up @@ -455,7 +459,7 @@ typedef void * HINSTANCE;
// On OSX, SIGTRAP doesn't really stop the thread cold when debugging.
// So if being debugged, use INT3 which is precise.
#if defined(OSX) || defined(PLATFORM_BSD)
# if defined(__arm__) || defined(__aarch64__)
# if defined(__arm__) || defined(__aarch64__) || defined(PLATFORM_RISCV64)
# ifdef __clang__
# define DebuggerBreak() do { if ( Plat_IsInDebugSession() ) { __builtin_debugtrap(); } else { raise(SIGTRAP); } } while(0)
# elif defined __GNUC__
Expand Down Expand Up @@ -898,7 +902,7 @@ static FORCEINLINE double fsel(double fComparand, double fValGE, double fLT)

#endif
#endif
#elif defined (__arm__) || defined (__aarch64__)
#elif defined (__arm__) || defined (__aarch64__) || defined(PLATFORM_RISCV64)
inline void SetupFPUControlWord() {}
#else
inline void SetupFPUControlWord()
Expand Down Expand Up @@ -1069,7 +1073,7 @@ inline T QWordSwapC( T dw )
// The typically used methods.
//-------------------------------------

#if (defined(__i386__) || defined(__amd64__) || defined(__arm__) || defined(__aarch64__)) && !defined(VALVE_LITTLE_ENDIAN)
#if (defined(__i386__) || defined(__amd64__) || defined(__arm__) || defined(__aarch64__) || defined(PLATFORM_RISCV64)) && !defined(VALVE_LITTLE_ENDIAN)
#define VALVE_LITTLE_ENDIAN 1
#endif

Expand Down Expand Up @@ -1235,7 +1239,7 @@ PLATFORM_INTERFACE struct tm * Plat_localtime( const time_t *timep, struct tm *

inline uint64 Plat_Rdtsc()
{
#if (defined( __arm__ ) || defined( __aarch64__ )) && defined (POSIX)
#if (defined( __arm__ ) || defined( __aarch64__ ) || defined( PLATFORM_RISCV64 )) && defined (POSIX)
struct timespec t;
clock_gettime( CLOCK_REALTIME, &t);
return t.tv_sec * 1000000000ULL + t.tv_nsec;
Expand Down
6 changes: 6 additions & 0 deletions public/tier0/tslist.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,13 @@ inline bool ThreadInterlockedAssignIf128( int128 volatile * pDest, const int128
// We do not want the original comparand modified by the swap
// so operate on a local copy.
int128 local_comparand = comparand;
#if defined( __riscv )
// RISC-V (without Zacas) has no 128-bit CAS instruction, so there is no
// __sync_bool_compare_and_swap_16. libatomic provides a (lock-based) 16-byte CAS.
return __atomic_compare_exchange_n( pDest, &local_comparand, value, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST );
#else
return __sync_bool_compare_and_swap( pDest, local_comparand, value );
#endif
}
#endif

Expand Down
9 changes: 9 additions & 0 deletions scripts/build-debian-riscv64.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/sh
# Native build on Linux riscv64 (RV64GC), e.g. Debian 13 (trixie).

git submodule init && git submodule update
sudo apt-get update
sudo apt-get install -y g++ python-is-python3 pkg-config libsimde-dev libopenal-dev libpng-dev libjpeg-dev libfreetype-dev libfontconfig-dev libcurl4-gnutls-dev libsdl2-dev zlib1g-dev libbz2-dev libedit-dev libgl-dev

./waf configure -T debug --disable-warns $* &&
./waf build
6 changes: 5 additions & 1 deletion tier0/cpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const tchar* GetProcessorVendorId();

static bool cpuid(uint32 function, uint32& out_eax, uint32& out_ebx, uint32& out_ecx, uint32& out_edx)
{
#if defined (__arm__) || defined (__aarch64__) || defined( _X360 )
#if defined (__arm__) || defined (__aarch64__) || defined( __riscv ) || defined( _X360 )
return false;
#elif defined(GNUC)

Expand Down Expand Up @@ -337,6 +337,8 @@ const tchar* GetProcessorVendorId()
return "PPC";
#elif defined ( __arm__ )
return "ARM";
#elif defined ( __riscv )
return "RISC-V";
#else
uint32 unused, VendorIDRegisters[3];

Expand Down Expand Up @@ -376,6 +378,8 @@ const tchar* GetProcessorArchName()
return "aarch64";
#elif defined __arm__ || defined _M_ARM
return "arm";
#elif defined(__riscv) && (__riscv_xlen == 64)
return "riscv64";
#else
#error "Unknown architecture"
#endif
Expand Down
2 changes: 1 addition & 1 deletion tier0/cpu_posix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ uint64 CalculateCPUFreq()
}
}

#if !defined(__arm__) && !defined(__aarch64__)
#if !defined(__arm__) && !defined(__aarch64__) && !defined(__riscv)
// fallback mechanism to calculate when failed
// Compute the period. Loop until we get 3 consecutive periods that
// are the same to within a small error. The error is chosen
Expand Down
2 changes: 1 addition & 1 deletion tier1/pathmatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ static bool s_bShowDiag;
#ifdef POSIX
#include <signal.h>
#define DEBUG_BREAK() raise(SIGINT)
#elif !defined (__arm__)
#elif !defined (__arm__) && !defined(__aarch64__) && !defined(__riscv)
#define DEBUG_BREAK() __asm__ __volatile__ ( "int $3" )
#else
#define DEBUG_BREAK()
Expand Down
2 changes: 1 addition & 1 deletion tier1/processor_detect_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ bool CheckMMXTechnology(void) { return false; }
bool CheckSSETechnology(void) { return false; }
bool CheckSSE2Technology(void) { return false; }
bool Check3DNowTechnology(void) { return false; }
#elif defined (__arm__) || defined (__aarch64__)
#elif defined (__arm__) || defined (__aarch64__) || defined(__riscv)
bool CheckMMXTechnology(void) { return false; }
bool CheckSSETechnology(void) { return false; }
bool CheckSSE2Technology(void) { return false; }
Expand Down
2 changes: 1 addition & 1 deletion tier1/reliabletimer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ int64 CReliableTimer::GetPerformanceCountNow()
uint64 ulNow;
SYS_TIMEBASE_GET( ulNow );
return ulNow;
#elif (defined( __arm__ ) || defined( __aarch64__ )) && defined (POSIX)
#elif (defined( __arm__ ) || defined( __aarch64__ ) || defined( __riscv )) && defined (POSIX)
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
return ts.tv_sec * 1000000000ULL + ts.tv_nsec;
Expand Down
8 changes: 7 additions & 1 deletion wscript
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,8 @@ def configure(conf):

if conf.env.DEST_CPU in ['x86', 'x86_64']:
flags += ['-mfpmath=sse']
elif conf.env.DEST_CPU in ['arm', 'aarch64']:
elif conf.env.DEST_CPU in ['arm', 'aarch64', 'riscv']:
# char is unsigned by default on ARM and RISC-V, the code assumes x86 (signed)
flags += ['-fsigned-char']

if conf.env.DEST_CPU == 'arm':
Expand All @@ -532,6 +533,11 @@ def configure(conf):
if conf.env.DEST_OS == 'freebsd':
linkflags += ['-lexecinfo']

if conf.env.DEST_CPU == 'riscv':
# 16-byte CAS (tier0/tslist.h) comes from libatomic on RISC-V.
# Added as LIB (not a linker flag) so it comes after the objects (--as-needed).
conf.env.append_unique('LIB', ['atomic'])

if conf.env.DEST_OS != 'win32':
cflags += flags
linkflags += flags
Expand Down