Use SSE when available for floating-point operations (bug 5841, r=her).

This commit is contained in:
David Anderson
2013-08-08 20:26:36 -07:00
parent f031ad23f6
commit bf325b72f1
7 changed files with 339 additions and 41 deletions
+2 -1
View File
@@ -37,7 +37,8 @@ binary.AddSourceFiles('sourcepawn/jit', [
'zlib/uncompr.c',
'zlib/zutil.c',
'md5/md5.cpp',
'../../knight/shared/KeCodeAllocator.cpp'
'../../knight/shared/KeCodeAllocator.cpp',
'../../public/jit/x86/assembler-x86.cpp'
])
SM.AutoVersion('sourcepawn/jit', binary)
SM.ExtractDebugInfo(extension, binary)
+5
View File
@@ -34,6 +34,7 @@ OBJECTS = dll_exports.cpp \
zlib/zutil.c \
OBJECTS += ../../knight/shared/KeCodeAllocator.cpp
OBJECTS += ../../public/jit/x86/assembler-x86.cpp
##############################################
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
@@ -75,6 +76,7 @@ ifeq "$(GCC_VERSION)" "4"
endif
OBJ_LINUX := $(OBJECTS:../../knight/shared/%.cpp=$(BIN_DIR)/knight/%.o)
OBJ_LINUX := $(OBJ_LINUX:../../public/jit/x86/%.cpp=$(BIN_DIR)/%.o)
OBJ_LINUX := $(OBJ_LINUX:%.cpp=$(BIN_DIR)/%.o)
OBJ_LINUX := $(OBJ_LINUX:%.c=$(BIN_DIR)/%.o)
@@ -89,6 +91,9 @@ $(BIN_DIR)/%.o: %.cpp
$(BIN_DIR)/knight/%.o: ../../knight/shared/%.cpp
$(CXX) $(INCLUDE) $(CFLAGS) $(CXXFLAGS) -o $@ -c $<
$(BIN_DIR)/assembler-x86.o: ../../public/jit/x86/assembler-x86.cpp
$(CXX) $(INCLUDE) $(CFLAGS) $(CXXFLAGS) -o $@ -c $<
all:
mkdir -p $(BIN_DIR)/x86
mkdir -p $(BIN_DIR)/md5
+79 -39
View File
@@ -983,10 +983,15 @@ Compiler::emitOp(OPCODE op)
break;
case OP_FLOAT:
__ fild32(Operand(edi, 0));
__ subl(esp, 4);
__ fstp32(Operand(esp, 0));
__ pop(pri);
if (MacroAssemblerX86::Features().sse2) {
__ cvtsi2ss(xmm0, Operand(edi, 0));
__ movd(pri, xmm0);
} else {
__ fild32(Operand(edi, 0));
__ subl(esp, 4);
__ fstp32(Operand(esp, 0));
__ pop(pri);
}
__ addl(stk, 4);
break;
@@ -994,34 +999,52 @@ Compiler::emitOp(OPCODE op)
case OP_FLOATSUB:
case OP_FLOATMUL:
case OP_FLOATDIV:
__ subl(esp, 4);
__ fld32(Operand(edi, 0));
if (MacroAssemblerX86::Features().sse2) {
__ movss(xmm0, Operand(stk, 0));
if (op == OP_FLOATADD)
__ addss(xmm0, Operand(stk, 4));
else if (op == OP_FLOATSUB)
__ subss(xmm0, Operand(stk, 4));
else if (op == OP_FLOATMUL)
__ mulss(xmm0, Operand(stk, 4));
else if (op == OP_FLOATDIV)
__ divss(xmm0, Operand(stk, 4));
__ movd(pri, xmm0);
} else {
__ subl(esp, 4);
__ fld32(Operand(stk, 0));
if (op == OP_FLOATADD)
__ fadd32(Operand(edi, 4));
else if (op == OP_FLOATSUB)
__ fsub32(Operand(edi, 4));
else if (op == OP_FLOATMUL)
__ fmul32(Operand(edi, 4));
else if (op == OP_FLOATDIV)
__ fdiv32(Operand(edi, 4));
if (op == OP_FLOATADD)
__ fadd32(Operand(stk, 4));
else if (op == OP_FLOATSUB)
__ fsub32(Operand(stk, 4));
else if (op == OP_FLOATMUL)
__ fmul32(Operand(stk, 4));
else if (op == OP_FLOATDIV)
__ fdiv32(Operand(stk, 4));
__ fstp32(Operand(esp, 0));
__ pop(pri);
__ fstp32(Operand(esp, 0));
__ pop(pri);
}
__ addl(stk, 8);
break;
case OP_RND_TO_NEAREST:
{
static float kRoundToNearest = 0.5f;
// From http://wurstcaptures.untergrund.net/assembler_tricks.html#fastfloorf
__ fld32(Operand(edi, 0));
__ fadd32(st0, st0);
__ fadd32(Operand(ExternalAddress(&kRoundToNearest)));
__ subl(esp, 4);
__ fistp32(Operand(esp, 0));
__ pop(pri);
__ sarl(pri, 1);
if (MacroAssemblerX86::Features().sse) {
// Assume no one is touching MXCSR.
__ cvtss2si(pri, Operand(stk, 0));
} else {
static float kRoundToNearest = 0.5f;
// From http://wurstcaptures.untergrund.net/assembler_tricks.html#fastfloorf
__ fld32(Operand(stk, 0));
__ fadd32(st0, st0);
__ fadd32(Operand(ExternalAddress(&kRoundToNearest)));
__ subl(esp, 4);
__ fistp32(Operand(esp, 0));
__ pop(pri);
__ sarl(pri, 1);
}
__ addl(stk, 4);
break;
}
@@ -1030,7 +1053,7 @@ Compiler::emitOp(OPCODE op)
{
static float kRoundToCeil = -0.5f;
// From http://wurstcaptures.untergrund.net/assembler_tricks.html#fastfloorf
__ fld32(Operand(edi, 0));
__ fld32(Operand(stk, 0));
__ fadd32(st0, st0);
__ fsubr32(Operand(ExternalAddress(&kRoundToCeil)));
__ subl(esp, 4);
@@ -1043,15 +1066,19 @@ Compiler::emitOp(OPCODE op)
}
case OP_RND_TO_ZERO:
__ fld32(Operand(edi, 0));
__ subl(esp, 8);
__ fstcw(Operand(esp, 4));
__ movl(Operand(esp, 0), 0xfff);
__ fldcw(Operand(esp, 0));
__ fistp32(Operand(esp, 0));
__ pop(pri);
__ fldcw(Operand(esp, 0));
__ addl(esp, 4);
if (MacroAssemblerX86::Features().sse) {
__ cvttss2si(pri, Operand(stk, 0));
} else {
__ fld32(Operand(stk, 0));
__ subl(esp, 8);
__ fstcw(Operand(esp, 4));
__ movl(Operand(esp, 0), 0xfff);
__ fldcw(Operand(esp, 0));
__ fistp32(Operand(esp, 0));
__ pop(pri);
__ fldcw(Operand(esp, 0));
__ addl(esp, 4);
}
__ addl(stk, 4);
break;
@@ -1071,10 +1098,15 @@ Compiler::emitOp(OPCODE op)
case OP_FLOATCMP:
{
Label bl, ab, done;
__ fld32(Operand(edi, 0));
__ fld32(Operand(edi, 4));
__ fucomip(st1);
__ fstp(st0);
if (MacroAssemblerX86::Features().sse) {
__ movss(xmm0, Operand(stk, 4));
__ ucomiss(xmm0, Operand(stk, 0));
} else {
__ fld32(Operand(stk, 0));
__ fld32(Operand(stk, 4));
__ fucomip(st1);
__ fstp(st0);
}
__ j(above, &ab);
__ j(below, &bl);
__ xorl(pri, pri);
@@ -1869,6 +1901,14 @@ bool JITX86::InitializeJIT()
if (!m_pJitGenArray)
return false;
MacroAssemblerX86 masm;
MacroAssemblerX86::GenerateFeatureDetection(masm);
void *code = LinkCode(masm);
if (!code)
return false;
MacroAssemblerX86::RunFeatureDetection(code);
KE_FreeCode(g_pCodeCache, code);
return true;
}
+1 -1
View File
@@ -35,7 +35,7 @@
#include <sp_vm_types.h>
#include <sp_vm_api.h>
#include <KeCodeAllocator.h>
#include <assembler-x86.h>
#include <macro-assembler-x86.h>
#include <ke_vector.h>
#include "jit_shared.h"
#include "BaseRuntime.h"