add oversampler
This commit is contained in:
8
oversampling/WDL/eel2/.gitignore
vendored
Normal file
8
oversampling/WDL/eel2/.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/*.obj
|
||||
/asm-nseel-x64-macho.asm
|
||||
/asm-nseel-x64.asm
|
||||
/loose_eel.exe
|
||||
|
||||
!/asm-nseel-x64-macho.o
|
||||
!/asm-nseel-x64.obj
|
||||
!/asm-nseel-arm64ec.obj
|
||||
167
oversampling/WDL/eel2/Makefile
Normal file
167
oversampling/WDL/eel2/Makefile
Normal file
@@ -0,0 +1,167 @@
|
||||
CC=gcc
|
||||
CFLAGS=-g -DWDL_FFT_REALSIZE=8 -Wall -Wno-unused-function -Wno-multichar -Wno-unused-result -Wshadow -Wtype-limits
|
||||
LFLAGS=
|
||||
CXX=g++
|
||||
|
||||
ifdef DEBUG
|
||||
CFLAGS += -D_DEBUG -O0 -DWDL_CHECK_FOR_NON_UTF8_FOPEN
|
||||
else
|
||||
CFLAGS += -DNDEBUG -O
|
||||
endif
|
||||
|
||||
CFLAGS += -D_FILE_OFFSET_BITS=64
|
||||
|
||||
OBJS=nseel-caltab.o nseel-compiler.o nseel-eval.o nseel-lextab.o nseel-ram.o nseel-yylex.o nseel-cfunc.o fft.o
|
||||
|
||||
SWELL_OBJS=
|
||||
LICE_OBJS=
|
||||
|
||||
OBJS2=
|
||||
|
||||
UNAME_S := $(shell uname -s)
|
||||
ARCH := $(shell uname -m)
|
||||
|
||||
ifeq ($(ARCH), aarch64)
|
||||
ifeq ($(shell $(CC) -dumpmachine | cut -f 1 -d -), arm)
|
||||
# helper for armv7l userspace on aarch64 cpu
|
||||
ARCH := armv7l
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
CC=clang
|
||||
CXX=clang++
|
||||
CFLAGS += -arch $(ARCH)
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH),arm64)
|
||||
CFLAGS += -fsigned-char
|
||||
else
|
||||
ifneq ($(filter arm%,$(ARCH)),)
|
||||
CFLAGS += -fsigned-char -mfpu=vfp -march=armv6t2 -marm
|
||||
endif
|
||||
ifeq ($(ARCH),aarch64)
|
||||
CFLAGS += -fsigned-char
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef ALLOW_WARNINGS
|
||||
ifneq ($(UNAME_S),Darwin)
|
||||
CFLAGS += -Werror
|
||||
endif
|
||||
endif
|
||||
ifndef DEPRECATED_WARNINGS
|
||||
CFLAGS += -Wno-deprecated-declarations
|
||||
endif
|
||||
|
||||
|
||||
default: loose_eel eel_pp
|
||||
|
||||
nseel-compiler.o: glue*.h ns-eel*.h
|
||||
nseel-cfunc.o: asm*.c ns-eel*.h
|
||||
loose_eel.o: eel*.h ns-eel*.h
|
||||
nseel-*.o: ns-eel*.h
|
||||
|
||||
vpath %.cpp ../lice ../swell
|
||||
vpath %.mm ../swell
|
||||
vpath %.c ../
|
||||
|
||||
ifdef MAXLOOP
|
||||
CFLAGS += -DNSEEL_LOOPFUNC_SUPPORT_MAXLEN=$(MAXLOOP)
|
||||
else
|
||||
CFLAGS += -DNSEEL_LOOPFUNC_SUPPORT_MAXLEN=0
|
||||
endif
|
||||
|
||||
ifdef DISASSEMBLE
|
||||
CFLAGS += -DEELSCRIPT_DO_DISASSEMBLE
|
||||
endif
|
||||
|
||||
ifndef NO_GFX
|
||||
LICE_OBJS += lice.o lice_image.o lice_line.o lice_ico.o lice_bmp.o lice_textnew.o lice_text.o lice_arc.o
|
||||
CFLAGS += -DEEL_LICE_WANT_STANDALONE
|
||||
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
CLANG_VER := $(shell clang --version|head -n 1| sed 's/.*version \([0-9][0-9]*\).*/\1/' )
|
||||
CLANG_GT_9 := $(shell [ $(CLANG_VER) -gt 9 ] && echo true )
|
||||
ifeq ($(CLANG_GT_9),true)
|
||||
CFLAGS += -mmacosx-version-min=10.7 -stdlib=libc++
|
||||
else
|
||||
CFLAGS += -mmacosx-version-min=10.5
|
||||
endif
|
||||
SWELL_OBJS += swell-wnd.o swell-gdi.o swell.o swell-misc.o swell-dlg.o swell-menu.o swell-kb.o
|
||||
LFLAGS += -lobjc -framework Cocoa -framework Carbon
|
||||
else
|
||||
|
||||
CFLAGS += -DSWELL_LICE_GDI -DSWELL_EXTRA_MINIMAL
|
||||
ifdef GDK2
|
||||
CFLAGS += -DSWELL_TARGET_GDK=2 $(shell pkg-config --cflags gdk-2.0)
|
||||
LFLAGS += $(shell pkg-config --libs gdk-2.0) -lX11 -lXi
|
||||
else
|
||||
CFLAGS += -DSWELL_TARGET_GDK=3 $(shell pkg-config --cflags gdk-3.0)
|
||||
LFLAGS += $(shell pkg-config --libs gdk-3.0) -lX11 -lXi
|
||||
endif
|
||||
ifndef NOFREETYPE
|
||||
CFLAGS += -DSWELL_FREETYPE $(shell pkg-config --cflags freetype2)
|
||||
LFLAGS += $(shell pkg-config --libs freetype2)
|
||||
endif
|
||||
|
||||
SWELL_OBJS += swell-wnd-generic.o swell-gdi-lice.o swell.o swell-misc-generic.o \
|
||||
swell-dlg-generic.o swell-menu-generic.o swell-kb-generic.o \
|
||||
swell-gdi-generic.o swell-ini.o swell-generic-gdk.o
|
||||
|
||||
LFLAGS += -ldl -lGL
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
ifdef PORTABLE
|
||||
CFLAGS += -DEEL_TARGET_PORTABLE
|
||||
else
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
ifeq ($(ARCH),x86_64)
|
||||
ASM_FMT = macho64
|
||||
NASM_OPTS = --prefix _
|
||||
OBJS2 += asm-nseel-x64-sse.o
|
||||
endif
|
||||
endif
|
||||
ifeq ($(UNAME_S),Linux)
|
||||
ifeq ($(ARCH),x86_64)
|
||||
ASM_FMT = elf64
|
||||
NASM_OPTS =
|
||||
OBJS2 += asm-nseel-x64-sse.o
|
||||
endif
|
||||
endif
|
||||
|
||||
asm-nseel-x64-sse.o: asm-nseel-x64-sse.asm
|
||||
nasm -D AMD64ABI -f $(ASM_FMT) $(NASM_OPTS) asm-nseel-x64-sse.asm
|
||||
|
||||
endif
|
||||
CXXFLAGS=$(CFLAGS)
|
||||
|
||||
ifeq ($(CXX),g++)
|
||||
GCC_VER := $(shell $(CXX) --version|head -n 1| sed 's/.* \([0-9][0-9]*\)[.][0-9.]*/\1/' )
|
||||
GCC_GT_10 := $(shell [ "$(GCC_VER)" -gt 10 ] && echo true )
|
||||
ifeq ($(GCC_GT_10),true)
|
||||
CXXFLAGS += -std=c++03
|
||||
endif
|
||||
endif
|
||||
|
||||
gen-yacc:
|
||||
yacc -v -d eel2.y
|
||||
|
||||
gen-lex: # the output of this, lex.nseel.c, is unused because we have a handwritten parser instead
|
||||
flex eel2.l
|
||||
|
||||
%.o : %.mm
|
||||
$(CXX) $(CXXFLAGS) -c -o $@ $^
|
||||
|
||||
loose_eel: loose_eel.o $(OBJS) $(OBJS2) $(SWELL_OBJS) $(LICE_OBJS)
|
||||
g++ -o $@ $^ $(CXXFLAGS) $(LFLAGS)
|
||||
|
||||
eel_pp: eel_pp.o $(OBJS) $(OBJS2)
|
||||
g++ -o $@ $^ $(CXXFLAGS) $(LFLAGS)
|
||||
|
||||
clean:
|
||||
-rm -f -- loose_eel loose_eel.o eel_pp.o eel_pp $(OBJS) $(SWELL_OBJS) $(LICE_OBJS)
|
||||
|
||||
.PHONY: clean gen-lex gen-yacc
|
||||
222
oversampling/WDL/eel2/a2i.php
Normal file
222
oversampling/WDL/eel2/a2i.php
Normal file
@@ -0,0 +1,222 @@
|
||||
<?php
|
||||
|
||||
|
||||
|
||||
function process_file($infn, $outfn)
|
||||
{
|
||||
|
||||
$in = fopen($infn,"r");
|
||||
if (!$in) die("error opening input $infn\n");
|
||||
$out = fopen($outfn,"w");
|
||||
if (!$out) die("error opening output $outfn\n");
|
||||
|
||||
fputs($out,"// THIS FILE AUTOGENERATED FROM $infn by a2i.php\n\n");
|
||||
|
||||
$inblock=0;
|
||||
$labelcnt=0;
|
||||
|
||||
while (($line = fgets($in)))
|
||||
{
|
||||
$line = rtrim($line);
|
||||
if (trim($line) == "FUNCTION_MARKER")
|
||||
{
|
||||
fputs($out,"_emit 0x89;\n");
|
||||
for ($tmp=0;$tmp<11;$tmp++) fputs($out,"_emit 0x90;\n");
|
||||
continue;
|
||||
}
|
||||
$nowrite=0;
|
||||
|
||||
{
|
||||
if (!$inblock)
|
||||
{
|
||||
if (strstr($line,"__asm__("))
|
||||
{
|
||||
$line=str_replace("__asm__(", "__asm {", $line);
|
||||
$inblock=1;
|
||||
if (isset($bthist)) unset($bthist);
|
||||
if (isset($btfut)) unset($btfut);
|
||||
$bthist = array();
|
||||
$btfut = array();
|
||||
}
|
||||
}
|
||||
|
||||
if ($inblock)
|
||||
{
|
||||
if (substr(trim($line),-2) == ");")
|
||||
{
|
||||
$line = str_replace(");","}",$line);
|
||||
$inblock=0;
|
||||
}
|
||||
|
||||
$sline = strstr($line, "\"");
|
||||
$lastchunk = strrchr($line,"\"");
|
||||
if ($sline && $lastchunk && strlen($sline) != strlen($lastchunk))
|
||||
{
|
||||
$beg_restore = substr($line,0,-strlen($sline));
|
||||
|
||||
if (strlen($lastchunk)>1)
|
||||
$end_restore = substr($line,1-strlen($lastchunk));
|
||||
else $end_restore="";
|
||||
|
||||
$sline = substr($sline,1,strlen($sline)-1-strlen($lastchunk));
|
||||
|
||||
// get rid of chars we can ignore
|
||||
$sline=preg_replace("/%\d+/","__TEMP_REPLACE__", $sline);
|
||||
|
||||
$sline=str_replace("\\n","", $sline);
|
||||
$sline=str_replace("\"","", $sline);
|
||||
$sline=str_replace("$","", $sline);
|
||||
$sline=str_replace("%","", $sline);
|
||||
|
||||
|
||||
// get rid of excess whitespace, especially around commas
|
||||
$sline=str_replace(" "," ", $sline);
|
||||
$sline=str_replace(" "," ", $sline);
|
||||
$sline=str_replace(" "," ", $sline);
|
||||
$sline=str_replace(", ",",", $sline);
|
||||
$sline=str_replace(" ,",",", $sline);
|
||||
|
||||
$sline=preg_replace("/st\\(([0-9]+)\\)/","FPREG_$1",$sline);
|
||||
|
||||
|
||||
if (preg_match("/^([0-9]+):/",trim($sline)))
|
||||
{
|
||||
$d = (int) $sline;
|
||||
$a = strstr($sline,":");
|
||||
if ($a) $sline = substr($a,1);
|
||||
|
||||
if (isset($btfut[$d]) && $btfut[$d] != "") $thislbl = $btfut[$d];
|
||||
else $thislbl = "label_" . $labelcnt++;
|
||||
|
||||
$btfut[$d]="";
|
||||
$bthist[$d] = $thislbl;
|
||||
|
||||
fputs($out,$thislbl . ":\n");
|
||||
}
|
||||
|
||||
$sploded = explode(" ",trim($sline));
|
||||
if ($sline != "" && count($sploded)>0)
|
||||
{
|
||||
$inst = trim($sploded[0]);
|
||||
$suffix = "";
|
||||
|
||||
$instline = strstr($sline,$inst);
|
||||
$beg_restore .= substr($sline,0,-strlen($instline));
|
||||
|
||||
$parms = trim(substr($instline,strlen($inst)));
|
||||
|
||||
if ($inst=="j") $inst="jmp";
|
||||
|
||||
//if ($inst == "fdiv" && $parms == "") $inst="fdivr";
|
||||
|
||||
if ($inst != "call" && substr($inst,-2) == "ll") $suffix = "ll";
|
||||
else if ($inst != "call" && $inst != "fmul" && substr($inst,-1) == "l") $suffix = "l";
|
||||
else if (substr($inst,0,1)=="f" && $inst != "fcos" && $inst != "fsincos" && $inst != "fabs" && $inst != "fchs" && substr($inst,-1) == "s") $suffix = "s";
|
||||
|
||||
|
||||
if ($suffix != "" && $inst != "jl") $inst = substr($inst,0,-strlen($suffix));
|
||||
|
||||
$parms = preg_replace("/\\((.{2,3}),(.{2,3})\\)/","($1+$2)",$parms);
|
||||
|
||||
$parms=preg_replace("/EEL_F_SUFFIX (-?[0-9]+)\\((.*)\\)/","qword ptr [$2+$1]",$parms);
|
||||
$parms=preg_replace("/EEL_F_SUFFIX \\((.*)\\)/","qword ptr [$1]",$parms);
|
||||
|
||||
if ($inst == "sh" && $suffix == "ll") { $suffix="l"; $inst="shl"; }
|
||||
|
||||
if ($suffix == "ll" || ($suffix == "l" && substr($inst,0,1) == "f" && substr($inst,0,2) != "fi")) $suffixstr = "qword ptr ";
|
||||
else if ($suffix == "l") $suffixstr = "dword ptr ";
|
||||
else if ($suffix == "s") $suffixstr = "dword ptr ";
|
||||
else $suffixstr = "";
|
||||
$parms=preg_replace("/(-?[0-9]+)\\((.*)\\)/",$suffixstr . "[$2+$1]",$parms);
|
||||
$parms=preg_replace("/\\((.*)\\)/",$suffixstr . "[$1]",$parms);
|
||||
|
||||
|
||||
$parms=str_replace("EEL_F_SUFFIX","qword ptr", $parms);
|
||||
|
||||
$plist = explode(",",$parms);
|
||||
if (count($plist) > 2) echo "Warning: too many parameters $parms!\n";
|
||||
else if (count($plist)==2)
|
||||
{
|
||||
$parms = trim($plist[1]) . ", " . trim($plist[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
|
||||
if ($inst=="fsts") $inst="fstsw";
|
||||
if ($inst=="call" && substr($parms,0,1) == "*") $parms=substr($parms,1);
|
||||
if (substr($inst,0,1) == "j")
|
||||
{
|
||||
if (substr($parms,-1) == "f")
|
||||
{
|
||||
$d = (int) substr($parms,0,-1);
|
||||
if (isset($btfut[$d]) && $btfut[$d] != "") $thislbl = $btfut[$d];
|
||||
else $btfut[$d] = $thislbl = "label_" . $labelcnt++;
|
||||
$parms = $thislbl;
|
||||
}
|
||||
else if (substr($parms,-1) == "b")
|
||||
{
|
||||
$d = (int) substr($parms,0,-1);
|
||||
if ($bthist[$d]=="") echo "Error resolving label $parms\n";
|
||||
$parms = $bthist[$d];
|
||||
}
|
||||
}
|
||||
if (stristr($parms,"[0xfefefefe]"))
|
||||
{
|
||||
if ($inst == "fmul" || $inst=="fadd" || $inst == "fcomp")
|
||||
{
|
||||
if ($inst=="fmul") $hdr="0x0D";
|
||||
if ($inst=="fadd") $hdr="0x05";
|
||||
if ($inst=="fcomp") $hdr="0x1D";
|
||||
|
||||
fputs($out,"_emit 0xDC; // $inst qword ptr [0xfefefefe]\n");
|
||||
fputs($out,"_emit $hdr;\n");
|
||||
fputs($out,"_emit 0xFE;\n");
|
||||
fputs($out,"_emit 0xFE;\n");
|
||||
fputs($out,"_emit 0xFE;\n");
|
||||
fputs($out,"_emit 0xFE;\n");
|
||||
$nowrite=1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$sline = $inst;
|
||||
if ($parms !="") $sline .= " " . $parms;
|
||||
$sline .= ";";
|
||||
|
||||
}
|
||||
|
||||
$sline=preg_replace("/FPREG_([0-9]+)/","st($1)",$sline);
|
||||
$line = $beg_restore . $sline . $end_restore;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (!$nowrite)
|
||||
{
|
||||
if (strstr($line,"__TEMP_REPLACE__"))
|
||||
{
|
||||
$a = strstr($line,"//REPLACE=");
|
||||
if ($a === false) die ("__TEMP_REPLACE__ found, no REPLACE=\n");
|
||||
$line=str_replace("__TEMP_REPLACE__",substr($a,10),$line);
|
||||
}
|
||||
fputs($out,$line . "\n");
|
||||
}
|
||||
}
|
||||
|
||||
if ($inblock) echo "Error (ended in __asm__ block???)\n";
|
||||
|
||||
|
||||
fclose($in);
|
||||
fclose($out);
|
||||
|
||||
};
|
||||
|
||||
process_file("asm-nseel-x86-gcc.c" , "asm-nseel-x86-msvc.c");
|
||||
// process_file("asm-miscfunc-x86-gcc.c" , "asm-miscfunc-x86-msvc.c");
|
||||
//process_file("asm-megabuf-x86-gcc.c" , "asm-megabuf-x86-msvc.c");
|
||||
|
||||
?>
|
||||
1270
oversampling/WDL/eel2/asm-nseel-aarch64-gcc.c
Normal file
1270
oversampling/WDL/eel2/asm-nseel-aarch64-gcc.c
Normal file
File diff suppressed because it is too large
Load Diff
1418
oversampling/WDL/eel2/asm-nseel-aarch64-msvc.asm
Normal file
1418
oversampling/WDL/eel2/asm-nseel-aarch64-msvc.asm
Normal file
File diff suppressed because it is too large
Load Diff
1308
oversampling/WDL/eel2/asm-nseel-arm-gcc.c
Normal file
1308
oversampling/WDL/eel2/asm-nseel-arm-gcc.c
Normal file
File diff suppressed because it is too large
Load Diff
1416
oversampling/WDL/eel2/asm-nseel-arm64ec.asm
Normal file
1416
oversampling/WDL/eel2/asm-nseel-arm64ec.asm
Normal file
File diff suppressed because it is too large
Load Diff
BIN
oversampling/WDL/eel2/asm-nseel-arm64ec.obj
Normal file
BIN
oversampling/WDL/eel2/asm-nseel-arm64ec.obj
Normal file
Binary file not shown.
BIN
oversampling/WDL/eel2/asm-nseel-multi-macho.o
Normal file
BIN
oversampling/WDL/eel2/asm-nseel-multi-macho.o
Normal file
Binary file not shown.
1436
oversampling/WDL/eel2/asm-nseel-ppc-gcc.c
Normal file
1436
oversampling/WDL/eel2/asm-nseel-ppc-gcc.c
Normal file
File diff suppressed because it is too large
Load Diff
BIN
oversampling/WDL/eel2/asm-nseel-x64-macho.o
Normal file
BIN
oversampling/WDL/eel2/asm-nseel-x64-macho.o
Normal file
Binary file not shown.
1357
oversampling/WDL/eel2/asm-nseel-x64-sse.asm
Normal file
1357
oversampling/WDL/eel2/asm-nseel-x64-sse.asm
Normal file
File diff suppressed because it is too large
Load Diff
BIN
oversampling/WDL/eel2/asm-nseel-x64.obj
Normal file
BIN
oversampling/WDL/eel2/asm-nseel-x64.obj
Normal file
Binary file not shown.
1332
oversampling/WDL/eel2/asm-nseel-x86-gcc.c
Normal file
1332
oversampling/WDL/eel2/asm-nseel-x86-gcc.c
Normal file
File diff suppressed because it is too large
Load Diff
3017
oversampling/WDL/eel2/asm-nseel-x86-msvc.c
Normal file
3017
oversampling/WDL/eel2/asm-nseel-x86-msvc.c
Normal file
File diff suppressed because it is too large
Load Diff
113
oversampling/WDL/eel2/eel2.l
Normal file
113
oversampling/WDL/eel2/eel2.l
Normal file
@@ -0,0 +1,113 @@
|
||||
%option reentrant
|
||||
%option prefix="nseel"
|
||||
%option bison-bridge
|
||||
%option bison-locations
|
||||
%option noyywrap
|
||||
%option never-interactive
|
||||
%option batch
|
||||
%option nounput
|
||||
|
||||
%{
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define YY_USER_ACTION yylloc->first_line = yylineno;
|
||||
|
||||
#define YY_FATAL_ERROR(msg) { ((struct yyguts_t*)yyscanner)->yyextra_r->errVar=1; }
|
||||
#define YY_INPUT(buf,result,max_size) { (result) = nseel_gets(yyextra,(buf),max_size); }
|
||||
|
||||
#define YY_EXTRA_TYPE compileContext *
|
||||
|
||||
#undef YY_BUF_SIZE
|
||||
#define YY_BUF_SIZE (NSEEL_MAX_VARIABLE_NAMELEN*2)
|
||||
|
||||
#undef YY_READ_BUF_SIZE
|
||||
#define YY_READ_BUF_SIZE (NSEEL_MAX_VARIABLE_NAMELEN)
|
||||
|
||||
#include "y.tab.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define YY_NO_UNISTD_H
|
||||
#endif
|
||||
|
||||
#include "ns-eel-int.h"
|
||||
|
||||
int nseel_gets(compileContext *ctx, char *buf, size_t sz);
|
||||
|
||||
#define PARSENUM *yylval = nseel_translate(yyextra,yytext, 0); return VALUE;
|
||||
#define EEL_ACTION(x) return x;
|
||||
|
||||
#ifdef stdin
|
||||
#undef stdin
|
||||
#endif
|
||||
#define stdin (0)
|
||||
|
||||
#ifdef stdout
|
||||
#undef stdout
|
||||
#endif
|
||||
#define stdout (0)
|
||||
|
||||
static int g_fake_errno;
|
||||
#ifdef errno
|
||||
#undef errno
|
||||
#endif
|
||||
|
||||
#define errno g_fake_errno
|
||||
|
||||
static void comment(yyscan_t yyscanner);
|
||||
|
||||
%}
|
||||
|
||||
%%
|
||||
|
||||
[0-9]+\.?[0-9]* PARSENUM;
|
||||
\.[0-9]+ PARSENUM;
|
||||
0[xX][0-9a-fA-F]* PARSENUM;
|
||||
\$[xX][0-9a-fA-F]* PARSENUM;
|
||||
\$\~[0-9]* PARSENUM;
|
||||
\$[Ee] PARSENUM;
|
||||
\$[Pp][Ii] PARSENUM;
|
||||
\$[Pp][Hh][Ii] PARSENUM;
|
||||
\$\'.\' PARSENUM;
|
||||
\#[a-zA-Z0-9\._]* *yylval = nseel_translate(yyextra,yytext, 0); return STRING_IDENTIFIER;
|
||||
\<\< return TOKEN_SHL;
|
||||
\>\> return TOKEN_SHR;
|
||||
\<= return TOKEN_LTE;
|
||||
\>= return TOKEN_GTE;
|
||||
== return TOKEN_EQ;
|
||||
=== return TOKEN_EQ_EXACT;
|
||||
\!= return TOKEN_NE;
|
||||
\!== return TOKEN_NE_EXACT;
|
||||
\&\& return TOKEN_LOGICAL_AND;
|
||||
\|\| return TOKEN_LOGICAL_OR;
|
||||
\+= return TOKEN_ADD_OP;
|
||||
-= return TOKEN_SUB_OP;
|
||||
%= return TOKEN_MOD_OP;
|
||||
\|= return TOKEN_OR_OP;
|
||||
\&= return TOKEN_AND_OP;
|
||||
\~= return TOKEN_XOR_OP;
|
||||
\/= return TOKEN_DIV_OP;
|
||||
\*= return TOKEN_MUL_OP;
|
||||
\^= return TOKEN_POW_OP;
|
||||
|
||||
[a-zA-Z_][a-zA-Z0-9\._]* &yylval = nseel_createCompiledValuePtr((compileContext *)yyextra, NULL, yytext); return IDENTIFIER;
|
||||
|
||||
[ \t\r\n]+ /* whitespace */
|
||||
\/\/.*$ /* comment */
|
||||
"/*" { comment(yyscanner); }
|
||||
|
||||
. return (int)yytext[0];
|
||||
|
||||
%%
|
||||
|
||||
static void comment(yyscan_t yyscanner)
|
||||
{
|
||||
int c,lc=0;
|
||||
|
||||
while (0 != (c = input(yyscanner)))
|
||||
{
|
||||
if (c == '/' && lc == '*') return;
|
||||
lc = c;
|
||||
}
|
||||
// end of file, ignore for now
|
||||
}
|
||||
370
oversampling/WDL/eel2/eel2.vim
Normal file
370
oversampling/WDL/eel2/eel2.vim
Normal file
@@ -0,0 +1,370 @@
|
||||
" Vim syntax file
|
||||
" This needs a lot of C-specific stuff removed, please help if you care =)
|
||||
" Language: EEL2, based on:
|
||||
"
|
||||
"
|
||||
" Language: C - Maintainer: Bram Moolenaar <Bram@vim.org> - Last Change: 2009 Nov 17
|
||||
|
||||
" Quit when a (custom) syntax file was already loaded
|
||||
if exists("b:current_syntax")
|
||||
finish
|
||||
endif
|
||||
|
||||
" A bunch of useful C keywords
|
||||
syn keyword cStatement function globals global local instance
|
||||
syn keyword cRepeat while loop
|
||||
syn keyword cRepeat sin cos tan sqrt log log10 asin acos atan atan2 exp abs sqr min max sign rand floor ceil invsqrt freembuf memcpy memset stack_psuh stack_pop stack_peek stack_exch
|
||||
syn keyword cRepeat atomic_setifequal atomic_exch atomic_add atomic_set atomic_get convolve_c fft ifft fft_permute fft_ipermute fopen fread fgets fgetc fwrite fprintf fseek ftell feof fflush fclose
|
||||
syn keyword cRepeat gfx_lineto gfx_lineto gfx_rectto gfx_rect gfx_line gfx_gradrect gfx_muladdrect gfx_deltablit gfx_transformblit gfx_blurto gfx_drawnumber gfx_drawchar gfx_drawstr gfx_measurestr gfx_printf gfx_setpixel gfx_getpixel gfx_getimgdim gfx_setimgdim gfx_loadimg gfx_blit gfx_blitext gfx_blit gfx_setfont gfx_getfont gfx_init gfx_quit gfx_getchar
|
||||
syn keyword cRepeat mdct imdct sleep time time_precise tcp_listen tcp_listen_end tcp_connect tcp_send tcp_recv tcp_set_block tcp_close strlen
|
||||
syn keyword cRepeat strcat strcpy strcmp stricmp strncat strncpy strncmp strnicmp str_setlen strcpy_from strcpy_substr strcpy_substr str_getchar str_setchar str_getchar str_setchar str_insert str_delsub sprintf printf match matchi
|
||||
|
||||
syn keyword cTodo contained TODO FIXME XXX
|
||||
|
||||
" It's easy to accidentally add a space after a backslash that was intended
|
||||
" for line continuation. Some compilers allow it, which makes it
|
||||
" unpredicatable and should be avoided.
|
||||
syn match cBadContinuation contained "\\\s\+$"
|
||||
|
||||
" cCommentGroup allows adding matches for special things in comments
|
||||
syn cluster cCommentGroup contains=cTodo,cBadContinuation
|
||||
|
||||
" String and Character constants
|
||||
" Highlight special characters (those which have a backslash) differently
|
||||
syn match cSpecial display contained "\\\(x\x\+\|\o\{1,3}\|.\|$\)"
|
||||
if !exists("c_no_utf")
|
||||
syn match cSpecial display contained "\\\(u\x\{4}\|U\x\{8}\)"
|
||||
endif
|
||||
if exists("c_no_cformat")
|
||||
syn region cString start=+L\="+ skip=+\\\\\|\\"+ end=+"+ contains=cSpecial,@Spell
|
||||
" cCppString: same as cString, but ends at end of line
|
||||
syn region cCppString start=+L\="+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end='$' contains=cSpecial,@Spell
|
||||
else
|
||||
if !exists("c_no_c99") " ISO C99
|
||||
syn match cFormat display "%\(\d\+\$\)\=[-+' #0*]*\(\d*\|\*\|\*\d\+\$\)\(\.\(\d*\|\*\|\*\d\+\$\)\)\=\([hlLjzt]\|ll\|hh\)\=\([aAbdiuoxXDOUfFeEgGcCsSpn]\|\[\^\=.[^]]*\]\)" contained
|
||||
else
|
||||
syn match cFormat display "%\(\d\+\$\)\=[-+' #0*]*\(\d*\|\*\|\*\d\+\$\)\(\.\(\d*\|\*\|\*\d\+\$\)\)\=\([hlL]\|ll\)\=\([bdiuoxXDOUfeEgGcCsSpn]\|\[\^\=.[^]]*\]\)" contained
|
||||
endif
|
||||
syn match cFormat display "%%" contained
|
||||
syn region cString start=+L\="+ skip=+\\\\\|\\"+ end=+"+ contains=cSpecial,cFormat,@Spell
|
||||
" cCppString: same as cString, but ends at end of line
|
||||
syn region cCppString start=+L\="+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end='$' contains=cSpecial,cFormat,@Spell
|
||||
endif
|
||||
|
||||
syn match cCharacter "L\='[^\\]'"
|
||||
syn match cCharacter "L'[^']*'" contains=cSpecial
|
||||
syn match cCharacter "'[^']*'" contains=cSpecial
|
||||
if exists("c_gnu")
|
||||
syn match cSpecialError "L\='\\[^'\"?\\abefnrtv]'"
|
||||
syn match cSpecialCharacter "L\='\\['\"?\\abefnrtv]'"
|
||||
else
|
||||
syn match cSpecialError "L\='\\[^'\"?\\abfnrtv]'"
|
||||
syn match cSpecialCharacter "L\='\\['\"?\\abfnrtv]'"
|
||||
endif
|
||||
syn match cSpecialCharacter display "L\='\\\o\{1,3}'"
|
||||
syn match cSpecialCharacter display "'\\x\x\{1,2}'"
|
||||
syn match cSpecialCharacter display "L'\\x\x\+'"
|
||||
|
||||
"when wanted, highlight trailing white space
|
||||
if exists("c_space_errors")
|
||||
if !exists("c_no_trail_space_error")
|
||||
syn match cSpaceError display excludenl "\s\+$"
|
||||
endif
|
||||
if !exists("c_no_tab_space_error")
|
||||
syn match cSpaceError display " \+\t"me=e-1
|
||||
endif
|
||||
endif
|
||||
|
||||
" This should be before cErrInParen to avoid problems with #define ({ xxx })
|
||||
if exists("c_curly_error")
|
||||
syntax match cCurlyError "}"
|
||||
syntax region cBlock start="{" end="}" contains=ALLBUT,cCurlyError,@cParenGroup,cErrInParen,cCppParen,cErrInBracket,cCppBracket,cCppString,@Spell fold
|
||||
else
|
||||
syntax region cBlock start="{" end="}" transparent fold
|
||||
endif
|
||||
|
||||
"catch errors caused by wrong parenthesis and brackets
|
||||
" also accept <% for {, %> for }, <: for [ and :> for ] (C99)
|
||||
" But avoid matching <::.
|
||||
syn cluster cParenGroup contains=cParenError,cIncluded,cSpecial,cCommentSkip,cCommentString,cComment2String,@cCommentGroup,cCommentStartError,cUserCont,cUserLabel,cOctalZero,cCppOut,cCppOut2,cCppSkip,cFormat,cNumber,cFloat,cOctal,cOctalError,cNumbersCom
|
||||
if exists("c_no_curly_error")
|
||||
syn region cParen transparent start='(' end=')' contains=ALLBUT,@cParenGroup,cCppParen,cCppString,@Spell
|
||||
" cCppParen: same as cParen but ends at end-of-line; used in cDefine
|
||||
syn region cCppParen transparent start='(' skip='\\$' excludenl end=')' end='$' contained contains=ALLBUT,@cParenGroup,cParen,cString,@Spell
|
||||
syn match cParenError display ")"
|
||||
syn match cErrInParen display contained "^[{}]\|^<%\|^%>"
|
||||
elseif exists("c_no_bracket_error")
|
||||
syn region cParen transparent start='(' end=')' contains=ALLBUT,@cParenGroup,cCppParen,cCppString,@Spell
|
||||
" cCppParen: same as cParen but ends at end-of-line; used in cDefine
|
||||
syn region cCppParen transparent start='(' skip='\\$' excludenl end=')' end='$' contained contains=ALLBUT,@cParenGroup,cParen,cString,@Spell
|
||||
syn match cParenError display ")"
|
||||
syn match cErrInParen display contained "[{}]\|<%\|%>"
|
||||
else
|
||||
syn region cParen transparent start='(' end=')' contains=ALLBUT,@cParenGroup,cCppParen,cErrInBracket,cCppBracket,cCppString,@Spell
|
||||
" cCppParen: same as cParen but ends at end-of-line; used in cDefine
|
||||
syn region cCppParen transparent start='(' skip='\\$' excludenl end=')' end='$' contained contains=ALLBUT,@cParenGroup,cErrInBracket,cParen,cBracket,cString,@Spell
|
||||
syn match cParenError display "[\])]"
|
||||
syn match cErrInParen display contained "[\]{}]\|<%\|%>"
|
||||
syn region cBracket transparent start='\[\|<::\@!' end=']\|:>' contains=ALLBUT,@cParenGroup,cErrInParen,cCppParen,cCppBracket,cCppString,@Spell
|
||||
" cCppBracket: same as cParen but ends at end-of-line; used in cDefine
|
||||
syn region cCppBracket transparent start='\[\|<::\@!' skip='\\$' excludenl end=']\|:>' end='$' contained contains=ALLBUT,@cParenGroup,cErrInParen,cParen,cBracket,cString,@Spell
|
||||
syn match cErrInBracket display contained "[){}]\|<%\|%>"
|
||||
endif
|
||||
|
||||
"integer number, or floating point number without a dot and with "f".
|
||||
syn case ignore
|
||||
syn match cNumbers display transparent "\<\d\|\.\d" contains=cNumber,cFloat,cOctalError,cOctal
|
||||
" Same, but without octal error (for comments)
|
||||
syn match cNumbersCom display contained transparent "\<\d\|\.\d" contains=cNumber,cFloat,cOctal
|
||||
syn match cNumber display contained "\d\+\(u\=l\{0,2}\|ll\=u\)\>"
|
||||
"hex number
|
||||
syn match cNumber display contained "0x\x\+\(u\=l\{0,2}\|ll\=u\)\>"
|
||||
" Flag the first zero of an octal number as something special
|
||||
syn match cOctal display contained "0\o\+\(u\=l\{0,2}\|ll\=u\)\>" contains=cOctalZero
|
||||
syn match cOctalZero display contained "\<0"
|
||||
syn match cFloat display contained "\d\+f"
|
||||
"floating point number, with dot, optional exponent
|
||||
syn match cFloat display contained "\d\+\.\d*\(e[-+]\=\d\+\)\=[fl]\="
|
||||
"floating point number, starting with a dot, optional exponent
|
||||
syn match cFloat display contained "\.\d\+\(e[-+]\=\d\+\)\=[fl]\=\>"
|
||||
"floating point number, without dot, with exponent
|
||||
syn match cFloat display contained "\d\+e[-+]\=\d\+[fl]\=\>"
|
||||
if !exists("c_no_c99")
|
||||
"hexadecimal floating point number, optional leading digits, with dot, with exponent
|
||||
syn match cFloat display contained "0x\x*\.\x\+p[-+]\=\d\+[fl]\=\>"
|
||||
"hexadecimal floating point number, with leading digits, optional dot, with exponent
|
||||
syn match cFloat display contained "0x\x\+\.\=p[-+]\=\d\+[fl]\=\>"
|
||||
endif
|
||||
|
||||
" flag an octal number with wrong digits
|
||||
syn match cOctalError display contained "0\o*[89]\d*"
|
||||
syn case match
|
||||
|
||||
if exists("c_comment_strings")
|
||||
" A comment can contain cString, cCharacter and cNumber.
|
||||
" But a "*/" inside a cString in a cComment DOES end the comment! So we
|
||||
" need to use a special type of cString: cCommentString, which also ends on
|
||||
" "*/", and sees a "*" at the start of the line as comment again.
|
||||
" Unfortunately this doesn't very well work for // type of comments :-(
|
||||
syntax match cCommentSkip contained "^\s*\*\($\|\s\+\)"
|
||||
syntax region cCommentString contained start=+L\=\\\@<!"+ skip=+\\\\\|\\"+ end=+"+ end=+\*/+me=s-1 contains=cSpecial,cCommentSkip
|
||||
syntax region cComment2String contained start=+L\=\\\@<!"+ skip=+\\\\\|\\"+ end=+"+ end="$" contains=cSpecial
|
||||
syntax region cCommentL start="//" skip="\\$" end="$" keepend contains=@cCommentGroup,cComment2String,cCharacter,cNumbersCom,cSpaceError,@Spell
|
||||
if exists("c_no_comment_fold")
|
||||
" Use "extend" here to have preprocessor lines not terminate halfway a
|
||||
" comment.
|
||||
syntax region cComment matchgroup=cCommentStart start="/\*" end="\*/" contains=@cCommentGroup,cCommentStartError,cCommentString,cCharacter,cNumbersCom,cSpaceError,@Spell extend
|
||||
else
|
||||
syntax region cComment matchgroup=cCommentStart start="/\*" end="\*/" contains=@cCommentGroup,cCommentStartError,cCommentString,cCharacter,cNumbersCom,cSpaceError,@Spell fold extend
|
||||
endif
|
||||
else
|
||||
syn region cCommentL start="//" skip="\\$" end="$" keepend contains=@cCommentGroup,cSpaceError,@Spell
|
||||
if exists("c_no_comment_fold")
|
||||
syn region cComment matchgroup=cCommentStart start="/\*" end="\*/" contains=@cCommentGroup,cCommentStartError,cSpaceError,@Spell extend
|
||||
else
|
||||
syn region cComment matchgroup=cCommentStart start="/\*" end="\*/" contains=@cCommentGroup,cCommentStartError,cSpaceError,@Spell fold extend
|
||||
endif
|
||||
endif
|
||||
" keep a // comment separately, it terminates a preproc. conditional
|
||||
syntax match cCommentError display "\*/"
|
||||
syntax match cCommentStartError display "/\*"me=e-1 contained
|
||||
|
||||
syn keyword cOperator sizeof
|
||||
if exists("c_gnu")
|
||||
syn keyword cStatement __asm__
|
||||
syn keyword cOperator typeof __real__ __imag__
|
||||
endif
|
||||
syn keyword cType int long short char void
|
||||
syn keyword cType signed unsigned float double
|
||||
if !exists("c_no_ansi") || exists("c_ansi_typedefs")
|
||||
syn keyword cType size_t ssize_t off_t wchar_t ptrdiff_t sig_atomic_t fpos_t
|
||||
syn keyword cType clock_t time_t va_list jmp_buf FILE DIR div_t ldiv_t
|
||||
syn keyword cType mbstate_t wctrans_t wint_t wctype_t
|
||||
endif
|
||||
if !exists("c_no_c99") " ISO C99
|
||||
syn keyword cType bool complex
|
||||
syn keyword cType int8_t int16_t int32_t int64_t
|
||||
syn keyword cType uint8_t uint16_t uint32_t uint64_t
|
||||
syn keyword cType int_least8_t int_least16_t int_least32_t int_least64_t
|
||||
syn keyword cType uint_least8_t uint_least16_t uint_least32_t uint_least64_t
|
||||
syn keyword cType int_fast8_t int_fast16_t int_fast32_t int_fast64_t
|
||||
syn keyword cType uint_fast8_t uint_fast16_t uint_fast32_t uint_fast64_t
|
||||
syn keyword cType intptr_t uintptr_t
|
||||
syn keyword cType intmax_t uintmax_t
|
||||
endif
|
||||
if exists("c_gnu")
|
||||
syn keyword cType __label__ __complex__ __volatile__
|
||||
endif
|
||||
|
||||
syn keyword cStructure struct union enum typedef
|
||||
syn keyword cStorageClass static register auto volatile extern const
|
||||
if exists("c_gnu")
|
||||
syn keyword cStorageClass inline __attribute__
|
||||
endif
|
||||
if !exists("c_no_c99")
|
||||
syn keyword cStorageClass inline restrict
|
||||
endif
|
||||
|
||||
if !exists("c_no_ansi") || exists("c_ansi_constants") || exists("c_gnu")
|
||||
if exists("c_gnu")
|
||||
syn keyword cConstant __GNUC__ __FUNCTION__ __PRETTY_FUNCTION__ __func__
|
||||
endif
|
||||
syn keyword cConstant __LINE__ __FILE__ __DATE__ __TIME__ __STDC__
|
||||
syn keyword cConstant __STDC_VERSION__
|
||||
syn keyword cConstant CHAR_BIT MB_LEN_MAX MB_CUR_MAX
|
||||
syn keyword cConstant UCHAR_MAX UINT_MAX ULONG_MAX USHRT_MAX
|
||||
syn keyword cConstant CHAR_MIN INT_MIN LONG_MIN SHRT_MIN
|
||||
syn keyword cConstant CHAR_MAX INT_MAX LONG_MAX SHRT_MAX
|
||||
syn keyword cConstant SCHAR_MIN SINT_MIN SLONG_MIN SSHRT_MIN
|
||||
syn keyword cConstant SCHAR_MAX SINT_MAX SLONG_MAX SSHRT_MAX
|
||||
if !exists("c_no_c99")
|
||||
syn keyword cConstant __func__
|
||||
syn keyword cConstant LLONG_MIN LLONG_MAX ULLONG_MAX
|
||||
syn keyword cConstant INT8_MIN INT16_MIN INT32_MIN INT64_MIN
|
||||
syn keyword cConstant INT8_MAX INT16_MAX INT32_MAX INT64_MAX
|
||||
syn keyword cConstant UINT8_MAX UINT16_MAX UINT32_MAX UINT64_MAX
|
||||
syn keyword cConstant INT_LEAST8_MIN INT_LEAST16_MIN INT_LEAST32_MIN INT_LEAST64_MIN
|
||||
syn keyword cConstant INT_LEAST8_MAX INT_LEAST16_MAX INT_LEAST32_MAX INT_LEAST64_MAX
|
||||
syn keyword cConstant UINT_LEAST8_MAX UINT_LEAST16_MAX UINT_LEAST32_MAX UINT_LEAST64_MAX
|
||||
syn keyword cConstant INT_FAST8_MIN INT_FAST16_MIN INT_FAST32_MIN INT_FAST64_MIN
|
||||
syn keyword cConstant INT_FAST8_MAX INT_FAST16_MAX INT_FAST32_MAX INT_FAST64_MAX
|
||||
syn keyword cConstant UINT_FAST8_MAX UINT_FAST16_MAX UINT_FAST32_MAX UINT_FAST64_MAX
|
||||
syn keyword cConstant INTPTR_MIN INTPTR_MAX UINTPTR_MAX
|
||||
syn keyword cConstant INTMAX_MIN INTMAX_MAX UINTMAX_MAX
|
||||
syn keyword cConstant PTRDIFF_MIN PTRDIFF_MAX SIG_ATOMIC_MIN SIG_ATOMIC_MAX
|
||||
syn keyword cConstant SIZE_MAX WCHAR_MIN WCHAR_MAX WINT_MIN WINT_MAX
|
||||
endif
|
||||
syn keyword cConstant FLT_RADIX FLT_ROUNDS
|
||||
syn keyword cConstant FLT_DIG FLT_MANT_DIG FLT_EPSILON
|
||||
syn keyword cConstant DBL_DIG DBL_MANT_DIG DBL_EPSILON
|
||||
syn keyword cConstant LDBL_DIG LDBL_MANT_DIG LDBL_EPSILON
|
||||
syn keyword cConstant FLT_MIN FLT_MAX FLT_MIN_EXP FLT_MAX_EXP
|
||||
syn keyword cConstant FLT_MIN_10_EXP FLT_MAX_10_EXP
|
||||
syn keyword cConstant DBL_MIN DBL_MAX DBL_MIN_EXP DBL_MAX_EXP
|
||||
syn keyword cConstant DBL_MIN_10_EXP DBL_MAX_10_EXP
|
||||
syn keyword cConstant LDBL_MIN LDBL_MAX LDBL_MIN_EXP LDBL_MAX_EXP
|
||||
syn keyword cConstant LDBL_MIN_10_EXP LDBL_MAX_10_EXP
|
||||
syn keyword cConstant HUGE_VAL CLOCKS_PER_SEC NULL
|
||||
syn keyword cConstant LC_ALL LC_COLLATE LC_CTYPE LC_MONETARY
|
||||
syn keyword cConstant LC_NUMERIC LC_TIME
|
||||
syn keyword cConstant SIG_DFL SIG_ERR SIG_IGN
|
||||
syn keyword cConstant SIGABRT SIGFPE SIGILL SIGHUP SIGINT SIGSEGV SIGTERM
|
||||
" Add POSIX signals as well...
|
||||
syn keyword cConstant SIGABRT SIGALRM SIGCHLD SIGCONT SIGFPE SIGHUP
|
||||
syn keyword cConstant SIGILL SIGINT SIGKILL SIGPIPE SIGQUIT SIGSEGV
|
||||
syn keyword cConstant SIGSTOP SIGTERM SIGTRAP SIGTSTP SIGTTIN SIGTTOU
|
||||
syn keyword cConstant SIGUSR1 SIGUSR2
|
||||
syn keyword cConstant _IOFBF _IOLBF _IONBF BUFSIZ EOF WEOF
|
||||
syn keyword cConstant FOPEN_MAX FILENAME_MAX L_tmpnam
|
||||
syn keyword cConstant SEEK_CUR SEEK_END SEEK_SET
|
||||
syn keyword cConstant TMP_MAX stderr stdin stdout
|
||||
syn keyword cConstant EXIT_FAILURE EXIT_SUCCESS RAND_MAX
|
||||
" Add POSIX errors as well
|
||||
syn keyword cConstant E2BIG EACCES EAGAIN EBADF EBADMSG EBUSY
|
||||
syn keyword cConstant ECANCELED ECHILD EDEADLK EDOM EEXIST EFAULT
|
||||
syn keyword cConstant EFBIG EILSEQ EINPROGRESS EINTR EINVAL EIO EISDIR
|
||||
syn keyword cConstant EMFILE EMLINK EMSGSIZE ENAMETOOLONG ENFILE ENODEV
|
||||
syn keyword cConstant ENOENT ENOEXEC ENOLCK ENOMEM ENOSPC ENOSYS
|
||||
syn keyword cConstant ENOTDIR ENOTEMPTY ENOTSUP ENOTTY ENXIO EPERM
|
||||
syn keyword cConstant EPIPE ERANGE EROFS ESPIPE ESRCH ETIMEDOUT EXDEV
|
||||
" math.h
|
||||
syn keyword cConstant M_E M_LOG2E M_LOG10E M_LN2 M_LN10 M_PI M_PI_2 M_PI_4
|
||||
syn keyword cConstant M_1_PI M_2_PI M_2_SQRTPI M_SQRT2 M_SQRT1_2
|
||||
endif
|
||||
if !exists("c_no_c99") " ISO C99
|
||||
syn keyword cConstant true false
|
||||
endif
|
||||
|
||||
" Accept %: for # (C99)
|
||||
syn region cPreCondit start="^\s*\(%:\|#\)\s*\(if\|ifdef\|ifndef\|elif\)\>" skip="\\$" end="$" keepend contains=cComment,cCommentL,cCppString,cCharacter,cCppParen,cParenError,cNumbers,cCommentError,cSpaceError
|
||||
syn match cPreCondit display "^\s*\(%:\|#\)\s*\(else\|endif\)\>"
|
||||
if !exists("c_no_if0")
|
||||
if !exists("c_no_if0_fold")
|
||||
syn region cCppOut start="^\s*\(%:\|#\)\s*if\s\+0\+\>" end=".\@=\|$" contains=cCppOut2 fold
|
||||
else
|
||||
syn region cCppOut start="^\s*\(%:\|#\)\s*if\s\+0\+\>" end=".\@=\|$" contains=cCppOut2
|
||||
endif
|
||||
syn region cCppOut2 contained start="0" end="^\s*\(%:\|#\)\s*\(endif\>\|else\>\|elif\>\)" contains=cSpaceError,cCppSkip
|
||||
syn region cCppSkip contained start="^\s*\(%:\|#\)\s*\(if\>\|ifdef\>\|ifndef\>\)" skip="\\$" end="^\s*\(%:\|#\)\s*endif\>" contains=cSpaceError,cCppSkip
|
||||
endif
|
||||
syn region cIncluded display contained start=+"+ skip=+\\\\\|\\"+ end=+"+
|
||||
syn match cIncluded display contained "<[^>]*>"
|
||||
syn match cInclude display "^\s*\(%:\|#\)\s*include\>\s*["<]" contains=cIncluded
|
||||
"syn match cLineSkip "\\$"
|
||||
syn cluster cPreProcGroup contains=cPreCondit,cIncluded,cInclude,cDefine,cErrInParen,cErrInBracket,cUserLabel,cSpecial,cOctalZero,cCppOut,cCppOut2,cCppSkip,cFormat,cNumber,cFloat,cOctal,cOctalError,cNumbersCom,cString,cCommentSkip,cCommentString,cComment2String,@cCommentGroup,cCommentStartError,cParen,cBracket,cMulti
|
||||
syn region cDefine start="^\s*\(%:\|#\)\s*\(define\|undef\)\>" skip="\\$" end="$" keepend contains=ALLBUT,@cPreProcGroup,@Spell
|
||||
syn region cPreProc start="^\s*\(%:\|#\)\s*\(pragma\>\|line\>\|warning\>\|warn\>\|error\>\)" skip="\\$" end="$" keepend contains=ALLBUT,@cPreProcGroup,@Spell
|
||||
|
||||
" Highlight User Labels
|
||||
syn cluster cMultiGroup contains=cIncluded,cSpecial,cCommentSkip,cCommentString,cComment2String,@cCommentGroup,cCommentStartError,cUserCont,cUserLabel,cOctalZero,cCppOut,cCppOut2,cCppSkip,cFormat,cNumber,cFloat,cOctal,cOctalError,cNumbersCom,cCppParen,cCppBracket,cCppString
|
||||
syn region cMulti transparent start='?' skip='::' end=':' end=')' end=';' contains=ALLBUT,@cMultiGroup,@Spell
|
||||
" Avoid matching foo::bar() in C++ by requiring that the next char is not ':'
|
||||
|
||||
syn match cUserLabel display "\I\i*" contained
|
||||
|
||||
|
||||
if exists("c_minlines")
|
||||
let b:c_minlines = c_minlines
|
||||
else
|
||||
if !exists("c_no_if0")
|
||||
let b:c_minlines = 50 " #if 0 constructs can be long
|
||||
else
|
||||
let b:c_minlines = 15 " mostly for () constructs
|
||||
endif
|
||||
endif
|
||||
if exists("c_curly_error")
|
||||
syn sync fromstart
|
||||
else
|
||||
exec "syn sync ccomment cComment minlines=" . b:c_minlines
|
||||
endif
|
||||
|
||||
" Define the default highlighting.
|
||||
" Only used when an item doesn't have highlighting yet
|
||||
hi def link cFormat cSpecial
|
||||
hi def link cCppString cString
|
||||
hi def link cCommentL cComment
|
||||
hi def link cCommentStart cComment
|
||||
hi def link cUserLabel Label
|
||||
hi def link cRepeat Repeat
|
||||
hi def link cCharacter Character
|
||||
hi def link cSpecialCharacter cSpecial
|
||||
hi def link cNumber Number
|
||||
hi def link cOctal Number
|
||||
hi def link cOctalZero PreProc " link this to Error if you want
|
||||
hi def link cFloat Float
|
||||
hi def link cOctalError cError
|
||||
hi def link cParenError cError
|
||||
hi def link cErrInParen cError
|
||||
hi def link cErrInBracket cError
|
||||
hi def link cCommentError cError
|
||||
hi def link cCommentStartError cError
|
||||
hi def link cSpaceError cError
|
||||
hi def link cSpecialError cError
|
||||
hi def link cCurlyError cError
|
||||
hi def link cOperator Operator
|
||||
hi def link cStructure Structure
|
||||
hi def link cStorageClass StorageClass
|
||||
hi def link cInclude Include
|
||||
hi def link cPreProc PreProc
|
||||
hi def link cDefine Macro
|
||||
hi def link cIncluded cString
|
||||
hi def link cError Error
|
||||
hi def link cStatement Statement
|
||||
hi def link cPreCondit PreCondit
|
||||
hi def link cType Type
|
||||
hi def link cConstant Constant
|
||||
hi def link cCommentString cString
|
||||
hi def link cComment2String cString
|
||||
hi def link cCommentSkip cComment
|
||||
hi def link cString String
|
||||
hi def link cComment Comment
|
||||
hi def link cSpecial SpecialChar
|
||||
hi def link cTodo Todo
|
||||
hi def link cBadContinuation Error
|
||||
hi def link cCppSkip cCppOut
|
||||
hi def link cCppOut2 cCppOut
|
||||
hi def link cCppOut Comment
|
||||
|
||||
let b:current_syntax = "eel2"
|
||||
|
||||
" vim: ts=8
|
||||
376
oversampling/WDL/eel2/eel2.y
Normal file
376
oversampling/WDL/eel2/eel2.y
Normal file
@@ -0,0 +1,376 @@
|
||||
%pure-parser
|
||||
%name-prefix="nseel"
|
||||
%parse-param { compileContext* context }
|
||||
%lex-param { void* scanner }
|
||||
|
||||
|
||||
/* this will prevent y.tab.c from ever calling yydestruct(), since we do not use it and it is a waste */
|
||||
%destructor {
|
||||
#define yydestruct(a,b,c,d,e)
|
||||
} VALUE
|
||||
|
||||
|
||||
%{
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "y.tab.h"
|
||||
#include "ns-eel-int.h"
|
||||
|
||||
#define scanner context->scanner
|
||||
#define YY_(x) ("")
|
||||
|
||||
%}
|
||||
|
||||
%token VALUE IDENTIFIER TOKEN_SHL TOKEN_SHR
|
||||
%token TOKEN_LTE TOKEN_GTE TOKEN_EQ TOKEN_EQ_EXACT TOKEN_NE TOKEN_NE_EXACT TOKEN_LOGICAL_AND TOKEN_LOGICAL_OR
|
||||
%token TOKEN_ADD_OP TOKEN_SUB_OP TOKEN_MOD_OP TOKEN_OR_OP TOKEN_AND_OP TOKEN_XOR_OP TOKEN_DIV_OP TOKEN_MUL_OP TOKEN_POW_OP
|
||||
%token STRING_LITERAL STRING_IDENTIFIER
|
||||
%expect 75
|
||||
%start program
|
||||
|
||||
%%
|
||||
|
||||
more_params:
|
||||
expression
|
||||
| expression ',' more_params
|
||||
{
|
||||
$$ = nseel_createMoreParametersOpcode(context,$1,$3);
|
||||
}
|
||||
;
|
||||
|
||||
string:
|
||||
STRING_LITERAL
|
||||
| STRING_LITERAL string
|
||||
{
|
||||
((struct eelStringSegmentRec *)$1)->_next = (struct eelStringSegmentRec *)$2;
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
assignable_value:
|
||||
IDENTIFIER
|
||||
{
|
||||
if (!($$ = nseel_resolve_named_symbol(context, $1, -1, NULL))) /* convert from purely named to namespace-relative, etc */
|
||||
{
|
||||
yyerror(&yyloc, context, "");
|
||||
YYERROR;
|
||||
}
|
||||
}
|
||||
/* we used to have VALUE in here rather than rvalue, to allow 1=1 1+=2 etc, but silly to,
|
||||
though this breaks Vmorph, which does 1=1 for a nop, and Jonas DrumReaplacer, which does x = 0 = y = 0 */
|
||||
| '(' expression ')'
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
| IDENTIFIER '(' expression ')' '(' expression ')'
|
||||
{
|
||||
int err;
|
||||
if (!($$ = nseel_setCompiledFunctionCallParameters(context,$1, $3, 0, 0, $6, &err)))
|
||||
{
|
||||
if (err == -1) yyerror(&yylsp[-2], context, "");
|
||||
else if (err == 0) yyerror(&yylsp[-6], context, "");
|
||||
else yyerror(&yylsp[-3], context, ""); // parameter count wrong
|
||||
|
||||
YYERROR;
|
||||
}
|
||||
}
|
||||
| IDENTIFIER '(' expression ')'
|
||||
{
|
||||
int err;
|
||||
if (!($$ = nseel_setCompiledFunctionCallParameters(context,$1, $3, 0, 0, 0, &err)))
|
||||
{
|
||||
if (err == 0) yyerror(&yylsp[-3], context, "");
|
||||
else yyerror(&yylsp[0], context, ""); // parameter count wrong
|
||||
YYERROR;
|
||||
}
|
||||
}
|
||||
| IDENTIFIER '(' ')'
|
||||
{
|
||||
int err;
|
||||
if (!($$ = nseel_setCompiledFunctionCallParameters(context,$1, nseel_createCompiledValue(context,0.0), 0, 0, 0,&err)))
|
||||
{
|
||||
if (err == 0) yyerror(&yylsp[-2], context, ""); // function not found
|
||||
else yyerror(&yylsp[0], context, ""); // parameter count wrong
|
||||
YYERROR;
|
||||
}
|
||||
}
|
||||
| IDENTIFIER '(' expression ',' expression ')'
|
||||
{
|
||||
int err;
|
||||
if (!($$ = nseel_setCompiledFunctionCallParameters(context,$1, $3, $5, 0, 0,&err)))
|
||||
{
|
||||
if (err == 0) yyerror(&yylsp[-5], context, "");
|
||||
else if (err == 2) yyerror(&yylsp[0], context, ""); // needs more than 2 parameters
|
||||
else yyerror(&yylsp[-2], context, ""); // less than 2
|
||||
YYERROR;
|
||||
}
|
||||
}
|
||||
| IDENTIFIER '(' expression ',' expression ',' more_params ')'
|
||||
{
|
||||
int err;
|
||||
if (!($$ = nseel_setCompiledFunctionCallParameters(context,$1, $3, $5, $7, 0, &err)))
|
||||
{
|
||||
if (err == 0) yyerror(&yylsp[-7], context, "");
|
||||
else if (err==2) yyerror(&yylsp[0], context, ""); // needs more parameters
|
||||
else if (err==4) yyerror(&yylsp[-4], context, ""); // needs single parameter
|
||||
else yyerror(&yylsp[-2], context, ""); // less parm
|
||||
YYERROR;
|
||||
}
|
||||
}
|
||||
| rvalue '[' ']'
|
||||
{
|
||||
$$ = nseel_createMemoryAccess(context,$1,0);
|
||||
}
|
||||
| rvalue '[' expression ']'
|
||||
{
|
||||
$$ = nseel_createMemoryAccess(context,$1,$3);
|
||||
}
|
||||
;
|
||||
|
||||
rvalue:
|
||||
VALUE
|
||||
| STRING_IDENTIFIER
|
||||
| string
|
||||
{
|
||||
$$ = nseel_eelMakeOpcodeFromStringSegments(context,(struct eelStringSegmentRec *)$1);
|
||||
}
|
||||
| assignable_value
|
||||
;
|
||||
|
||||
|
||||
assignment:
|
||||
rvalue
|
||||
| assignable_value '=' if_else_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_ASSIGN,2,$1,$3);
|
||||
}
|
||||
| assignable_value TOKEN_ADD_OP if_else_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_ADD_OP,2,$1,$3);
|
||||
}
|
||||
| assignable_value TOKEN_SUB_OP if_else_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_SUB_OP,2,$1,$3);
|
||||
}
|
||||
| assignable_value TOKEN_MOD_OP if_else_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_MOD_OP,2,$1,$3);
|
||||
}
|
||||
| assignable_value TOKEN_OR_OP if_else_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_OR_OP,2,$1,$3);
|
||||
}
|
||||
| assignable_value TOKEN_AND_OP if_else_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_AND_OP,2,$1,$3);
|
||||
}
|
||||
| assignable_value TOKEN_XOR_OP if_else_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_XOR_OP,2,$1,$3);
|
||||
}
|
||||
| assignable_value TOKEN_DIV_OP if_else_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_DIV_OP,2,$1,$3);
|
||||
}
|
||||
| assignable_value TOKEN_MUL_OP if_else_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_MUL_OP,2,$1,$3);
|
||||
}
|
||||
| assignable_value TOKEN_POW_OP if_else_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_POW_OP,2,$1,$3);
|
||||
}
|
||||
| STRING_IDENTIFIER '=' if_else_expr
|
||||
{
|
||||
$$ = nseel_createFunctionByName(context,"strcpy",2,$1,$3,NULL);
|
||||
}
|
||||
| STRING_IDENTIFIER TOKEN_ADD_OP if_else_expr
|
||||
{
|
||||
$$ = nseel_createFunctionByName(context,"strcat",2,$1,$3,NULL);
|
||||
}
|
||||
;
|
||||
|
||||
unary_expr:
|
||||
assignment
|
||||
| '+' unary_expr
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
| '-' unary_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_UMINUS,1,$2,0);
|
||||
}
|
||||
| '!' unary_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_NOT,1,$2,0);
|
||||
}
|
||||
;
|
||||
|
||||
pow_expr:
|
||||
unary_expr
|
||||
| pow_expr '^' unary_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_POW,2,$1,$3);
|
||||
}
|
||||
;
|
||||
|
||||
mod_expr:
|
||||
pow_expr
|
||||
| mod_expr '%' pow_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_MOD,2,$1,$3);
|
||||
}
|
||||
| mod_expr TOKEN_SHL pow_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_SHL,2,$1,$3);
|
||||
}
|
||||
| mod_expr TOKEN_SHR pow_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_SHR,2,$1,$3);
|
||||
}
|
||||
;
|
||||
|
||||
div_expr:
|
||||
mod_expr
|
||||
| div_expr '/' mod_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_DIVIDE,2,$1,$3);
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
mul_expr:
|
||||
div_expr
|
||||
| mul_expr '*' div_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_MULTIPLY,2,$1,$3);
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
sub_expr:
|
||||
mul_expr
|
||||
| sub_expr '-' mul_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_SUB,2,$1,$3);
|
||||
}
|
||||
;
|
||||
|
||||
add_expr:
|
||||
sub_expr
|
||||
| add_expr '+' sub_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_ADD,2,$1,$3);
|
||||
}
|
||||
;
|
||||
|
||||
andor_expr:
|
||||
add_expr
|
||||
| andor_expr '&' add_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_AND,2,$1,$3);
|
||||
}
|
||||
| andor_expr '|' add_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_OR,2,$1,$3);
|
||||
}
|
||||
| andor_expr '~' add_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_XOR,2,$1,$3);
|
||||
}
|
||||
;
|
||||
|
||||
cmp_expr:
|
||||
andor_expr
|
||||
| cmp_expr '<' andor_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_LT,2,$1,$3);
|
||||
}
|
||||
| cmp_expr '>' andor_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_GT,2,$1,$3);
|
||||
}
|
||||
| cmp_expr TOKEN_LTE andor_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_LTE,2,$1,$3);
|
||||
}
|
||||
| cmp_expr TOKEN_GTE andor_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_GTE,2,$1,$3);
|
||||
}
|
||||
| cmp_expr TOKEN_EQ andor_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_EQ,2,$1,$3);
|
||||
}
|
||||
| cmp_expr TOKEN_EQ_EXACT andor_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_EQ_EXACT,2,$1,$3);
|
||||
}
|
||||
| cmp_expr TOKEN_NE andor_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_NE,2,$1,$3);
|
||||
}
|
||||
| cmp_expr TOKEN_NE_EXACT andor_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_NE_EXACT,2,$1,$3);
|
||||
}
|
||||
;
|
||||
|
||||
logical_and_or_expr:
|
||||
cmp_expr
|
||||
| logical_and_or_expr TOKEN_LOGICAL_AND cmp_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_LOGICAL_AND,2,$1,$3);
|
||||
}
|
||||
| logical_and_or_expr TOKEN_LOGICAL_OR cmp_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_LOGICAL_OR,2,$1,$3);
|
||||
}
|
||||
;
|
||||
|
||||
if_else_expr:
|
||||
logical_and_or_expr
|
||||
| logical_and_or_expr '?' if_else_expr ':' if_else_expr
|
||||
{
|
||||
$$ = nseel_createIfElse(context, $1, $3, $5);
|
||||
}
|
||||
| logical_and_or_expr '?' ':' if_else_expr
|
||||
{
|
||||
$$ = nseel_createIfElse(context, $1, 0, $4);
|
||||
}
|
||||
| logical_and_or_expr '?' if_else_expr
|
||||
{
|
||||
$$ = nseel_createIfElse(context, $1, $3, 0);
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
expression:
|
||||
if_else_expr
|
||||
| expression ';' if_else_expr
|
||||
{
|
||||
$$ = nseel_createSimpleCompiledFunction(context,FN_JOIN_STATEMENTS,2,$1,$3);
|
||||
}
|
||||
| expression ';'
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
program:
|
||||
expression
|
||||
{
|
||||
if (@1.first_line) { }
|
||||
context->result = $1;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
%%
|
||||
71
oversampling/WDL/eel2/eel_atomic.h
Normal file
71
oversampling/WDL/eel2/eel_atomic.h
Normal file
@@ -0,0 +1,71 @@
|
||||
#ifndef __EEL_ATOMIC_H__
|
||||
#define __EEL_ATOMIC_H__
|
||||
|
||||
// requires these to be defined
|
||||
//#define EEL_ATOMIC_SET_SCOPE(opaque) WDL_Mutex *mutex = (opaque?&((effectProcessor *)opaque)->m_atomic_mutex:&atomic_mutex);
|
||||
//#define EEL_ATOMIC_ENTER mutex->Enter()
|
||||
//#define EEL_ATOMIC_LEAVE mutex->Leave()
|
||||
|
||||
static EEL_F NSEEL_CGEN_CALL atomic_setifeq(void *opaque, EEL_F *a, EEL_F *cmp, EEL_F *nd)
|
||||
{
|
||||
EEL_F ret;
|
||||
EEL_ATOMIC_SET_SCOPE(opaque)
|
||||
EEL_ATOMIC_ENTER;
|
||||
ret = *a;
|
||||
if (fabs(ret - *cmp) < NSEEL_CLOSEFACTOR) *a = *nd;
|
||||
EEL_ATOMIC_LEAVE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static EEL_F NSEEL_CGEN_CALL atomic_exch(void *opaque, EEL_F *a, EEL_F *b)
|
||||
{
|
||||
EEL_F tmp;
|
||||
EEL_ATOMIC_SET_SCOPE(opaque)
|
||||
EEL_ATOMIC_ENTER;
|
||||
tmp = *b;
|
||||
*b = *a;
|
||||
*a = tmp;
|
||||
EEL_ATOMIC_LEAVE;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static EEL_F NSEEL_CGEN_CALL atomic_add(void *opaque, EEL_F *a, EEL_F *b)
|
||||
{
|
||||
EEL_F tmp;
|
||||
EEL_ATOMIC_SET_SCOPE(opaque)
|
||||
EEL_ATOMIC_ENTER;
|
||||
tmp = (*a += *b);
|
||||
EEL_ATOMIC_LEAVE;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static EEL_F NSEEL_CGEN_CALL atomic_set(void *opaque, EEL_F *a, EEL_F *b)
|
||||
{
|
||||
EEL_F tmp;
|
||||
EEL_ATOMIC_SET_SCOPE(opaque)
|
||||
EEL_ATOMIC_ENTER;
|
||||
tmp = *a = *b;
|
||||
EEL_ATOMIC_LEAVE;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static EEL_F NSEEL_CGEN_CALL atomic_get(void *opaque, EEL_F *a)
|
||||
{
|
||||
EEL_F tmp;
|
||||
EEL_ATOMIC_SET_SCOPE(opaque)
|
||||
EEL_ATOMIC_ENTER;
|
||||
tmp = *a;
|
||||
EEL_ATOMIC_LEAVE;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static void EEL_atomic_register()
|
||||
{
|
||||
NSEEL_addfunc_retval("atomic_setifequal",3, NSEEL_PProc_THIS, &atomic_setifeq);
|
||||
NSEEL_addfunc_retval("atomic_exch",2, NSEEL_PProc_THIS, &atomic_exch);
|
||||
NSEEL_addfunc_retval("atomic_add",2, NSEEL_PProc_THIS, &atomic_add);
|
||||
NSEEL_addfunc_retval("atomic_set",2, NSEEL_PProc_THIS, &atomic_set);
|
||||
NSEEL_addfunc_retval("atomic_get",1, NSEEL_PProc_THIS, &atomic_get);
|
||||
}
|
||||
|
||||
#endif
|
||||
81
oversampling/WDL/eel2/eel_eval.h
Normal file
81
oversampling/WDL/eel2/eel_eval.h
Normal file
@@ -0,0 +1,81 @@
|
||||
#ifndef _EEL_EVAL_H_
|
||||
#define _EEL_EVAL_H_
|
||||
|
||||
#ifndef EEL_EVAL_GET_CACHED
|
||||
#define EEL_EVAL_GET_CACHED(str, ch) (NULL)
|
||||
#endif
|
||||
|
||||
#ifndef EEL_EVAL_SET_CACHED
|
||||
#define EEL_EVAL_SET_CACHED(sv, ch) { NSEEL_code_free(ch); free(sv); }
|
||||
#endif
|
||||
|
||||
#ifndef EEL_EVAL_SCOPE_ENTER
|
||||
#define EEL_EVAL_SCOPE_ENTER 1
|
||||
#define EEL_EVAL_SCOPE_LEAVE
|
||||
#endif
|
||||
|
||||
static EEL_F NSEEL_CGEN_CALL _eel_eval(void *opaque, EEL_F *s)
|
||||
{
|
||||
NSEEL_VMCTX r = EEL_EVAL_GET_VMCTX(opaque);
|
||||
NSEEL_CODEHANDLE ch = NULL;
|
||||
char *sv=NULL;
|
||||
if (r)
|
||||
{
|
||||
EEL_STRING_MUTEXLOCK_SCOPE
|
||||
const char *str=EEL_STRING_GET_FOR_INDEX(*s,NULL);
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
if (!str)
|
||||
{
|
||||
EEL_STRING_DEBUGOUT("eval() passed invalid string handle %f",*s);
|
||||
}
|
||||
#endif
|
||||
if (str && *str)
|
||||
{
|
||||
sv=EEL_EVAL_GET_CACHED(str,ch);
|
||||
if (!sv) sv=strdup(str);
|
||||
}
|
||||
}
|
||||
if (sv)
|
||||
{
|
||||
if (!ch) ch = NSEEL_code_compile(r,sv,0);
|
||||
if (ch)
|
||||
{
|
||||
if (EEL_EVAL_SCOPE_ENTER)
|
||||
{
|
||||
NSEEL_code_execute(ch);
|
||||
EEL_EVAL_SCOPE_LEAVE
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
EEL_STRING_DEBUGOUT("eval() reentrancy limit reached");
|
||||
#endif
|
||||
}
|
||||
|
||||
EEL_EVAL_SET_CACHED(sv,ch);
|
||||
return 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
const char *err=NSEEL_code_getcodeerror(r);
|
||||
if (err) EEL_STRING_DEBUGOUT("eval() error: %s",err);
|
||||
#endif
|
||||
}
|
||||
free(sv);
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
void EEL_eval_register()
|
||||
{
|
||||
NSEEL_addfunc_retval("eval",1,NSEEL_PProc_THIS,&_eel_eval);
|
||||
}
|
||||
|
||||
#ifdef EEL_WANT_DOCUMENTATION
|
||||
static const char *eel_eval_function_reference =
|
||||
"eval\t\"code\"\tExecutes code passed in. Code can use functions, but functions created in code can't be used elsewhere.\0"
|
||||
;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
396
oversampling/WDL/eel2/eel_fft.h
Normal file
396
oversampling/WDL/eel2/eel_fft.h
Normal file
@@ -0,0 +1,396 @@
|
||||
#ifndef __EEL_FFT_H_
|
||||
#define __EEL_FFT_H_
|
||||
|
||||
#include "../fft.h"
|
||||
#if WDL_FFT_REALSIZE != EEL_F_SIZE
|
||||
#error WDL_FFT_REALSIZE -- EEL_F_SIZE size mismatch
|
||||
#endif
|
||||
|
||||
#ifndef EEL_FFT_MINBITLEN
|
||||
#define EEL_FFT_MINBITLEN 4
|
||||
#endif
|
||||
|
||||
#ifndef EEL_FFT_MAXBITLEN
|
||||
#define EEL_FFT_MAXBITLEN 15
|
||||
#endif
|
||||
|
||||
#ifndef EEL_FFT_MINBITLEN_REORDER
|
||||
#define EEL_FFT_MINBITLEN_REORDER (EEL_FFT_MINBITLEN-1)
|
||||
#endif
|
||||
|
||||
//#define EEL_SUPER_FAST_FFT_REORDERING // quite a bit faster (50-100%) than "normal", but uses a 256kb lookup
|
||||
//#define EEL_SLOW_FFT_REORDERING // 20%-80% slower than normal, alloca() use, no reason to ever use this
|
||||
|
||||
#ifdef EEL_SUPER_FAST_FFT_REORDERING
|
||||
static int *fft_reorder_table_for_bitsize(int bitsz)
|
||||
{
|
||||
static int s_tab[ (2 << EEL_FFT_MAXBITLEN) + 24*(EEL_FFT_MAXBITLEN-EEL_FFT_MINBITLEN_REORDER+1) ]; // big 256kb table, ugh
|
||||
if (bitsz<=EEL_FFT_MINBITLEN_REORDER) return s_tab;
|
||||
return s_tab + (1<<bitsz) + (bitsz-EEL_FFT_MINBITLEN_REORDER) * 24;
|
||||
}
|
||||
static void fft_make_reorder_table(int bitsz, int *tab)
|
||||
{
|
||||
const int fft_sz=1<<bitsz;
|
||||
char flag[1<<EEL_FFT_MAXBITLEN];
|
||||
int x;
|
||||
int *tabstart = tab;
|
||||
memset(flag,0,fft_sz);
|
||||
|
||||
for (x=0;x<fft_sz;x++)
|
||||
{
|
||||
int fx;
|
||||
if (!flag[x] && (fx=WDL_fft_permute(fft_sz,x))!=x)
|
||||
{
|
||||
flag[x]=1;
|
||||
*tab++ = x;
|
||||
do
|
||||
{
|
||||
flag[fx]=1;
|
||||
*tab++ = fx;
|
||||
fx = WDL_fft_permute(fft_sz, fx);
|
||||
}
|
||||
while (fx != x);
|
||||
*tab++ = 0; // delimit a run
|
||||
}
|
||||
else flag[x]=1;
|
||||
}
|
||||
*tab++ = 0; // doublenull terminated
|
||||
}
|
||||
|
||||
static void fft_reorder_buffer(int bitsz, WDL_FFT_COMPLEX *data, int fwd)
|
||||
{
|
||||
const int *tab=fft_reorder_table_for_bitsize(bitsz);
|
||||
if (!fwd)
|
||||
{
|
||||
while (*tab)
|
||||
{
|
||||
const int sidx=*tab++;
|
||||
WDL_FFT_COMPLEX a=data[sidx];
|
||||
for (;;)
|
||||
{
|
||||
WDL_FFT_COMPLEX ta;
|
||||
const int idx=*tab++;
|
||||
if (!idx) break;
|
||||
ta=data[idx];
|
||||
data[idx]=a;
|
||||
a=ta;
|
||||
}
|
||||
data[sidx] = a;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (*tab)
|
||||
{
|
||||
const int sidx=*tab++;
|
||||
int lidx = sidx;
|
||||
const WDL_FFT_COMPLEX sta=data[lidx];
|
||||
for (;;)
|
||||
{
|
||||
const int idx=*tab++;
|
||||
if (!idx) break;
|
||||
|
||||
data[lidx]=data[idx];
|
||||
lidx=idx;
|
||||
}
|
||||
data[lidx] = sta;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
#ifndef EEL_SLOW_FFT_REORDERING
|
||||
// moderate speed mode, minus the big 256k table
|
||||
|
||||
static void fft_reorder_buffer(int bitsz, WDL_FFT_COMPLEX *data, int fwd)
|
||||
{
|
||||
// this is a good compromise, quite a bit faster than out of place reordering, but no separate 256kb lookup required
|
||||
/*
|
||||
these generated via:
|
||||
static void fft_make_reorder_table(int bitsz)
|
||||
{
|
||||
int fft_sz=1<<bitsz,x;
|
||||
char flag[65536]={0,};
|
||||
printf("static const int tab%d[]={ ",fft_sz);
|
||||
for (x=0;x<fft_sz;x++)
|
||||
{
|
||||
int fx;
|
||||
if (!flag[x] && (fx=WDL_fft_permute(fft_sz,x))!=x)
|
||||
{
|
||||
printf("%d, ",x);
|
||||
do { flag[fx]=1; fx = WDL_fft_permute(fft_sz, fx); } while (fx != x);
|
||||
}
|
||||
flag[x]=1;
|
||||
}
|
||||
printf(" 0 };\n");
|
||||
}
|
||||
*/
|
||||
|
||||
static const int tab4_8_32[]={ 1, 0 };
|
||||
static const int tab16[]={ 1, 3, 0 };
|
||||
static const int tab64[]={ 1, 3, 9, 0 };
|
||||
static const int tab128[]={ 1, 3, 4, 9, 14, 0 };
|
||||
static const int tab256[]={ 1, 3, 6, 12, 13, 14, 19, 0 };
|
||||
static const int tab512[]={ 1, 4, 7, 9, 18, 50, 115, 0 };
|
||||
static const int tab1024[]={ 1, 3, 4, 25, 26, 77, 79, 0 };
|
||||
static const int tab2048[]={ 1, 58, 59, 106, 135, 206, 210, 212, 0 };
|
||||
static const int tab4096[]={ 1, 3, 12, 25, 54, 221, 313, 431, 453, 0 };
|
||||
static const int tab8192[]={ 1, 12, 18, 26, 30, 100, 101, 106, 113, 144, 150, 237, 244, 247, 386, 468, 513, 1210, 4839, 0 };
|
||||
static const int tab16384[]={ 1, 3, 6, 24, 1219, 0 };
|
||||
static const int tab32768[]={ 1, 3, 4, 7, 13, 18, 31, 64, 113, 145, 203, 246, 594, 956, 1871, 2439, 4959, 19175, 0 };
|
||||
const int *tab;
|
||||
|
||||
switch (bitsz)
|
||||
{
|
||||
case 1: return; // no reorder necessary
|
||||
case 2:
|
||||
case 3:
|
||||
case 5: tab = tab4_8_32; break;
|
||||
case 4: tab=tab16; break;
|
||||
case 6: tab=tab64; break;
|
||||
case 7: tab=tab128; break;
|
||||
case 8: tab=tab256; break;
|
||||
case 9: tab=tab512; break;
|
||||
case 10: tab=tab1024; break;
|
||||
case 11: tab=tab2048; break;
|
||||
case 12: tab=tab4096; break;
|
||||
case 13: tab=tab8192; break;
|
||||
case 14: tab=tab16384; break;
|
||||
case 15: tab=tab32768; break;
|
||||
default: return; // no reorder possible
|
||||
}
|
||||
|
||||
const int fft_sz=1<<bitsz;
|
||||
const int *tb2 = WDL_fft_permute_tab(fft_sz);
|
||||
if (!tb2) return; // ugh
|
||||
|
||||
if (!fwd)
|
||||
{
|
||||
while (*tab)
|
||||
{
|
||||
const int sidx=*tab++;
|
||||
WDL_FFT_COMPLEX a=data[sidx];
|
||||
int idx=sidx;
|
||||
for (;;)
|
||||
{
|
||||
WDL_FFT_COMPLEX ta;
|
||||
idx=tb2[idx];
|
||||
if (idx==sidx) break;
|
||||
ta=data[idx];
|
||||
data[idx]=a;
|
||||
a=ta;
|
||||
}
|
||||
data[sidx] = a;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (*tab)
|
||||
{
|
||||
const int sidx=*tab++;
|
||||
int lidx = sidx;
|
||||
const WDL_FFT_COMPLEX sta=data[lidx];
|
||||
for (;;)
|
||||
{
|
||||
const int idx=tb2[lidx];
|
||||
if (idx==sidx) break;
|
||||
|
||||
data[lidx]=data[idx];
|
||||
lidx=idx;
|
||||
}
|
||||
data[lidx] = sta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // not fast ,not slow, just right
|
||||
|
||||
#endif
|
||||
|
||||
//#define TIMING
|
||||
//#include "../timing.h"
|
||||
|
||||
// 0=fw, 1=iv, 2=fwreal, 3=ireal, 4=permutec, 6=permuter
|
||||
// low bit: is inverse
|
||||
// second bit: was isreal, but no longer used
|
||||
// third bit: is permute
|
||||
static void FFT(int sizebits, EEL_F *data, int dir)
|
||||
{
|
||||
if (dir >= 4 && dir < 8)
|
||||
{
|
||||
if (dir == 4 || dir == 5)
|
||||
{
|
||||
//timingEnter(0);
|
||||
#if defined(EEL_SUPER_FAST_FFT_REORDERING) || !defined(EEL_SLOW_FFT_REORDERING)
|
||||
fft_reorder_buffer(sizebits,(WDL_FFT_COMPLEX*)data,dir==4);
|
||||
#else
|
||||
// old blech
|
||||
const int flen=1<<sizebits;
|
||||
int x;
|
||||
EEL_F *tmp=(EEL_F*)alloca(sizeof(EEL_F)*flen*2);
|
||||
const int flen2=flen+flen;
|
||||
// reorder entries, now
|
||||
memcpy(tmp,data,sizeof(EEL_F)*flen*2);
|
||||
|
||||
if (dir == 4)
|
||||
{
|
||||
for (x = 0; x < flen2; x += 2)
|
||||
{
|
||||
int y=WDL_fft_permute(flen,x/2)*2;
|
||||
data[x]=tmp[y];
|
||||
data[x+1]=tmp[y+1];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (x = 0; x < flen2; x += 2)
|
||||
{
|
||||
int y=WDL_fft_permute(flen,x/2)*2;
|
||||
data[y]=tmp[x];
|
||||
data[y+1]=tmp[x+1];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//timingLeave(0);
|
||||
}
|
||||
}
|
||||
else if (dir >= 0 && dir < 2)
|
||||
{
|
||||
WDL_fft((WDL_FFT_COMPLEX*)data,1<<sizebits,dir&1);
|
||||
}
|
||||
else if (dir >= 2 && dir < 4)
|
||||
{
|
||||
WDL_real_fft((WDL_FFT_REAL*)data,1<<sizebits,dir&1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static EEL_F * fft_func(int dir, EEL_F **blocks, EEL_F *start, EEL_F *length)
|
||||
{
|
||||
const int offs = (int)(*start + 0.0001);
|
||||
const int itemSizeShift=(dir&2)?0:1;
|
||||
int l=(int)(*length + 0.0001);
|
||||
int bitl=0;
|
||||
int ilen;
|
||||
EEL_F *ptr;
|
||||
while (l>1 && bitl < EEL_FFT_MAXBITLEN)
|
||||
{
|
||||
bitl++;
|
||||
l>>=1;
|
||||
}
|
||||
if (bitl < ((dir&4) ? EEL_FFT_MINBITLEN_REORDER : EEL_FFT_MINBITLEN)) // smallest FFT is 16 item, smallest reorder is 8 item
|
||||
{
|
||||
return start;
|
||||
}
|
||||
ilen=1<<bitl;
|
||||
|
||||
|
||||
// check to make sure we don't cross a boundary
|
||||
if (offs/NSEEL_RAM_ITEMSPERBLOCK != (offs + (ilen<<itemSizeShift) - 1)/NSEEL_RAM_ITEMSPERBLOCK)
|
||||
{
|
||||
return start;
|
||||
}
|
||||
|
||||
ptr=__NSEEL_RAMAlloc(blocks,offs);
|
||||
if (!ptr || ptr==&nseel_ramalloc_onfail)
|
||||
{
|
||||
return start;
|
||||
}
|
||||
|
||||
FFT(bitl,ptr,dir);
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
static EEL_F * NSEEL_CGEN_CALL eel_fft(EEL_F **blocks, EEL_F *start, EEL_F *length)
|
||||
{
|
||||
return fft_func(0,blocks,start,length);
|
||||
}
|
||||
|
||||
static EEL_F * NSEEL_CGEN_CALL eel_ifft(EEL_F **blocks, EEL_F *start, EEL_F *length)
|
||||
{
|
||||
return fft_func(1,blocks,start,length);
|
||||
}
|
||||
|
||||
static EEL_F * NSEEL_CGEN_CALL eel_fft_real(EEL_F **blocks, EEL_F *start, EEL_F *length)
|
||||
{
|
||||
return fft_func(2,blocks,start,length);
|
||||
}
|
||||
|
||||
static EEL_F * NSEEL_CGEN_CALL eel_ifft_real(EEL_F **blocks, EEL_F *start, EEL_F *length)
|
||||
{
|
||||
return fft_func(3,blocks,start,length);
|
||||
}
|
||||
|
||||
static EEL_F * NSEEL_CGEN_CALL eel_fft_permute(EEL_F **blocks, EEL_F *start, EEL_F *length)
|
||||
{
|
||||
return fft_func(4,blocks,start,length);
|
||||
}
|
||||
|
||||
static EEL_F * NSEEL_CGEN_CALL eel_ifft_permute(EEL_F **blocks, EEL_F *start, EEL_F *length)
|
||||
{
|
||||
return fft_func(5,blocks,start,length);
|
||||
}
|
||||
|
||||
static EEL_F * NSEEL_CGEN_CALL eel_convolve_c(EEL_F **blocks,EEL_F *dest, EEL_F *src, EEL_F *lenptr)
|
||||
{
|
||||
const int dest_offs = (int)(*dest + 0.0001);
|
||||
const int src_offs = (int)(*src + 0.0001);
|
||||
const int len = ((int)(*lenptr + 0.0001)) * 2;
|
||||
EEL_F *srcptr,*destptr;
|
||||
|
||||
if (len < 1 || len > NSEEL_RAM_ITEMSPERBLOCK || dest_offs < 0 || src_offs < 0 ||
|
||||
dest_offs >= NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK || src_offs >= NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK) return dest;
|
||||
if ((dest_offs&(NSEEL_RAM_ITEMSPERBLOCK-1)) + len > NSEEL_RAM_ITEMSPERBLOCK) return dest;
|
||||
if ((src_offs&(NSEEL_RAM_ITEMSPERBLOCK-1)) + len > NSEEL_RAM_ITEMSPERBLOCK) return dest;
|
||||
|
||||
srcptr = __NSEEL_RAMAlloc(blocks,src_offs);
|
||||
if (!srcptr || srcptr==&nseel_ramalloc_onfail) return dest;
|
||||
destptr = __NSEEL_RAMAlloc(blocks,dest_offs);
|
||||
if (!destptr || destptr==&nseel_ramalloc_onfail) return dest;
|
||||
|
||||
|
||||
WDL_fft_complexmul((WDL_FFT_COMPLEX*)destptr,(WDL_FFT_COMPLEX*)srcptr,(len/2)&~1);
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
void EEL_fft_register()
|
||||
{
|
||||
WDL_fft_init();
|
||||
#if defined(EEL_SUPER_FAST_FFT_REORDERING)
|
||||
if (!fft_reorder_table_for_bitsize(EEL_FFT_MINBITLEN_REORDER)[0])
|
||||
{
|
||||
int x;
|
||||
for (x=EEL_FFT_MINBITLEN_REORDER;x<=EEL_FFT_MAXBITLEN;x++) fft_make_reorder_table(x,fft_reorder_table_for_bitsize(x));
|
||||
}
|
||||
#endif
|
||||
NSEEL_addfunc_retptr("convolve_c",3,NSEEL_PProc_RAM,&eel_convolve_c);
|
||||
NSEEL_addfunc_retptr("fft",2,NSEEL_PProc_RAM,&eel_fft);
|
||||
NSEEL_addfunc_retptr("ifft",2,NSEEL_PProc_RAM,&eel_ifft);
|
||||
NSEEL_addfunc_retptr("fft_real",2,NSEEL_PProc_RAM,&eel_fft_real);
|
||||
NSEEL_addfunc_retptr("ifft_real",2,NSEEL_PProc_RAM,&eel_ifft_real);
|
||||
NSEEL_addfunc_retptr("fft_permute",2,NSEEL_PProc_RAM,&eel_fft_permute);
|
||||
NSEEL_addfunc_retptr("fft_ipermute",2,NSEEL_PProc_RAM,&eel_ifft_permute);
|
||||
}
|
||||
|
||||
#ifdef EEL_WANT_DOCUMENTATION
|
||||
static const char *eel_fft_function_reference =
|
||||
"convolve_c\tdest,src,size\tMultiplies each of size complex pairs in dest by the complex pairs in src. Often used for convolution.\0"
|
||||
"fft\tbuffer,size\tPerforms a FFT on the data in the local memory buffer at the offset specified by the first parameter. The size of the FFT is specified "
|
||||
"by the second parameter, which must be 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, or 32768. The outputs are permuted, so if "
|
||||
"you plan to use them in-order, call fft_permute(buffer, size) before and fft_ipermute(buffer,size) after your in-order use. Your inputs or "
|
||||
"outputs will need to be scaled down by 1/size, if used.\n"
|
||||
"Note that fft()/ifft() require real / imaginary input pairs, so a 256 point FFT actually works with 512 items.\n"
|
||||
"Note that fft()/ifft() must NOT cross a 65,536 item boundary, so be sure to specify the offset accordingly.\0"
|
||||
"ifft\tbuffer,size\tPerform an inverse FFT. For more information see fft().\0"
|
||||
"fft_real\tbuffer,size\tPerforms an FFT, but takes size input samples and produces size/2 complex output pairs. Usually used along with fft_permute(size/2). Inputs/outputs will need to be scaled by 0.5/size.\0"
|
||||
"ifft_real\tbuffer,size\tPerforms an inverse FFT, but takes size/2 complex input pairs and produces size real output values. Usually used along with fft_ipermute(size/2).\0"
|
||||
"fft_permute\tbuffer,size\tPermute the output of fft() to have bands in-order. See fft() for more information.\0"
|
||||
"fft_ipermute\tbuffer,size\tPermute the input for ifft(), taking bands from in-order to the order ifft() requires. See fft() for more information.\0"
|
||||
;
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
262
oversampling/WDL/eel2/eel_files.h
Normal file
262
oversampling/WDL/eel2/eel_files.h
Normal file
@@ -0,0 +1,262 @@
|
||||
#ifndef __EEL_FILES_H__
|
||||
#define __EEL_FILES_H__
|
||||
|
||||
// should include eel_strings.h before this, probably
|
||||
//#define EEL_FILE_OPEN(fn,mode) ((instance)opaque)->OpenFile(fn,mode)
|
||||
//#define EEL_FILE_GETFP(fp) ((instance)opaque)->GetFileFP(fp)
|
||||
//#define EEL_FILE_CLOSE(fpindex) ((instance)opaque)->CloseFile(fpindex)
|
||||
|
||||
static EEL_F NSEEL_CGEN_CALL _eel_fopen(void *opaque, EEL_F *fn_index, EEL_F *mode_index)
|
||||
{
|
||||
EEL_STRING_MUTEXLOCK_SCOPE
|
||||
const char *fn = EEL_STRING_GET_FOR_INDEX(*fn_index,NULL);
|
||||
const char *mode = EEL_STRING_GET_FOR_INDEX(*mode_index,NULL);
|
||||
if (!fn || !mode) return 0;
|
||||
return (EEL_F) EEL_FILE_OPEN(fn,mode);
|
||||
}
|
||||
static EEL_F NSEEL_CGEN_CALL _eel_fclose(void *opaque, EEL_F *fpp)
|
||||
{
|
||||
EEL_F ret=EEL_FILE_CLOSE((int)*fpp);
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
if (ret < 0) EEL_STRING_DEBUGOUT("fclose(): file handle %f not valid",*fpp);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
static EEL_F NSEEL_CGEN_CALL _eel_fgetc(void *opaque, EEL_F *fpp)
|
||||
{
|
||||
EEL_STRING_MUTEXLOCK_SCOPE
|
||||
FILE *fp = EEL_FILE_GETFP((int)*fpp);
|
||||
if (fp) return (EEL_F)fgetc(fp);
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
EEL_STRING_DEBUGOUT("fgetc(): file handle %f not valid",*fpp);
|
||||
#endif
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
static EEL_F NSEEL_CGEN_CALL _eel_ftell(void *opaque, EEL_F *fpp)
|
||||
{
|
||||
EEL_STRING_MUTEXLOCK_SCOPE
|
||||
FILE *fp = EEL_FILE_GETFP((int)*fpp);
|
||||
if (fp) return (EEL_F)ftell(fp);
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
EEL_STRING_DEBUGOUT("ftell(): file handle %f not valid",*fpp);
|
||||
#endif
|
||||
return -1.0;
|
||||
}
|
||||
static EEL_F NSEEL_CGEN_CALL _eel_fflush(void *opaque, EEL_F *fpp)
|
||||
{
|
||||
EEL_STRING_MUTEXLOCK_SCOPE
|
||||
FILE *fp = EEL_FILE_GETFP((int)*fpp);
|
||||
if (fp) { fflush(fp); return 0.0; }
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
EEL_STRING_DEBUGOUT("fflush(): file handle %f not valid",*fpp);
|
||||
#endif
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
static EEL_F NSEEL_CGEN_CALL _eel_feof(void *opaque, EEL_F *fpp)
|
||||
{
|
||||
EEL_STRING_MUTEXLOCK_SCOPE
|
||||
FILE *fp = EEL_FILE_GETFP((int)*fpp);
|
||||
if (fp) return feof(fp) ? 1.0 : 0.0;
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
EEL_STRING_DEBUGOUT("feof(): file handle %f not valid",*fpp);
|
||||
#endif
|
||||
return -1.0;
|
||||
}
|
||||
static EEL_F NSEEL_CGEN_CALL _eel_fseek(void *opaque, EEL_F *fpp, EEL_F *offset, EEL_F *wh)
|
||||
{
|
||||
EEL_STRING_MUTEXLOCK_SCOPE
|
||||
FILE *fp = EEL_FILE_GETFP((int)*fpp);
|
||||
if (fp) return fseek(fp, (int) *offset, *wh<0 ? SEEK_SET : *wh > 0 ? SEEK_END : SEEK_CUR);
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
EEL_STRING_DEBUGOUT("fseek(): file handle %f not valid",*fpp);
|
||||
#endif
|
||||
return -1.0;
|
||||
}
|
||||
static EEL_F NSEEL_CGEN_CALL _eel_fgets(void *opaque, EEL_F *fpp, EEL_F *strOut)
|
||||
{
|
||||
EEL_STRING_MUTEXLOCK_SCOPE
|
||||
EEL_STRING_STORAGECLASS *wr=NULL;
|
||||
EEL_STRING_GET_FOR_WRITE(*strOut, &wr);
|
||||
|
||||
FILE *fp = EEL_FILE_GETFP((int)*fpp);
|
||||
if (!fp)
|
||||
{
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
EEL_STRING_DEBUGOUT("fgets(): file handle %f not valid",*fpp);
|
||||
#endif
|
||||
if (wr) wr->Set("");
|
||||
return 0.0;
|
||||
}
|
||||
char buf[16384];
|
||||
buf[0]=0;
|
||||
fgets(buf,sizeof(buf),fp);
|
||||
if (wr)
|
||||
{
|
||||
wr->Set(buf);
|
||||
return (EEL_F)wr->GetLength();
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
EEL_STRING_DEBUGOUT("fgets: bad destination specifier passed %f, throwing away %d bytes",*strOut, (int)strlen(buf));
|
||||
#endif
|
||||
return (int)strlen(buf);
|
||||
}
|
||||
}
|
||||
static EEL_F NSEEL_CGEN_CALL _eel_fread(void *opaque, EEL_F *fpp, EEL_F *strOut, EEL_F *flen)
|
||||
{
|
||||
int use_len = (int) *flen;
|
||||
if (use_len < 1) return 0.0;
|
||||
|
||||
EEL_STRING_MUTEXLOCK_SCOPE
|
||||
EEL_STRING_STORAGECLASS *wr=NULL;
|
||||
EEL_STRING_GET_FOR_WRITE(*strOut, &wr);
|
||||
if (!wr)
|
||||
{
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
EEL_STRING_DEBUGOUT("fread: bad destination specifier passed %f, not reading %d bytes",*strOut, use_len);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
FILE *fp = EEL_FILE_GETFP((int)*fpp);
|
||||
if (!fp)
|
||||
{
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
EEL_STRING_DEBUGOUT("fread(): file handle %f not valid",*fpp);
|
||||
#endif
|
||||
if (wr) wr->Set("");
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
wr->SetLen(use_len);
|
||||
if (wr->GetLength() != use_len)
|
||||
{
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
EEL_STRING_DEBUGOUT("fread: error allocating storage for read of %d bytes", use_len);
|
||||
#endif
|
||||
return -1.0;
|
||||
}
|
||||
use_len = (int)fread((char *)wr->Get(),1,use_len,fp);
|
||||
wr->SetLen(use_len > 0 ? use_len : 0, true);
|
||||
return (EEL_F) use_len;
|
||||
}
|
||||
|
||||
static EEL_F NSEEL_CGEN_CALL _eel_fwrite(void *opaque, EEL_F *fpp, EEL_F *strOut, EEL_F *flen)
|
||||
{
|
||||
EEL_STRING_MUTEXLOCK_SCOPE
|
||||
int use_len = (int) *flen;
|
||||
|
||||
EEL_STRING_STORAGECLASS *wr=NULL;
|
||||
const char *str=EEL_STRING_GET_FOR_INDEX(*strOut, &wr);
|
||||
if (!wr && !str)
|
||||
{
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
EEL_STRING_DEBUGOUT("fwrite: bad source specifier passed %f, not writing %d bytes",*strOut, use_len);
|
||||
#endif
|
||||
return -1.0;
|
||||
}
|
||||
if (!wr)
|
||||
{
|
||||
const int ssl = (int)strlen(str);
|
||||
if (use_len < 1 || use_len > ssl) use_len = ssl;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (use_len < 1 || use_len > wr->GetLength()) use_len = wr->GetLength();
|
||||
}
|
||||
|
||||
if (use_len < 1) return 0.0;
|
||||
|
||||
FILE *fp = EEL_FILE_GETFP((int)*fpp);
|
||||
if (!fp)
|
||||
{
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
EEL_STRING_DEBUGOUT("fwrite(): file handle %f not valid",*fpp);
|
||||
#endif
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return (EEL_F) fwrite(str,1,use_len,fp);
|
||||
}
|
||||
|
||||
static EEL_F NSEEL_CGEN_CALL _eel_fprintf(void *opaque, INT_PTR nparam, EEL_F **parm)
|
||||
{
|
||||
if (opaque && nparam > 1)
|
||||
{
|
||||
EEL_STRING_MUTEXLOCK_SCOPE
|
||||
FILE *fp = EEL_FILE_GETFP((int)*(parm[0]));
|
||||
if (!fp)
|
||||
{
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
EEL_STRING_DEBUGOUT("fprintf(): file handle %f not valid",parm[0][0]);
|
||||
#endif
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
EEL_STRING_STORAGECLASS *wr_src=NULL;
|
||||
const char *fmt = EEL_STRING_GET_FOR_INDEX(*(parm[1]),&wr_src);
|
||||
if (fmt)
|
||||
{
|
||||
char buf[16384];
|
||||
const int len = eel_format_strings(opaque,fmt,wr_src?(fmt+wr_src->GetLength()) : NULL, buf,(int)sizeof(buf),(int)nparam-2,parm+2);
|
||||
|
||||
if (len >= 0)
|
||||
{
|
||||
return (EEL_F) fwrite(buf,1,len,fp);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
EEL_STRING_DEBUGOUT("fprintf: bad format string %s",fmt);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
EEL_STRING_DEBUGOUT("fprintf: bad format specifier passed %f",*(parm[1]));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
void EEL_file_register()
|
||||
{
|
||||
NSEEL_addfunc_retval("fopen",2,NSEEL_PProc_THIS,&_eel_fopen);
|
||||
|
||||
NSEEL_addfunc_retval("fread",3,NSEEL_PProc_THIS,&_eel_fread);
|
||||
NSEEL_addfunc_retval("fgets",2,NSEEL_PProc_THIS,&_eel_fgets);
|
||||
NSEEL_addfunc_retval("fgetc",1,NSEEL_PProc_THIS,&_eel_fgetc);
|
||||
|
||||
NSEEL_addfunc_retval("fwrite",3,NSEEL_PProc_THIS,&_eel_fwrite);
|
||||
NSEEL_addfunc_varparm("fprintf",2,NSEEL_PProc_THIS,&_eel_fprintf);
|
||||
|
||||
NSEEL_addfunc_retval("fseek",3,NSEEL_PProc_THIS,&_eel_fseek);
|
||||
NSEEL_addfunc_retval("ftell",1,NSEEL_PProc_THIS,&_eel_ftell);
|
||||
NSEEL_addfunc_retval("feof",1,NSEEL_PProc_THIS,&_eel_feof);
|
||||
NSEEL_addfunc_retval("fflush",1,NSEEL_PProc_THIS,&_eel_fflush);
|
||||
NSEEL_addfunc_retval("fclose",1,NSEEL_PProc_THIS,&_eel_fclose);
|
||||
}
|
||||
|
||||
#ifdef EEL_WANT_DOCUMENTATION
|
||||
static const char *eel_file_function_reference =
|
||||
"fopen\t\"fn\",\"mode\"\tOpens a file \"fn\" with mode \"mode\". For read, use \"r\" or \"rb\", write \"w\" or \"wb\". Returns a positive integer on success.\0"
|
||||
"fclose\tfp\tCloses a file previously opened with fopen().\0"
|
||||
"fread\tfp,#str,length\tReads from file fp into #str, up to length bytes. Returns actual length read, or negative if error.\0"
|
||||
"fgets\tfp,#str\tReads a line from file fp into #str. Returns length of #str read.\0"
|
||||
"fgetc\tfp\tReads a character from file fp, returns -1 if EOF.\0"
|
||||
"fwrite\tfp,#str,len\tWrites up to len characters of #str to file fp. If len is less than 1, the full contents of #str will be written. Returns the number of bytes written to file.\0"
|
||||
"fprintf\tfp,\"format\"[,...]\tFormats a string and writes it to file fp. For more information on format specifiers, see sprintf(). Returns bytes written to file.\0"
|
||||
"fseek\tfp,offset,whence\tSeeks file fp, offset bytes from whence reference. Whence negative specifies start of file, positive whence specifies end of file, and zero whence specifies current file position.\0"
|
||||
"ftell\tfp\tRetunrs the current file position.\0"
|
||||
"feof\tfp\tReturns nonzero if the file fp is at the end of file.\0"
|
||||
"fflush\tfp\tIf file fp is open for writing, flushes out any buffered data to disk.\0"
|
||||
;
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
104
oversampling/WDL/eel2/eel_import.h
Normal file
104
oversampling/WDL/eel2/eel_import.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/*******************************************************************************************
|
||||
* imported EEL
|
||||
******************************************************************************************/
|
||||
|
||||
void (*NSEEL_addfunc_ret_type)(const char *name, int np, int ret_type, NSEEL_PPPROC pproc, void *fptr, eel_function_table *destination); // ret_type=-1 for bool, 1 for value, 0 for ptr
|
||||
void (*NSEEL_addfunc_varparm_ex)(const char *name, int min_np, int want_exact, NSEEL_PPPROC pproc, EEL_F (NSEEL_CGEN_CALL *fptr)(void *, INT_PTR, EEL_F **), eel_function_table *destination);
|
||||
|
||||
|
||||
NSEEL_VMCTX (*NSEEL_VM_alloc)(); // return a handle
|
||||
void (*NSEEL_VM_SetGRAM)(NSEEL_VMCTX, void **);
|
||||
void (*NSEEL_VM_free)(NSEEL_VMCTX ctx); // free when done with a VM and ALL of its code have been freed, as well
|
||||
void (*NSEEL_VM_SetFunctionTable)(NSEEL_VMCTX, eel_function_table *tab); // use NULL to use default (global) table
|
||||
EEL_F *(*NSEEL_VM_regvar)(NSEEL_VMCTX ctx, const char *name); // register a variable (before compilation)
|
||||
|
||||
void (*NSEEL_VM_SetCustomFuncThis)(NSEEL_VMCTX ctx, void *thisptr);
|
||||
NSEEL_CODEHANDLE (*NSEEL_code_compile_ex)(NSEEL_VMCTX ctx, const char *code, int lineoffs, int flags);
|
||||
void (*NSEEL_VM_set_var_resolver)(NSEEL_VMCTX ctx, EEL_F *(*res)(void *userctx, const char *name), void *userctx);
|
||||
char *(*NSEEL_code_getcodeerror)(NSEEL_VMCTX ctx);
|
||||
void (*NSEEL_code_execute)(NSEEL_CODEHANDLE code);
|
||||
void (*NSEEL_code_free)(NSEEL_CODEHANDLE code);
|
||||
EEL_F *(*nseel_int_register_var)(compileContext *ctx, const char *name, int isReg, const char **namePtrOut);
|
||||
void (*NSEEL_VM_enumallvars)(NSEEL_VMCTX ctx, int (*func)(const char *name, EEL_F *val, void *ctx), void *userctx);
|
||||
EEL_F *(*NSEEL_VM_getramptr)(NSEEL_VMCTX ctx, unsigned int offs, int *validAmt);
|
||||
void ** (*eel_gmem_attach)(const char *nm, bool is_alloc);
|
||||
void (*eel_fft_register)(eel_function_table*);
|
||||
|
||||
struct eelStringSegmentRec {
|
||||
struct eelStringSegmentRec *_next;
|
||||
const char *str_start; // escaped characters, including opening/trailing characters
|
||||
int str_len;
|
||||
};
|
||||
void (*NSEEL_VM_SetStringFunc)(NSEEL_VMCTX ctx,
|
||||
EEL_F (*onString)(void *caller_this, struct eelStringSegmentRec *list),
|
||||
EEL_F (*onNamedString)(void *caller_this, const char *name));
|
||||
|
||||
// call with NULL to calculate size, or non-null to generate to buffer (returning size used -- will not null terminate, caller responsibility)
|
||||
int (*nseel_stringsegments_tobuf)(char *bufOut, int bufout_sz, struct eelStringSegmentRec *list);
|
||||
|
||||
void *(*NSEEL_PProc_RAM)(void *data, int data_size, struct _compileContext *ctx);
|
||||
void *(*NSEEL_PProc_THIS)(void *data, int data_size, struct _compileContext *ctx);
|
||||
|
||||
void (*eel_enterfp)(int s[2]);
|
||||
void (*eel_leavefp)(int s[2]);
|
||||
|
||||
|
||||
eel_function_table g_eel_function_table;
|
||||
#define NSEEL_ADDFUNC_DESTINATION (&g_eel_function_table)
|
||||
|
||||
//
|
||||
// adds a function that returns a value (EEL_F)
|
||||
#define NSEEL_addfunc_retval(name,np,pproc,fptr) \
|
||||
NSEEL_addfunc_ret_type(name,np,1,pproc,(void *)(fptr),NSEEL_ADDFUNC_DESTINATION)
|
||||
|
||||
// adds a function that returns a pointer (EEL_F*)
|
||||
#define NSEEL_addfunc_retptr(name,np,pproc,fptr) \
|
||||
NSEEL_addfunc_ret_type(name,np,0,pproc,(void *)(fptr),NSEEL_ADDFUNC_DESTINATION)
|
||||
|
||||
// adds a void or bool function
|
||||
#define NSEEL_addfunc_retbool(name,np,pproc,fptr) \
|
||||
NSEEL_addfunc_ret_type(name,np,-1,pproc,(void *)(fptr),NSEEL_ADDFUNC_DESTINATION)
|
||||
|
||||
// adds a function that takes min_np or more parameters (func sig needs to be EEL_F func(void *ctx, INT_PTR np, EEL_F **parms)
|
||||
#define NSEEL_addfunc_varparm(name, min_np, pproc, fptr) \
|
||||
NSEEL_addfunc_varparm_ex(name,min_np,0,pproc,fptr,NSEEL_ADDFUNC_DESTINATION)
|
||||
|
||||
// adds a function that takes np parameters via func: sig needs to be EEL_F func(void *ctx, INT_PTR np, EEL_F **parms)
|
||||
#define NSEEL_addfunc_exparms(name, np, pproc, fptr) \
|
||||
NSEEL_addfunc_varparm_ex(name,np,1,pproc,fptr,NSEEL_ADDFUNC_DESTINATION)
|
||||
|
||||
class eel_string_context_state;
|
||||
|
||||
#define __NS_EELINT_H__
|
||||
|
||||
#define EEL_IMPORT_ALL(IMPORT_FUNC) \
|
||||
IMPORT_FUNC(NSEEL_addfunc_ret_type) \
|
||||
IMPORT_FUNC(NSEEL_addfunc_varparm_ex) \
|
||||
IMPORT_FUNC(NSEEL_VM_free) \
|
||||
IMPORT_FUNC(NSEEL_VM_SetFunctionTable) \
|
||||
IMPORT_FUNC(NSEEL_VM_regvar) \
|
||||
IMPORT_FUNC(NSEEL_VM_SetCustomFuncThis) \
|
||||
IMPORT_FUNC(NSEEL_code_compile_ex) \
|
||||
IMPORT_FUNC(NSEEL_code_getcodeerror) \
|
||||
IMPORT_FUNC(NSEEL_code_execute) \
|
||||
IMPORT_FUNC(NSEEL_code_free) \
|
||||
IMPORT_FUNC(NSEEL_PProc_THIS) \
|
||||
IMPORT_FUNC(NSEEL_PProc_RAM) \
|
||||
IMPORT_FUNC(NSEEL_VM_SetStringFunc) \
|
||||
IMPORT_FUNC(NSEEL_VM_enumallvars) \
|
||||
IMPORT_FUNC(NSEEL_VM_getramptr) \
|
||||
IMPORT_FUNC(NSEEL_VM_SetGRAM) \
|
||||
IMPORT_FUNC(eel_gmem_attach) \
|
||||
IMPORT_FUNC(eel_fft_register) \
|
||||
IMPORT_FUNC(nseel_stringsegments_tobuf) \
|
||||
IMPORT_FUNC(nseel_int_register_var) \
|
||||
IMPORT_FUNC(eel_leavefp) \
|
||||
IMPORT_FUNC(eel_enterfp) \
|
||||
IMPORT_FUNC(NSEEL_VM_set_var_resolver) \
|
||||
IMPORT_FUNC(NSEEL_VM_alloc) /* keep NSEEL_VM_alloc last */
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************************
|
||||
* END of imported EEL
|
||||
******************************************************************************************/
|
||||
3223
oversampling/WDL/eel2/eel_lice.h
Normal file
3223
oversampling/WDL/eel2/eel_lice.h
Normal file
File diff suppressed because it is too large
Load Diff
782
oversampling/WDL/eel2/eel_mdct.h
Normal file
782
oversampling/WDL/eel2/eel_mdct.h
Normal file
@@ -0,0 +1,782 @@
|
||||
#ifndef _EEL_MDCT_H_
|
||||
#define _EEL_MDCT_H_
|
||||
|
||||
|
||||
#include "ns-eel-int.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#define EEL_DCT_MINBITLEN 5
|
||||
#define EEL_DCT_MAXBITLEN 12
|
||||
|
||||
|
||||
#define PI 3.1415926535897932384626433832795
|
||||
|
||||
typedef struct {
|
||||
int n;
|
||||
int log2n;
|
||||
EEL_F *trig;
|
||||
int *bitrev;
|
||||
EEL_F scale;
|
||||
EEL_F *window;
|
||||
} mdct_lookup;
|
||||
|
||||
static void mdct(EEL_F *in, EEL_F *out, int len)
|
||||
{
|
||||
int k;
|
||||
EEL_F pioverlen = PI * 0.5 / (EEL_F)len;
|
||||
for (k = 0; k < len / 2; k ++)
|
||||
{
|
||||
int i;
|
||||
EEL_F d = 0.0;
|
||||
for (i = 0; i < len; i ++)
|
||||
{
|
||||
d += in[i] * cos(pioverlen * (2.0 * i + 1.0 + len * 0.5) * (2.0 * k + 1.0));
|
||||
}
|
||||
out[k] = (EEL_F)d;
|
||||
}
|
||||
}
|
||||
|
||||
static void imdct(EEL_F *in, EEL_F *out, int len)
|
||||
{
|
||||
int k;
|
||||
EEL_F fourovern = 4.0 / (EEL_F)len;
|
||||
EEL_F pioverlen = PI * 0.5 / (EEL_F)len;
|
||||
for (k = 0; k < len; k ++)
|
||||
{
|
||||
int i;
|
||||
EEL_F d = 0.0;
|
||||
for (i = 0; i < len / 2; i ++)
|
||||
{
|
||||
d += in[i] * cos(pioverlen * (2.0 * k + 1.0 + len * 0.5) * (2 * i + 1.0));
|
||||
}
|
||||
out[k] = (EEL_F)(d * fourovern);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MDCT/iMDCT borrowed from Vorbis, thanks xiph!
|
||||
|
||||
|
||||
#define cPI3_8 .38268343236508977175
|
||||
#define cPI2_8 .70710678118654752441
|
||||
#define cPI1_8 .92387953251128675613
|
||||
|
||||
#define FLOAT_CONV(x) ((EEL_F) ( x ))
|
||||
#define MULT_NORM(x) (x)
|
||||
#define HALVE(x) ((x)*.5f)
|
||||
|
||||
|
||||
|
||||
/* 8 point butterfly (in place, 4 register) */
|
||||
static void mdct_butterfly_8(EEL_F *x) {
|
||||
EEL_F r0 = x[6] + x[2];
|
||||
EEL_F r1 = x[6] - x[2];
|
||||
EEL_F r2 = x[4] + x[0];
|
||||
EEL_F r3 = x[4] - x[0];
|
||||
|
||||
x[6] = r0 + r2;
|
||||
x[4] = r0 - r2;
|
||||
|
||||
r0 = x[5] - x[1];
|
||||
r2 = x[7] - x[3];
|
||||
x[0] = r1 + r0;
|
||||
x[2] = r1 - r0;
|
||||
|
||||
r0 = x[5] + x[1];
|
||||
r1 = x[7] + x[3];
|
||||
x[3] = r2 + r3;
|
||||
x[1] = r2 - r3;
|
||||
x[7] = r1 + r0;
|
||||
x[5] = r1 - r0;
|
||||
|
||||
}
|
||||
|
||||
/* 16 point butterfly (in place, 4 register) */
|
||||
static void mdct_butterfly_16(EEL_F *x) {
|
||||
EEL_F r0 = x[1] - x[9];
|
||||
EEL_F r1 = x[0] - x[8];
|
||||
|
||||
x[8] += x[0];
|
||||
x[9] += x[1];
|
||||
x[0] = MULT_NORM((r0 + r1) * cPI2_8);
|
||||
x[1] = MULT_NORM((r0 - r1) * cPI2_8);
|
||||
|
||||
r0 = x[3] - x[11];
|
||||
r1 = x[10] - x[2];
|
||||
x[10] += x[2];
|
||||
x[11] += x[3];
|
||||
x[2] = r0;
|
||||
x[3] = r1;
|
||||
|
||||
r0 = x[12] - x[4];
|
||||
r1 = x[13] - x[5];
|
||||
x[12] += x[4];
|
||||
x[13] += x[5];
|
||||
x[4] = MULT_NORM((r0 - r1) * cPI2_8);
|
||||
x[5] = MULT_NORM((r0 + r1) * cPI2_8);
|
||||
|
||||
r0 = x[14] - x[6];
|
||||
r1 = x[15] - x[7];
|
||||
x[14] += x[6];
|
||||
x[15] += x[7];
|
||||
x[6] = r0;
|
||||
x[7] = r1;
|
||||
|
||||
mdct_butterfly_8(x);
|
||||
mdct_butterfly_8(x + 8);
|
||||
}
|
||||
|
||||
/* 32 point butterfly (in place, 4 register) */
|
||||
static void mdct_butterfly_32(EEL_F *x) {
|
||||
EEL_F r0 = x[30] - x[14];
|
||||
EEL_F r1 = x[31] - x[15];
|
||||
|
||||
x[30] += x[14];
|
||||
x[31] += x[15];
|
||||
x[14] = r0;
|
||||
x[15] = r1;
|
||||
|
||||
r0 = x[28] - x[12];
|
||||
r1 = x[29] - x[13];
|
||||
x[28] += x[12];
|
||||
x[29] += x[13];
|
||||
x[12] = MULT_NORM( r0 * cPI1_8 - r1 * cPI3_8 );
|
||||
x[13] = MULT_NORM( r0 * cPI3_8 + r1 * cPI1_8 );
|
||||
|
||||
r0 = x[26] - x[10];
|
||||
r1 = x[27] - x[11];
|
||||
x[26] += x[10];
|
||||
x[27] += x[11];
|
||||
x[10] = MULT_NORM(( r0 - r1 ) * cPI2_8);
|
||||
x[11] = MULT_NORM(( r0 + r1 ) * cPI2_8);
|
||||
|
||||
r0 = x[24] - x[8];
|
||||
r1 = x[25] - x[9];
|
||||
x[24] += x[8];
|
||||
x[25] += x[9];
|
||||
x[8] = MULT_NORM( r0 * cPI3_8 - r1 * cPI1_8 );
|
||||
x[9] = MULT_NORM( r1 * cPI3_8 + r0 * cPI1_8 );
|
||||
|
||||
r0 = x[22] - x[6];
|
||||
r1 = x[7] - x[23];
|
||||
x[22] += x[6];
|
||||
x[23] += x[7];
|
||||
x[6] = r1;
|
||||
x[7] = r0;
|
||||
|
||||
r0 = x[4] - x[20];
|
||||
r1 = x[5] - x[21];
|
||||
x[20] += x[4];
|
||||
x[21] += x[5];
|
||||
x[4] = MULT_NORM( r1 * cPI1_8 + r0 * cPI3_8 );
|
||||
x[5] = MULT_NORM( r1 * cPI3_8 - r0 * cPI1_8 );
|
||||
|
||||
r0 = x[2] - x[18];
|
||||
r1 = x[3] - x[19];
|
||||
x[18] += x[2];
|
||||
x[19] += x[3];
|
||||
x[2] = MULT_NORM(( r1 + r0 ) * cPI2_8);
|
||||
x[3] = MULT_NORM(( r1 - r0 ) * cPI2_8);
|
||||
|
||||
r0 = x[0] - x[16];
|
||||
r1 = x[1] - x[17];
|
||||
x[16] += x[0];
|
||||
x[17] += x[1];
|
||||
x[0] = MULT_NORM( r1 * cPI3_8 + r0 * cPI1_8 );
|
||||
x[1] = MULT_NORM( r1 * cPI1_8 - r0 * cPI3_8 );
|
||||
|
||||
mdct_butterfly_16(x);
|
||||
mdct_butterfly_16(x + 16);
|
||||
|
||||
}
|
||||
|
||||
/* N point first stage butterfly (in place, 2 register) */
|
||||
static void mdct_butterfly_first(EEL_F *T,
|
||||
EEL_F *x,
|
||||
int points) {
|
||||
|
||||
EEL_F *x1 = x + points - 8;
|
||||
EEL_F *x2 = x + (points >> 1) - 8;
|
||||
EEL_F r0;
|
||||
EEL_F r1;
|
||||
|
||||
do {
|
||||
|
||||
r0 = x1[6] - x2[6];
|
||||
r1 = x1[7] - x2[7];
|
||||
x1[6] += x2[6];
|
||||
x1[7] += x2[7];
|
||||
x2[6] = MULT_NORM(r1 * T[1] + r0 * T[0]);
|
||||
x2[7] = MULT_NORM(r1 * T[0] - r0 * T[1]);
|
||||
|
||||
r0 = x1[4] - x2[4];
|
||||
r1 = x1[5] - x2[5];
|
||||
x1[4] += x2[4];
|
||||
x1[5] += x2[5];
|
||||
x2[4] = MULT_NORM(r1 * T[5] + r0 * T[4]);
|
||||
x2[5] = MULT_NORM(r1 * T[4] - r0 * T[5]);
|
||||
|
||||
r0 = x1[2] - x2[2];
|
||||
r1 = x1[3] - x2[3];
|
||||
x1[2] += x2[2];
|
||||
x1[3] += x2[3];
|
||||
x2[2] = MULT_NORM(r1 * T[9] + r0 * T[8]);
|
||||
x2[3] = MULT_NORM(r1 * T[8] - r0 * T[9]);
|
||||
|
||||
r0 = x1[0] - x2[0];
|
||||
r1 = x1[1] - x2[1];
|
||||
x1[0] += x2[0];
|
||||
x1[1] += x2[1];
|
||||
x2[0] = MULT_NORM(r1 * T[13] + r0 * T[12]);
|
||||
x2[1] = MULT_NORM(r1 * T[12] - r0 * T[13]);
|
||||
|
||||
x1 -= 8;
|
||||
x2 -= 8;
|
||||
T += 16;
|
||||
|
||||
} while(x2 >= x);
|
||||
}
|
||||
|
||||
/* N/stage point generic N stage butterfly (in place, 2 register) */
|
||||
static void mdct_butterfly_generic(EEL_F *T,
|
||||
EEL_F *x,
|
||||
int points,
|
||||
int trigint) {
|
||||
|
||||
EEL_F *x1 = x + points - 8;
|
||||
EEL_F *x2 = x + (points >> 1) - 8;
|
||||
EEL_F r0;
|
||||
EEL_F r1;
|
||||
|
||||
do {
|
||||
|
||||
r0 = x1[6] - x2[6];
|
||||
r1 = x1[7] - x2[7];
|
||||
x1[6] += x2[6];
|
||||
x1[7] += x2[7];
|
||||
x2[6] = MULT_NORM(r1 * T[1] + r0 * T[0]);
|
||||
x2[7] = MULT_NORM(r1 * T[0] - r0 * T[1]);
|
||||
|
||||
T += trigint;
|
||||
|
||||
r0 = x1[4] - x2[4];
|
||||
r1 = x1[5] - x2[5];
|
||||
x1[4] += x2[4];
|
||||
x1[5] += x2[5];
|
||||
x2[4] = MULT_NORM(r1 * T[1] + r0 * T[0]);
|
||||
x2[5] = MULT_NORM(r1 * T[0] - r0 * T[1]);
|
||||
|
||||
T += trigint;
|
||||
|
||||
r0 = x1[2] - x2[2];
|
||||
r1 = x1[3] - x2[3];
|
||||
x1[2] += x2[2];
|
||||
x1[3] += x2[3];
|
||||
x2[2] = MULT_NORM(r1 * T[1] + r0 * T[0]);
|
||||
x2[3] = MULT_NORM(r1 * T[0] - r0 * T[1]);
|
||||
|
||||
T += trigint;
|
||||
|
||||
r0 = x1[0] - x2[0];
|
||||
r1 = x1[1] - x2[1];
|
||||
x1[0] += x2[0];
|
||||
x1[1] += x2[1];
|
||||
x2[0] = MULT_NORM(r1 * T[1] + r0 * T[0]);
|
||||
x2[1] = MULT_NORM(r1 * T[0] - r0 * T[1]);
|
||||
|
||||
T += trigint;
|
||||
x1 -= 8;
|
||||
x2 -= 8;
|
||||
|
||||
} while(x2 >= x);
|
||||
}
|
||||
|
||||
static void mdct_butterflies(mdct_lookup *init,
|
||||
EEL_F *x,
|
||||
int points) {
|
||||
|
||||
EEL_F *T = init->trig;
|
||||
int stages = init->log2n - 5;
|
||||
int i, j;
|
||||
|
||||
if(--stages > 0) {
|
||||
mdct_butterfly_first(T, x, points);
|
||||
}
|
||||
|
||||
for(i = 1; --stages > 0; i++) {
|
||||
for(j = 0; j < (1 << i); j++)
|
||||
mdct_butterfly_generic(T, x + (points >> i)*j, points >> i, 4 << i);
|
||||
}
|
||||
|
||||
for(j = 0; j < points; j += 32)
|
||||
mdct_butterfly_32(x + j);
|
||||
|
||||
}
|
||||
|
||||
static void mdct_bitreverse(mdct_lookup *init,
|
||||
EEL_F *x) {
|
||||
int n = init->n;
|
||||
int *bit = init->bitrev;
|
||||
EEL_F *w0 = x;
|
||||
EEL_F *w1 = x = w0 + (n >> 1);
|
||||
EEL_F *T = init->trig + n;
|
||||
|
||||
do {
|
||||
EEL_F *x0 = x + bit[0];
|
||||
EEL_F *x1 = x + bit[1];
|
||||
|
||||
EEL_F r0 = x0[1] - x1[1];
|
||||
EEL_F r1 = x0[0] + x1[0];
|
||||
EEL_F r2 = MULT_NORM(r1 * T[0] + r0 * T[1]);
|
||||
EEL_F r3 = MULT_NORM(r1 * T[1] - r0 * T[0]);
|
||||
|
||||
w1 -= 4;
|
||||
|
||||
r0 = HALVE(x0[1] + x1[1]);
|
||||
r1 = HALVE(x0[0] - x1[0]);
|
||||
|
||||
w0[0] = r0 + r2;
|
||||
w1[2] = r0 - r2;
|
||||
w0[1] = r1 + r3;
|
||||
w1[3] = r3 - r1;
|
||||
|
||||
x0 = x + bit[2];
|
||||
x1 = x + bit[3];
|
||||
|
||||
r0 = x0[1] - x1[1];
|
||||
r1 = x0[0] + x1[0];
|
||||
r2 = MULT_NORM(r1 * T[2] + r0 * T[3]);
|
||||
r3 = MULT_NORM(r1 * T[3] - r0 * T[2]);
|
||||
|
||||
r0 = HALVE(x0[1] + x1[1]);
|
||||
r1 = HALVE(x0[0] - x1[0]);
|
||||
|
||||
w0[2] = r0 + r2;
|
||||
w1[0] = r0 - r2;
|
||||
w0[3] = r1 + r3;
|
||||
w1[1] = r3 - r1;
|
||||
|
||||
T += 4;
|
||||
bit += 4;
|
||||
w0 += 4;
|
||||
|
||||
} while(w0 < w1);
|
||||
}
|
||||
|
||||
static void megabuf_mdct_apply_window(void *init, EEL_F *inbuf, EEL_F *outbuf)
|
||||
{
|
||||
mdct_lookup *p = (mdct_lookup *)init;
|
||||
EEL_F *w;
|
||||
int cnt;
|
||||
if (!p) return;
|
||||
|
||||
w = p->window;
|
||||
if (!w) return;
|
||||
|
||||
cnt = p->n / 2;
|
||||
while (cnt--) *outbuf++ = *inbuf++ * *w++;
|
||||
cnt = p->n / 2;
|
||||
while (cnt--) *outbuf++ = *inbuf++ * *--w;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void *megabuf_mdct_init(int n) {
|
||||
mdct_lookup *lookup = (mdct_lookup *)calloc(sizeof(mdct_lookup), 1);
|
||||
int i;
|
||||
EEL_F c = (PI / (EEL_F) n);
|
||||
int *bitrev;
|
||||
EEL_F *T;
|
||||
int n2, log2n;
|
||||
if (!lookup) return 0;
|
||||
|
||||
lookup->n = n;
|
||||
lookup->window = (EEL_F *)calloc(sizeof(EEL_F), n / 2);
|
||||
if (!lookup->window) return lookup;
|
||||
|
||||
for (i = 0; i < n / 2; i ++)
|
||||
{
|
||||
lookup->window[i] = sin(c * (i + 0.5));
|
||||
}
|
||||
|
||||
if (n <= 32) return lookup;
|
||||
bitrev = (int*)calloc(sizeof(int), (n / 4));
|
||||
lookup->bitrev = bitrev;
|
||||
if (!bitrev) return lookup;
|
||||
|
||||
T = (EEL_F*)calloc(sizeof(EEL_F), (n + n / 4));
|
||||
lookup->trig = T;
|
||||
if (!T) return lookup;
|
||||
|
||||
n2 = n >> 1;
|
||||
log2n = lookup->log2n = (int)(log((double)n) / log(2.0) + 0.5);
|
||||
|
||||
/* trig lookups... */
|
||||
|
||||
for(i = 0; i < n / 4; i++) {
|
||||
T[i * 2] = FLOAT_CONV(cos((PI / n) * (4 * i)));
|
||||
T[i * 2 + 1] = FLOAT_CONV(-sin((PI / n) * (4 * i)));
|
||||
T[n2 + i * 2] = FLOAT_CONV(cos((PI / (2 * n)) * (2 * i + 1)));
|
||||
T[n2 + i * 2 + 1] = FLOAT_CONV(sin((PI / (2 * n)) * (2 * i + 1)));
|
||||
}
|
||||
for(i = 0; i < n / 8; i++) {
|
||||
T[n + i * 2] = FLOAT_CONV(cos((PI / n) * (4 * i + 2)) * .5);
|
||||
T[n + i * 2 + 1] = FLOAT_CONV(-sin((PI / n) * (4 * i + 2)) * .5);
|
||||
}
|
||||
|
||||
/* bitreverse lookup... */
|
||||
|
||||
{
|
||||
int mask = (1 << (log2n - 1)) - 1, j;
|
||||
int msb = 1 << (log2n - 2);
|
||||
for(i = 0; i < n / 8; i++) {
|
||||
int acc = 0;
|
||||
for(j = 0; msb >> j; j++)
|
||||
if((msb >> j)&i)acc |= 1 << j;
|
||||
bitrev[i * 2] = ((~acc)&mask) - 1;
|
||||
bitrev[i * 2 + 1] = acc;
|
||||
|
||||
}
|
||||
}
|
||||
lookup->scale = FLOAT_CONV(4.f / n);
|
||||
return lookup;
|
||||
}
|
||||
|
||||
static void megabuf_mdct_backward(void *init, EEL_F *in, EEL_F *out) {
|
||||
mdct_lookup *lookup = (mdct_lookup *)init;
|
||||
int n, n2, n4;
|
||||
EEL_F *iX, *oX, *T;
|
||||
if (!lookup) return;
|
||||
n = lookup->n;
|
||||
if (n <= 32 || !lookup->bitrev || !lookup->trig)
|
||||
{
|
||||
imdct(in, out, n);
|
||||
return;
|
||||
}
|
||||
n2 = n >> 1;
|
||||
n4 = n >> 2;
|
||||
|
||||
/* rotate */
|
||||
|
||||
iX = in + n2 - 7;
|
||||
oX = out + n2 + n4;
|
||||
T = lookup->trig + n4;
|
||||
|
||||
do {
|
||||
oX -= 4;
|
||||
oX[0] = MULT_NORM(-iX[2] * T[3] - iX[0] * T[2]);
|
||||
oX[1] = MULT_NORM (iX[0] * T[3] - iX[2] * T[2]);
|
||||
oX[2] = MULT_NORM(-iX[6] * T[1] - iX[4] * T[0]);
|
||||
oX[3] = MULT_NORM (iX[4] * T[1] - iX[6] * T[0]);
|
||||
iX -= 8;
|
||||
T += 4;
|
||||
} while(iX >= in);
|
||||
|
||||
iX = in + n2 - 8;
|
||||
oX = out + n2 + n4;
|
||||
T = lookup->trig + n4;
|
||||
|
||||
do {
|
||||
T -= 4;
|
||||
oX[0] = MULT_NORM (iX[4] * T[3] + iX[6] * T[2]);
|
||||
oX[1] = MULT_NORM (iX[4] * T[2] - iX[6] * T[3]);
|
||||
oX[2] = MULT_NORM (iX[0] * T[1] + iX[2] * T[0]);
|
||||
oX[3] = MULT_NORM (iX[0] * T[0] - iX[2] * T[1]);
|
||||
iX -= 8;
|
||||
oX += 4;
|
||||
} while(iX >= in);
|
||||
|
||||
mdct_butterflies(lookup, out + n2, n2);
|
||||
mdct_bitreverse(lookup, out);
|
||||
|
||||
/* roatate + window */
|
||||
|
||||
{
|
||||
EEL_F *oX1 = out + n2 + n4;
|
||||
EEL_F *oX2 = out + n2 + n4;
|
||||
iX = out;
|
||||
T = lookup->trig + n2;
|
||||
|
||||
do {
|
||||
oX1 -= 4;
|
||||
|
||||
oX1[3] = MULT_NORM (iX[0] * T[1] - iX[1] * T[0]);
|
||||
oX2[0] = -MULT_NORM (iX[0] * T[0] + iX[1] * T[1]);
|
||||
|
||||
oX1[2] = MULT_NORM (iX[2] * T[3] - iX[3] * T[2]);
|
||||
oX2[1] = -MULT_NORM (iX[2] * T[2] + iX[3] * T[3]);
|
||||
|
||||
oX1[1] = MULT_NORM (iX[4] * T[5] - iX[5] * T[4]);
|
||||
oX2[2] = -MULT_NORM (iX[4] * T[4] + iX[5] * T[5]);
|
||||
|
||||
oX1[0] = MULT_NORM (iX[6] * T[7] - iX[7] * T[6]);
|
||||
oX2[3] = -MULT_NORM (iX[6] * T[6] + iX[7] * T[7]);
|
||||
|
||||
oX2 += 4;
|
||||
iX += 8;
|
||||
T += 8;
|
||||
} while(iX < oX1);
|
||||
|
||||
iX = out + n2 + n4;
|
||||
oX1 = out + n4;
|
||||
oX2 = oX1;
|
||||
|
||||
do {
|
||||
oX1 -= 4;
|
||||
iX -= 4;
|
||||
|
||||
oX2[0] = -(oX1[3] = iX[3]);
|
||||
oX2[1] = -(oX1[2] = iX[2]);
|
||||
oX2[2] = -(oX1[1] = iX[1]);
|
||||
oX2[3] = -(oX1[0] = iX[0]);
|
||||
|
||||
oX2 += 4;
|
||||
} while(oX2 < iX);
|
||||
|
||||
iX = out + n2 + n4;
|
||||
oX1 = out + n2 + n4;
|
||||
oX2 = out + n2;
|
||||
do {
|
||||
oX1 -= 4;
|
||||
oX1[0] = iX[3];
|
||||
oX1[1] = iX[2];
|
||||
oX1[2] = iX[1];
|
||||
oX1[3] = iX[0];
|
||||
iX += 4;
|
||||
} while(oX1 > oX2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void megabuf_mdct_forward(void *init, EEL_F *in, EEL_F *out) {
|
||||
mdct_lookup *lookup = (mdct_lookup *)init;
|
||||
int n, n2, n4, n8;
|
||||
EEL_F *w, *w2;
|
||||
if (!lookup) return;
|
||||
|
||||
n = lookup->n;
|
||||
if (n <= 32 || !lookup->bitrev || !lookup->trig)
|
||||
{
|
||||
mdct(in, out, n);
|
||||
return;
|
||||
}
|
||||
n2 = n >> 1;
|
||||
n4 = n >> 2;
|
||||
n8 = n >> 3;
|
||||
EEL_F oldw[1<<EEL_DCT_MAXBITLEN];
|
||||
w = oldw;
|
||||
w2 = w + n2;
|
||||
|
||||
/* rotate */
|
||||
|
||||
/* window + rotate + step 1 */
|
||||
|
||||
{
|
||||
EEL_F r0;
|
||||
EEL_F r1;
|
||||
EEL_F *x0 = in + n2 + n4;
|
||||
EEL_F *x1 = x0 + 1;
|
||||
EEL_F *T = lookup->trig + n2;
|
||||
|
||||
int i = 0;
|
||||
|
||||
for(i = 0; i < n8; i += 2) {
|
||||
x0 -= 4;
|
||||
T -= 2;
|
||||
r0 = x0[2] + x1[0];
|
||||
r1 = x0[0] + x1[2];
|
||||
w2[i] = MULT_NORM(r1 * T[1] + r0 * T[0]);
|
||||
w2[i + 1] = MULT_NORM(r1 * T[0] - r0 * T[1]);
|
||||
x1 += 4;
|
||||
}
|
||||
|
||||
x1 = in + 1;
|
||||
|
||||
for(; i < n2 - n8; i += 2) {
|
||||
T -= 2;
|
||||
x0 -= 4;
|
||||
r0 = x0[2] - x1[0];
|
||||
r1 = x0[0] - x1[2];
|
||||
w2[i] = MULT_NORM(r1 * T[1] + r0 * T[0]);
|
||||
w2[i + 1] = MULT_NORM(r1 * T[0] - r0 * T[1]);
|
||||
x1 += 4;
|
||||
}
|
||||
|
||||
x0 = in + n;
|
||||
|
||||
for(; i < n2; i += 2) {
|
||||
T -= 2;
|
||||
x0 -= 4;
|
||||
r0 = -x0[2] - x1[0];
|
||||
r1 = -x0[0] - x1[2];
|
||||
w2[i] = MULT_NORM(r1 * T[1] + r0 * T[0]);
|
||||
w2[i + 1] = MULT_NORM(r1 * T[0] - r0 * T[1]);
|
||||
x1 += 4;
|
||||
}
|
||||
|
||||
|
||||
mdct_butterflies(lookup, w + n2, n2);
|
||||
mdct_bitreverse(lookup, w);
|
||||
|
||||
/* roatate + window */
|
||||
|
||||
T = lookup->trig + n2;
|
||||
x0 = out + n2;
|
||||
|
||||
for(i = 0; i < n4; i++) {
|
||||
x0--;
|
||||
out[i] = MULT_NORM((w[0] * T[0] + w[1] * T[1]) * lookup->scale);
|
||||
x0[0] = MULT_NORM((w[0] * T[1] - w[1] * T[0]) * lookup->scale);
|
||||
w += 2;
|
||||
T += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
static void dct(EEL_F *in, EEL_F *out, int len)
|
||||
{
|
||||
int k;
|
||||
EEL_F wk = sqrt(2.0 / len);
|
||||
EEL_F overtwolen = 0.5 / (EEL_F)len;
|
||||
for (k = 0; k < len; k ++)
|
||||
{
|
||||
int n;
|
||||
EEL_F d = 0.0;
|
||||
for (n = 0; n < len; n ++)
|
||||
{
|
||||
int an = n + 1;
|
||||
d += in[n] * cos(PI * (2.0 * n + 1.0) * (EEL_F)k * overtwolen);
|
||||
}
|
||||
if (!k) d /= sqrt(len);
|
||||
else d *= wk;
|
||||
out[k] = (EEL_F)d;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void idct(EEL_F *in, EEL_F *out, int len)
|
||||
{
|
||||
int n;
|
||||
EEL_F dd0 = 1.0 / sqrt(len);
|
||||
EEL_F dd1 = sqrt(2.0 / len);
|
||||
EEL_F overtwolen = 0.5 / len;
|
||||
for (n = 0; n < len; n ++)
|
||||
{
|
||||
int k;
|
||||
EEL_F d = 0.0;
|
||||
for (k = 0; k < len; k ++)
|
||||
{
|
||||
EEL_F dd;
|
||||
if (!k) dd = dd0 * in[k];
|
||||
else dd = dd1 * in[k];
|
||||
d += dd * cos(PI * (2.0 * n + 1.0) * k * overtwolen);
|
||||
}
|
||||
out[n] = (EEL_F)d;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// 0 is megabuf blocks
|
||||
// 1 is need_free flag
|
||||
|
||||
|
||||
static EEL_F * NSEEL_CGEN_CALL mdct_func(int dir, EEL_F **blocks, EEL_F *start, EEL_F *length)
|
||||
{
|
||||
int l = (int)(*length + 0.0001);
|
||||
int offs = (int)(*start + 0.0001);
|
||||
int bitl = 0;
|
||||
int ilen;
|
||||
int bidx;
|
||||
EEL_F *ptr;
|
||||
while (l > 1 && bitl < EEL_DCT_MAXBITLEN)
|
||||
{
|
||||
bitl++;
|
||||
l >>= 1;
|
||||
}
|
||||
if (bitl < EEL_DCT_MINBITLEN)
|
||||
{
|
||||
return start;
|
||||
}
|
||||
ilen = 1 << bitl;
|
||||
|
||||
bidx = bitl - EEL_DCT_MINBITLEN;
|
||||
|
||||
|
||||
// check to make sure we don't cross a boundary
|
||||
if (offs / NSEEL_RAM_ITEMSPERBLOCK != (offs + ilen * 2 - 1) / NSEEL_RAM_ITEMSPERBLOCK)
|
||||
{
|
||||
return start;
|
||||
}
|
||||
|
||||
ptr = __NSEEL_RAMAlloc(blocks, offs);
|
||||
if (!ptr || ptr == &nseel_ramalloc_onfail)
|
||||
{
|
||||
return start;
|
||||
}
|
||||
|
||||
if (ilen > 1)
|
||||
{
|
||||
static void *mdct_ctxs[1 + EEL_DCT_MAXBITLEN - EEL_DCT_MINBITLEN];
|
||||
|
||||
if (!mdct_ctxs[bidx])
|
||||
{
|
||||
NSEEL_HOSTSTUB_EnterMutex();
|
||||
if (!mdct_ctxs[bidx])
|
||||
mdct_ctxs[bidx] = megabuf_mdct_init(ilen);
|
||||
NSEEL_HOSTSTUB_LeaveMutex();
|
||||
}
|
||||
|
||||
if (mdct_ctxs[bidx])
|
||||
{
|
||||
EEL_F buf[1 << EEL_DCT_MAXBITLEN];
|
||||
if (dir < 0)
|
||||
{
|
||||
megabuf_mdct_backward(mdct_ctxs[bidx], ptr, buf);
|
||||
megabuf_mdct_apply_window(mdct_ctxs[bidx], buf, ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
megabuf_mdct_apply_window(mdct_ctxs[bidx], ptr, buf);
|
||||
megabuf_mdct_forward(mdct_ctxs[bidx], buf, ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static EEL_F * NSEEL_CGEN_CALL megabuf_mdct(EEL_F **blocks, EEL_F *start, EEL_F *length)
|
||||
{
|
||||
return mdct_func(0, blocks, start, length);
|
||||
}
|
||||
|
||||
static EEL_F * NSEEL_CGEN_CALL megabuf_imdct(EEL_F **blocks, EEL_F *start, EEL_F *length)
|
||||
{
|
||||
return mdct_func(-1, blocks, start, length);
|
||||
}
|
||||
|
||||
void EEL_mdct_register()
|
||||
{
|
||||
NSEEL_addfunc_retptr("mdct", 2, NSEEL_PProc_RAM, &megabuf_mdct);
|
||||
NSEEL_addfunc_retptr("imdct", 2, NSEEL_PProc_RAM, &megabuf_imdct);
|
||||
}
|
||||
|
||||
#ifdef EEL_WANT_DOCUMENTATION
|
||||
static const char *eel_mdct_function_reference =
|
||||
"mdct\tbuffer,length\tPerforms a windowed modified DCT, taking length inputs and producing length/2 outputs. buffer must not cross a 65,536 item boundary, and length must be 64, 128, 256, 512, 2048 or 4096.\0"
|
||||
"imdct\tbuffer,length\tPerforms a windowed inverse modified DCT, taking length/2 inputs and producing length outputs. buffer must not cross a 65,536 item boundary, and length must be 64, 128, 256, 512, 2048 or 4096.\0"
|
||||
;
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
73
oversampling/WDL/eel2/eel_misc.h
Normal file
73
oversampling/WDL/eel2/eel_misc.h
Normal file
@@ -0,0 +1,73 @@
|
||||
#ifndef _EEL_MISC_H_
|
||||
#define _EEL_MISC_H_
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include <time.h>
|
||||
// some generic EEL functions for things like time
|
||||
|
||||
#ifndef EEL_MISC_NO_SLEEP
|
||||
static EEL_F NSEEL_CGEN_CALL _eel_sleep(void *opaque, EEL_F *amt)
|
||||
{
|
||||
if (*amt >= 0.0)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (*amt > 30000000.0) Sleep(30000000);
|
||||
else Sleep((DWORD)(*amt+0.5));
|
||||
#else
|
||||
if (*amt > 30000000.0) usleep(((useconds_t)30000000)*1000);
|
||||
else usleep((useconds_t)(*amt*1000.0+0.5));
|
||||
#endif
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static EEL_F * NSEEL_CGEN_CALL _eel_time(void *opaque, EEL_F *v)
|
||||
{
|
||||
*v = (EEL_F) time(NULL);
|
||||
return v;
|
||||
}
|
||||
|
||||
static EEL_F * NSEEL_CGEN_CALL _eel_time_precise(void *opaque, EEL_F *v)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
LARGE_INTEGER freq,now;
|
||||
QueryPerformanceFrequency(&freq);
|
||||
QueryPerformanceCounter(&now);
|
||||
*v = (double)now.QuadPart / (double)freq.QuadPart;
|
||||
// *v = (EEL_F)timeGetTime() * 0.001;
|
||||
#else
|
||||
struct timeval tm={0,};
|
||||
gettimeofday(&tm,NULL);
|
||||
*v = tm.tv_sec + tm.tv_usec*0.000001;
|
||||
#endif
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
void EEL_misc_register()
|
||||
{
|
||||
#ifndef EEL_MISC_NO_SLEEP
|
||||
NSEEL_addfunc_retval("sleep",1,NSEEL_PProc_THIS,&_eel_sleep);
|
||||
#endif
|
||||
NSEEL_addfunc_retptr("time",1,NSEEL_PProc_THIS,&_eel_time);
|
||||
NSEEL_addfunc_retptr("time_precise",1,NSEEL_PProc_THIS,&_eel_time_precise);
|
||||
}
|
||||
|
||||
#ifdef EEL_WANT_DOCUMENTATION
|
||||
static const char *eel_misc_function_reference =
|
||||
#ifndef EEL_MISC_NO_SLEEP
|
||||
"sleep\tms\tYields the CPU for the millisecond count specified, calling Sleep() on Windows or usleep() on other platforms.\0"
|
||||
#endif
|
||||
"time\t[&val]\tSets the parameter (or a temporary buffer if omitted) to the number of seconds since January 1, 1970, and returns a reference to that value. "
|
||||
"The granularity of the value returned is 1 second.\0"
|
||||
"time_precise\t[&val]\tSets the parameter (or a temporary buffer if omitted) to a system-local timestamp in seconds, and returns a reference to that value. "
|
||||
"The granularity of the value returned is system defined (but generally significantly smaller than one second).\0"
|
||||
;
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
564
oversampling/WDL/eel2/eel_net.h
Normal file
564
oversampling/WDL/eel2/eel_net.h
Normal file
@@ -0,0 +1,564 @@
|
||||
#ifndef _EEL_NET_H_
|
||||
#define _EEL_NET_H_
|
||||
|
||||
// x = tcp_listen(port[,interface, connected_ip_out]) poll this, returns connection id > 0, or <0 on error, or 0 if no new connect -- interface only valid on first call (or after tcp_listen_end(port))
|
||||
// tcp_listen_end(port);
|
||||
|
||||
// connection = tcp_connect(host, port[, block]) // connection id > 0 on ok
|
||||
// tcp_set_block(connection, block?)
|
||||
// tcp_close(connection)
|
||||
|
||||
// tcp_send(connection, string[, length]) // can return 0 if block, -1 if error, otherwise returns length sent
|
||||
// tcp_recv(connection, string[, maxlength]) // 0 on nothing, -1 on error, otherwise returns length recv'd
|
||||
|
||||
|
||||
// need:
|
||||
// #define EEL_NET_GET_CONTEXT(opaque) (((sInst *)opaque)->m_net_state)
|
||||
|
||||
// you must pass a JNL_AsyncDNS object to eel_net_state to support nonblocking connect with DNS resolution, otherwise DNS will block
|
||||
// #define EEL_NET_NO_SYNC_DNS -- never ever call gethostbyname() synchronously, may disable DNS for blocking connect, or if a JNL_IAsyncDNS is not provided.
|
||||
|
||||
#ifndef EEL_NET_MAXSEND
|
||||
#define EEL_NET_MAXSEND (EEL_STRING_MAXUSERSTRING_LENGTH_HINT+4096)
|
||||
#endif
|
||||
|
||||
|
||||
#include "../jnetlib/netinc.h"
|
||||
#define JNL_NO_IMPLEMENTATION
|
||||
#include "../jnetlib/asyncdns.h"
|
||||
|
||||
class eel_net_state
|
||||
{
|
||||
public:
|
||||
enum { STATE_FREE=0, STATE_RESOLVING, STATE_CONNECTED, STATE_ERR };
|
||||
enum { CONNECTION_ID_BASE=0x110000 };
|
||||
|
||||
eel_net_state(int max_con, JNL_IAsyncDNS *dns);
|
||||
~eel_net_state();
|
||||
|
||||
struct connection_state {
|
||||
char *hostname; // set during resolve only
|
||||
SOCKET sock;
|
||||
int state; // STATE_RESOLVING...
|
||||
int port;
|
||||
bool blockmode;
|
||||
};
|
||||
WDL_TypedBuf<connection_state> m_cons;
|
||||
WDL_IntKeyedArray<SOCKET> m_listens;
|
||||
JNL_IAsyncDNS *m_dns;
|
||||
|
||||
EEL_F onConnect(char *hostNameOwned, int port, int block);
|
||||
EEL_F onClose(void *opaque, EEL_F handle);
|
||||
EEL_F set_block(void *opaque, EEL_F handle, bool block);
|
||||
EEL_F onListen(void *opaque, EEL_F handle, int mode, EEL_F *ifStr, EEL_F *ipOut);
|
||||
|
||||
int __run_connect(connection_state *cs, unsigned int ip);
|
||||
int __run(connection_state *cs);
|
||||
int do_send(void *opaque, EEL_F h, const char *src, int len);
|
||||
int do_recv(void *opaque, EEL_F h, char *buf, int maxlen);
|
||||
#ifdef _WIN32
|
||||
bool m_had_socketlib_init;
|
||||
#endif
|
||||
};
|
||||
|
||||
eel_net_state::eel_net_state(int max_con, JNL_IAsyncDNS *dns)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
m_had_socketlib_init=false;
|
||||
#endif
|
||||
|
||||
m_cons.Resize(max_con);
|
||||
int x;
|
||||
for (x=0;x<m_cons.GetSize();x++)
|
||||
{
|
||||
m_cons.Get()[x].state = STATE_FREE;
|
||||
m_cons.Get()[x].sock = INVALID_SOCKET;
|
||||
m_cons.Get()[x].hostname = NULL;
|
||||
}
|
||||
m_dns=dns;
|
||||
}
|
||||
|
||||
eel_net_state::~eel_net_state()
|
||||
{
|
||||
int x;
|
||||
for (x=0;x<m_cons.GetSize();x++)
|
||||
{
|
||||
SOCKET s=m_cons.Get()[x].sock;
|
||||
if (s != INVALID_SOCKET)
|
||||
{
|
||||
shutdown(s,SHUT_RDWR);
|
||||
closesocket(s);
|
||||
}
|
||||
free(m_cons.Get()[x].hostname);
|
||||
}
|
||||
for (x=0;x<m_listens.GetSize();x++)
|
||||
{
|
||||
SOCKET s=m_listens.Enumerate(x);
|
||||
shutdown(s, SHUT_RDWR);
|
||||
closesocket(s);
|
||||
}
|
||||
}
|
||||
EEL_F eel_net_state::onConnect(char *hostNameOwned, int port, int block)
|
||||
{
|
||||
int x;
|
||||
#ifdef _WIN32
|
||||
if (!m_had_socketlib_init)
|
||||
{
|
||||
m_had_socketlib_init=1;
|
||||
WSADATA wsaData;
|
||||
WSAStartup(MAKEWORD(1, 1), &wsaData);
|
||||
}
|
||||
#endif
|
||||
for(x=0;x<m_cons.GetSize();x++)
|
||||
{
|
||||
connection_state *s=m_cons.Get()+x;
|
||||
if (s->state == STATE_FREE)
|
||||
{
|
||||
unsigned int ip=inet_addr(hostNameOwned);
|
||||
if (m_dns && ip == INADDR_NONE && !block)
|
||||
{
|
||||
const int r=m_dns->resolve(hostNameOwned,&ip);
|
||||
if (r<0) break; // error!
|
||||
|
||||
if (r>0) ip = INADDR_NONE;
|
||||
}
|
||||
#ifndef EEL_NET_NO_SYNC_DNS
|
||||
else if (ip == INADDR_NONE)
|
||||
{
|
||||
struct hostent *he = gethostbyname(hostNameOwned);
|
||||
if (he) ip = *(int *)he->h_addr;
|
||||
}
|
||||
#endif
|
||||
if (hostNameOwned || ip != INADDR_NONE)
|
||||
{
|
||||
if (ip != INADDR_NONE)
|
||||
{
|
||||
free(hostNameOwned);
|
||||
hostNameOwned=NULL;
|
||||
}
|
||||
|
||||
s->state = STATE_RESOLVING;
|
||||
s->hostname = hostNameOwned;
|
||||
s->blockmode = !!block;
|
||||
s->port = port;
|
||||
if (hostNameOwned || __run_connect(s,ip)) return x + CONNECTION_ID_BASE;
|
||||
|
||||
s->state=STATE_FREE;
|
||||
s->hostname=NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(hostNameOwned);
|
||||
return -1;
|
||||
}
|
||||
|
||||
EEL_F eel_net_state::onListen(void *opaque, EEL_F handle, int mode, EEL_F *ifStr, EEL_F *ipOut)
|
||||
{
|
||||
const int port = (int) handle;
|
||||
if (port < 1 || port > 65535)
|
||||
{
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
EEL_STRING_DEBUGOUT("tcp_listen(%d): invalid port specified, will never succeed",port);
|
||||
#endif
|
||||
return 0.0;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
if (!m_had_socketlib_init)
|
||||
{
|
||||
m_had_socketlib_init=1;
|
||||
WSADATA wsaData;
|
||||
WSAStartup(MAKEWORD(1, 1), &wsaData);
|
||||
}
|
||||
#endif
|
||||
SOCKET *sockptr = m_listens.GetPtr(port);
|
||||
if (mode<0)
|
||||
{
|
||||
if (!sockptr) return -1.0;
|
||||
|
||||
SOCKET ss=*sockptr;
|
||||
m_listens.Delete(port);
|
||||
if (ss != INVALID_SOCKET)
|
||||
{
|
||||
shutdown(ss, SHUT_RDWR);
|
||||
closesocket(ss);
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
if (!sockptr)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
memset((char *) &sin, 0,sizeof(sin));
|
||||
if (ifStr)
|
||||
{
|
||||
EEL_STRING_MUTEXLOCK_SCOPE
|
||||
const char *fn = EEL_STRING_GET_FOR_INDEX(*ifStr,NULL);
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
if (!fn) EEL_STRING_DEBUGOUT("tcp_listen(%d): bad string identifier %f for second parameter (interface)",port,*ifStr);
|
||||
#endif
|
||||
if (fn && *fn) sin.sin_addr.s_addr=inet_addr(fn);
|
||||
|
||||
}
|
||||
if (!sin.sin_addr.s_addr || sin.sin_addr.s_addr==INADDR_NONE) sin.sin_addr.s_addr = INADDR_ANY;
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons( (short) port );
|
||||
SOCKET sock = socket(AF_INET,SOCK_STREAM,0);
|
||||
if (sock != INVALID_SOCKET)
|
||||
{
|
||||
SET_SOCK_DEFAULTS(sock);
|
||||
SET_SOCK_BLOCK(sock,0);
|
||||
if (bind(sock,(struct sockaddr *)&sin,sizeof(sin)) || listen(sock,8)==-1)
|
||||
{
|
||||
shutdown(sock, SHUT_RDWR);
|
||||
closesocket(sock);
|
||||
sock=INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
//if (sock == INVALID_SOCKET) EEL_STRING_DEBUGOUT("tcp_listen(%d): failed listening on port",port);
|
||||
// we report -1 to the caller, no need to error message
|
||||
#endif
|
||||
m_listens.Insert(port,sock);
|
||||
sockptr = m_listens.GetPtr(port);
|
||||
}
|
||||
if (!sockptr || *sockptr == INVALID_SOCKET) return -1;
|
||||
|
||||
struct sockaddr_in saddr;
|
||||
socklen_t length = sizeof(struct sockaddr_in);
|
||||
SOCKET newsock = accept(*sockptr, (struct sockaddr *) &saddr, &length);
|
||||
if (newsock == INVALID_SOCKET)
|
||||
{
|
||||
return 0; // nothing to report here
|
||||
}
|
||||
SET_SOCK_DEFAULTS(newsock);
|
||||
|
||||
int x;
|
||||
for(x=0;x<m_cons.GetSize();x++)
|
||||
{
|
||||
connection_state *cs=m_cons.Get()+x;
|
||||
if (cs->state == STATE_FREE)
|
||||
{
|
||||
cs->state=STATE_CONNECTED;
|
||||
free(cs->hostname);
|
||||
cs->hostname=NULL;
|
||||
cs->sock = newsock;
|
||||
cs->blockmode=true;
|
||||
cs->port=0;
|
||||
if (ipOut)
|
||||
{
|
||||
EEL_STRING_MUTEXLOCK_SCOPE
|
||||
WDL_FastString *ws=NULL;
|
||||
EEL_STRING_GET_FOR_WRITE(*ipOut,&ws);
|
||||
if (ws)
|
||||
{
|
||||
const unsigned int a = ntohl(saddr.sin_addr.s_addr);
|
||||
ws->SetFormatted(128,"%d.%d.%d.%d",(a>>24)&0xff,(a>>16)&0xff,(a>>8)&0xff,a&0xff);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
EEL_STRING_DEBUGOUT("tcp_listen(%d): bad string identifier %f for third parameter (IP-out)",port,*ipOut);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return x + CONNECTION_ID_BASE;
|
||||
}
|
||||
}
|
||||
shutdown(newsock, SHUT_RDWR);
|
||||
closesocket(newsock);
|
||||
return -1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
int eel_net_state::__run_connect(connection_state *cs, unsigned int ip)
|
||||
{
|
||||
SOCKET s=socket(AF_INET,SOCK_STREAM,0);
|
||||
if (s == INVALID_SOCKET) return 0;
|
||||
SET_SOCK_DEFAULTS(s);
|
||||
|
||||
if (!cs->blockmode) SET_SOCK_BLOCK(s,0);
|
||||
|
||||
struct sockaddr_in sa={0,};
|
||||
sa.sin_family=AF_INET;
|
||||
sa.sin_addr.s_addr = ip;
|
||||
sa.sin_port = htons(cs->port);
|
||||
if (!connect(s,(struct sockaddr *)&sa,16) || (!cs->blockmode && JNL_ERRNO == JNL_EINPROGRESS))
|
||||
{
|
||||
cs->state = STATE_CONNECTED;
|
||||
cs->sock = s;
|
||||
return 1;
|
||||
}
|
||||
shutdown(s, SHUT_RDWR);
|
||||
closesocket(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int eel_net_state::__run(connection_state *cs)
|
||||
{
|
||||
if (cs->sock != INVALID_SOCKET) return 0;
|
||||
|
||||
if (!cs->hostname) return -1;
|
||||
|
||||
unsigned int ip=INADDR_NONE;
|
||||
const int r=m_dns ? m_dns->resolve(cs->hostname,&ip) : -1;
|
||||
if (r>0) return 0;
|
||||
|
||||
free(cs->hostname);
|
||||
cs->hostname=NULL;
|
||||
|
||||
if (r<0 || !__run_connect(cs,ip))
|
||||
{
|
||||
cs->state = STATE_ERR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int eel_net_state::do_recv(void *opaque, EEL_F h, char *buf, int maxlen)
|
||||
{
|
||||
const int idx=(int)h-CONNECTION_ID_BASE;
|
||||
if (idx>=0 && idx<m_cons.GetSize())
|
||||
{
|
||||
connection_state *s=m_cons.Get()+idx;
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
if (s->sock == INVALID_SOCKET && !s->hostname)
|
||||
EEL_STRING_DEBUGOUT("tcp_recv: connection identifier %f is not open",h);
|
||||
#endif
|
||||
if (__run(s) || s->sock == INVALID_SOCKET) return s->state == STATE_ERR ? -1 : 0;
|
||||
|
||||
if (maxlen == 0) return 0;
|
||||
|
||||
const int rv=(int)recv(s->sock,buf,maxlen,0);
|
||||
if (rv < 0 && !s->blockmode && (JNL_ERRNO == JNL_EWOULDBLOCK || JNL_ERRNO == JNL_ENOTCONN)) return 0;
|
||||
|
||||
if (!rv) return -1; // TCP, 0=connection terminated
|
||||
|
||||
return rv;
|
||||
}
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
EEL_STRING_DEBUGOUT("tcp_recv: connection identifier %f is out of range",h);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
int eel_net_state::do_send(void *opaque, EEL_F h, const char *src, int len)
|
||||
{
|
||||
const int idx=(int)h-CONNECTION_ID_BASE;
|
||||
if (idx>=0 && idx<m_cons.GetSize())
|
||||
{
|
||||
connection_state *s=m_cons.Get()+idx;
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
if (s->sock == INVALID_SOCKET && !s->hostname)
|
||||
EEL_STRING_DEBUGOUT("tcp_send: connection identifier %f is not open",h);
|
||||
#endif
|
||||
if (__run(s) || s->sock == INVALID_SOCKET) return s->state == STATE_ERR ? -1 : 0;
|
||||
const int rv=(int)send(s->sock,src,len,0);
|
||||
if (rv < 0 && !s->blockmode && (JNL_ERRNO == JNL_EWOULDBLOCK || JNL_ERRNO == JNL_ENOTCONN)) return 0;
|
||||
return rv;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
EEL_STRING_DEBUGOUT("tcp_send: connection identifier %f out of range",h);
|
||||
#endif
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
EEL_F eel_net_state::set_block(void *opaque, EEL_F handle, bool block)
|
||||
{
|
||||
int idx=(int)handle-CONNECTION_ID_BASE;
|
||||
if (idx>=0 && idx<m_cons.GetSize())
|
||||
{
|
||||
connection_state *s=m_cons.Get()+idx;
|
||||
if (s->blockmode != block)
|
||||
{
|
||||
s->blockmode=block;
|
||||
if (s->sock != INVALID_SOCKET)
|
||||
{
|
||||
SET_SOCK_BLOCK(s->sock,(block?1:0));
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
if (!s->hostname) EEL_STRING_DEBUGOUT("tcp_set_block: connection identifier %f is not open",handle);
|
||||
#endif
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
EEL_STRING_DEBUGOUT("tcp_set_block: connection identifier %f out of range",handle);
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
EEL_F eel_net_state::onClose(void *opaque, EEL_F handle)
|
||||
{
|
||||
int idx=(int)handle-CONNECTION_ID_BASE;
|
||||
if (idx>=0 && idx<m_cons.GetSize())
|
||||
{
|
||||
connection_state *s=m_cons.Get()+idx;
|
||||
const bool hadhn = !!s->hostname;
|
||||
free(s->hostname);
|
||||
s->hostname = NULL;
|
||||
s->state = STATE_ERR;
|
||||
if (s->sock != INVALID_SOCKET)
|
||||
{
|
||||
shutdown(s->sock,SHUT_RDWR);
|
||||
closesocket(s->sock);
|
||||
s->sock = INVALID_SOCKET;
|
||||
return 1.0;
|
||||
}
|
||||
else if (!hadhn)
|
||||
{
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
EEL_STRING_DEBUGOUT("tcp_close: connection identifier %f is not open",handle);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
EEL_STRING_DEBUGOUT("tcp_close: connection identifier %f is out of range",handle);
|
||||
#endif
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
|
||||
static EEL_F NSEEL_CGEN_CALL _eel_tcp_connect(void *opaque, INT_PTR np, EEL_F **parms)
|
||||
{
|
||||
eel_net_state *ctx;
|
||||
if (np > 1 && NULL != (ctx=EEL_NET_GET_CONTEXT(opaque)))
|
||||
{
|
||||
char *dest=NULL;
|
||||
{
|
||||
EEL_STRING_MUTEXLOCK_SCOPE
|
||||
const char *fn = EEL_STRING_GET_FOR_INDEX(parms[0][0],NULL);
|
||||
if (fn) dest=strdup(fn);
|
||||
else
|
||||
{
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
EEL_STRING_DEBUGOUT("tcp_connect(): host string identifier %f invalid",parms[0][0]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (dest) return ctx->onConnect(dest, (int) (parms[1][0]+0.5), np < 3 || parms[2][0] >= 0.5);
|
||||
}
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
static EEL_F NSEEL_CGEN_CALL _eel_tcp_set_block(void *opaque, EEL_F *handle, EEL_F *bl)
|
||||
{
|
||||
eel_net_state *ctx;
|
||||
if (NULL != (ctx=EEL_NET_GET_CONTEXT(opaque))) return ctx->set_block(opaque,*handle, *bl >= 0.5);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static EEL_F NSEEL_CGEN_CALL _eel_tcp_close(void *opaque, EEL_F *handle)
|
||||
{
|
||||
eel_net_state *ctx;
|
||||
if (NULL != (ctx=EEL_NET_GET_CONTEXT(opaque))) return ctx->onClose(opaque,*handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static EEL_F NSEEL_CGEN_CALL _eel_tcp_recv(void *opaque, INT_PTR np, EEL_F **parms)
|
||||
{
|
||||
eel_net_state *ctx;
|
||||
if (np > 1 && NULL != (ctx=EEL_NET_GET_CONTEXT(opaque)))
|
||||
{
|
||||
char buf[EEL_STRING_MAXUSERSTRING_LENGTH_HINT];
|
||||
int ml = np > 2 ? (int)parms[2][0] : 4096;
|
||||
if (ml < 0 || ml > EEL_STRING_MAXUSERSTRING_LENGTH_HINT) ml = EEL_STRING_MAXUSERSTRING_LENGTH_HINT;
|
||||
|
||||
ml=ctx->do_recv(opaque,parms[0][0],buf,ml);
|
||||
|
||||
{
|
||||
EEL_STRING_MUTEXLOCK_SCOPE
|
||||
WDL_FastString *ws=NULL;
|
||||
EEL_STRING_GET_FOR_WRITE(parms[1][0],&ws);
|
||||
if (ws)
|
||||
{
|
||||
if (ml<=0) ws->Set("");
|
||||
else ws->SetRaw(buf,ml);
|
||||
}
|
||||
}
|
||||
return ml;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static EEL_F NSEEL_CGEN_CALL _eel_tcp_send(void *opaque, INT_PTR np, EEL_F **parms)
|
||||
{
|
||||
eel_net_state *ctx;
|
||||
if (np > 1 && NULL != (ctx=EEL_NET_GET_CONTEXT(opaque)))
|
||||
{
|
||||
char buf[EEL_NET_MAXSEND];
|
||||
|
||||
int l;
|
||||
{
|
||||
EEL_STRING_MUTEXLOCK_SCOPE
|
||||
WDL_FastString *ws=NULL;
|
||||
const char *fn = EEL_STRING_GET_FOR_INDEX(parms[1][0],&ws);
|
||||
l = ws ? ws->GetLength() : (int) strlen(fn);
|
||||
if (np > 2)
|
||||
{
|
||||
int al=(int)parms[2][0];
|
||||
if (al<0) al=0;
|
||||
if (al<l) l=al;
|
||||
}
|
||||
if (l > 0) memcpy(buf,fn,l);
|
||||
}
|
||||
if (l>0) return ctx->do_send(opaque,parms[0][0],buf,l);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static EEL_F NSEEL_CGEN_CALL _eel_tcp_listen(void *opaque, INT_PTR np, EEL_F **parms)
|
||||
{
|
||||
eel_net_state *ctx;
|
||||
if (NULL != (ctx=EEL_NET_GET_CONTEXT(opaque))) return ctx->onListen(opaque,parms[0][0],1,np>1?parms[1]:NULL,np>2?parms[2]:NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static EEL_F NSEEL_CGEN_CALL _eel_tcp_listen_end(void *opaque, EEL_F *handle)
|
||||
{
|
||||
eel_net_state *ctx;
|
||||
if (NULL != (ctx=EEL_NET_GET_CONTEXT(opaque))) return ctx->onListen(opaque,*handle,-1,NULL,NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void EEL_tcp_register()
|
||||
{
|
||||
NSEEL_addfunc_varparm("tcp_listen",1,NSEEL_PProc_THIS,&_eel_tcp_listen);
|
||||
NSEEL_addfunc_retval("tcp_listen_end",1,NSEEL_PProc_THIS,&_eel_tcp_listen_end);
|
||||
|
||||
NSEEL_addfunc_varparm("tcp_connect",2,NSEEL_PProc_THIS,&_eel_tcp_connect);
|
||||
NSEEL_addfunc_varparm("tcp_send",2,NSEEL_PProc_THIS,&_eel_tcp_send);
|
||||
NSEEL_addfunc_varparm("tcp_recv",2,NSEEL_PProc_THIS,&_eel_tcp_recv);
|
||||
|
||||
NSEEL_addfunc_retval("tcp_set_block",2,NSEEL_PProc_THIS,&_eel_tcp_set_block);
|
||||
NSEEL_addfunc_retval("tcp_close",1,NSEEL_PProc_THIS,&_eel_tcp_close);
|
||||
}
|
||||
|
||||
#ifdef EEL_WANT_DOCUMENTATION
|
||||
const char *eel_net_function_reference =
|
||||
"tcp_listen\tport[,\"interface\",#ip_out]\tListens on port specified. Returns less than 0 if could not listen, 0 if no new connection available, or greater than 0 (as a TCP connection ID) if a new connection was made. If a connection made and #ip_out specified, it will be set to the remote IP. interface can be empty for all interfaces, otherwise an interface IP as a string.\0"
|
||||
"tcp_listen_end\tport\tEnds listening on port specified.\0"
|
||||
"tcp_connect\t\"address\",port[,block]\tCreate a new TCP connection to address:port. If block is specified and 0, connection will be made nonblocking. Returns TCP connection ID greater than 0 on success.\0"
|
||||
"tcp_send\tconnection,\"str\"[,len]\tSends a string to connection. Returns -1 on error, 0 if connection is non-blocking and would block, otherwise returns length sent. If len is specified and not less than 1, only the first len bytes of the string parameter will be sent.\0"
|
||||
"tcp_recv\tconnection,#str[,maxlen]\tReceives data from a connection to #str. If maxlen is specified, no more than maxlen bytes will be received. If non-blocking, 0 will be returned if would block. Returns less than 0 if error.\0"
|
||||
"tcp_set_block\tconnection,block\tSets whether a connection blocks.\0"
|
||||
"tcp_close\tconnection\tCloses a TCP connection created by tcp_listen() or tcp_connect().\0"
|
||||
;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
47
oversampling/WDL/eel2/eel_pp.cpp
Normal file
47
oversampling/WDL/eel2/eel_pp.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "../wdlstring.h"
|
||||
#include "../ptrlist.h"
|
||||
#include "eel_pproc.h"
|
||||
|
||||
void NSEEL_HOSTSTUB_EnterMutex() { }
|
||||
void NSEEL_HOSTSTUB_LeaveMutex() { }
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
fprintf(stderr,"Usage: %s [scriptfile | -]\n",argv[0]);
|
||||
return 1;
|
||||
}
|
||||
FILE *fp = strcmp(argv[1],"-") ? fopen(argv[1],"rb") : stdin;
|
||||
if (!fp)
|
||||
{
|
||||
fprintf(stderr,"Error: could not open %s\n",argv[1]);
|
||||
return 1;
|
||||
}
|
||||
WDL_FastString file_str, pp_str;
|
||||
for (;;)
|
||||
{
|
||||
char buf[4096];
|
||||
if (!fgets(buf,sizeof(buf),fp)) break;
|
||||
file_str.Append(buf);
|
||||
}
|
||||
if (fp != stdin) fclose(fp);
|
||||
|
||||
EEL2_PreProcessor pproc;
|
||||
const char *err = pproc.preprocess(file_str.Get(),&pp_str);
|
||||
if (err)
|
||||
{
|
||||
fprintf(stderr,"Error: %s\n",err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("%s",pp_str.Get());
|
||||
|
||||
return 0;
|
||||
}
|
||||
469
oversampling/WDL/eel2/eel_pproc.h
Normal file
469
oversampling/WDL/eel2/eel_pproc.h
Normal file
@@ -0,0 +1,469 @@
|
||||
#ifndef _EEL2_PREPROC_H_
|
||||
#define _EEL2_PREPROC_H_
|
||||
#include "ns-eel-int.h"
|
||||
#include "../win32_utf8.h"
|
||||
|
||||
#define EEL2_PREPROCESS_OPEN_TOKEN "<?"
|
||||
|
||||
class EEL2_PreProcessor
|
||||
{
|
||||
enum { LITERAL_BASE = 100000 };
|
||||
public:
|
||||
EEL2_PreProcessor(int max_sz = 64<<20, int max_include_depth=20)
|
||||
{
|
||||
m_max_sz = max_sz;
|
||||
m_fsout = NULL;
|
||||
m_vm = NSEEL_VM_alloc();
|
||||
m_max_include_depth = max_include_depth;
|
||||
m_output_linecnt = 0;
|
||||
m_cur_depth = 0;
|
||||
NSEEL_VM_SetCustomFuncThis(m_vm, this);
|
||||
NSEEL_VM_SetStringFunc(m_vm, addStringCallback, NULL);
|
||||
if (!m_ftab.list_size)
|
||||
{
|
||||
NSEEL_addfunc_varparm_ex("printf",1,0,NSEEL_PProc_THIS,&pp_printf,&m_ftab);
|
||||
NSEEL_addfunc_varparm_ex("include",1,1,NSEEL_PProc_THIS,&pp_include,&m_ftab);
|
||||
}
|
||||
NSEEL_VM_SetFunctionTable(m_vm, &m_ftab);
|
||||
m_suppress = NSEEL_VM_regvar(m_vm, "_suppress");
|
||||
}
|
||||
|
||||
void define(const char *name, double val)
|
||||
{
|
||||
EEL_F *v = NSEEL_VM_regvar(m_vm,name);
|
||||
if (v) *v = val;
|
||||
}
|
||||
|
||||
~EEL2_PreProcessor()
|
||||
{
|
||||
for (int x = 0; x < m_code_handles.GetSize(); x ++)
|
||||
NSEEL_code_free((NSEEL_CODEHANDLE) m_code_handles.Get(x));
|
||||
m_literal_strings.Empty(true,free);
|
||||
if (m_vm) NSEEL_VM_free(m_vm);
|
||||
m_suppress = NULL;
|
||||
}
|
||||
|
||||
void clear_line_info()
|
||||
{
|
||||
m_line_tab.Resize(0);
|
||||
}
|
||||
const char *preprocess(const char *str, WDL_FastString *fs)
|
||||
{
|
||||
if (!m_vm || !m_suppress)
|
||||
return "preprocessor: memory error";
|
||||
if (!m_cur_depth)
|
||||
{
|
||||
m_line_tab.Resize(0);
|
||||
m_output_linecnt = 0;
|
||||
*m_suppress = 0.0;
|
||||
}
|
||||
int input_linecnt = 0;
|
||||
for (;;)
|
||||
{
|
||||
const bool suppress = m_suppress && *m_suppress > 0.0;
|
||||
|
||||
int lc = 0;
|
||||
const char *tag = str;
|
||||
while (*tag && strncmp(tag,EEL2_PREPROCESS_OPEN_TOKEN,2)) if (*tag++ == '\n') lc++;
|
||||
|
||||
if (lc)
|
||||
{
|
||||
input_linecnt += lc;
|
||||
if (suppress)
|
||||
add_line_inf(m_output_linecnt,lc);
|
||||
else
|
||||
m_output_linecnt += lc;
|
||||
}
|
||||
|
||||
if (!*tag)
|
||||
{
|
||||
if (!suppress) fs->Append(str);
|
||||
return NULL;
|
||||
}
|
||||
if (!suppress && tag > str) fs->Append(str,(int)(tag-str));
|
||||
|
||||
tag += 2;
|
||||
while (*tag == ' ' || *tag == '\t') tag++;
|
||||
str = tag;
|
||||
lc = 0;
|
||||
while (*str && strncmp(str,"?>",2)) if (*str++ == '\n') lc++;
|
||||
|
||||
if (!*str)
|
||||
{
|
||||
m_tmp.SetFormatted(512, "%d: unterminated preprocessor " EEL2_PREPROCESS_OPEN_TOKEN " block", input_linecnt+1);
|
||||
return m_tmp.Get();
|
||||
}
|
||||
|
||||
if (lc)
|
||||
{
|
||||
input_linecnt += lc;
|
||||
add_line_inf(m_output_linecnt,lc);
|
||||
}
|
||||
if (str > tag)
|
||||
{
|
||||
m_tmp.Set(tag,(int)(str-tag));
|
||||
NSEEL_CODEHANDLE ch = NSEEL_code_compile_ex(m_vm, m_tmp.Get(), 0, NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS);
|
||||
if (!ch)
|
||||
{
|
||||
const char *err = NSEEL_code_getcodeerror(m_vm);
|
||||
if (err)
|
||||
{
|
||||
const int line_ref = atoi(err);
|
||||
while (*err >= '0' && *err <= '9') err++;
|
||||
m_tmp.SetFormatted(512,"%d: preprocessor%s%s",input_linecnt+line_ref,*err && *err != ':' ? ": ":"",err);
|
||||
return m_tmp.Get();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lc = 0;
|
||||
const int oldlen = fs->GetLength();
|
||||
m_fsout = fs;
|
||||
NSEEL_code_execute(ch);
|
||||
m_fsout = NULL;
|
||||
m_code_handles.Add(ch);
|
||||
for (int x = oldlen; x < fs->GetLength(); x ++) if (fs->Get()[x] == '\n') lc++;
|
||||
if (lc)
|
||||
{
|
||||
add_line_inf(m_output_linecnt,-lc);
|
||||
m_output_linecnt += lc;
|
||||
}
|
||||
}
|
||||
}
|
||||
str += 2;
|
||||
}
|
||||
}
|
||||
|
||||
const char *translate_error_line(const char *err_line)
|
||||
{
|
||||
if (m_line_tab.GetSize()<2) return err_line;
|
||||
int l = atoi(err_line)-1;
|
||||
if (l<0) return err_line;
|
||||
|
||||
// tab is a list of pairs
|
||||
// [<output position>, delta]
|
||||
// delta>0 if input lines were skipped
|
||||
// delta<0 if output lines were added
|
||||
|
||||
int nl = l;
|
||||
for (int x = m_line_tab.GetSize()-2; x >= 0; x -= 2)
|
||||
{
|
||||
int p = m_line_tab.Get()[x];
|
||||
if (nl > p)
|
||||
{
|
||||
int delta = m_line_tab.Get()[x+1];
|
||||
nl += delta;
|
||||
if (nl < p) nl = p;
|
||||
}
|
||||
}
|
||||
|
||||
if (l == nl) return err_line;
|
||||
|
||||
while (*err_line >= '0' && *err_line <= '9') err_line++;
|
||||
if (*err_line == ':') err_line++;
|
||||
m_tmp.SetFormatted(512,"%d:%s",1 + nl,err_line);
|
||||
return m_tmp.Get();
|
||||
}
|
||||
|
||||
NSEEL_VMCTX m_vm;
|
||||
WDL_PtrList<char> m_literal_strings;
|
||||
WDL_FastString m_tmp, *m_fsout;
|
||||
WDL_TypedBuf<int> m_line_tab; // expose this in case the caller wants to keep copies around
|
||||
EEL_F *m_suppress;
|
||||
int m_max_sz;
|
||||
int m_cur_depth, m_max_include_depth;
|
||||
int m_output_linecnt;
|
||||
static eel_function_table m_ftab;
|
||||
WDL_PtrList<void> m_code_handles;
|
||||
WDL_PtrList<const char> m_include_paths;
|
||||
|
||||
void add_line_inf(int output_linecnt, int lc)
|
||||
{
|
||||
if (!m_cur_depth)
|
||||
{
|
||||
m_line_tab.Add(output_linecnt); // log lc lines of input skipped
|
||||
m_line_tab.Add(lc);
|
||||
}
|
||||
}
|
||||
|
||||
static EEL_F addStringCallback(void *opaque, struct eelStringSegmentRec *list)
|
||||
{
|
||||
EEL2_PreProcessor *_this = (EEL2_PreProcessor*)opaque;
|
||||
if (!_this) return -1.0;
|
||||
|
||||
const int sz = nseel_stringsegments_tobuf(NULL,0,list);
|
||||
char *ns = (char *)malloc(sz+1);
|
||||
if (WDL_NOT_NORMALLY(!ns)) return -1.0;
|
||||
nseel_stringsegments_tobuf(ns,sz,list);
|
||||
|
||||
const int nstr = _this->m_literal_strings.GetSize();
|
||||
for (int x=0;x<nstr;x++)
|
||||
{
|
||||
char *s = _this->m_literal_strings.Get(x);
|
||||
if (!strcmp(s,ns))
|
||||
{
|
||||
free(ns);
|
||||
return x + LITERAL_BASE;
|
||||
}
|
||||
}
|
||||
_this->m_literal_strings.Add(ns);
|
||||
return nstr + LITERAL_BASE;
|
||||
}
|
||||
|
||||
const char *GetString(EEL_F v)
|
||||
{
|
||||
if (v >= LITERAL_BASE && v < LITERAL_BASE + m_literal_strings.GetSize())
|
||||
return m_literal_strings.Get((int) (v - LITERAL_BASE));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int eel_validate_format_specifier(const char *fmt_in, char *typeOut,
|
||||
char *fmtOut, int fmtOut_sz,
|
||||
char *varOut, int varOut_sz,
|
||||
int *varOut_used
|
||||
)
|
||||
{
|
||||
const char *fmt = fmt_in+1;
|
||||
int state=0;
|
||||
if (fmt_in[0] != '%') return 0; // ugh passed a non-specifier
|
||||
|
||||
*varOut_used = 0;
|
||||
*varOut = 0;
|
||||
|
||||
if (fmtOut_sz-- < 2) return 0;
|
||||
*fmtOut++ = '%';
|
||||
|
||||
while (*fmt)
|
||||
{
|
||||
const char c = *fmt++;
|
||||
if (fmtOut_sz < 2) return 0;
|
||||
|
||||
if (c == 'f'|| c=='e' || c=='E' || c=='g' || c=='G' || c == 'd' || c == 'u' ||
|
||||
c == 'x' || c == 'X' || c == 'c' || c == 'C' || c =='s' || c=='S' || c=='i')
|
||||
{
|
||||
*typeOut = c;
|
||||
fmtOut[0] = c;
|
||||
fmtOut[1] = 0;
|
||||
return (int) (fmt - fmt_in);
|
||||
}
|
||||
else if (c == '.')
|
||||
{
|
||||
*fmtOut++ = c; fmtOut_sz--;
|
||||
if (state&(2)) break;
|
||||
state |= 2;
|
||||
}
|
||||
else if (c == '+')
|
||||
{
|
||||
*fmtOut++ = c; fmtOut_sz--;
|
||||
if (state&(32|16|8|4)) break;
|
||||
state |= 8;
|
||||
}
|
||||
else if (c == '-' || c == ' ')
|
||||
{
|
||||
*fmtOut++ = c; fmtOut_sz--;
|
||||
if (state&(32|16|8|4)) break;
|
||||
state |= 16;
|
||||
}
|
||||
else if (c >= '0' && c <= '9')
|
||||
{
|
||||
*fmtOut++ = c; fmtOut_sz--;
|
||||
state|=4;
|
||||
}
|
||||
else if (c == '{')
|
||||
{
|
||||
if (state & 64) break;
|
||||
state|=64;
|
||||
if (*fmt == '.' || (*fmt >= '0' && *fmt <= '9')) return 0; // symbol name can't start with 0-9 or .
|
||||
|
||||
while (*fmt != '}')
|
||||
{
|
||||
if ((*fmt >= 'a' && *fmt <= 'z') ||
|
||||
(*fmt >= 'A' && *fmt <= 'Z') ||
|
||||
(*fmt >= '0' && *fmt <= '9') ||
|
||||
*fmt == '_' || *fmt == '.' || *fmt == '#')
|
||||
{
|
||||
if (varOut_sz < 2) return 0;
|
||||
*varOut++ = *fmt++;
|
||||
varOut_sz -- ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0; // bad character in variable name
|
||||
}
|
||||
}
|
||||
fmt++;
|
||||
*varOut = 0;
|
||||
*varOut_used=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int eel_format_strings(void *opaque, const char *fmt, const char *fmt_end, char *buf, int buf_sz, int num_fmt_parms, EEL_F **fmt_parms)
|
||||
{
|
||||
EEL2_PreProcessor *_this = (EEL2_PreProcessor*)opaque;
|
||||
int fmt_parmpos = 0;
|
||||
char *op = buf;
|
||||
while ((fmt_end ? fmt < fmt_end : *fmt) && op < buf+buf_sz-128)
|
||||
{
|
||||
if (fmt[0] == '%' && fmt[1] == '%')
|
||||
{
|
||||
*op++ = '%';
|
||||
fmt+=2;
|
||||
}
|
||||
else if (fmt[0] == '%')
|
||||
{
|
||||
char ct=0;
|
||||
char fs[128];
|
||||
char varname[128];
|
||||
int varname_used=0;
|
||||
const int l=eel_validate_format_specifier(fmt,&ct,fs,sizeof(fs),varname,sizeof(varname),&varname_used);
|
||||
if (!l || !ct)
|
||||
{
|
||||
*op=0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const EEL_F *varptr = NULL;
|
||||
if (!varname_used)
|
||||
{
|
||||
if (fmt_parmpos < num_fmt_parms) varptr = fmt_parms[fmt_parmpos];
|
||||
fmt_parmpos++;
|
||||
}
|
||||
double v = varptr ? (double)*varptr : 0.0;
|
||||
|
||||
if (ct == 's' || ct=='S')
|
||||
{
|
||||
const char *str = _this->GetString(v);
|
||||
const int maxl=(int) (buf+buf_sz - 2 - op);
|
||||
snprintf(op,maxl,fs,str ? str : "");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ct == 'x' || ct == 'X' || ct == 'd' || ct == 'u' || ct=='i')
|
||||
{
|
||||
snprintf(op,64,fs,(int) (v));
|
||||
}
|
||||
else if (ct == 'c')
|
||||
{
|
||||
*op++=(char) (int)v;
|
||||
*op=0;
|
||||
}
|
||||
else if (ct == 'C')
|
||||
{
|
||||
const unsigned int iv = (unsigned int) v;
|
||||
int bs = 0;
|
||||
if (iv & 0xff000000) bs=24;
|
||||
else if (iv & 0x00ff0000) bs=16;
|
||||
else if (iv & 0x0000ff00) bs=8;
|
||||
while (bs>=0)
|
||||
{
|
||||
const char c=(char) (iv>>bs);
|
||||
*op++=c?c:' ';
|
||||
bs-=8;
|
||||
}
|
||||
*op=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(op,64,fs,v);
|
||||
}
|
||||
}
|
||||
|
||||
while (*op) op++;
|
||||
|
||||
fmt += l;
|
||||
}
|
||||
else
|
||||
{
|
||||
*op++ = *fmt++;
|
||||
}
|
||||
|
||||
}
|
||||
*op=0;
|
||||
return (int) (op - buf);
|
||||
}
|
||||
|
||||
static EEL_F NSEEL_CGEN_CALL pp_printf(void *opaque, INT_PTR num_param, EEL_F **parms)
|
||||
{
|
||||
if (num_param>0 && opaque)
|
||||
{
|
||||
EEL2_PreProcessor *_this = (EEL2_PreProcessor*)opaque;
|
||||
const char *fmt = _this->GetString(parms[0][0]);
|
||||
if (fmt)
|
||||
{
|
||||
char buf[16384];
|
||||
const int len = eel_format_strings(opaque,fmt,NULL,buf,(int)sizeof(buf), (int)num_param-1, parms+1);
|
||||
|
||||
if (len >= 0)
|
||||
{
|
||||
if (_this->m_fsout && _this->m_fsout->GetLength() < _this->m_max_sz)
|
||||
{
|
||||
_this->m_fsout->Append(buf,len);
|
||||
}
|
||||
return 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
static EEL_F NSEEL_CGEN_CALL pp_include(void *opaque, INT_PTR num_param, EEL_F **parms)
|
||||
{
|
||||
if (num_param>0 && opaque)
|
||||
{
|
||||
EEL2_PreProcessor *_this = (EEL2_PreProcessor*)opaque;
|
||||
if (_this->m_cur_depth >= _this->m_max_include_depth) return -1.0;
|
||||
|
||||
const char *fn = _this->GetString(parms[0][0]);
|
||||
if (!fn || !*fn) return -2.0;
|
||||
|
||||
WDL_FastString fullfn;
|
||||
for (int x = _this->m_include_paths.GetSize()-1; x >= 0; x--)
|
||||
{
|
||||
const char *p = _this->m_include_paths.Get(x);
|
||||
if (p && *p)
|
||||
{
|
||||
fullfn.Set(p);
|
||||
fullfn.Append(WDL_DIRCHAR_STR);
|
||||
fullfn.Append(fn);
|
||||
FILE *fp = fopenUTF8(fullfn.Get(),"rb");
|
||||
if (fp)
|
||||
{
|
||||
double rv = 0.0;
|
||||
_this->m_cur_depth++;
|
||||
fullfn.Set("");
|
||||
while (fullfn.GetLength() < (4<<20))
|
||||
{
|
||||
char buf[512];
|
||||
if (!fgets(buf,sizeof(buf),fp)) break;
|
||||
fullfn.Append(buf);
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
WDL_FastString *outp = _this->m_fsout;
|
||||
if (_this->preprocess(fullfn.Get(),outp))
|
||||
{
|
||||
rv = -3.0;
|
||||
}
|
||||
_this->m_fsout = outp;
|
||||
|
||||
_this->m_cur_depth--;
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -4.0;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
eel_function_table EEL2_PreProcessor::m_ftab;
|
||||
|
||||
#endif
|
||||
1668
oversampling/WDL/eel2/eel_strings.h
Normal file
1668
oversampling/WDL/eel2/eel_strings.h
Normal file
File diff suppressed because it is too large
Load Diff
834
oversampling/WDL/eel2/eelscript.h
Normal file
834
oversampling/WDL/eel2/eelscript.h
Normal file
@@ -0,0 +1,834 @@
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#ifndef EELSCRIPT_NO_LICE
|
||||
#include "../swell/swell.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "../wdltypes.h"
|
||||
#include "../ptrlist.h"
|
||||
#include "../wdlstring.h"
|
||||
#include "../assocarray.h"
|
||||
#include "../queue.h"
|
||||
#include "../mutex.h"
|
||||
#include "../win32_utf8.h"
|
||||
#include "ns-eel.h"
|
||||
|
||||
|
||||
#ifndef EELSCRIPT_MAX_FILE_HANDLES
|
||||
#define EELSCRIPT_MAX_FILE_HANDLES 512
|
||||
#endif
|
||||
#ifndef EELSCRIPT_FILE_HANDLE_INDEX_BASE
|
||||
#define EELSCRIPT_FILE_HANDLE_INDEX_BASE 1000000
|
||||
#endif
|
||||
#ifndef EEL_STRING_MAXUSERSTRING_LENGTH_HINT
|
||||
#define EEL_STRING_MAXUSERSTRING_LENGTH_HINT (1<<16) // 64KB per string max
|
||||
#endif
|
||||
#ifndef EEL_STRING_MAX_USER_STRINGS
|
||||
#define EEL_STRING_MAX_USER_STRINGS 32768
|
||||
#endif
|
||||
#ifndef EEL_STRING_LITERAL_BASE
|
||||
#define EEL_STRING_LITERAL_BASE 2000000
|
||||
#endif
|
||||
#ifndef EELSCRIPT_LICE_MAX_IMAGES
|
||||
#define EELSCRIPT_LICE_MAX_IMAGES 1024
|
||||
#endif
|
||||
|
||||
#ifndef EELSCRIPT_LICE_MAX_FONTS
|
||||
#define EELSCRIPT_LICE_MAX_FONTS 128
|
||||
#endif
|
||||
|
||||
#ifndef EELSCRIPT_NET_MAXCON
|
||||
#define EELSCRIPT_NET_MAXCON 4096
|
||||
#endif
|
||||
|
||||
#ifndef EELSCRIPT_LICE_CLASSNAME
|
||||
#define EELSCRIPT_LICE_CLASSNAME "eelscript_gfx"
|
||||
#endif
|
||||
|
||||
|
||||
// #define EELSCRIPT_NO_NET
|
||||
// #define EELSCRIPT_NO_LICE
|
||||
// #define EELSCRIPT_NO_FILE
|
||||
// #define EELSCRIPT_NO_FFT
|
||||
// #define EELSCRIPT_NO_MDCT
|
||||
// #define EELSCRIPT_NO_EVAL
|
||||
|
||||
class eel_string_context_state;
|
||||
#ifndef EELSCRIPT_NO_NET
|
||||
class eel_net_state;
|
||||
#endif
|
||||
#ifndef EELSCRIPT_NO_LICE
|
||||
class eel_lice_state;
|
||||
#endif
|
||||
|
||||
#ifndef EELSCRIPT_NO_PREPROC
|
||||
#include "eel_pproc.h"
|
||||
#endif
|
||||
|
||||
class eelScriptInst {
|
||||
public:
|
||||
|
||||
static int init();
|
||||
|
||||
eelScriptInst();
|
||||
virtual ~eelScriptInst();
|
||||
|
||||
NSEEL_CODEHANDLE compile_code(const char *code, const char **err);
|
||||
int runcode(const char *code, int showerr, const char *showerrfn, bool canfree, bool ignoreEndOfInputChk, bool doExec);
|
||||
int loadfile(const char *fn, const char *callerfn, bool allowstdin);
|
||||
|
||||
NSEEL_VMCTX m_vm;
|
||||
|
||||
WDL_PtrList<void> m_code_freelist;
|
||||
|
||||
#ifndef EELSCRIPT_NO_FILE
|
||||
FILE *m_handles[EELSCRIPT_MAX_FILE_HANDLES];
|
||||
virtual EEL_F OpenFile(const char *fn, const char *mode)
|
||||
{
|
||||
if (!*fn || !*mode) return 0.0;
|
||||
#ifndef EELSCRIPT_NO_STDIO
|
||||
if (!strcmp(fn,"stdin")) return 1;
|
||||
if (!strcmp(fn,"stdout")) return 2;
|
||||
if (!strcmp(fn,"stderr")) return 3;
|
||||
#endif
|
||||
|
||||
WDL_FastString fnstr(fn);
|
||||
if (!translateFilename(&fnstr,mode)) return 0.0;
|
||||
|
||||
int x;
|
||||
for (x=0;x<EELSCRIPT_MAX_FILE_HANDLES && m_handles[x];x++);
|
||||
if (x>= EELSCRIPT_MAX_FILE_HANDLES) return 0.0;
|
||||
|
||||
FILE *fp = fopenUTF8(fnstr.Get(),mode);
|
||||
if (!fp) return 0.0;
|
||||
m_handles[x]=fp;
|
||||
return x + EELSCRIPT_FILE_HANDLE_INDEX_BASE;
|
||||
}
|
||||
virtual EEL_F CloseFile(int fp_idx)
|
||||
{
|
||||
fp_idx-=EELSCRIPT_FILE_HANDLE_INDEX_BASE;
|
||||
if (fp_idx>=0 && fp_idx<EELSCRIPT_MAX_FILE_HANDLES && m_handles[fp_idx])
|
||||
{
|
||||
fclose(m_handles[fp_idx]);
|
||||
m_handles[fp_idx]=0;
|
||||
return 0.0;
|
||||
}
|
||||
return -1.0;
|
||||
}
|
||||
virtual FILE *GetFileFP(int fp_idx)
|
||||
{
|
||||
#ifndef EELSCRIPT_NO_STDIO
|
||||
if (fp_idx==1) return stdin;
|
||||
if (fp_idx==2) return stdout;
|
||||
if (fp_idx==3) return stderr;
|
||||
#endif
|
||||
fp_idx-=EELSCRIPT_FILE_HANDLE_INDEX_BASE;
|
||||
if (fp_idx>=0 && fp_idx<EELSCRIPT_MAX_FILE_HANDLES) return m_handles[fp_idx];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
virtual bool translateFilename(WDL_FastString *fs, const char *mode) { return true; }
|
||||
|
||||
virtual bool GetFilenameForParameter(EEL_F idx, WDL_FastString *fs, int iswrite);
|
||||
|
||||
eel_string_context_state *m_string_context;
|
||||
#ifndef EELSCRIPT_NO_NET
|
||||
eel_net_state *m_net_state;
|
||||
#endif
|
||||
#ifndef EELSCRIPT_NO_LICE
|
||||
eel_lice_state *m_gfx_state;
|
||||
#endif
|
||||
|
||||
#ifndef EELSCRIPT_NO_EVAL
|
||||
struct evalCacheEnt {
|
||||
char *str;
|
||||
NSEEL_CODEHANDLE ch;
|
||||
};
|
||||
int m_eval_depth;
|
||||
WDL_TypedBuf<evalCacheEnt> m_eval_cache;
|
||||
virtual char *evalCacheGet(const char *str, NSEEL_CODEHANDLE *ch);
|
||||
virtual void evalCacheDispose(char *key, NSEEL_CODEHANDLE ch);
|
||||
WDL_Queue m_defer_eval, m_atexit_eval;
|
||||
void runCodeQ(WDL_Queue *q, const char *fname);
|
||||
void runAtExitCode()
|
||||
{
|
||||
runCodeQ(&m_atexit_eval,"atexit");
|
||||
m_atexit_eval.Clear(); // make sure nothing gets added in atexit(), in case the user called runAtExitCode before destroying
|
||||
}
|
||||
#endif
|
||||
virtual bool run_deferred(); // requires eval support to be useful
|
||||
virtual bool has_deferred();
|
||||
|
||||
|
||||
WDL_StringKeyedArray<bool> m_loaded_fnlist; // imported file list (to avoid repeats)
|
||||
|
||||
#ifndef EELSCRIPT_NO_PREPROC
|
||||
EEL2_PreProcessor m_preproc;
|
||||
#endif
|
||||
};
|
||||
|
||||
//#define EEL_STRINGS_MUTABLE_LITERALS
|
||||
//#define EEL_STRING_WANT_MUTEX
|
||||
|
||||
|
||||
#define EEL_STRING_GET_CONTEXT_POINTER(opaque) (((eelScriptInst *)opaque)->m_string_context)
|
||||
#ifndef EEL_STRING_STDOUT_WRITE
|
||||
#ifndef EELSCRIPT_NO_STDIO
|
||||
#define EEL_STRING_STDOUT_WRITE(x,len) { fwrite(x,len,1,stdout); fflush(stdout); }
|
||||
#endif
|
||||
#endif
|
||||
#include "eel_strings.h"
|
||||
|
||||
#include "eel_misc.h"
|
||||
|
||||
|
||||
#ifndef EELSCRIPT_NO_FILE
|
||||
#define EEL_FILE_OPEN(fn,mode) ((eelScriptInst*)opaque)->OpenFile(fn,mode)
|
||||
#define EEL_FILE_GETFP(fp) ((eelScriptInst*)opaque)->GetFileFP(fp)
|
||||
#define EEL_FILE_CLOSE(fpindex) ((eelScriptInst*)opaque)->CloseFile(fpindex)
|
||||
|
||||
#include "eel_files.h"
|
||||
#endif
|
||||
|
||||
#ifndef EELSCRIPT_NO_FFT
|
||||
#include "eel_fft.h"
|
||||
#endif
|
||||
|
||||
#ifndef EELSCRIPT_NO_MDCT
|
||||
#include "eel_mdct.h"
|
||||
#endif
|
||||
|
||||
#ifndef EELSCRIPT_NO_NET
|
||||
#define EEL_NET_GET_CONTEXT(opaque) (((eelScriptInst *)opaque)->m_net_state)
|
||||
#include "eel_net.h"
|
||||
#endif
|
||||
|
||||
#ifndef EELSCRIPT_NO_LICE
|
||||
#ifndef EEL_LICE_WANT_STANDALONE
|
||||
#define EEL_LICE_WANT_STANDALONE
|
||||
#endif
|
||||
#ifndef EELSCRIPT_LICE_NOUPDATE
|
||||
#define EEL_LICE_WANT_STANDALONE_UPDATE // gfx_update() which runs message pump and updates screen etc
|
||||
#endif
|
||||
|
||||
#define EEL_LICE_GET_FILENAME_FOR_STRING(idx, fs, p) (((eelScriptInst*)opaque)->GetFilenameForParameter(idx,fs,p))
|
||||
#define EEL_LICE_GET_CONTEXT(opaque) ((opaque) ? (((eelScriptInst *)opaque)->m_gfx_state) : NULL)
|
||||
#include "eel_lice.h"
|
||||
#endif
|
||||
|
||||
#ifndef EELSCRIPT_NO_EVAL
|
||||
#define EEL_EVAL_GET_CACHED(str, ch) ((eelScriptInst *)opaque)->evalCacheGet(str,&(ch))
|
||||
#define EEL_EVAL_SET_CACHED(str, ch) ((eelScriptInst *)opaque)->evalCacheDispose(str,ch)
|
||||
#define EEL_EVAL_GET_VMCTX(opaque) (((eelScriptInst *)opaque)->m_vm)
|
||||
#define EEL_EVAL_SCOPE_ENTER (((eelScriptInst *)opaque)->m_eval_depth < 3 ? \
|
||||
++((eelScriptInst *)opaque)->m_eval_depth : 0)
|
||||
#define EEL_EVAL_SCOPE_LEAVE ((eelScriptInst *)opaque)->m_eval_depth--;
|
||||
#include "eel_eval.h"
|
||||
|
||||
static EEL_F NSEEL_CGEN_CALL _eel_defer(void *opaque, EEL_F *s)
|
||||
{
|
||||
EEL_STRING_MUTEXLOCK_SCOPE
|
||||
const char *str=EEL_STRING_GET_FOR_INDEX(*s,NULL);
|
||||
if (str && *str && *s >= EEL_STRING_MAX_USER_STRINGS) // don't allow defer(0) etc
|
||||
{
|
||||
eelScriptInst *inst = (eelScriptInst *)opaque;
|
||||
if (inst->m_defer_eval.Available() < EEL_STRING_MAXUSERSTRING_LENGTH_HINT)
|
||||
{
|
||||
inst->m_defer_eval.Add(str,strlen(str)+1);
|
||||
return 1.0;
|
||||
}
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
EEL_STRING_DEBUGOUT("defer(): too much defer() code already added, ignoring");
|
||||
#endif
|
||||
}
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
else if (!str)
|
||||
{
|
||||
EEL_STRING_DEBUGOUT("defer(): invalid string identifier specified %f",*s);
|
||||
}
|
||||
else if (*s < EEL_STRING_MAX_USER_STRINGS)
|
||||
{
|
||||
EEL_STRING_DEBUGOUT("defer(): user string identifier %f specified but not allowed",*s);
|
||||
}
|
||||
#endif
|
||||
return 0.0;
|
||||
}
|
||||
static EEL_F NSEEL_CGEN_CALL _eel_atexit(void *opaque, EEL_F *s)
|
||||
{
|
||||
EEL_STRING_MUTEXLOCK_SCOPE
|
||||
const char *str=EEL_STRING_GET_FOR_INDEX(*s,NULL);
|
||||
if (str && *str && *s >= EEL_STRING_MAX_USER_STRINGS) // don't allow atexit(0) etc
|
||||
{
|
||||
eelScriptInst *inst = (eelScriptInst *)opaque;
|
||||
if (inst->m_atexit_eval.Available() < EEL_STRING_MAXUSERSTRING_LENGTH_HINT)
|
||||
{
|
||||
inst->m_atexit_eval.Add(str,strlen(str)+1);
|
||||
return 1.0;
|
||||
}
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
EEL_STRING_DEBUGOUT("atexit(): too much atexit() code already added, ignoring");
|
||||
#endif
|
||||
}
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
else if (!str)
|
||||
{
|
||||
EEL_STRING_DEBUGOUT("atexit(): invalid string identifier specified %f",*s);
|
||||
}
|
||||
else if (*s < EEL_STRING_MAX_USER_STRINGS)
|
||||
{
|
||||
EEL_STRING_DEBUGOUT("atexit(): user string identifier %f specified but not allowed",*s);
|
||||
}
|
||||
#endif
|
||||
return 0.0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#define opaque ((void *)this)
|
||||
|
||||
eelScriptInst::eelScriptInst() : m_loaded_fnlist(false)
|
||||
{
|
||||
#ifndef EELSCRIPT_NO_FILE
|
||||
memset(m_handles,0,sizeof(m_handles));
|
||||
#endif
|
||||
m_vm = NSEEL_VM_alloc();
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
if (!m_vm) EEL_STRING_DEBUGOUT("NSEEL_VM_alloc(): failed");
|
||||
#endif
|
||||
NSEEL_VM_SetCustomFuncThis(m_vm,this);
|
||||
#ifdef NSEEL_ADDFUNC_DESTINATION
|
||||
NSEEL_VM_SetFunctionTable(m_vm,NSEEL_ADDFUNC_DESTINATION);
|
||||
#endif
|
||||
|
||||
m_string_context = new eel_string_context_state;
|
||||
eel_string_initvm(m_vm);
|
||||
#ifndef EELSCRIPT_NO_NET
|
||||
m_net_state = new eel_net_state(EELSCRIPT_NET_MAXCON,NULL);
|
||||
#endif
|
||||
#ifndef EELSCRIPT_NO_LICE
|
||||
m_gfx_state = new eel_lice_state(m_vm,this,EELSCRIPT_LICE_MAX_IMAGES,EELSCRIPT_LICE_MAX_FONTS);
|
||||
|
||||
m_gfx_state->resetVarsToStock();
|
||||
#endif
|
||||
#ifndef EELSCRIPT_NO_EVAL
|
||||
m_eval_depth=0;
|
||||
#endif
|
||||
}
|
||||
|
||||
eelScriptInst::~eelScriptInst()
|
||||
{
|
||||
#ifndef EELSCRIPT_NO_EVAL
|
||||
if (m_atexit_eval.GetSize()>0) runAtExitCode();
|
||||
#endif
|
||||
int x;
|
||||
m_code_freelist.Empty((void (*)(void *))NSEEL_code_free);
|
||||
#ifndef EELSCRIPT_NO_EVAL
|
||||
for (x=0;x<m_eval_cache.GetSize();x++)
|
||||
{
|
||||
free(m_eval_cache.Get()[x].str);
|
||||
NSEEL_code_free(m_eval_cache.Get()[x].ch);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_vm) NSEEL_VM_free(m_vm);
|
||||
|
||||
#ifndef EELSCRIPT_NO_FILE
|
||||
for (x=0;x<EELSCRIPT_MAX_FILE_HANDLES;x++)
|
||||
{
|
||||
if (m_handles[x]) fclose(m_handles[x]);
|
||||
m_handles[x]=0;
|
||||
}
|
||||
#endif
|
||||
delete m_string_context;
|
||||
#ifndef EELSCRIPT_NO_NET
|
||||
delete m_net_state;
|
||||
#endif
|
||||
#ifndef EELSCRIPT_NO_LICE
|
||||
delete m_gfx_state;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool eelScriptInst::GetFilenameForParameter(EEL_F idx, WDL_FastString *fs, int iswrite)
|
||||
{
|
||||
const char *fmt = EEL_STRING_GET_FOR_INDEX(idx,NULL);
|
||||
if (!fmt) return false;
|
||||
fs->Set(fmt);
|
||||
return translateFilename(fs,iswrite?"w":"r");
|
||||
}
|
||||
|
||||
NSEEL_CODEHANDLE eelScriptInst::compile_code(const char *code, const char **err)
|
||||
{
|
||||
if (!m_vm)
|
||||
{
|
||||
*err = "EEL VM not initialized";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef EELSCRIPT_NO_PREPROC
|
||||
WDL_FastString str;
|
||||
if (strstr(code,EEL2_PREPROCESS_OPEN_TOKEN))
|
||||
{
|
||||
const char *pperr = m_preproc.preprocess(code,&str);
|
||||
if (pperr)
|
||||
{
|
||||
*err = pperr;
|
||||
return NULL;
|
||||
}
|
||||
code = str.Get();
|
||||
}
|
||||
else
|
||||
m_preproc.clear_line_info();
|
||||
#endif
|
||||
|
||||
NSEEL_CODEHANDLE ch = NSEEL_code_compile_ex(m_vm, code, 0, NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS);
|
||||
if (ch)
|
||||
{
|
||||
m_string_context->update_named_vars(m_vm);
|
||||
m_code_freelist.Add((void*)ch);
|
||||
return ch;
|
||||
}
|
||||
*err = NSEEL_code_getcodeerror(m_vm);
|
||||
#ifndef EELSCRIPT_NO_PREPROC
|
||||
if (*err) *err = m_preproc.translate_error_line(*err);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int eelScriptInst::runcode(const char *codeptr, int showerr, const char *showerrfn, bool canfree, bool ignoreEndOfInputChk, bool doExec)
|
||||
{
|
||||
if (m_vm)
|
||||
{
|
||||
const char *err = NULL;
|
||||
NSEEL_CODEHANDLE code = NULL;
|
||||
#ifndef EELSCRIPT_NO_PREPROC
|
||||
WDL_FastString str;
|
||||
if (strstr(codeptr,EEL2_PREPROCESS_OPEN_TOKEN))
|
||||
{
|
||||
err = m_preproc.preprocess(codeptr,&str);
|
||||
if (err) goto on_preproc_error;
|
||||
codeptr = str.Get();
|
||||
}
|
||||
else
|
||||
m_preproc.clear_line_info();
|
||||
#endif
|
||||
|
||||
code = NSEEL_code_compile_ex(m_vm,codeptr,0,canfree ? 0 : NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS);
|
||||
if (code) m_string_context->update_named_vars(m_vm);
|
||||
|
||||
if (!code && (err=NSEEL_code_getcodeerror(m_vm)))
|
||||
{
|
||||
if (!ignoreEndOfInputChk && (NSEEL_code_geterror_flag(m_vm)&1)) return 1;
|
||||
#ifndef EELSCRIPT_NO_PREPROC
|
||||
err = m_preproc.translate_error_line(err);
|
||||
on_preproc_error:
|
||||
#endif
|
||||
if (showerr)
|
||||
{
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
if (showerr==2)
|
||||
{
|
||||
EEL_STRING_DEBUGOUT("Warning: %s:%s",WDL_get_filepart(showerrfn),err);
|
||||
}
|
||||
else
|
||||
{
|
||||
EEL_STRING_DEBUGOUT("%s:%s",WDL_get_filepart(showerrfn),err);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (code)
|
||||
{
|
||||
#ifdef EELSCRIPT_DO_DISASSEMBLE
|
||||
codeHandleType *p = (codeHandleType*)code;
|
||||
|
||||
char buf[512];
|
||||
buf[0]=0;
|
||||
#ifdef _WIN32
|
||||
GetTempPath(sizeof(buf)-64,buf);
|
||||
lstrcatn(buf,"jsfx-out",sizeof(buf));
|
||||
#else
|
||||
lstrcpyn_safe(buf,"/tmp/jsfx-out",sizeof(buf));
|
||||
#endif
|
||||
FILE *fp = fopenUTF8(buf,"wb");
|
||||
if (fp)
|
||||
{
|
||||
fwrite(p->code,1,p->code_size,fp);
|
||||
fclose(fp);
|
||||
char buf2[2048];
|
||||
#ifdef _WIN32
|
||||
snprintf(buf2,sizeof(buf2),"disasm \"%s\"",buf);
|
||||
#else
|
||||
#ifdef __aarch64__
|
||||
snprintf(buf2,sizeof(buf2), "objdump -D -b binary -maarch64 \"%s\"",buf);
|
||||
#elif defined(__arm__)
|
||||
snprintf(buf2,sizeof(buf2), "objdump -D -b binary -m arm \"%s\"",buf);
|
||||
#elif defined(__LP64__)
|
||||
#ifdef __APPLE__
|
||||
snprintf(buf2,sizeof(buf2),"distorm3 --b64 \"%s\"",buf);
|
||||
#else
|
||||
snprintf(buf2,sizeof(buf2),"objdump -D -b binary -m i386:x86-64 \"%s\"",buf);
|
||||
#endif
|
||||
#else
|
||||
snprintf(buf2,sizeof(buf2),"distorm3 --b32 \"%s\"",buf);
|
||||
#endif
|
||||
#endif
|
||||
system(buf2);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (doExec) NSEEL_code_execute(code);
|
||||
if (canfree) NSEEL_code_free(code);
|
||||
else m_code_freelist.Add((void*)code);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
FILE *eelscript_resolvePath(WDL_FastString &usefn, const char *fn, const char *callerfn)
|
||||
{
|
||||
// resolve path relative to current
|
||||
int x;
|
||||
bool had_abs=false;
|
||||
for (x=0;x<2; x ++)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (!x && ((fn[0] == '\\' && fn[1] == '\\') || (fn[0] && fn[1] == ':')))
|
||||
#else
|
||||
if (!x && fn[0] == '/')
|
||||
#endif
|
||||
{
|
||||
usefn.Set(fn);
|
||||
had_abs=true;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *fnu = fn;
|
||||
if (x)
|
||||
{
|
||||
while (*fnu) fnu++;
|
||||
while (fnu >= fn && *fnu != '\\' && *fnu != '/') fnu--;
|
||||
if (fnu < fn) break;
|
||||
fnu++;
|
||||
}
|
||||
|
||||
usefn.Set(callerfn);
|
||||
int l=usefn.GetLength();
|
||||
while (l > 0 && usefn.Get()[l-1] != '\\' && usefn.Get()[l-1] != '/') l--;
|
||||
if (l > 0)
|
||||
{
|
||||
usefn.SetLen(l);
|
||||
usefn.Append(fnu);
|
||||
}
|
||||
else
|
||||
{
|
||||
usefn.Set(fnu);
|
||||
}
|
||||
int last_slash_pos=-1;
|
||||
for (l = 0; l < usefn.GetLength(); l ++)
|
||||
{
|
||||
if (usefn.Get()[l] == '/' || usefn.Get()[l] == '\\')
|
||||
{
|
||||
if (usefn.Get()[l+1] == '.' && usefn.Get()[l+2] == '.' &&
|
||||
(usefn.Get()[l+3] == '/' || usefn.Get()[l+3] == '\\'))
|
||||
{
|
||||
if (last_slash_pos >= 0)
|
||||
usefn.DeleteSub(last_slash_pos, l+3-last_slash_pos);
|
||||
else
|
||||
usefn.DeleteSub(0,l+3+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
last_slash_pos=l;
|
||||
}
|
||||
}
|
||||
// take currentfn, remove filename part, add fnu
|
||||
}
|
||||
}
|
||||
|
||||
FILE *fp = fopenUTF8(usefn.Get(),"r");
|
||||
if (fp) return fp;
|
||||
}
|
||||
if (had_abs) usefn.Set(fn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int eelScriptInst::loadfile(const char *fn, const char *callerfn, bool allowstdin)
|
||||
{
|
||||
WDL_FastString usefn;
|
||||
FILE *fp = NULL;
|
||||
if (!strcmp(fn,"-"))
|
||||
{
|
||||
if (callerfn)
|
||||
{
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
EEL_STRING_DEBUGOUT("@import: can't import \"-\" (stdin)");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
if (allowstdin)
|
||||
{
|
||||
fp = stdin;
|
||||
fn = "(stdin)";
|
||||
}
|
||||
}
|
||||
else if (!callerfn)
|
||||
{
|
||||
fp = fopenUTF8(fn,"r");
|
||||
if (fp) m_loaded_fnlist.Insert(fn,true);
|
||||
}
|
||||
else
|
||||
{
|
||||
fp = eelscript_resolvePath(usefn,fn,callerfn);
|
||||
if (fp)
|
||||
{
|
||||
if (m_loaded_fnlist.Get(usefn.Get()))
|
||||
{
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
m_loaded_fnlist.Insert(usefn.Get(),true);
|
||||
fn = usefn.Get();
|
||||
}
|
||||
}
|
||||
|
||||
if (!fp)
|
||||
{
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
if (callerfn)
|
||||
EEL_STRING_DEBUGOUT("Warning: @import could not open '%s'",fn);
|
||||
else
|
||||
EEL_STRING_DEBUGOUT("Error opening %s",fn);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifndef EELSCRIPT_NO_PREPROC
|
||||
WDL_FastString incpath(fn);
|
||||
incpath.remove_filepart();
|
||||
m_preproc.m_include_paths.Add(incpath.Get());
|
||||
#endif
|
||||
|
||||
WDL_FastString code;
|
||||
char line[4096];
|
||||
for (;;)
|
||||
{
|
||||
line[0]=0;
|
||||
fgets(line,sizeof(line),fp);
|
||||
if (!line[0]) break;
|
||||
if (!strnicmp(line,"@import",7) && isspace((unsigned char)line[7]))
|
||||
{
|
||||
char *p=line+7;
|
||||
while (isspace((unsigned char)*p)) p++;
|
||||
|
||||
char *ep=p;
|
||||
while (*ep) ep++;
|
||||
while (ep>p && isspace((unsigned char)ep[-1])) ep--;
|
||||
*ep=0;
|
||||
|
||||
if (*p) loadfile(p,fn,false);
|
||||
}
|
||||
else
|
||||
{
|
||||
code.Append(line);
|
||||
}
|
||||
}
|
||||
if (fp != stdin) fclose(fp);
|
||||
|
||||
int rv = runcode(code.Get(),callerfn ? 2 : 1, fn,false,true,!callerfn);
|
||||
|
||||
#ifndef EELSCRIPT_NO_PREPROC
|
||||
m_preproc.m_include_paths.Delete(m_preproc.m_include_paths.GetSize()-1);
|
||||
#endif
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
char *eelScriptInst::evalCacheGet(const char *str, NSEEL_CODEHANDLE *ch)
|
||||
{
|
||||
// should mutex protect if multiple threads access this eelScriptInst context
|
||||
int x=m_eval_cache.GetSize();
|
||||
while (--x >= 0)
|
||||
{
|
||||
char *ret;
|
||||
if (!strcmp(ret=m_eval_cache.Get()[x].str, str))
|
||||
{
|
||||
*ch = m_eval_cache.Get()[x].ch;
|
||||
m_eval_cache.Delete(x);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void eelScriptInst::evalCacheDispose(char *key, NSEEL_CODEHANDLE ch)
|
||||
{
|
||||
// should mutex protect if multiple threads access this eelScriptInst context
|
||||
evalCacheEnt ecc;
|
||||
ecc.str= key;
|
||||
ecc.ch = ch;
|
||||
if (m_eval_cache.GetSize() > 1024)
|
||||
{
|
||||
NSEEL_code_free(m_eval_cache.Get()->ch);
|
||||
free(m_eval_cache.Get()->str);
|
||||
m_eval_cache.Delete(0);
|
||||
}
|
||||
m_eval_cache.Add(ecc);
|
||||
}
|
||||
|
||||
int eelScriptInst::init()
|
||||
{
|
||||
EEL_string_register();
|
||||
#ifndef EELSCRIPT_NO_FILE
|
||||
EEL_file_register();
|
||||
#endif
|
||||
#ifndef EELSCRIPT_NO_FFT
|
||||
EEL_fft_register();
|
||||
#endif
|
||||
#ifndef EELSCRIPT_NO_MDCT
|
||||
EEL_mdct_register();
|
||||
#endif
|
||||
EEL_misc_register();
|
||||
#ifndef EELSCRIPT_NO_EVAL
|
||||
EEL_eval_register();
|
||||
NSEEL_addfunc_retval("defer",1,NSEEL_PProc_THIS,&_eel_defer);
|
||||
NSEEL_addfunc_retval("runloop", 1, NSEEL_PProc_THIS, &_eel_defer);
|
||||
NSEEL_addfunc_retval("atexit",1,NSEEL_PProc_THIS,&_eel_atexit);
|
||||
#endif
|
||||
#ifndef EELSCRIPT_NO_NET
|
||||
EEL_tcp_register();
|
||||
#endif
|
||||
#ifndef EELSCRIPT_NO_LICE
|
||||
eel_lice_register();
|
||||
#ifdef _WIN32
|
||||
eel_lice_register_standalone(GetModuleHandle(NULL),EELSCRIPT_LICE_CLASSNAME,NULL,NULL);
|
||||
#else
|
||||
eel_lice_register_standalone(NULL,EELSCRIPT_LICE_CLASSNAME,NULL,NULL);
|
||||
#endif
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool eelScriptInst::has_deferred()
|
||||
{
|
||||
#ifndef EELSCRIPT_NO_EVAL
|
||||
return m_defer_eval.Available() && m_vm;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef EELSCRIPT_NO_EVAL
|
||||
void eelScriptInst::runCodeQ(WDL_Queue *q, const char *callername)
|
||||
{
|
||||
const int endptr = q->Available();
|
||||
int offs = 0;
|
||||
while (offs < endptr)
|
||||
{
|
||||
if (q->Available() < endptr) break; // should never happen, but safety first!
|
||||
|
||||
const char *ptr = (const char *)q->Get() + offs;
|
||||
offs += strlen(ptr)+1;
|
||||
|
||||
NSEEL_CODEHANDLE ch=NULL;
|
||||
char *sv=evalCacheGet(ptr,&ch);
|
||||
|
||||
if (!sv) sv=strdup(ptr);
|
||||
if (!ch) ch=NSEEL_code_compile(m_vm,sv,0);
|
||||
if (!ch)
|
||||
{
|
||||
free(sv);
|
||||
#ifdef EEL_STRING_DEBUGOUT
|
||||
const char *err = NSEEL_code_getcodeerror(m_vm);
|
||||
if (err) EEL_STRING_DEBUGOUT("%s: error in code: %s",callername,err);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
NSEEL_code_execute(ch);
|
||||
evalCacheDispose(sv,ch);
|
||||
}
|
||||
}
|
||||
q->Advance(endptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool eelScriptInst::run_deferred()
|
||||
{
|
||||
#ifndef EELSCRIPT_NO_EVAL
|
||||
if (!m_defer_eval.Available()||!m_vm) return false;
|
||||
|
||||
runCodeQ(&m_defer_eval,"defer");
|
||||
m_defer_eval.Compact();
|
||||
return m_defer_eval.Available()>0;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef EEL_WANT_DOCUMENTATION
|
||||
#include "ns-eel-func-ref.h"
|
||||
|
||||
void EELScript_GenerateFunctionList(WDL_PtrList<const char> *fs)
|
||||
{
|
||||
const char *p = nseel_builtin_function_reference;
|
||||
while (*p) { fs->Add(p); p += strlen(p) + 1; }
|
||||
p = eel_strings_function_reference;
|
||||
while (*p) { fs->Add(p); p += strlen(p) + 1; }
|
||||
p = eel_misc_function_reference;
|
||||
while (*p) { fs->Add(p); p += strlen(p) + 1; }
|
||||
#ifndef EELSCRIPT_NO_EVAL
|
||||
fs->Add("atexit\t\"code\"\t"
|
||||
#ifndef EELSCRIPT_HELP_NO_DEFER_DESC
|
||||
"Adds code to be executed when the script finishes."
|
||||
#endif
|
||||
);
|
||||
fs->Add("defer\t\"code\"\t"
|
||||
#ifndef EELSCRIPT_HELP_NO_DEFER_DESC
|
||||
"Adds code which will be executed some small amount of time after the current code finishes. Identical to runloop()"
|
||||
#endif
|
||||
);
|
||||
fs->Add("runloop\t\"code\"\t"
|
||||
#ifndef EELSCRIPT_HELP_NO_DEFER_DESC
|
||||
"Adds code which will be executed some small amount of time after the current code finishes. Identical to defer()"
|
||||
#endif
|
||||
);
|
||||
|
||||
p = eel_eval_function_reference;
|
||||
while (*p) { fs->Add(p); p += strlen(p) + 1; }
|
||||
#endif
|
||||
#ifndef EELSCRIPT_NO_NET
|
||||
p = eel_net_function_reference;
|
||||
while (*p) { fs->Add(p); p += strlen(p) + 1; }
|
||||
#endif
|
||||
#ifndef EELSCRIPT_NO_FFT
|
||||
p = eel_fft_function_reference;
|
||||
while (*p) { fs->Add(p); p += strlen(p) + 1; }
|
||||
#endif
|
||||
#ifndef EELSCRIPT_NO_FILE
|
||||
p = eel_file_function_reference;
|
||||
while (*p) { fs->Add(p); p += strlen(p) + 1; }
|
||||
#endif
|
||||
#ifndef EELSCRIPT_NO_MDCT
|
||||
p = eel_mdct_function_reference;
|
||||
while (*p) { fs->Add(p); p += strlen(p) + 1; }
|
||||
#endif
|
||||
#ifndef EELSCRIPT_NO_LICE
|
||||
p = eel_lice_function_reference;
|
||||
while (*p) { fs->Add(p); p += strlen(p) + 1; }
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#undef opaque
|
||||
448
oversampling/WDL/eel2/glue_aarch64.h
Normal file
448
oversampling/WDL/eel2/glue_aarch64.h
Normal file
@@ -0,0 +1,448 @@
|
||||
#ifndef _NSEEL_GLUE_AARCH64_H_
|
||||
#define _NSEEL_GLUE_AARCH64_H_
|
||||
|
||||
#define GLUE_MOD_IS_64
|
||||
|
||||
// x0=return value, first parm, x1-x2 parms (x3-x7 more params)
|
||||
// x8 return struct?
|
||||
// x9-x15 temporary
|
||||
// x16-x17 = PLT, linker
|
||||
// x18 reserved (TLS)
|
||||
// x19-x28 callee-saved
|
||||
// x19 = worktable
|
||||
// x20 = ramtable
|
||||
// x21 = consttab
|
||||
// x22 = worktable ptr
|
||||
// x23-x28 spare
|
||||
// x29 frame pointer
|
||||
// x30 link register
|
||||
// x31 SP/zero
|
||||
|
||||
// x0=p1
|
||||
// x1=p2
|
||||
// x2=p3
|
||||
|
||||
// d0 is return value for fp?
|
||||
// d/v/f0-7 = arguments/results
|
||||
// 8-15 callee saved
|
||||
// 16-31 temporary
|
||||
|
||||
// v8-v15 spill registers
|
||||
#define GLUE_MAX_SPILL_REGS 8
|
||||
#define GLUE_SAVE_TO_SPILL_SIZE(x) (4)
|
||||
#define GLUE_RESTORE_SPILL_TO_FPREG2_SIZE(x) (4)
|
||||
|
||||
static void GLUE_RESTORE_SPILL_TO_FPREG2(void *b, int ws)
|
||||
{
|
||||
*(unsigned int *)b = 0x1e604101 + (ws<<5); // fmov d1, d8+ws
|
||||
}
|
||||
static void GLUE_SAVE_TO_SPILL(void *b, int ws)
|
||||
{
|
||||
*(unsigned int *)b = 0x1e604008 + ws; // fmov d8+ws, d0
|
||||
}
|
||||
|
||||
|
||||
#define GLUE_HAS_FPREG2 1
|
||||
|
||||
static const unsigned int GLUE_COPY_FPSTACK_TO_FPREG2[] = { 0x1e604001 }; // fmov d1, d0
|
||||
static unsigned int GLUE_POP_STACK_TO_FPREG2[] = {
|
||||
0xfc4107e1 // ldr d1, [sp], #16
|
||||
};
|
||||
|
||||
#define GLUE_MAX_FPSTACK_SIZE 0 // no stack support
|
||||
#define GLUE_MAX_JMPSIZE ((1<<20) - 1024) // maximum relative jump size
|
||||
|
||||
// endOfInstruction is end of jump with relative offset, offset passed in is offset from end of dest instruction.
|
||||
// 0 = current instruction
|
||||
static void GLUE_JMP_SET_OFFSET(void *endOfInstruction, int offset)
|
||||
{
|
||||
unsigned int *a = (unsigned int*) endOfInstruction - 1;
|
||||
offset += 4;
|
||||
offset >>= 2; // as dwords
|
||||
if ((a[0] & 0xFC000000) == 0x14000000)
|
||||
{
|
||||
// NC b = 0x14 + 26 bit offset
|
||||
a[0] = 0x14000000 | (offset & 0x3FFFFFF);
|
||||
}
|
||||
else if ((a[0] & 0xFF000000) == 0x54000000)
|
||||
{
|
||||
// condb = 0x54 + 20 bit offset + 5 bit condition: 0=eq, 1=ne, b=lt, c=gt, d=le, a=ge
|
||||
a[0] = 0x54000000 | (a[0] & 0xF) | ((offset & 0x7FFFF) << 5);
|
||||
}
|
||||
}
|
||||
|
||||
static const unsigned int GLUE_JMP_NC[] = { 0x14000000 };
|
||||
|
||||
static const unsigned int GLUE_JMP_IF_P1_Z[]=
|
||||
{
|
||||
0x7100001f, // cmp w0, #0
|
||||
0x54000000, // b.eq
|
||||
};
|
||||
static const unsigned int GLUE_JMP_IF_P1_NZ[]=
|
||||
{
|
||||
0x7100001f, // cmp w0, #0
|
||||
0x54000001, // b.ne
|
||||
};
|
||||
|
||||
#define GLUE_MOV_PX_DIRECTVALUE_TOFPREG2_SIZE 16 // wr=-2, sets d1
|
||||
#define GLUE_MOV_PX_DIRECTVALUE_SIZE 12
|
||||
static void GLUE_MOV_PX_DIRECTVALUE_GEN(void *b, INT_PTR v, int wv)
|
||||
{
|
||||
static const unsigned int tab[3] = {
|
||||
0xd2800000, // mov x0, #0000 (val<<5) | reg
|
||||
0xf2a00000, // movk x0, #0000, lsl 16 (val<<5) | reg
|
||||
0xf2c00000, // movk x0, #0000, lsl 32 (val<<5) | reg
|
||||
};
|
||||
// 0xABAAA, B is register, A are bits of word
|
||||
unsigned int *p=(unsigned int *)b;
|
||||
int wvo = wv;
|
||||
if (wv<0) wv=0;
|
||||
p[0] = tab[0] | wv | ((v&0xFFFF)<<5);
|
||||
p[1] = tab[1] | wv | (((v>>16)&0xFFFF)<<5);
|
||||
p[2] = tab[2] | wv | (((v>>32)&0xFFFF)<<5);
|
||||
if (wvo == -2) p[3] = 0xfd400001; // ldr d1, [x0]
|
||||
}
|
||||
|
||||
const static unsigned int GLUE_FUNC_ENTER[2] = { 0xa9bf7bfd, 0x910003fd }; // stp x29, x30, [sp, #-16]! ; mov x29, sp
|
||||
#define GLUE_FUNC_ENTER_SIZE 4
|
||||
const static unsigned int GLUE_FUNC_LEAVE[1] = { 0 }; // let GLUE_RET pop
|
||||
#define GLUE_FUNC_LEAVE_SIZE 0
|
||||
const static unsigned int GLUE_RET[]={ 0xa8c17bfd, 0xd65f03c0 }; // ldp x29,x30, [sp], #16 ; ret
|
||||
|
||||
static int GLUE_RESET_WTP(unsigned char *out, void *ptr)
|
||||
{
|
||||
const static unsigned int GLUE_SET_WTP_FROM_R19 = 0xaa1303f6; // mov r22, r19
|
||||
if (out) memcpy(out,&GLUE_SET_WTP_FROM_R19,sizeof(GLUE_SET_WTP_FROM_R19));
|
||||
return 4;
|
||||
}
|
||||
|
||||
|
||||
const static unsigned int GLUE_PUSH_P1[1]={ 0xf81f0fe0 }; // str x0, [sp, #-16]!
|
||||
|
||||
#define GLUE_STORE_P1_TO_STACK_AT_OFFS_SIZE(offs) ((offs)>=32768 ? 8 : 4)
|
||||
static void GLUE_STORE_P1_TO_STACK_AT_OFFS(void *b, int offs)
|
||||
{
|
||||
if (offs >= 32768)
|
||||
{
|
||||
// add x1, sp, (offs/4096) lsl 12
|
||||
*(unsigned int *)b = 0x914003e1 + ((offs>>12)<<10);
|
||||
|
||||
// str x0, [x1, #offs & 4095]
|
||||
offs &= 4095;
|
||||
offs <<= 10-3;
|
||||
offs &= 0x7FFC00;
|
||||
((unsigned int *)b)[1] = 0xf9000020 + offs;
|
||||
}
|
||||
else
|
||||
{
|
||||
// str x0, [sp, #offs]
|
||||
offs <<= 10-3;
|
||||
offs &= 0x7FFC00;
|
||||
*(unsigned int *)b = 0xf90003e0 + offs;
|
||||
}
|
||||
}
|
||||
|
||||
#define GLUE_MOVE_PX_STACKPTR_SIZE 4
|
||||
static void GLUE_MOVE_PX_STACKPTR_GEN(void *b, int wv)
|
||||
{
|
||||
// mov xX, sp
|
||||
*(unsigned int *)b = 0x910003e0 + wv;
|
||||
}
|
||||
|
||||
#define GLUE_MOVE_STACK_SIZE 4
|
||||
static void GLUE_MOVE_STACK(void *b, int amt)
|
||||
{
|
||||
if (amt>=0)
|
||||
{
|
||||
if (amt >= 4096)
|
||||
*(unsigned int*)b = 0x914003ff | (((amt+4095)>>12)<<10);
|
||||
else
|
||||
*(unsigned int*)b = 0x910003ff | (amt << 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
amt = -amt;
|
||||
if (amt >= 4096)
|
||||
*(unsigned int*)b = 0xd14003ff | (((amt+4095)>>12)<<10);
|
||||
else
|
||||
*(unsigned int*)b = 0xd10003ff | (amt << 10);
|
||||
}
|
||||
}
|
||||
|
||||
#define GLUE_POP_PX_SIZE 4
|
||||
static void GLUE_POP_PX(void *b, int wv)
|
||||
{
|
||||
((unsigned int *)b)[0] = 0xf84107e0 | wv; // ldr x, [sp], 16
|
||||
}
|
||||
|
||||
#define GLUE_SET_PX_FROM_P1_SIZE 4
|
||||
static void GLUE_SET_PX_FROM_P1(void *b, int wv)
|
||||
{
|
||||
*(unsigned int *)b = 0xaa0003e0 | wv;
|
||||
}
|
||||
|
||||
|
||||
static const unsigned int GLUE_PUSH_P1PTR_AS_VALUE[] =
|
||||
{
|
||||
0xfd400007, // ldr d7, [x0]
|
||||
0xfc1f0fe7, // str d7, [sp, #-16]!
|
||||
};
|
||||
|
||||
static int GLUE_POP_VALUE_TO_ADDR(unsigned char *buf, void *destptr)
|
||||
{
|
||||
if (buf)
|
||||
{
|
||||
unsigned int *bufptr = (unsigned int *)buf;
|
||||
*bufptr++ = 0xfc4107e7; // ldr d7, [sp], #16
|
||||
GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0);
|
||||
bufptr += GLUE_MOV_PX_DIRECTVALUE_SIZE/4;
|
||||
*bufptr++ = 0xfd000007; // str d7, [x0]
|
||||
}
|
||||
return 2*4 + GLUE_MOV_PX_DIRECTVALUE_SIZE;
|
||||
}
|
||||
|
||||
static int GLUE_COPY_VALUE_AT_P1_TO_PTR(unsigned char *buf, void *destptr)
|
||||
{
|
||||
if (buf)
|
||||
{
|
||||
unsigned int *bufptr = (unsigned int *)buf;
|
||||
*bufptr++ = 0xfd400007; // ldr d7, [x0]
|
||||
GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0);
|
||||
bufptr += GLUE_MOV_PX_DIRECTVALUE_SIZE/4;
|
||||
*bufptr++ = 0xfd000007; // str d7, [x0]
|
||||
}
|
||||
return 2*4 + GLUE_MOV_PX_DIRECTVALUE_SIZE;
|
||||
}
|
||||
|
||||
|
||||
#define GLUE_CALL_CODE(bp, cp, rt) do { \
|
||||
GLUE_SCR_TYPE f; \
|
||||
static const double consttab[] = { \
|
||||
NSEEL_CLOSEFACTOR, \
|
||||
0.0, \
|
||||
1.0, \
|
||||
-1.0, \
|
||||
-0.5, /* for invsqrt */ \
|
||||
1.5, \
|
||||
}; \
|
||||
if (!(h->compile_flags&NSEEL_CODE_COMPILE_FLAG_NOFPSTATE) && \
|
||||
!((f=glue_getscr())&(1<<24))) { \
|
||||
glue_setscr(f|(1<<24)); \
|
||||
eel_callcode64(bp, cp, rt, (void *)consttab); \
|
||||
glue_setscr(f); \
|
||||
} else eel_callcode64(bp, cp, rt, (void *)consttab);\
|
||||
} while(0)
|
||||
|
||||
#ifndef _MSC_VER
|
||||
static void eel_callcode64(INT_PTR bp, INT_PTR cp, INT_PTR rt, void *consttab)
|
||||
{
|
||||
__asm__(
|
||||
"mov x1, %2\n"
|
||||
"mov x2, %3\n"
|
||||
"mov x3, %1\n"
|
||||
"mov x0, %0\n"
|
||||
"stp x29, x30, [sp, #-64]!\n"
|
||||
"stp x18, x20, [sp, 16]\n"
|
||||
"stp x21, x19, [sp, 32]\n"
|
||||
"stp x22, x23, [sp, 48]\n"
|
||||
"mov x29, sp\n"
|
||||
"mov x19, x3\n"
|
||||
"mov x20, x1\n"
|
||||
"mov x21, x2\n"
|
||||
"blr x0\n"
|
||||
"ldp x29, x30, [sp], 16\n"
|
||||
"ldp x18, x20, [sp], 16\n"
|
||||
"ldp x21, x19, [sp], 16\n"
|
||||
"ldp x22, x23, [sp], 16\n"
|
||||
::"r" (cp), "r" (bp), "r" (rt), "r" (consttab) :"x0","x1","x2","x3","x4","x5","x6","x7",
|
||||
"x8","x9","x10","x11","x12","x13","x14","x15",
|
||||
"v8","v9","v10","v11","v12","v13","v14","v15");
|
||||
|
||||
};
|
||||
#else
|
||||
void eel_callcode64(INT_PTR bp, INT_PTR cp, INT_PTR rt, void *consttab);
|
||||
#endif
|
||||
|
||||
static unsigned char *EEL_GLUE_set_immediate(void *_p, INT_PTR newv)
|
||||
{
|
||||
unsigned int *p=(unsigned int *)_p;
|
||||
WDL_ASSERT(!(newv>>48));
|
||||
// 0xd2800000, // mov x0, #0000 (val<<5) | reg
|
||||
// 0xf2a00000, // movk x0, #0000, lsl 16 (val<<5) | reg
|
||||
// 0xf2c00000, // movk x0, #0000, lsl 32 (val<<5) | reg
|
||||
while (((p[0]>>5)&0xffff)!=0xdead ||
|
||||
((p[1]>>5)&0xffff)!=0xbeef ||
|
||||
((p[2]>>5)&0xffff)!=0xbeef) p++;
|
||||
|
||||
p[0] = (p[0] & 0xFFE0001F) | ((newv&0xffff)<<5);
|
||||
p[1] = (p[1] & 0xFFE0001F) | (((newv>>16)&0xffff)<<5);
|
||||
p[2] = (p[2] & 0xFFE0001F) | (((newv>>32)&0xffff)<<5);
|
||||
|
||||
return (unsigned char *)(p+2);
|
||||
}
|
||||
|
||||
#define GLUE_SET_PX_FROM_WTP_SIZE sizeof(int)
|
||||
static void GLUE_SET_PX_FROM_WTP(void *b, int wv)
|
||||
{
|
||||
*(unsigned int *)b = 0xaa1603e0 + wv; // mov x, x22
|
||||
}
|
||||
|
||||
static int GLUE_POP_FPSTACK_TO_PTR(unsigned char *buf, void *destptr)
|
||||
{
|
||||
if (buf)
|
||||
{
|
||||
unsigned int *bufptr = (unsigned int *)buf;
|
||||
GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0);
|
||||
bufptr += GLUE_MOV_PX_DIRECTVALUE_SIZE/4;
|
||||
|
||||
*bufptr++ = 0xfd000000; // str d0, [x0]
|
||||
}
|
||||
return GLUE_MOV_PX_DIRECTVALUE_SIZE + sizeof(int);
|
||||
}
|
||||
|
||||
#define GLUE_POP_FPSTACK_SIZE 0
|
||||
static const unsigned int GLUE_POP_FPSTACK[1] = { 0 }; // no need to pop, not a stack
|
||||
|
||||
static const unsigned int GLUE_POP_FPSTACK_TOSTACK[] = {
|
||||
0xfc1f0fe0, // str d0, [sp, #-16]!
|
||||
|
||||
};
|
||||
|
||||
static const unsigned int GLUE_POP_FPSTACK_TO_WTP[] = {
|
||||
0xfc0086c0, // str d0, [x22], #8
|
||||
};
|
||||
|
||||
#define GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE 4
|
||||
static void GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(void *b, int wv)
|
||||
{
|
||||
*(unsigned int *)b = 0xfd400000 + (wv<<5); // ldr d0, [xX]
|
||||
}
|
||||
|
||||
#define GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE (sizeof(GLUE_POP_FPSTACK_TO_WTP) + GLUE_SET_PX_FROM_WTP_SIZE)
|
||||
static void GLUE_POP_FPSTACK_TO_WTP_TO_PX(unsigned char *buf, int wv)
|
||||
{
|
||||
GLUE_SET_PX_FROM_WTP(buf,wv);
|
||||
memcpy(buf + GLUE_SET_PX_FROM_WTP_SIZE,GLUE_POP_FPSTACK_TO_WTP,sizeof(GLUE_POP_FPSTACK_TO_WTP));
|
||||
};
|
||||
|
||||
static const unsigned int GLUE_SET_P1_Z[] = { 0x52800000 }; // mov w0, #0
|
||||
static const unsigned int GLUE_SET_P1_NZ[] = { 0x52800020 }; // mov w0, #1
|
||||
|
||||
|
||||
static void *GLUE_realAddress(void *fn, int *size)
|
||||
{
|
||||
while ((*(int*)fn & 0xFC000000) == 0x14000000)
|
||||
{
|
||||
int offset = (*(int*)fn & 0x3FFFFFF);
|
||||
if (offset & 0x2000000)
|
||||
offset |= 0xFC000000;
|
||||
|
||||
fn = (int*)fn + offset;
|
||||
}
|
||||
static const unsigned int sig[] = {
|
||||
#ifndef _MSC_VER
|
||||
0xaa0003e0,
|
||||
#endif
|
||||
0xaa0103e1,
|
||||
#ifndef _MSC_VER
|
||||
0xaa0203e2
|
||||
#endif
|
||||
};
|
||||
unsigned char *p = (unsigned char *)fn;
|
||||
|
||||
while (memcmp(p,sig,sizeof(sig))) p+=4;
|
||||
p+=sizeof(sig);
|
||||
fn = p;
|
||||
|
||||
while (memcmp(p,sig,sizeof(sig))) p+=4;
|
||||
*size = p - (unsigned char *)fn;
|
||||
return fn;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#define GLUE_SCR_TYPE unsigned long
|
||||
static unsigned long __attribute__((unused)) glue_getscr()
|
||||
{
|
||||
unsigned long rv;
|
||||
asm volatile ( "mrs %0, fpcr" : "=r" (rv));
|
||||
return rv;
|
||||
}
|
||||
static void __attribute__((unused)) glue_setscr(unsigned long v)
|
||||
{
|
||||
asm volatile ( "msr fpcr, %0" :: "r"(v));
|
||||
}
|
||||
#else
|
||||
#define GLUE_SCR_TYPE unsigned long long
|
||||
GLUE_SCR_TYPE glue_getscr();
|
||||
void glue_setscr(unsigned long long);
|
||||
#endif
|
||||
|
||||
void eel_enterfp(int _s[2])
|
||||
{
|
||||
GLUE_SCR_TYPE *s = (GLUE_SCR_TYPE*)_s;
|
||||
s[0] = glue_getscr();
|
||||
glue_setscr(s[0] | (1<<24));
|
||||
}
|
||||
void eel_leavefp(int _s[2])
|
||||
{
|
||||
const GLUE_SCR_TYPE *s = (GLUE_SCR_TYPE*)_s;
|
||||
glue_setscr(s[0]);
|
||||
}
|
||||
|
||||
#define GLUE_HAS_FUSE 1
|
||||
static int GLUE_FUSE(compileContext *ctx, unsigned char *code, int left_size, int right_size, int fuse_flags, int spill_reg)
|
||||
{
|
||||
if (left_size>=4 && right_size == 4)
|
||||
{
|
||||
unsigned int instr = ((unsigned int *)code)[-1];
|
||||
if (spill_reg >= 0 && (instr & 0xfffffc1f) == 0x1e604001) // fmov d1, dX
|
||||
{
|
||||
const int src_reg = (instr>>5)&0x1f;
|
||||
if (src_reg == spill_reg + 8)
|
||||
{
|
||||
instr = ((unsigned int *)code)[0];
|
||||
if ((instr & 0xffffcfff) == 0x1e600820)
|
||||
{
|
||||
((unsigned int *)code)[-1] = instr + ((src_reg-1) << 5);
|
||||
return -4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef _M_ARM64EC
|
||||
#define DEF_F1(n) static double eel_##n(double a) { return n(a); }
|
||||
#define DEF_F2(n) static double eel_##n(double a, double b) { return n(a,b); }
|
||||
DEF_F1(cos)
|
||||
#define cos eel_cos
|
||||
DEF_F1(sin)
|
||||
#define sin eel_sin
|
||||
DEF_F1(tan)
|
||||
#define tan eel_tan
|
||||
DEF_F1(log)
|
||||
#define log eel_log
|
||||
DEF_F1(log10)
|
||||
#define log10 eel_log10
|
||||
DEF_F1(acos)
|
||||
#define acos eel_acos
|
||||
DEF_F1(asin)
|
||||
#define asin eel_asin
|
||||
DEF_F1(atan)
|
||||
#define atan eel_atan
|
||||
DEF_F1(exp)
|
||||
#define exp eel_exp
|
||||
DEF_F2(pow)
|
||||
#define pow eel_pow
|
||||
DEF_F2(atan2)
|
||||
#define atan2 eel_atan2
|
||||
// ceil and floor will be wrapped by defs in nseel-compiler.c
|
||||
|
||||
#pragma comment(lib,"onecore.lib")
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
335
oversampling/WDL/eel2/glue_arm.h
Normal file
335
oversampling/WDL/eel2/glue_arm.h
Normal file
@@ -0,0 +1,335 @@
|
||||
#ifndef _NSEEL_GLUE_ARM_H_
|
||||
#define _NSEEL_GLUE_ARM_H_
|
||||
|
||||
// r0=return value, first parm, r1-r2 parms
|
||||
// r3+ should be reserved
|
||||
// blx addr
|
||||
// stmfd sp!, {register list, lr}
|
||||
// ldmfd sp!, {register list, pc}
|
||||
|
||||
// let's make r8 = worktable
|
||||
// let's make r7 = ramtable
|
||||
// r6 = consttab
|
||||
// r5 = worktable ptr
|
||||
|
||||
// r0=p1
|
||||
// r1=p2
|
||||
// r2=p3
|
||||
|
||||
// d0 is return value?
|
||||
|
||||
|
||||
#define GLUE_HAS_FPREG2 1
|
||||
|
||||
static const unsigned int GLUE_COPY_FPSTACK_TO_FPREG2[] = {
|
||||
0xeeb01b40 // fcpyd d1, d0
|
||||
};
|
||||
|
||||
static unsigned int GLUE_POP_STACK_TO_FPREG2[] = {
|
||||
0xed9d1b00,// vldr d1, [sp]
|
||||
0xe28dd008,// add sp, sp, #8
|
||||
};
|
||||
|
||||
#define GLUE_MAX_SPILL_REGS 8
|
||||
#define GLUE_SAVE_TO_SPILL_SIZE(x) (4)
|
||||
#define GLUE_RESTORE_SPILL_TO_FPREG2_SIZE(x) (4)
|
||||
|
||||
static void GLUE_RESTORE_SPILL_TO_FPREG2(void *b, int ws)
|
||||
{
|
||||
*(unsigned int *)b = 0xeeb01b48 + ws; // fcpyd d1, d8+ws
|
||||
}
|
||||
static void GLUE_SAVE_TO_SPILL(void *b, int ws)
|
||||
{
|
||||
*(unsigned int *)b = 0xeeb08b40 + (ws<<12); // fcpyd d8+ws, d0
|
||||
}
|
||||
|
||||
|
||||
#define GLUE_MAX_FPSTACK_SIZE 0 // no stack support
|
||||
#define GLUE_MAX_JMPSIZE ((1<<25) - 1024) // maximum relative jump size
|
||||
|
||||
// endOfInstruction is end of jump with relative offset, offset passed in is offset from end of dest instruction.
|
||||
// TODO: verify, but offset probably from next instruction (PC is ahead)
|
||||
#define GLUE_JMP_SET_OFFSET(endOfInstruction,offset) (((int *)(endOfInstruction))[-1] = (((int *)(endOfInstruction))[-1]&0xFF000000)|((((offset)>>2)-1)))
|
||||
|
||||
// /=conditional=always = 0xE
|
||||
// |/= 101(L), so 8+2+0 = 10 = A
|
||||
static const unsigned int GLUE_JMP_NC[] = { 0xEA000000 };
|
||||
|
||||
static const unsigned int GLUE_JMP_IF_P1_Z[]=
|
||||
{
|
||||
0xe1100000, // tst r0, r0
|
||||
0x0A000000, // branch if Z set
|
||||
};
|
||||
static const unsigned int GLUE_JMP_IF_P1_NZ[]=
|
||||
{
|
||||
0xe1100000, // tst r0, r0
|
||||
0x1A000000, // branch if Z clear
|
||||
};
|
||||
|
||||
#define GLUE_MOV_PX_DIRECTVALUE_TOFPREG2_SIZE 12 // wr=-2, sets d1
|
||||
#define GLUE_MOV_PX_DIRECTVALUE_SIZE 8
|
||||
static void GLUE_MOV_PX_DIRECTVALUE_GEN(void *b, INT_PTR v, int wv)
|
||||
{
|
||||
// requires ARMv6thumb2 or later
|
||||
const unsigned int reg_add = wdl_max(wv,0) << 12;
|
||||
static const unsigned int tab[2] = {
|
||||
0xe3000000, // movw r0, #0000
|
||||
0xe3400000, // movt r0, #0000
|
||||
};
|
||||
// 0xABAAA, B is register, A are bits of word
|
||||
unsigned int *p=(unsigned int *)b;
|
||||
p[0] = tab[0] | reg_add | (v&0xfff) | ((v&0xf000)<<4);
|
||||
p[1] = tab[1] | reg_add | ((v>>16)&0xfff) | ((v&0xf0000000)>>12);
|
||||
if (wv == -2) p[2] = 0xed901b00; // fldd d1, [r0]
|
||||
}
|
||||
|
||||
const static unsigned int GLUE_FUNC_ENTER[1] = { 0xe92d4010 }; // push {r4, lr}
|
||||
#define GLUE_FUNC_ENTER_SIZE 4
|
||||
const static unsigned int GLUE_FUNC_LEAVE[1] = { 0 }; // let GLUE_RET pop
|
||||
#define GLUE_FUNC_LEAVE_SIZE 0
|
||||
const static unsigned int GLUE_RET[]={ 0xe8bd8010 }; // pop {r4, pc}
|
||||
|
||||
static int GLUE_RESET_WTP(unsigned char *out, void *ptr)
|
||||
{
|
||||
const static unsigned int GLUE_SET_WTP_FROM_R8 = 0xe1a05008; // mov r5, r8
|
||||
if (out) memcpy(out,&GLUE_SET_WTP_FROM_R8,sizeof(GLUE_SET_WTP_FROM_R8));
|
||||
return sizeof(GLUE_SET_WTP_FROM_R8);
|
||||
}
|
||||
|
||||
|
||||
const static unsigned int GLUE_PUSH_P1[1]={ 0xe52d0008 }; // push {r0}, aligned to 8
|
||||
|
||||
|
||||
static int arm_encode_constforalu(int amt)
|
||||
{
|
||||
int nrot = 16;
|
||||
while (amt >= 0x100 && nrot > 1)
|
||||
{
|
||||
// ARM encodes integers for ALU operations as rotated right by third nibble*2
|
||||
amt = (amt + 3)>>2;
|
||||
nrot--;
|
||||
}
|
||||
return ((nrot&15) << 8) | amt;
|
||||
}
|
||||
|
||||
|
||||
#define GLUE_STORE_P1_TO_STACK_AT_OFFS_SIZE(x) ((x)>=4096 ? 8 : 4)
|
||||
static void GLUE_STORE_P1_TO_STACK_AT_OFFS(void *b, int offs)
|
||||
{
|
||||
if (offs >= 4096)
|
||||
{
|
||||
// add r2, sp, (offs&~4095)
|
||||
*(unsigned int *)b = 0xe28d2000 | arm_encode_constforalu(offs&~4095);
|
||||
// str r0, [r2, offs&4095]
|
||||
((unsigned int *)b)[1] = 0xe5820000 + (offs&4095);
|
||||
}
|
||||
else
|
||||
{
|
||||
// str r0, [sp, #offs]
|
||||
*(unsigned int *)b = 0xe58d0000 + offs;
|
||||
}
|
||||
}
|
||||
|
||||
#define GLUE_MOVE_PX_STACKPTR_SIZE 4
|
||||
static void GLUE_MOVE_PX_STACKPTR_GEN(void *b, int wv)
|
||||
{
|
||||
// mov rX, sp
|
||||
*(unsigned int *)b = 0xe1a0000d + (wv<<12);
|
||||
}
|
||||
|
||||
#define GLUE_MOVE_STACK_SIZE 4
|
||||
static void GLUE_MOVE_STACK(void *b, int amt)
|
||||
{
|
||||
unsigned int instr = 0xe28dd000;
|
||||
if (amt < 0)
|
||||
{
|
||||
instr = 0xe24dd000;
|
||||
amt=-amt;
|
||||
}
|
||||
*(unsigned int*)b = instr | arm_encode_constforalu(amt);
|
||||
}
|
||||
|
||||
#define GLUE_POP_PX_SIZE 4
|
||||
static void GLUE_POP_PX(void *b, int wv)
|
||||
{
|
||||
((unsigned int *)b)[0] = 0xe49d0008 | (wv<<12); // pop {rX}, aligned to 8
|
||||
}
|
||||
|
||||
#define GLUE_SET_PX_FROM_P1_SIZE 4
|
||||
static void GLUE_SET_PX_FROM_P1(void *b, int wv)
|
||||
{
|
||||
*(unsigned int *)b = 0xe1a00000 | (wv<<12); // mov rX, r0
|
||||
}
|
||||
|
||||
|
||||
static const unsigned int GLUE_PUSH_P1PTR_AS_VALUE[] =
|
||||
{
|
||||
0xed907b00, // fldd d7, [r0]
|
||||
0xe24dd008, // sub sp, sp, #8
|
||||
0xed8d7b00, // fstd d7, [sp]
|
||||
};
|
||||
|
||||
static int GLUE_POP_VALUE_TO_ADDR(unsigned char *buf, void *destptr)
|
||||
{
|
||||
if (buf)
|
||||
{
|
||||
unsigned int *bufptr = (unsigned int *)buf;
|
||||
*bufptr++ = 0xed9d7b00; // fldd d7, [sp]
|
||||
*bufptr++ = 0xe28dd008; // add sp, sp, #8
|
||||
GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0);
|
||||
bufptr += GLUE_MOV_PX_DIRECTVALUE_SIZE/4;
|
||||
*bufptr++ = 0xed807b00; // fstd d7, [r0]
|
||||
}
|
||||
return 3*4 + GLUE_MOV_PX_DIRECTVALUE_SIZE;
|
||||
}
|
||||
|
||||
static int GLUE_COPY_VALUE_AT_P1_TO_PTR(unsigned char *buf, void *destptr)
|
||||
{
|
||||
if (buf)
|
||||
{
|
||||
unsigned int *bufptr = (unsigned int *)buf;
|
||||
*bufptr++ = 0xed907b00; // fldd d7, [r0]
|
||||
GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0);
|
||||
bufptr += GLUE_MOV_PX_DIRECTVALUE_SIZE/4;
|
||||
*bufptr++ = 0xed807b00; // fstd d7, [r0]
|
||||
}
|
||||
return 2*4 + GLUE_MOV_PX_DIRECTVALUE_SIZE;
|
||||
}
|
||||
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#define GLUE_CALL_CODE(bp, cp, rt) do { \
|
||||
unsigned int f; \
|
||||
if (!(h->compile_flags&NSEEL_CODE_COMPILE_FLAG_NOFPSTATE) && \
|
||||
!((f=glue_getscr())&(1<<24))) { \
|
||||
glue_setscr(f|(1<<24)); \
|
||||
eel_callcode32(bp, cp, rt); \
|
||||
glue_setscr(f); \
|
||||
} else eel_callcode32(bp, cp, rt);\
|
||||
} while(0)
|
||||
|
||||
static const double __consttab[] = {
|
||||
NSEEL_CLOSEFACTOR,
|
||||
0.0,
|
||||
1.0,
|
||||
-1.0,
|
||||
-0.5, // for invsqrt
|
||||
1.5,
|
||||
};
|
||||
|
||||
static void eel_callcode32(INT_PTR bp, INT_PTR cp, INT_PTR rt)
|
||||
{
|
||||
__asm__ volatile(
|
||||
"mov r7, %2\n"
|
||||
"mov r6, %3\n"
|
||||
"mov r8, %1\n"
|
||||
"mov r0, %0\n"
|
||||
"mov r1, sp\n"
|
||||
"bic sp, sp, #7\n"
|
||||
"push {r1, lr}\n"
|
||||
"blx r0\n"
|
||||
"pop {r1, lr}\n"
|
||||
"mov sp, r1\n"
|
||||
::"r" (cp), "r" (bp), "r" (rt), "r" (__consttab) :
|
||||
"r5", "r6", "r7", "r8", "r10",
|
||||
"d8","d9","d10","d11","d12","d13","d14","d15");
|
||||
};
|
||||
#endif
|
||||
|
||||
static unsigned char *EEL_GLUE_set_immediate(void *_p, INT_PTR newv)
|
||||
{
|
||||
unsigned int *p=(unsigned int *)_p;
|
||||
while ((p[0]&0x000F0FFF) != 0x000d0ead &&
|
||||
(p[1]&0x000F0FFF) != 0x000b0eef) p++;
|
||||
p[0] = (p[0]&0xFFF0F000) | (newv&0xFFF) | ((newv << 4) & 0xF0000);
|
||||
p[1] = (p[1]&0xFFF0F000) | ((newv>>16)&0xFFF) | ((newv >> 12)&0xF0000);
|
||||
|
||||
return (unsigned char *)(p+1);
|
||||
}
|
||||
|
||||
#define GLUE_SET_PX_FROM_WTP_SIZE sizeof(int)
|
||||
static void GLUE_SET_PX_FROM_WTP(void *b, int wv)
|
||||
{
|
||||
*(unsigned int *)b = 0xe1a00005 + (wv<<12); // mov rX, r5
|
||||
}
|
||||
|
||||
static int GLUE_POP_FPSTACK_TO_PTR(unsigned char *buf, void *destptr)
|
||||
{
|
||||
if (buf)
|
||||
{
|
||||
unsigned int *bufptr = (unsigned int *)buf;
|
||||
GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0);
|
||||
bufptr += GLUE_MOV_PX_DIRECTVALUE_SIZE/4;
|
||||
|
||||
*bufptr++ = 0xed800b00; // fstd d0, [r0]
|
||||
}
|
||||
return GLUE_MOV_PX_DIRECTVALUE_SIZE + sizeof(int);
|
||||
}
|
||||
|
||||
#define GLUE_POP_FPSTACK_SIZE 0
|
||||
static const unsigned int GLUE_POP_FPSTACK[1] = { 0 }; // no need to pop, not a stack
|
||||
|
||||
static const unsigned int GLUE_POP_FPSTACK_TOSTACK[] = {
|
||||
0xe24dd008, // sub sp, sp, #8
|
||||
0xed8d0b00, // fstd d0, [sp]
|
||||
};
|
||||
|
||||
static const unsigned int GLUE_POP_FPSTACK_TO_WTP[] = {
|
||||
0xed850b00, // fstd d0, [r5]
|
||||
0xe2855008, // add r5, r5, #8
|
||||
};
|
||||
|
||||
#define GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE 4
|
||||
static void GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(void *b, int wv)
|
||||
{
|
||||
*(unsigned int *)b = 0xed900b00 + (wv<<16); // fldd d0, [rX]
|
||||
}
|
||||
|
||||
#define GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE (sizeof(GLUE_POP_FPSTACK_TO_WTP) + GLUE_SET_PX_FROM_WTP_SIZE)
|
||||
static void GLUE_POP_FPSTACK_TO_WTP_TO_PX(unsigned char *buf, int wv)
|
||||
{
|
||||
GLUE_SET_PX_FROM_WTP(buf,wv);
|
||||
memcpy(buf + GLUE_SET_PX_FROM_WTP_SIZE,GLUE_POP_FPSTACK_TO_WTP,sizeof(GLUE_POP_FPSTACK_TO_WTP));
|
||||
};
|
||||
|
||||
static const unsigned int GLUE_SET_P1_Z[] = { 0xe3a00000 }; // mov r0, #0
|
||||
static const unsigned int GLUE_SET_P1_NZ[] = { 0xe3a00001 }; // mov r0, #1
|
||||
|
||||
|
||||
static void *GLUE_realAddress(void *fn, int *size)
|
||||
{
|
||||
static const unsigned int sig[3] = { 0xe1a00000, 0xe1a01001, 0xe1a02002 };
|
||||
unsigned char *p = (unsigned char *)fn;
|
||||
|
||||
while (memcmp(p,sig,sizeof(sig))) p+=4;
|
||||
p+=sizeof(sig);
|
||||
fn = p;
|
||||
|
||||
while (memcmp(p,sig,sizeof(sig))) p+=4;
|
||||
*size = p - (unsigned char *)fn;
|
||||
return fn;
|
||||
}
|
||||
|
||||
static unsigned int __attribute__((unused)) glue_getscr()
|
||||
{
|
||||
unsigned int rv;
|
||||
asm volatile ( "fmrx %0, fpscr" : "=r" (rv));
|
||||
return rv;
|
||||
}
|
||||
static void __attribute__((unused)) glue_setscr(unsigned int v)
|
||||
{
|
||||
asm volatile ( "fmxr fpscr, %0" :: "r"(v));
|
||||
}
|
||||
|
||||
void eel_enterfp(int s[2])
|
||||
{
|
||||
s[0] = glue_getscr();
|
||||
glue_setscr(s[0] | (1<<24)); // could also do 3<<22 for RTZ
|
||||
}
|
||||
void eel_leavefp(int s[2])
|
||||
{
|
||||
glue_setscr(s[0]);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
1029
oversampling/WDL/eel2/glue_port.h
Normal file
1029
oversampling/WDL/eel2/glue_port.h
Normal file
File diff suppressed because it is too large
Load Diff
285
oversampling/WDL/eel2/glue_ppc.h
Normal file
285
oversampling/WDL/eel2/glue_ppc.h
Normal file
@@ -0,0 +1,285 @@
|
||||
#ifndef _NSEEL_GLUE_PPC_H_
|
||||
#define _NSEEL_GLUE_PPC_H_
|
||||
|
||||
#define GLUE_MAX_FPSTACK_SIZE 0 // no stack support
|
||||
#define GLUE_MAX_JMPSIZE 30000 // maximum relative jump size for this arch (if not defined, any jump is possible)
|
||||
|
||||
|
||||
// endOfInstruction is end of jump with relative offset, offset passed in is offset from end of dest instruction.
|
||||
// on PPC the offset needs to be from the start of the instruction (hence +4), and also the low two bits are flags so
|
||||
// we make sure they are clear (they should always be clear, anyway, since we always generate 4 byte instructions)
|
||||
#define GLUE_JMP_SET_OFFSET(endOfInstruction,offset) (((short *)(endOfInstruction))[-1] = ((offset) + 4) & 0xFFFC)
|
||||
|
||||
static const unsigned char GLUE_JMP_NC[] = { 0x48,0, 0, 0, }; // b <offset>
|
||||
|
||||
static const unsigned int GLUE_JMP_IF_P1_Z[]=
|
||||
{
|
||||
0x2f830000, //cmpwi cr7, r3, 0
|
||||
0x419e0000, // beq cr7, offset-bytes-from-startofthisinstruction
|
||||
};
|
||||
static const unsigned int GLUE_JMP_IF_P1_NZ[]=
|
||||
{
|
||||
0x2f830000, //cmpwi cr7, r3, 0
|
||||
0x409e0000, // bne cr7, offset-bytes-from-startofthisinstruction
|
||||
};
|
||||
|
||||
|
||||
#define GLUE_MOV_PX_DIRECTVALUE_SIZE 8
|
||||
static void GLUE_MOV_PX_DIRECTVALUE_GEN(void *b, INT_PTR v, int wv)
|
||||
{
|
||||
static const unsigned short tab[3][2] = {
|
||||
{0x3C60, 0x6063}, // addis r3, r0, hw -- ori r3,r3, lw
|
||||
{0x3DC0, 0x61CE}, // addis r14, r0, hw -- ori r14, r14, lw
|
||||
{0x3DE0, 0x61EF}, // addis r15, r0, hw -- oris r15, r15, lw
|
||||
};
|
||||
unsigned int uv=(unsigned int)v;
|
||||
unsigned short *p=(unsigned short *)b;
|
||||
|
||||
*p++ = tab[wv][0]; // addis rX, r0, hw
|
||||
*p++ = (uv>>16)&0xffff;
|
||||
*p++ = tab[wv][1]; // ori rX, rX, lw
|
||||
*p++ = uv&0xffff;
|
||||
}
|
||||
|
||||
|
||||
// mflr r5
|
||||
// stwu r5, -16(r1)
|
||||
const static unsigned int GLUE_FUNC_ENTER[2] = { 0x7CA802A6, 0x94A1FFF0 };
|
||||
#define GLUE_FUNC_ENTER_SIZE 8
|
||||
|
||||
// lwz r5, 0(r1)
|
||||
// addi r1, r1, 16
|
||||
// mtlr r5
|
||||
const static unsigned int GLUE_FUNC_LEAVE[3] = { 0x80A10000, 0x38210010, 0x7CA803A6 };
|
||||
#define GLUE_FUNC_LEAVE_SIZE 12
|
||||
|
||||
const static unsigned int GLUE_RET[]={0x4E800020}; // blr
|
||||
|
||||
static int GLUE_RESET_WTP(unsigned char *out, void *ptr)
|
||||
{
|
||||
const static unsigned int GLUE_SET_WTP_FROM_R17=0x7E308B78; // mr r16 (dest), r17 (src)
|
||||
if (out) memcpy(out,&GLUE_SET_WTP_FROM_R17,sizeof(GLUE_SET_WTP_FROM_R17));
|
||||
return sizeof(GLUE_SET_WTP_FROM_R17);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// stwu r3, -16(r1)
|
||||
const static unsigned int GLUE_PUSH_P1[1]={ 0x9461FFF0};
|
||||
|
||||
|
||||
#define GLUE_POP_PX_SIZE 8
|
||||
static void GLUE_POP_PX(void *b, int wv)
|
||||
{
|
||||
static const unsigned int tab[3] ={
|
||||
0x80610000, // lwz r3, 0(r1)
|
||||
0x81c10000, // lwz r14, 0(r1)
|
||||
0x81e10000, // lwz r15, 0(r1)
|
||||
};
|
||||
((unsigned int *)b)[0] = tab[wv];
|
||||
((unsigned int *)b)[1] = 0x38210010; // addi r1,r1, 16
|
||||
}
|
||||
|
||||
#define GLUE_SET_PX_FROM_P1_SIZE 4
|
||||
static void GLUE_SET_PX_FROM_P1(void *b, int wv)
|
||||
{
|
||||
static const unsigned int tab[3]={
|
||||
0x7c631b78, // never used: mr r3, r3
|
||||
0x7c6e1b78, // mr r14, r3
|
||||
0x7c6f1b78, // mr r15, r3
|
||||
};
|
||||
*(unsigned int *)b = tab[wv];
|
||||
}
|
||||
|
||||
|
||||
|
||||
// lfd f2, 0(r3)
|
||||
// stfdu f2, -16(r1)
|
||||
static const unsigned int GLUE_PUSH_P1PTR_AS_VALUE[] = { 0xC8430000, 0xDC41FFF0 };
|
||||
|
||||
static int GLUE_POP_VALUE_TO_ADDR(unsigned char *buf, void *destptr)
|
||||
{
|
||||
// lfd f2, 0(r1)
|
||||
// addi r1,r1,16
|
||||
// GLUE_MOV_PX_DIRECTVALUE_GEN / GLUE_MOV_PX_DIRECTVALUE_SIZE (r3)
|
||||
// stfd f2, 0(r3)
|
||||
if (buf)
|
||||
{
|
||||
unsigned int *bufptr = (unsigned int *)buf;
|
||||
*bufptr++ = 0xC8410000;
|
||||
*bufptr++ = 0x38210010;
|
||||
GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0);
|
||||
bufptr += GLUE_MOV_PX_DIRECTVALUE_SIZE/4;
|
||||
*bufptr++ = 0xd8430000;
|
||||
}
|
||||
return 2*4 + GLUE_MOV_PX_DIRECTVALUE_SIZE + 4;
|
||||
}
|
||||
|
||||
static int GLUE_COPY_VALUE_AT_P1_TO_PTR(unsigned char *buf, void *destptr)
|
||||
{
|
||||
// lfd f2, 0(r3)
|
||||
// GLUE_MOV_PX_DIRECTVALUE_GEN / GLUE_MOV_PX_DIRECTVALUE_SIZE (r3)
|
||||
// stfd f2, 0(r3)
|
||||
|
||||
if (buf)
|
||||
{
|
||||
unsigned int *bufptr = (unsigned int *)buf;
|
||||
*bufptr++ = 0xc8430000;
|
||||
GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0);
|
||||
bufptr += GLUE_MOV_PX_DIRECTVALUE_SIZE/4;
|
||||
*bufptr++ = 0xd8430000;
|
||||
}
|
||||
|
||||
return 4 + GLUE_MOV_PX_DIRECTVALUE_SIZE + 4;
|
||||
}
|
||||
|
||||
|
||||
static void GLUE_CALL_CODE(INT_PTR bp, INT_PTR cp, INT_PTR rt)
|
||||
{
|
||||
static const double consttab[] = {
|
||||
NSEEL_CLOSEFACTOR,
|
||||
4503601774854144.0 /* 0x43300000, 0x80000000, used for integer conversion*/,
|
||||
};
|
||||
// we could have r18 refer to the current user-stack pointer, someday, perhaps
|
||||
__asm__(
|
||||
"subi r1, r1, 128\n"
|
||||
"stfd f31, 8(r1)\n"
|
||||
"stfd f30, 16(r1)\n"
|
||||
"stmw r13, 32(r1)\n"
|
||||
"mtctr %0\n"
|
||||
"mr r17, %1\n"
|
||||
"mr r13, %2\n"
|
||||
"lfd f31, 0(%3)\n"
|
||||
"lfd f30, 8(%3)\n"
|
||||
"subi r17, r17, 8\n"
|
||||
"mflr r0\n"
|
||||
"stw r0, 24(r1)\n"
|
||||
"bctrl\n"
|
||||
"lwz r0, 24(r1)\n"
|
||||
"mtlr r0\n"
|
||||
"lmw r13, 32(r1)\n"
|
||||
"lfd f31, 8(r1)\n"
|
||||
"lfd f30, 16(r1)\n"
|
||||
"addi r1, r1, 128\n"
|
||||
::"r" (cp), "r" (bp), "r" (rt), "r" (consttab));
|
||||
};
|
||||
|
||||
static unsigned char *EEL_GLUE_set_immediate(void *_p, INT_PTR newv)
|
||||
{
|
||||
// 64 bit ppc would take some work
|
||||
unsigned int *p=(unsigned int *)_p;
|
||||
while ((p[0]&0x0000FFFF) != 0x0000dead &&
|
||||
(p[1]&0x0000FFFF) != 0x0000beef) p++;
|
||||
p[0] = (p[0]&0xFFFF0000) | (((newv)>>16)&0xFFFF);
|
||||
p[1] = (p[1]&0xFFFF0000) | ((newv)&0xFFFF);
|
||||
|
||||
return (unsigned char *)(p+1);
|
||||
}
|
||||
|
||||
#define GLUE_SET_PX_FROM_WTP_SIZE sizeof(int)
|
||||
static void GLUE_SET_PX_FROM_WTP(void *b, int wv)
|
||||
{
|
||||
static const unsigned int tab[3]={
|
||||
0x7e038378, // mr r3, r16
|
||||
0x7e0e8378, // mr r14, r16
|
||||
0x7e0f8378, // mr r15, r16
|
||||
};
|
||||
*(unsigned int *)b = tab[wv];
|
||||
}
|
||||
static int GLUE_POP_FPSTACK_TO_PTR(unsigned char *buf, void *destptr)
|
||||
{
|
||||
// set r3 to destptr
|
||||
// stfd f1, 0(r3)
|
||||
if (buf)
|
||||
{
|
||||
unsigned int *bufptr = (unsigned int *)buf;
|
||||
GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0);
|
||||
bufptr += GLUE_MOV_PX_DIRECTVALUE_SIZE/4;
|
||||
|
||||
*bufptr++ = 0xD8230000; // stfd f1, 0(r3)
|
||||
}
|
||||
return GLUE_MOV_PX_DIRECTVALUE_SIZE + sizeof(int);
|
||||
}
|
||||
#define GLUE_POP_FPSTACK_SIZE 0
|
||||
static const unsigned int GLUE_POP_FPSTACK[1] = { 0 }; // no need to pop, not a stack
|
||||
|
||||
static const unsigned int GLUE_POP_FPSTACK_TOSTACK[] = {
|
||||
0xdc21fff0, // stfdu f1, -16(r1)
|
||||
};
|
||||
|
||||
static const unsigned int GLUE_POP_FPSTACK_TO_WTP[] = {
|
||||
0xdc300008, // stfdu f1, 8(r16)
|
||||
};
|
||||
|
||||
#define GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE 4
|
||||
static void GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(void *b, int wv)
|
||||
{
|
||||
static const unsigned int tab[3] = {
|
||||
0xC8230000, // lfd f1, 0(r3)
|
||||
0xC82E0000, // lfd f1, 0(r14)
|
||||
0xC82F0000, // lfd f1, 0(r15)
|
||||
};
|
||||
*(unsigned int *)b = tab[wv];
|
||||
}
|
||||
|
||||
#define GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE (sizeof(GLUE_POP_FPSTACK_TO_WTP) + GLUE_SET_PX_FROM_WTP_SIZE)
|
||||
static void GLUE_POP_FPSTACK_TO_WTP_TO_PX(unsigned char *buf, int wv)
|
||||
{
|
||||
memcpy(buf,GLUE_POP_FPSTACK_TO_WTP,sizeof(GLUE_POP_FPSTACK_TO_WTP));
|
||||
GLUE_SET_PX_FROM_WTP(buf + sizeof(GLUE_POP_FPSTACK_TO_WTP),wv); // ppc preincs the WTP, so we do this after
|
||||
};
|
||||
|
||||
static unsigned int GLUE_POP_STACK_TO_FPSTACK[1] = { 0 }; // todo
|
||||
|
||||
|
||||
static const unsigned int GLUE_SET_P1_Z[] = { 0x38600000 }; // li r3, 0
|
||||
static const unsigned int GLUE_SET_P1_NZ[] = { 0x38600001 }; // li r3, 1
|
||||
|
||||
|
||||
static void *GLUE_realAddress(void *fn, int *size)
|
||||
{
|
||||
// magic numbers: mr r0,r0 ; mr r1,r1 ; mr r2, r2
|
||||
static const unsigned char sig[12] = { 0x7c, 0x00, 0x03, 0x78, 0x7c, 0x21, 0x0b, 0x78, 0x7c, 0x42, 0x13, 0x78 };
|
||||
unsigned char *p = (unsigned char *)fn;
|
||||
|
||||
while (memcmp(p,sig,sizeof(sig))) p+=4;
|
||||
p+=sizeof(sig);
|
||||
fn = p;
|
||||
|
||||
while (memcmp(p,sig,sizeof(sig))) p+=4;
|
||||
*size = p - (unsigned char *)fn;
|
||||
return fn;
|
||||
}
|
||||
|
||||
#define GLUE_STORE_P1_TO_STACK_AT_OFFS_SIZE(x) 4
|
||||
static void GLUE_STORE_P1_TO_STACK_AT_OFFS(void *b, int offs)
|
||||
{
|
||||
// limited to 32k offset
|
||||
*(unsigned int *)b = 0x90610000 + (offs&0xffff);
|
||||
}
|
||||
|
||||
#define GLUE_MOVE_PX_STACKPTR_SIZE 4
|
||||
static void GLUE_MOVE_PX_STACKPTR_GEN(void *b, int wv)
|
||||
{
|
||||
static const unsigned int tab[3] =
|
||||
{
|
||||
0x7c230b78, // mr r3, r1
|
||||
0x7c2e0b78, // mr r14, r1
|
||||
0x7c2f0b78, // mr r15, r1
|
||||
};
|
||||
* (unsigned int *)b = tab[wv];
|
||||
}
|
||||
|
||||
#define GLUE_MOVE_STACK_SIZE 4
|
||||
static void GLUE_MOVE_STACK(void *b, int amt)
|
||||
{
|
||||
// this should be updated to allow for more than 32k moves, but no real need
|
||||
((unsigned int *)b)[0] = 0x38210000 + (amt&0xffff); // addi r1,r1, amt
|
||||
}
|
||||
|
||||
|
||||
|
||||
// end of ppc
|
||||
|
||||
#endif
|
||||
678
oversampling/WDL/eel2/glue_x86.h
Normal file
678
oversampling/WDL/eel2/glue_x86.h
Normal file
@@ -0,0 +1,678 @@
|
||||
#ifndef _NSEEL_GLUE_X86_H_
|
||||
#define _NSEEL_GLUE_X86_H_
|
||||
|
||||
#define GLUE_MAX_FPSTACK_SIZE 8
|
||||
|
||||
// endOfInstruction is end of jump with relative offset, offset is offset from end of instruction to jump to
|
||||
#define GLUE_JMP_SET_OFFSET(endOfInstruction,offset) (((int *)(endOfInstruction))[-1] = (offset))
|
||||
|
||||
static const unsigned char GLUE_JMP_NC[] = { 0xE9, 0,0,0,0, }; // jmp<offset>
|
||||
static const unsigned char GLUE_JMP_IF_P1_Z[] = {0x85, 0xC0, 0x0F, 0x84, 0,0,0,0 }; // test eax, eax, jz
|
||||
static const unsigned char GLUE_JMP_IF_P1_NZ[] = {0x85, 0xC0, 0x0F, 0x85, 0,0,0,0 }; // test eax, eax, jnz
|
||||
|
||||
#define GLUE_FUNC_ENTER_SIZE 0
|
||||
#define GLUE_FUNC_LEAVE_SIZE 0
|
||||
const static unsigned int GLUE_FUNC_ENTER[1];
|
||||
const static unsigned int GLUE_FUNC_LEAVE[1];
|
||||
|
||||
// x86
|
||||
// stack is 16 byte aligned
|
||||
// when pushing values to stack, alignment pushed first, then value (value is at the lower address)
|
||||
// when pushing pointers to stack, alignment pushed first, then pointer (pointer is at the lower address)
|
||||
|
||||
static const unsigned char GLUE_PUSH_P1PTR_AS_VALUE[] =
|
||||
{
|
||||
0x83, 0xEC, 8, /* sub esp, 8 */
|
||||
0xff, 0x70, 0x4, /* push dword [eax+4] */
|
||||
0xff, 0x30, /* push dword [eax] */
|
||||
};
|
||||
|
||||
static int GLUE_POP_VALUE_TO_ADDR(unsigned char *buf, void *destptr)
|
||||
{
|
||||
if (buf)
|
||||
{
|
||||
*buf++ = 0xB8; *(void **) buf = destptr; buf+=4; // mov eax, directvalue
|
||||
|
||||
*buf++ = 0x8f; *buf++ = 0x00; // pop dword [eax]
|
||||
*buf++ = 0x8f; *buf++ = 0x40; *buf++ = 4; // pop dword [eax+4]
|
||||
|
||||
*buf++ = 0x59; // pop ecx (alignment)
|
||||
*buf++ = 0x59; // pop ecx (alignment)
|
||||
}
|
||||
|
||||
return 12;
|
||||
}
|
||||
|
||||
static int GLUE_COPY_VALUE_AT_P1_TO_PTR(unsigned char *buf, void *destptr)
|
||||
{
|
||||
if (buf)
|
||||
{
|
||||
*buf++ = 0x8B; *buf++ = 0x38; // mov edi, [eax]
|
||||
*buf++ = 0x8B; *buf++ = 0x48; *buf++ = 0x04; // mov ecx, [eax+4]
|
||||
|
||||
|
||||
*buf++ = 0xB8; *(void **) buf = destptr; buf+=4; // mov eax, directvalue
|
||||
*buf++ = 0x89; *buf++ = 0x38; // mov [eax], edi
|
||||
*buf++ = 0x89; *buf++ = 0x48; *buf++ = 0x04; // mov [eax+4], ecx
|
||||
}
|
||||
|
||||
return 2 + 3 + 5 + 2 + 3;
|
||||
}
|
||||
|
||||
static int GLUE_POP_FPSTACK_TO_PTR(unsigned char *buf, void *destptr)
|
||||
{
|
||||
if (buf)
|
||||
{
|
||||
*buf++ = 0xB8; *(void **) buf = destptr; buf+=4; // mov eax, directvalue
|
||||
*buf++ = 0xDD; *buf++ = 0x18; // fstp qword [eax]
|
||||
}
|
||||
return 1+4+2;
|
||||
}
|
||||
|
||||
|
||||
#define GLUE_MOV_PX_DIRECTVALUE_SIZE 5
|
||||
#define GLUE_MOV_PX_DIRECTVALUE_TOSTACK_SIZE 6 // length when wv == -1
|
||||
|
||||
static void GLUE_MOV_PX_DIRECTVALUE_GEN(void *b, INT_PTR v, int wv)
|
||||
{
|
||||
if (wv==-1)
|
||||
{
|
||||
const static unsigned char t[2] = {0xDD, 0x05};
|
||||
memcpy(b,t,2);
|
||||
b= ((unsigned char *)b)+2;
|
||||
}
|
||||
else
|
||||
{
|
||||
const static unsigned char tab[3] = {
|
||||
0xB8 /* mov eax, dv*/,
|
||||
0xBF /* mov edi, dv */ ,
|
||||
0xB9 /* mov ecx, dv */
|
||||
};
|
||||
*((unsigned char *)b) = tab[wv]; // mov eax, dv
|
||||
b= ((unsigned char *)b)+1;
|
||||
}
|
||||
*(INT_PTR *)b = v;
|
||||
}
|
||||
const static unsigned char GLUE_PUSH_P1[4]={0x83, 0xEC, 12, 0x50}; // sub esp, 12, push eax
|
||||
|
||||
#define GLUE_STORE_P1_TO_STACK_AT_OFFS_SIZE(x) 7
|
||||
static void GLUE_STORE_P1_TO_STACK_AT_OFFS(void *b, int offs)
|
||||
{
|
||||
((unsigned char *)b)[0] = 0x89; // mov [esp+offs], eax
|
||||
((unsigned char *)b)[1] = 0x84;
|
||||
((unsigned char *)b)[2] = 0x24;
|
||||
*(int *)((unsigned char *)b+3) = offs;
|
||||
}
|
||||
|
||||
#define GLUE_MOVE_PX_STACKPTR_SIZE 2
|
||||
static void GLUE_MOVE_PX_STACKPTR_GEN(void *b, int wv)
|
||||
{
|
||||
static const unsigned char tab[3][GLUE_MOVE_PX_STACKPTR_SIZE]=
|
||||
{
|
||||
{ 0x89, 0xe0 }, // mov eax, esp
|
||||
{ 0x89, 0xe7 }, // mov edi, esp
|
||||
{ 0x89, 0xe1 }, // mov ecx, esp
|
||||
};
|
||||
memcpy(b,tab[wv],GLUE_MOVE_PX_STACKPTR_SIZE);
|
||||
}
|
||||
|
||||
#define GLUE_MOVE_STACK_SIZE 6
|
||||
static void GLUE_MOVE_STACK(void *b, int amt)
|
||||
{
|
||||
((unsigned char *)b)[0] = 0x81;
|
||||
if (amt <0)
|
||||
{
|
||||
((unsigned char *)b)[1] = 0xEC;
|
||||
*(int *)((char*)b+2) = -amt; // sub esp, -amt
|
||||
}
|
||||
else
|
||||
{
|
||||
((unsigned char *)b)[1] = 0xc4;
|
||||
*(int *)((char*)b+2) = amt; // add esp, amt
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define GLUE_POP_PX_SIZE 4
|
||||
static void GLUE_POP_PX(void *b, int wv)
|
||||
{
|
||||
static const unsigned char tab[3][GLUE_POP_PX_SIZE]=
|
||||
{
|
||||
{0x58,/*pop eax*/ 0x83, 0xC4, 12 /* add esp, 12*/},
|
||||
{0x5F,/*pop edi*/ 0x83, 0xC4, 12},
|
||||
{0x59,/*pop ecx*/ 0x83, 0xC4, 12},
|
||||
};
|
||||
memcpy(b,tab[wv],GLUE_POP_PX_SIZE);
|
||||
}
|
||||
|
||||
#define GLUE_SET_PX_FROM_P1_SIZE 2
|
||||
static void GLUE_SET_PX_FROM_P1(void *b, int wv)
|
||||
{
|
||||
static const unsigned char tab[3][GLUE_SET_PX_FROM_P1_SIZE]={
|
||||
{0x90,0x90}, // should never be used! (nopnop)
|
||||
{0x89,0xC7}, // mov edi, eax
|
||||
{0x89,0xC1}, // mov ecx, eax
|
||||
};
|
||||
memcpy(b,tab[wv],GLUE_SET_PX_FROM_P1_SIZE);
|
||||
}
|
||||
|
||||
#define GLUE_POP_FPSTACK_SIZE 2
|
||||
static const unsigned char GLUE_POP_FPSTACK[2] = { 0xDD, 0xD8 }; // fstp st0
|
||||
|
||||
static const unsigned char GLUE_POP_FPSTACK_TOSTACK[] = {
|
||||
0x83, 0xEC, 16, // sub esp, 16
|
||||
0xDD, 0x1C, 0x24 // fstp qword (%esp)
|
||||
};
|
||||
|
||||
static const unsigned char GLUE_POP_STACK_TO_FPSTACK[] = {
|
||||
0xDD, 0x04, 0x24, // fld qword (%esp)
|
||||
0x83, 0xC4, 16 // add esp, 16
|
||||
};
|
||||
|
||||
static const unsigned char GLUE_POP_FPSTACK_TO_WTP[] = {
|
||||
0xDD, 0x1E, /* fstp qword [esi] */
|
||||
0x83, 0xC6, 8, /* add esi, 8 */
|
||||
};
|
||||
|
||||
#define GLUE_SET_PX_FROM_WTP_SIZE 2
|
||||
static void GLUE_SET_PX_FROM_WTP(void *b, int wv)
|
||||
{
|
||||
static const unsigned char tab[3][GLUE_SET_PX_FROM_WTP_SIZE]={
|
||||
{0x89,0xF0}, // mov eax, esi
|
||||
{0x89,0xF7}, // mov edi, esi
|
||||
{0x89,0xF1}, // mov ecx, esi
|
||||
};
|
||||
memcpy(b,tab[wv],GLUE_SET_PX_FROM_WTP_SIZE);
|
||||
}
|
||||
|
||||
#define GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE 2
|
||||
static void GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(void *b, int wv)
|
||||
{
|
||||
static const unsigned char tab[3][GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE]={
|
||||
{0xDD,0x00}, // fld qword [eax]
|
||||
{0xDD,0x07}, // fld qword [edi]
|
||||
{0xDD,0x01}, // fld qword [ecx]
|
||||
};
|
||||
memcpy(b,tab[wv],GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE);
|
||||
}
|
||||
|
||||
#define GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE (GLUE_SET_PX_FROM_WTP_SIZE + sizeof(GLUE_POP_FPSTACK_TO_WTP))
|
||||
static void GLUE_POP_FPSTACK_TO_WTP_TO_PX(unsigned char *buf, int wv)
|
||||
{
|
||||
GLUE_SET_PX_FROM_WTP(buf,wv);
|
||||
memcpy(buf + GLUE_SET_PX_FROM_WTP_SIZE,GLUE_POP_FPSTACK_TO_WTP,sizeof(GLUE_POP_FPSTACK_TO_WTP));
|
||||
};
|
||||
|
||||
|
||||
const static unsigned char GLUE_RET=0xC3;
|
||||
|
||||
static int GLUE_RESET_WTP(unsigned char *out, void *ptr)
|
||||
{
|
||||
if (out)
|
||||
{
|
||||
*out++ = 0xBE; // mov esi, constant
|
||||
memcpy(out,&ptr,sizeof(void *));
|
||||
out+=sizeof(void *);
|
||||
}
|
||||
return 1+sizeof(void *);
|
||||
}
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4731)
|
||||
#endif
|
||||
|
||||
#define GLUE_TABPTR_IGNORED
|
||||
#define GLUE_CALL_CODE(bp, cp, rt) do { \
|
||||
if (h->compile_flags&NSEEL_CODE_COMPILE_FLAG_NOFPSTATE) eel_callcode32_fast(cp, rt); \
|
||||
else eel_callcode32(cp, rt);\
|
||||
} while(0)
|
||||
|
||||
static void eel_callcode32(INT_PTR cp, INT_PTR ramptr)
|
||||
{
|
||||
#ifndef NSEEL_EEL1_COMPAT_MODE
|
||||
short oldsw, newsw;
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
|
||||
__asm
|
||||
{
|
||||
#ifndef NSEEL_EEL1_COMPAT_MODE
|
||||
fnstcw [oldsw]
|
||||
mov ax, [oldsw]
|
||||
or ax, 0x23F // 53 or 64 bit precision (depending on whether 0x100 is set), and masking all exceptions
|
||||
mov [newsw], ax
|
||||
fldcw [newsw]
|
||||
#endif
|
||||
|
||||
mov eax, cp
|
||||
mov ebx, ramptr
|
||||
|
||||
pushad
|
||||
mov ebp, esp
|
||||
and esp, -16
|
||||
|
||||
// on win32, which _MSC_VER implies, we keep things aligned to 16 bytes, and if we call a win32 function,
|
||||
// the stack is 16 byte aligned before the call, meaning that if calling a function with no frame pointer,
|
||||
// the stack would be aligned to a 16 byte boundary +4, which isn't good for performance. Having said that,
|
||||
// normally we compile with frame pointers (which brings that to 16 byte + 8, which is fine), or ICC, which
|
||||
// for nontrivial functions will align the stack itself (for very short functions, it appears to weigh the
|
||||
// cost of aligning the stack vs that of the slower misaligned double accesses).
|
||||
|
||||
// it may be worthwhile (at some point) to put some logic in the code that calls out to functions
|
||||
// (generic1parm etc) to detect which alignment would be most optimal.
|
||||
sub esp, 12
|
||||
call eax
|
||||
mov esp, ebp
|
||||
popad
|
||||
#ifndef NSEEL_EEL1_COMPAT_MODE
|
||||
fldcw [oldsw]
|
||||
#endif
|
||||
};
|
||||
|
||||
#else // gcc x86
|
||||
__asm__(
|
||||
#ifndef NSEEL_EEL1_COMPAT_MODE
|
||||
"fnstcw %2\n"
|
||||
"movw %2, %%ax\n"
|
||||
"orw $0x23F, %%ax\n" // 53 or 64 bit precision (depending on whether 0x100 is set), and masking all exceptions
|
||||
"movw %%ax, %3\n"
|
||||
"fldcw %3\n"
|
||||
#endif
|
||||
"pushl %%ebx\n"
|
||||
"movl %%ecx, %%ebx\n"
|
||||
"pushl %%ebp\n"
|
||||
"movl %%esp, %%ebp\n"
|
||||
"andl $-16, %%esp\n" // align stack to 16 bytes
|
||||
"subl $12, %%esp\n" // call will push 4 bytes on stack, align for that
|
||||
"call *%%edx\n"
|
||||
"leave\n"
|
||||
"popl %%ebx\n"
|
||||
#ifndef NSEEL_EEL1_COMPAT_MODE
|
||||
"fldcw %2\n"
|
||||
#endif
|
||||
::
|
||||
"d" (cp), "c" (ramptr)
|
||||
#ifndef NSEEL_EEL1_COMPAT_MODE
|
||||
, "m" (oldsw), "m" (newsw)
|
||||
#endif
|
||||
: "%eax","%esi","%edi");
|
||||
#endif //gcc x86
|
||||
}
|
||||
|
||||
void eel_enterfp(int s[2])
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
__asm
|
||||
{
|
||||
mov ecx, s
|
||||
fnstcw [ecx]
|
||||
mov ax, [ecx]
|
||||
or ax, 0x23F // 53 or 64 bit precision (depending on whether 0x100 is set), and masking all exceptions
|
||||
mov [ecx+4], ax
|
||||
fldcw [ecx+4]
|
||||
};
|
||||
#else
|
||||
__asm__(
|
||||
"fnstcw (%%ecx)\n"
|
||||
"movw (%%ecx), %%ax\n"
|
||||
"orw $0x23F, %%ax\n" // 53 or 64 bit precision (depending on whether 0x100 is set), and masking all exceptions
|
||||
"movw %%ax, 4(%%ecx)\n"
|
||||
"fldcw 4(%%ecx)\n"
|
||||
:: "c" (s) : "%eax");
|
||||
#endif
|
||||
}
|
||||
void eel_leavefp(int s[2])
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
__asm
|
||||
{
|
||||
mov ecx, s
|
||||
fldcw [ecx]
|
||||
};
|
||||
#else
|
||||
__asm__(
|
||||
"fldcw (%%ecx)\n"
|
||||
:: "c" (s) : "%eax");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void eel_callcode32_fast(INT_PTR cp, INT_PTR ramptr)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
|
||||
__asm
|
||||
{
|
||||
mov eax, cp
|
||||
mov ebx, ramptr
|
||||
|
||||
pushad
|
||||
mov ebp, esp
|
||||
and esp, -16
|
||||
|
||||
// on win32, which _MSC_VER implies, we keep things aligned to 16 bytes, and if we call a win32 function,
|
||||
// the stack is 16 byte aligned before the call, meaning that if calling a function with no frame pointer,
|
||||
// the stack would be aligned to a 16 byte boundary +4, which isn't good for performance. Having said that,
|
||||
// normally we compile with frame pointers (which brings that to 16 byte + 8, which is fine), or ICC, which
|
||||
// for nontrivial functions will align the stack itself (for very short functions, it appears to weigh the
|
||||
// cost of aligning the stack vs that of the slower misaligned double accesses).
|
||||
|
||||
// it may be worthwhile (at some point) to put some logic in the code that calls out to functions
|
||||
// (generic1parm etc) to detect which alignment would be most optimal.
|
||||
sub esp, 12
|
||||
call eax
|
||||
mov esp, ebp
|
||||
popad
|
||||
};
|
||||
|
||||
#else // gcc x86
|
||||
__asm__(
|
||||
"pushl %%ebx\n"
|
||||
"movl %%ecx, %%ebx\n"
|
||||
"pushl %%ebp\n"
|
||||
"movl %%esp, %%ebp\n"
|
||||
"andl $-16, %%esp\n" // align stack to 16 bytes
|
||||
"subl $12, %%esp\n" // call will push 4 bytes on stack, align for that
|
||||
"call *%%edx\n"
|
||||
"leave\n"
|
||||
"popl %%ebx\n"
|
||||
::
|
||||
"d" (cp), "c" (ramptr)
|
||||
: "%eax","%esi","%edi");
|
||||
#endif //gcc x86
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
static unsigned char *EEL_GLUE_set_immediate(void *_p, INT_PTR newv)
|
||||
{
|
||||
char *p=(char*)_p;
|
||||
INT_PTR scan = 0xFEFEFEFE;
|
||||
while (*(INT_PTR *)p != scan) p++;
|
||||
*(INT_PTR *)p = newv;
|
||||
return (unsigned char *) (((INT_PTR*)p)+1);
|
||||
}
|
||||
|
||||
#define INT_TO_LECHARS(x) ((x)&0xff),(((x)>>8)&0xff), (((x)>>16)&0xff), (((x)>>24)&0xff)
|
||||
|
||||
|
||||
#define GLUE_INLINE_LOOPS
|
||||
|
||||
#define GLUE_LOOP_LOADCNT_SIZE (nseel_has_sse3() ? sizeof(GLUE_LOOP_LOADCNT_SSE3) : sizeof(GLUE_LOOP_LOADCNT_NOSSE3))
|
||||
#define GLUE_LOOP_LOADCNT (nseel_has_sse3() ? GLUE_LOOP_LOADCNT_SSE3 : GLUE_LOOP_LOADCNT_NOSSE3)
|
||||
static const unsigned char GLUE_LOOP_LOADCNT_SSE3[]={
|
||||
0xdb, 0x0e, // fisttp dword [esi]
|
||||
0x8B, 0x0E, // mov ecx, [esi]
|
||||
0x81, 0xf9, 1,0,0,0, // cmp ecx, 1
|
||||
0x0F, 0x8C, 0,0,0,0, // JL <skipptr>
|
||||
};
|
||||
|
||||
static const unsigned char GLUE_LOOP_LOADCNT_NOSSE3[]={
|
||||
0xd9, 0x7e, 0x04, // fnstcw [esi+4]
|
||||
0x66, 0x8b, 0x46, 0x04, // mov ax, [esi+4]
|
||||
0x66, 0x0d, 0x00, 0x0c, // or ax, 0xC00
|
||||
0x66, 0x89, 0x46, 0x08, // mov [esi+8], ax
|
||||
0xd9, 0x6e, 0x08, // fldcw [esi+8]
|
||||
0xDB, 0x1E, // fistp dword [esi]
|
||||
0xd9, 0x6e, 0x04, // fldcw [esi+4]
|
||||
0x8B, 0x0E, // mov ecx, [esi]
|
||||
0x81, 0xf9, 1,0,0,0, // cmp ecx, 1
|
||||
0x0F, 0x8C, 0,0,0,0, // JL <skipptr>
|
||||
};
|
||||
|
||||
#if NSEEL_LOOPFUNC_SUPPORT_MAXLEN > 0
|
||||
#define GLUE_LOOP_CLAMPCNT_SIZE sizeof(GLUE_LOOP_CLAMPCNT)
|
||||
static const unsigned char GLUE_LOOP_CLAMPCNT[]={
|
||||
0x81, 0xf9, INT_TO_LECHARS(NSEEL_LOOPFUNC_SUPPORT_MAXLEN), // cmp ecx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN
|
||||
0x0F, 0x8C, 5,0,0,0, // JL over-the-mov
|
||||
0xB9, INT_TO_LECHARS(NSEEL_LOOPFUNC_SUPPORT_MAXLEN), // mov ecx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN
|
||||
};
|
||||
#else
|
||||
|
||||
#define GLUE_LOOP_CLAMPCNT_SIZE 0
|
||||
#define GLUE_LOOP_CLAMPCNT ""
|
||||
|
||||
#endif
|
||||
|
||||
#define GLUE_LOOP_BEGIN_SIZE sizeof(GLUE_LOOP_BEGIN)
|
||||
static const unsigned char GLUE_LOOP_BEGIN[]={
|
||||
0x56, //push esi
|
||||
0x51, // push ecx
|
||||
0x81, 0xEC, 0x08, 0,0,0, // sub esp, 8
|
||||
};
|
||||
static const unsigned char GLUE_LOOP_END[]={
|
||||
0x81, 0xC4, 0x08, 0,0,0, // add esp, 8
|
||||
0x59, //pop ecx
|
||||
0x5E, // pop esi
|
||||
0x49, // dec ecx
|
||||
0x0f, 0x85, 0,0,0,0, // jnz ...
|
||||
};
|
||||
|
||||
|
||||
#if NSEEL_LOOPFUNC_SUPPORT_MAXLEN > 0
|
||||
#define GLUE_WHILE_SETUP_SIZE sizeof(GLUE_WHILE_SETUP)
|
||||
static const unsigned char GLUE_WHILE_SETUP[]={
|
||||
0xB9, INT_TO_LECHARS(NSEEL_LOOPFUNC_SUPPORT_MAXLEN), // mov ecx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN
|
||||
};
|
||||
static const unsigned char GLUE_WHILE_BEGIN[]={
|
||||
0x56, //push esi
|
||||
0x51, // push ecx
|
||||
0x81, 0xEC, 0x08, 0,0,0, // sub esp, 8
|
||||
};
|
||||
static const unsigned char GLUE_WHILE_END[]={
|
||||
0x81, 0xC4, 0x08, 0,0,0, // add esp, 8
|
||||
0x59, //pop ecx
|
||||
0x5E, // pop esi
|
||||
|
||||
|
||||
0x49, // dec ecx
|
||||
0x0f, 0x84, 0,0,0,0, // jz endpt
|
||||
};
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#define GLUE_WHILE_SETUP_SIZE 0
|
||||
#define GLUE_WHILE_SETUP ""
|
||||
#define GLUE_WHILE_END_NOJUMP
|
||||
static const unsigned char GLUE_WHILE_BEGIN[]={
|
||||
0x56, //push esi
|
||||
0x81, 0xEC, 12, 0,0,0, // sub esp, 12
|
||||
};
|
||||
static const unsigned char GLUE_WHILE_END[]={
|
||||
0x81, 0xC4, 12, 0,0,0, // add esp, 12
|
||||
0x5E, // pop esi
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
static const unsigned char GLUE_WHILE_CHECK_RV[] = {
|
||||
0x85, 0xC0, // test eax, eax
|
||||
0x0F, 0x85, 0,0,0,0 // jnz looppt
|
||||
};
|
||||
|
||||
static const unsigned char GLUE_SET_P1_Z[] = { 0x29, 0xC0 }; // sub eax, eax
|
||||
static const unsigned char GLUE_SET_P1_NZ[] = { 0xb0, 0x01 }; // mov al, 1
|
||||
|
||||
static const unsigned char GLUE_FXCH[] = {0xd9, 0xc9};
|
||||
|
||||
#define GLUE_HAS_FLDZ
|
||||
static const unsigned char GLUE_FLDZ[] = {0xd9, 0xee};
|
||||
#define GLUE_HAS_FLD1
|
||||
static const unsigned char GLUE_FLD1[] = {0xd9, 0xe8};
|
||||
|
||||
static EEL_F negativezeropointfive=-0.5f;
|
||||
static EEL_F onepointfive=1.5f;
|
||||
#define GLUE_INVSQRT_NEEDREPL &negativezeropointfive, &onepointfive,
|
||||
|
||||
|
||||
#define GLUE_HAS_NATIVE_TRIGSQRTLOG
|
||||
|
||||
|
||||
void nseel_asm_or(void);
|
||||
void nseel_asm_or0(void);
|
||||
void nseel_asm_or_op(void);
|
||||
void nseel_asm_and(void);
|
||||
void nseel_asm_and_op(void);
|
||||
void nseel_asm_xor(void);
|
||||
void nseel_asm_xor_op(void);
|
||||
void nseel_asm_shl(void);
|
||||
void nseel_asm_shr(void);
|
||||
void nseel_asm_mod(void);
|
||||
void nseel_asm_mod_op(void);
|
||||
void nseel_asm_stack_peek(void);
|
||||
void _asm_gmegabuf(void);
|
||||
void _asm_megabuf(void);
|
||||
|
||||
static struct roundinftab {
|
||||
void *fn;
|
||||
char istores; // number of fistp's
|
||||
char flag; // 0=fistpll, 1=fistpl, 2=fistpl 4(%esp)
|
||||
int newsz;
|
||||
void *newfn;
|
||||
} s_round_fixes[] = {
|
||||
{ nseel_asm_or, 2, },
|
||||
{ nseel_asm_or_op, 2, },
|
||||
{ nseel_asm_or0, 1, },
|
||||
{ nseel_asm_and, 2, },
|
||||
{ nseel_asm_and_op, 2, },
|
||||
{ nseel_asm_xor, 2, },
|
||||
{ nseel_asm_xor_op, 2, },
|
||||
{ nseel_asm_shl, 2, 1, },
|
||||
{ nseel_asm_shr, 2, 1, },
|
||||
{ nseel_asm_mod, 2, 1, },
|
||||
{ nseel_asm_mod_op, 2, 1, },
|
||||
{ nseel_asm_stack_peek, 1, 1, },
|
||||
{ _asm_megabuf, 1, 1, },
|
||||
{ _asm_gmegabuf, 1, 2, },
|
||||
};
|
||||
|
||||
static void eel_fixup_sse3(unsigned char *p, unsigned char *endp, int np, int flag)
|
||||
{
|
||||
const int isz = flag == 2 ? 3 : 2;
|
||||
while (p+isz <= endp && np > 0)
|
||||
{
|
||||
if (flag == 0 && p[0] == 0xdf && (p[1]&0xbe) == 0x3e)
|
||||
{
|
||||
*p++ = 0xdd;
|
||||
*p -= 0x30;
|
||||
if (*p & 0x40) p++;
|
||||
np--;
|
||||
}
|
||||
else if (flag == 1 && p[0] == 0xdb && (p[1]&0xbe) == 0x1e)
|
||||
{
|
||||
*++p -= 0x10;
|
||||
if (*p & 0x40) p++;
|
||||
np--;
|
||||
}
|
||||
else if (flag == 2 && p[0] == 0xdb && (p[1]&0xbf) == 0x1c && p[2] == 0x24)
|
||||
{
|
||||
*++p -= 0x10;
|
||||
if (*p & 0x40) p++;
|
||||
p++;
|
||||
np--;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
WDL_ASSERT(np == 0);
|
||||
}
|
||||
|
||||
static int nseel_has_sse3()
|
||||
{
|
||||
static char c;
|
||||
if (!c)
|
||||
{
|
||||
int features = 1;
|
||||
#ifdef _MSC_VER
|
||||
__asm {
|
||||
mov eax, 1
|
||||
cpuid
|
||||
mov [features], ecx
|
||||
};
|
||||
#else
|
||||
__asm__(
|
||||
"movl $1, %%eax\n"
|
||||
"pushl %%ebx\n"
|
||||
"pushl %%edx\n"
|
||||
"cpuid\n"
|
||||
"popl %%edx\n"
|
||||
"popl %%ebx\n"
|
||||
: "=c" (features) : : "%eax");
|
||||
#endif
|
||||
c=(features&1) ? 1 : -1;
|
||||
}
|
||||
return c>0;
|
||||
}
|
||||
static void *GLUE_realAddress(void *fn, int *size)
|
||||
{
|
||||
static const unsigned char sig[12] = { 0x89, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 };
|
||||
unsigned char *p = (unsigned char *)fn;
|
||||
|
||||
size_t rmatch;
|
||||
const size_t nmatch = sizeof(s_round_fixes) / sizeof(s_round_fixes[0]);
|
||||
for (rmatch = 0; rmatch < nmatch && s_round_fixes[rmatch].fn != fn; rmatch++);
|
||||
if (rmatch < nmatch && s_round_fixes[rmatch].newfn && s_round_fixes[rmatch].newsz)
|
||||
{
|
||||
*size = s_round_fixes[rmatch].newsz;
|
||||
return s_round_fixes[rmatch].newfn;
|
||||
}
|
||||
|
||||
#if defined(_DEBUG) && defined(_MSC_VER)
|
||||
if (*p == 0xE9) // this means jump to the following address (debug stub)
|
||||
{
|
||||
p += 5 + *(int *)(p+1);
|
||||
}
|
||||
#endif
|
||||
|
||||
while (memcmp(p,sig,sizeof(sig))) p++;
|
||||
p+=sizeof(sig);
|
||||
fn = p;
|
||||
|
||||
while (memcmp(p,sig,sizeof(sig))) p++;
|
||||
*size = p - (unsigned char *)fn;
|
||||
|
||||
if (rmatch < nmatch)
|
||||
{
|
||||
static const unsigned char prefix[] = {
|
||||
0xd9, 0x7e, 0x10, // fnstcw [esi+16]
|
||||
0x66, 0x8b, 0x46, 0x10, // mov ax, [esi+16]
|
||||
0x66, 0x0d, 0x00, 0x0c, // or ax, 0xC00
|
||||
0x66, 0x89, 0x46, 0x14, // mov [esi+20], ax
|
||||
0xd9, 0x6e, 0x14, // fldcw [esi+20]
|
||||
};
|
||||
static const unsigned char postfix[] = {
|
||||
0xd9, 0x6e, 0x10, // fldcw [esi+16]
|
||||
};
|
||||
|
||||
const int has_sse = nseel_has_sse3();
|
||||
|
||||
unsigned char *tmp = (unsigned char *) malloc(*size + (has_sse ? 0 : sizeof(prefix) + sizeof(postfix)));
|
||||
if (tmp)
|
||||
{
|
||||
if (has_sse)
|
||||
{
|
||||
memcpy(tmp,fn,*size);
|
||||
eel_fixup_sse3(tmp,tmp + *size,s_round_fixes[rmatch].istores, s_round_fixes[rmatch].flag);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(tmp,prefix,sizeof(prefix));
|
||||
memcpy(tmp+sizeof(prefix),fn,*size);
|
||||
memcpy(tmp+sizeof(prefix)+*size,postfix,sizeof(postfix));
|
||||
|
||||
*size += sizeof(prefix) + sizeof(postfix);
|
||||
}
|
||||
fn = tmp;
|
||||
s_round_fixes[rmatch].newsz = *size;
|
||||
s_round_fixes[rmatch].newfn = fn;
|
||||
}
|
||||
}
|
||||
|
||||
return fn;
|
||||
}
|
||||
|
||||
#endif
|
||||
638
oversampling/WDL/eel2/glue_x86_64_sse.h
Normal file
638
oversampling/WDL/eel2/glue_x86_64_sse.h
Normal file
@@ -0,0 +1,638 @@
|
||||
#ifndef _NSEEL_GLUE_X86_64_SSE_H_
|
||||
#define _NSEEL_GLUE_X86_64_SSE_H_
|
||||
|
||||
// SSE version (needs the appropriate .o linked!)
|
||||
#define GLUE_MOD_IS_64
|
||||
#define GLUE_PREFER_NONFP_DV_ASSIGNS
|
||||
#define GLUE_HAS_FPREG2 1
|
||||
|
||||
static const unsigned int GLUE_COPY_FPSTACK_TO_FPREG2[] = { 0xc8100ff2 }; // movsd %xmm0,%xmm1
|
||||
static unsigned char GLUE_POP_STACK_TO_FPREG2[] = {
|
||||
0xf2, 0x0f, 0x10, 0x0c, 0x24, // movsd (%rsp), %xmm1
|
||||
0x48, 0x81, 0xC4, 16, 0,0,0, // add rsp, 16
|
||||
};
|
||||
|
||||
// spill registers
|
||||
#define GLUE_MAX_SPILL_REGS 4
|
||||
#ifdef _WIN32
|
||||
// win64: xmm6-xmm15 are nonvolatile, so we use xmm6-xmm9 as spill registers (xmm8/xmm9 are 5 byte encodings)
|
||||
#define GLUE_SAVE_TO_SPILL_SIZE(x) (4 + ((x)>1))
|
||||
#define GLUE_RESTORE_SPILL_TO_FPREG2_SIZE(x) (4 + ((x)>1))
|
||||
|
||||
static void GLUE_RESTORE_SPILL_TO_FPREG2(void *b, int ws)
|
||||
{
|
||||
if (ws < 2)
|
||||
{
|
||||
*(unsigned int *)b = 0xce100ff2 + (ws<<24); // movsd xmm1, xmm6+ws
|
||||
}
|
||||
else
|
||||
{
|
||||
// movsd xmm1, xmm8 + (ws-2)
|
||||
*(unsigned int *)b = 0x100f41f2;
|
||||
((unsigned char *)b)[4] = 0xc8 + (ws-2);
|
||||
}
|
||||
}
|
||||
static void GLUE_SAVE_TO_SPILL(void *b, int ws)
|
||||
{
|
||||
if (ws < 2)
|
||||
{
|
||||
*(unsigned int *)b = 0xf0100ff2 + (ws<<27); // movsd xmm6+ws, xmm0
|
||||
}
|
||||
else
|
||||
{
|
||||
// movsd xmm8+(ws-2), xmm0
|
||||
*(unsigned int *)b = 0x100f44f2;
|
||||
((unsigned char *)b)[4] = 0xc0 + ((ws-2)<<3);
|
||||
}
|
||||
}
|
||||
#else
|
||||
// non-win32: our function stubs preserve xmm4-xmm7
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define GLUE_VALIDATE_SPILLS
|
||||
#endif
|
||||
|
||||
#ifdef GLUE_VALIDATE_SPILLS
|
||||
|
||||
static unsigned char save_validate[]={
|
||||
0x48,0x83,0xec,0x10, // subq $16, %rsp
|
||||
0xf2,0x0f,0x11,0x04,0x24, // movsd %xmm0, (%rsp)
|
||||
0x66,0x48,0x0f,0x6e,0xe4, // movq %rsp, %xmm4 (+ws<<3)
|
||||
};
|
||||
|
||||
static unsigned char restore_validate[] = {
|
||||
0xf2, 0x0f, 0x10, 0xcc, // movsd %xmm7, %xmm1 (+ws)
|
||||
0x66, 0x48, 0x0f, 0x6e, 0xdc, // movq %rsp, %xmm3
|
||||
0x66, 0x0f, 0x2e, 0xd9, // ucomisd %xmm1, %xmm3
|
||||
0x74, 0x02, // je 2 <skip>
|
||||
0xcd, 0x03, // int $3
|
||||
0xf2, 0x0f, 0x10, 0x0c, 0x24, // movsd (%rsp), %xmm1
|
||||
0x48, 0x83, 0xc4, 0x10, // addq $16, %rsp
|
||||
};
|
||||
#define GLUE_SAVE_TO_SPILL_SIZE(x) (sizeof(save_validate))
|
||||
#define GLUE_RESTORE_SPILL_TO_FPREG2_SIZE(x) (sizeof(restore_validate))
|
||||
|
||||
#else
|
||||
|
||||
#define GLUE_SAVE_TO_SPILL_SIZE(x) (4)
|
||||
#define GLUE_RESTORE_SPILL_TO_FPREG2_SIZE(x) (4)
|
||||
|
||||
#endif
|
||||
|
||||
static void GLUE_RESTORE_SPILL_TO_FPREG2(void *b, int ws)
|
||||
{
|
||||
#ifdef GLUE_VALIDATE_SPILLS
|
||||
char *p = (char*) b;
|
||||
memcpy(p,restore_validate,sizeof(restore_validate));
|
||||
p[3] += ws;
|
||||
#else
|
||||
*(unsigned int *)b = 0xcc100ff2 + (ws<<24); // movsd xmm1, xmm4+ws
|
||||
#endif
|
||||
}
|
||||
static void GLUE_SAVE_TO_SPILL(void *b, int ws)
|
||||
{
|
||||
#ifdef GLUE_VALIDATE_SPILLS
|
||||
char *p = (char*) b;
|
||||
memcpy(p,save_validate,sizeof(save_validate));
|
||||
p[sizeof(save_validate)-1] += ws<<3;
|
||||
#else
|
||||
*(unsigned int *)b = 0xe0100ff2 + (ws<<27); // movsd xmm4+ws, xmm0
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#define GLUE_MAX_FPSTACK_SIZE 0
|
||||
#define GLUE_JMP_SET_OFFSET(endOfInstruction,offset) (((int *)(endOfInstruction))[-1] = (int) (offset))
|
||||
|
||||
static const unsigned char GLUE_JMP_NC[] = { 0xE9, 0,0,0,0, }; // jmp<offset>
|
||||
static const unsigned char GLUE_JMP_IF_P1_Z[] = {0x85, 0xC0, 0x0F, 0x84, 0,0,0,0 }; // test eax, eax, jz
|
||||
static const unsigned char GLUE_JMP_IF_P1_NZ[] = {0x85, 0xC0, 0x0F, 0x85, 0,0,0,0 }; // test eax, eax, jnz
|
||||
|
||||
|
||||
#define GLUE_FUNC_ENTER_SIZE 0
|
||||
#define GLUE_FUNC_LEAVE_SIZE 0
|
||||
const static unsigned int GLUE_FUNC_ENTER[1];
|
||||
const static unsigned int GLUE_FUNC_LEAVE[1];
|
||||
|
||||
// on x86-64:
|
||||
// stack is always 16 byte aligned
|
||||
// pushing values to the stack (for eel functions) has alignment pushed first, then value (value is at the lower address)
|
||||
// pushing pointers to the stack has the pointer pushed first, then the alignment (pointer is at the higher address)
|
||||
#define GLUE_MOV_PX_DIRECTVALUE_SIZE 10
|
||||
#define GLUE_MOV_PX_DIRECTVALUE_TOSTACK_SIZE 14 // wr=-1, sets xmm0
|
||||
#define GLUE_MOV_PX_DIRECTVALUE_TOFPREG2_SIZE 14 // wr=-2, sets xmm1
|
||||
static void GLUE_MOV_PX_DIRECTVALUE_GEN(void *b, INT_PTR v, int wr) {
|
||||
const static unsigned short tab[3] =
|
||||
{
|
||||
0xB848 /* mov rax, dv*/,
|
||||
0xBF48 /* mov rdi, dv */ ,
|
||||
0xB948 /* mov rcx, dv */
|
||||
};
|
||||
unsigned short *bb = (unsigned short *)b;
|
||||
*bb++ = tab[wdl_max(wr,0)]; // mov rax, directvalue
|
||||
*(INT_PTR *)bb = v;
|
||||
if (wr == -2) *(unsigned int *)(bb + 4) = 0x08100ff2; // movsd (%rax), %xmm1
|
||||
else if (wr == -1) *(unsigned int *)(bb + 4) = 0x00100ff2; // movsd (%rax), %xmm0
|
||||
}
|
||||
|
||||
const static unsigned char GLUE_PUSH_P1[2]={ 0x50,0x50}; // push rax (pointer); push rax (alignment)
|
||||
|
||||
#define GLUE_STORE_P1_TO_STACK_AT_OFFS_SIZE(x) 8
|
||||
static void GLUE_STORE_P1_TO_STACK_AT_OFFS(void *b, int offs)
|
||||
{
|
||||
((unsigned char *)b)[0] = 0x48; // mov [rsp+offs], rax
|
||||
((unsigned char *)b)[1] = 0x89;
|
||||
((unsigned char *)b)[2] = 0x84;
|
||||
((unsigned char *)b)[3] = 0x24;
|
||||
*(int *)((unsigned char *)b+4) = offs;
|
||||
}
|
||||
|
||||
#define GLUE_MOVE_PX_STACKPTR_SIZE 3
|
||||
static void GLUE_MOVE_PX_STACKPTR_GEN(void *b, int wv)
|
||||
{
|
||||
static const unsigned char tab[3][GLUE_MOVE_PX_STACKPTR_SIZE]=
|
||||
{
|
||||
{ 0x48, 0x89, 0xe0 }, // mov rax, rsp
|
||||
{ 0x48, 0x89, 0xe7 }, // mov rdi, rsp
|
||||
{ 0x48, 0x89, 0xe1 }, // mov rcx, rsp
|
||||
};
|
||||
memcpy(b,tab[wv],GLUE_MOVE_PX_STACKPTR_SIZE);
|
||||
}
|
||||
|
||||
#define GLUE_MOVE_STACK_SIZE 7
|
||||
static void GLUE_MOVE_STACK(void *b, int amt)
|
||||
{
|
||||
((unsigned char *)b)[0] = 0x48;
|
||||
((unsigned char *)b)[1] = 0x81;
|
||||
if (amt < 0)
|
||||
{
|
||||
((unsigned char *)b)[2] = 0xEC;
|
||||
*(int *)((char*)b+3) = -amt; // sub rsp, -amt32
|
||||
}
|
||||
else
|
||||
{
|
||||
((unsigned char *)b)[2] = 0xc4;
|
||||
*(int *)((char*)b+3) = amt; // add rsp, amt32
|
||||
}
|
||||
}
|
||||
|
||||
#define GLUE_POP_PX_SIZE 2
|
||||
static void GLUE_POP_PX(void *b, int wv)
|
||||
{
|
||||
static const unsigned char tab[3][GLUE_POP_PX_SIZE]=
|
||||
{
|
||||
{0x58,/*pop rax*/ 0x58}, // pop alignment, then pop pointer
|
||||
{0x5F,/*pop rdi*/ 0x5F},
|
||||
{0x59,/*pop rcx*/ 0x59},
|
||||
};
|
||||
memcpy(b,tab[wv],GLUE_POP_PX_SIZE);
|
||||
}
|
||||
|
||||
static const unsigned char GLUE_PUSH_P1PTR_AS_VALUE[] =
|
||||
{
|
||||
0x50, /*push rax - for alignment */
|
||||
0xff, 0x30, /* push qword [rax] */
|
||||
};
|
||||
|
||||
static int GLUE_POP_VALUE_TO_ADDR(unsigned char *buf, void *destptr) // trashes P2 (rdi) and P3 (rcx)
|
||||
{
|
||||
if (buf)
|
||||
{
|
||||
*buf++ = 0x48; *buf++ = 0xB9; *(void **) buf = destptr; buf+=8; // mov rcx, directvalue
|
||||
*buf++ = 0x8f; *buf++ = 0x01; // pop qword [rcx]
|
||||
*buf++ = 0x5F ; // pop rdi (alignment, safe to trash rdi though)
|
||||
}
|
||||
return 1+10+2;
|
||||
}
|
||||
|
||||
static int GLUE_COPY_VALUE_AT_P1_TO_PTR(unsigned char *buf, void *destptr) // trashes P2/P3
|
||||
{
|
||||
if (buf)
|
||||
{
|
||||
*buf++ = 0x48; *buf++ = 0xB9; *(void **) buf = destptr; buf+=8; // mov rcx, directvalue
|
||||
*buf++ = 0x48; *buf++ = 0x8B; *buf++ = 0x38; // mov rdi, [rax]
|
||||
*buf++ = 0x48; *buf++ = 0x89; *buf++ = 0x39; // mov [rcx], rdi
|
||||
}
|
||||
|
||||
return 3 + 10 + 3;
|
||||
}
|
||||
|
||||
static int GLUE_POP_FPSTACK_TO_PTR(unsigned char *buf, void *destptr)
|
||||
{
|
||||
if (buf)
|
||||
{
|
||||
*buf++ = 0x48;
|
||||
*buf++ = 0xB8;
|
||||
*(void **) buf = destptr; buf+=8; // mov rax, directvalue
|
||||
|
||||
*buf++ = 0xf2; // movsd %xmm0, (%rax)
|
||||
*buf++ = 0x0f;
|
||||
*buf++ = 0x11;
|
||||
*buf++ = 0x00;
|
||||
}
|
||||
return 2+8+4;
|
||||
}
|
||||
|
||||
|
||||
#define GLUE_SET_PX_FROM_P1_SIZE 3
|
||||
static void GLUE_SET_PX_FROM_P1(void *b, int wv)
|
||||
{
|
||||
static const unsigned char tab[3][GLUE_SET_PX_FROM_P1_SIZE]={
|
||||
{0x90,0x90,0x90}, // should never be used! (nopnop)
|
||||
{0x48,0x89,0xC7}, // mov rdi, rax
|
||||
{0x48,0x89,0xC1}, // mov rcx, rax
|
||||
};
|
||||
memcpy(b,tab[wv],GLUE_SET_PX_FROM_P1_SIZE);
|
||||
}
|
||||
|
||||
|
||||
#define GLUE_POP_FPSTACK_SIZE 0
|
||||
static const unsigned char GLUE_POP_FPSTACK[1] = { 0 };
|
||||
|
||||
static const unsigned char GLUE_POP_FPSTACK_TOSTACK[] = {
|
||||
0x48, 0x81, 0xEC, 16, 0,0,0, // sub rsp, 16
|
||||
0xf2, 0x0f, 0x11, 0x04, 0x24, // movsd xmm0, (%rsp)
|
||||
};
|
||||
|
||||
static const unsigned char GLUE_POP_FPSTACK_TO_WTP[] = {
|
||||
0xf2, 0x0f, 0x11, 0x06, // movsd xmm0, (%rsi)
|
||||
0x48, 0x81, 0xC6, 8, 0,0,0,/* add rsi, 8 */
|
||||
};
|
||||
|
||||
#define GLUE_SET_PX_FROM_WTP_SIZE 3
|
||||
static void GLUE_SET_PX_FROM_WTP(void *b, int wv)
|
||||
{
|
||||
static const unsigned char tab[3][GLUE_SET_PX_FROM_WTP_SIZE]={
|
||||
{0x48, 0x89,0xF0}, // mov rax, rsi
|
||||
{0x48, 0x89,0xF7}, // mov rdi, rsi
|
||||
{0x48, 0x89,0xF1}, // mov rcx, rsi
|
||||
};
|
||||
memcpy(b,tab[wv],GLUE_SET_PX_FROM_WTP_SIZE);
|
||||
}
|
||||
|
||||
#define GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE 4
|
||||
static void GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(void *b, int wv)
|
||||
{
|
||||
static const unsigned char tab[3][GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE]={
|
||||
{0xf2, 0x0f, 0x10, 0x00}, // movsd (%rax), %xmm0
|
||||
{0xf2, 0x0f, 0x10, 0x07}, // movsd (%rdi), %xmm0
|
||||
{0xf2, 0x0f, 0x10, 0x01}, // movsd (%rcx), %xmm0
|
||||
};
|
||||
memcpy(b,tab[wv],GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE);
|
||||
}
|
||||
|
||||
#define GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE (GLUE_SET_PX_FROM_WTP_SIZE + sizeof(GLUE_POP_FPSTACK_TO_WTP))
|
||||
static void GLUE_POP_FPSTACK_TO_WTP_TO_PX(unsigned char *buf, int wv)
|
||||
{
|
||||
GLUE_SET_PX_FROM_WTP(buf,wv);
|
||||
memcpy(buf + GLUE_SET_PX_FROM_WTP_SIZE,GLUE_POP_FPSTACK_TO_WTP,sizeof(GLUE_POP_FPSTACK_TO_WTP));
|
||||
};
|
||||
|
||||
|
||||
const static unsigned char GLUE_RET=0xC3;
|
||||
|
||||
static int GLUE_RESET_WTP(unsigned char *out, void *ptr)
|
||||
{
|
||||
if (out)
|
||||
{
|
||||
*out++ = 0x48;
|
||||
*out++ = 0xBE; // mov rsi, constant64
|
||||
*(void **)out = ptr;
|
||||
out+=sizeof(void *);
|
||||
}
|
||||
return 2+sizeof(void *);
|
||||
}
|
||||
|
||||
extern void eel_callcode64(INT_PTR code, INT_PTR ram_tab);
|
||||
extern void eel_callcode64_fast(INT_PTR code, INT_PTR ram_tab);
|
||||
#define GLUE_CALL_CODE(bp, cp, rt) do { \
|
||||
if (h->compile_flags&NSEEL_CODE_COMPILE_FLAG_NOFPSTATE) eel_callcode64_fast(cp, rt); \
|
||||
else eel_callcode64(cp, rt);\
|
||||
} while(0)
|
||||
#define GLUE_TABPTR_IGNORED
|
||||
|
||||
static unsigned char *EEL_GLUE_set_immediate(void *_p, INT_PTR newv)
|
||||
{
|
||||
char *p=(char*)_p;
|
||||
INT_PTR scan = 0xFEFEFEFEFEFEFEFE;
|
||||
while (*(INT_PTR *)p != scan) p++;
|
||||
*(INT_PTR *)p = newv;
|
||||
return (unsigned char *) (((INT_PTR*)p)+1);
|
||||
}
|
||||
|
||||
#define INT_TO_LECHARS(x) ((x)&0xff),(((x)>>8)&0xff), (((x)>>16)&0xff), (((x)>>24)&0xff)
|
||||
|
||||
#define GLUE_INLINE_LOOPS
|
||||
|
||||
static const unsigned char GLUE_LOOP_LOADCNT[]={
|
||||
0xf2, 0x48, 0x0f, 0x2c, 0xc8, // cvttsd2si %xmm0, %rcx
|
||||
0x48, 0x81, 0xf9, 1,0,0,0, // cmp rcx, 1
|
||||
0x0F, 0x8C, 0,0,0,0, // JL <skipptr>
|
||||
};
|
||||
|
||||
#if NSEEL_LOOPFUNC_SUPPORT_MAXLEN > 0
|
||||
#define GLUE_LOOP_CLAMPCNT_SIZE sizeof(GLUE_LOOP_CLAMPCNT)
|
||||
static const unsigned char GLUE_LOOP_CLAMPCNT[]={
|
||||
0x48, 0x81, 0xf9, INT_TO_LECHARS(NSEEL_LOOPFUNC_SUPPORT_MAXLEN), // cmp rcx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN
|
||||
0x0F, 0x8C, 10,0,0,0, // JL over-the-mov
|
||||
0x48, 0xB9, INT_TO_LECHARS(NSEEL_LOOPFUNC_SUPPORT_MAXLEN), 0,0,0,0, // mov rcx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN
|
||||
};
|
||||
#else
|
||||
#define GLUE_LOOP_CLAMPCNT_SIZE 0
|
||||
#define GLUE_LOOP_CLAMPCNT ""
|
||||
#endif
|
||||
|
||||
#define GLUE_LOOP_BEGIN_SIZE sizeof(GLUE_LOOP_BEGIN)
|
||||
static const unsigned char GLUE_LOOP_BEGIN[]={
|
||||
0x56, //push rsi
|
||||
0x51, // push rcx
|
||||
};
|
||||
static const unsigned char GLUE_LOOP_END[]={
|
||||
0x59, //pop rcx
|
||||
0x5E, // pop rsi
|
||||
0xff, 0xc9, // dec rcx
|
||||
0x0f, 0x85, 0,0,0,0, // jnz ...
|
||||
};
|
||||
|
||||
|
||||
|
||||
#if NSEEL_LOOPFUNC_SUPPORT_MAXLEN > 0
|
||||
static const unsigned char GLUE_WHILE_SETUP[]={
|
||||
0x48, 0xB9, INT_TO_LECHARS(NSEEL_LOOPFUNC_SUPPORT_MAXLEN), 0,0,0,0, // mov rcx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN
|
||||
};
|
||||
#define GLUE_WHILE_SETUP_SIZE sizeof(GLUE_WHILE_SETUP)
|
||||
|
||||
static const unsigned char GLUE_WHILE_BEGIN[]={
|
||||
0x56, //push rsi
|
||||
0x51, // push rcx
|
||||
};
|
||||
static const unsigned char GLUE_WHILE_END[]={
|
||||
0x59, //pop rcx
|
||||
0x5E, // pop rsi
|
||||
|
||||
0xff, 0xc9, // dec rcx
|
||||
0x0f, 0x84, 0,0,0,0, // jz endpt
|
||||
};
|
||||
|
||||
|
||||
#else
|
||||
#define GLUE_WHILE_SETUP ""
|
||||
#define GLUE_WHILE_SETUP_SIZE 0
|
||||
#define GLUE_WHILE_END_NOJUMP
|
||||
|
||||
static const unsigned char GLUE_WHILE_BEGIN[]={
|
||||
0x56, //push rsi
|
||||
0x51, // push rcx
|
||||
};
|
||||
static const unsigned char GLUE_WHILE_END[]={
|
||||
0x59, //pop rcx
|
||||
0x5E, // pop rsi
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static const unsigned char GLUE_WHILE_CHECK_RV[] = {
|
||||
0x85, 0xC0, // test eax, eax
|
||||
0x0F, 0x85, 0,0,0,0 // jnz looppt
|
||||
};
|
||||
|
||||
static const unsigned char GLUE_SET_P1_Z[] = { 0x48, 0x29, 0xC0 }; // sub rax, rax
|
||||
static const unsigned char GLUE_SET_P1_NZ[] = { 0xb0, 0x01 }; // mov al, 1
|
||||
|
||||
|
||||
#define GLUE_HAS_FLDZ
|
||||
static const unsigned char GLUE_FLDZ[] = {
|
||||
0x0f, 0x57, 0xc0 //xorps %xmm0, %xmm0
|
||||
};
|
||||
|
||||
|
||||
static EEL_F negativezeropointfive=-0.5f;
|
||||
static EEL_F onepointfive=1.5f;
|
||||
#define GLUE_INVSQRT_NEEDREPL &negativezeropointfive, &onepointfive,
|
||||
|
||||
|
||||
static void *GLUE_realAddress(void *fn, int *size)
|
||||
{
|
||||
static const unsigned char new_sig[8] = { 0x89, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x00 };
|
||||
int sz = 0;
|
||||
while (memcmp((char*)fn + sz,new_sig,sizeof(new_sig))) sz++;
|
||||
*size = sz;
|
||||
return fn;
|
||||
}
|
||||
|
||||
#define GLUE_HAS_FUSE 1
|
||||
static int GLUE_FUSE(compileContext *ctx, unsigned char *code, int left_size, int right_size, int fuse_flags, int spill_reg)
|
||||
{
|
||||
const UINT_PTR base = (UINT_PTR) ctx->ram_state->blocks;
|
||||
const int is_sse_op = right_size == 4 && // add/mul/sub/min/max
|
||||
code[0] == 0xf2 &&
|
||||
code[1] == 0x0f &&
|
||||
code[3] == 0xc1 && // low nibble is xmm1
|
||||
(code[2] == 0x58 || code[2] == 0x59 || code[2] == 0x5c || code[2]==0x5d || code[2] == 0x5f);
|
||||
|
||||
if (spill_reg >= 0)
|
||||
{
|
||||
#ifndef GLUE_VALIDATE_SPILLS
|
||||
if (is_sse_op)
|
||||
{
|
||||
char tmp[32];
|
||||
const int sz = GLUE_RESTORE_SPILL_TO_FPREG2_SIZE(spill_reg);
|
||||
GLUE_RESTORE_SPILL_TO_FPREG2(tmp,spill_reg);
|
||||
if (left_size>=sz && !memcmp(code-sz,tmp,sz))
|
||||
{
|
||||
code[-2] = code[2]; // modify the movsd into an addsd
|
||||
code[-1] -= 8; // movsd uses 0xc8+(xmmX&7), addsd etc use 0xc0
|
||||
return -4;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
if (left_size==28)
|
||||
{
|
||||
// if const64_1 is within a 32-bit offset of ctx->ram_blocks->blocks, we can use [r12+offs]
|
||||
if (code[-28] == 0x48 && code[-27] == 0xb8 && // mov rax, const64_1
|
||||
*(int *)(code - 18) == 0x08100ff2 && // movsd xmm1, [rax]
|
||||
code[-14] == 0x48 && code[-13] == 0xb8 && // mov rax, const64_2
|
||||
*(int *)(code - 4) == 0x00100ff2 // movsd xmm0, [rax]
|
||||
)
|
||||
{
|
||||
UINT_PTR c1, c2;
|
||||
INT_PTR c2offs,c1offs;
|
||||
unsigned char opc[3];
|
||||
int wrpos = -28;
|
||||
if (is_sse_op) memcpy(opc,code,3);
|
||||
memcpy(&c1,code-26,8);
|
||||
memcpy(&c2,code-12,8);
|
||||
|
||||
#define PTR_32_OK(x) ((x) == (INT_PTR)(int)(x))
|
||||
c2offs = c2-base;
|
||||
if (!PTR_32_OK(c2offs))
|
||||
{
|
||||
code[wrpos++] = 0x48;
|
||||
code[wrpos++] = 0xb8;
|
||||
memcpy(code+wrpos,&c2,8); // mov rax, const64_2
|
||||
wrpos += 8;
|
||||
}
|
||||
|
||||
c1offs = c1-base;
|
||||
if (!PTR_32_OK(c1offs))
|
||||
{
|
||||
code[wrpos++] = 0x48;
|
||||
code[wrpos++] = 0xbf;
|
||||
memcpy(code+wrpos,&c1,8); // mov rdi, const64_1
|
||||
wrpos += 8;
|
||||
}
|
||||
|
||||
if (!PTR_32_OK(c2offs))
|
||||
{
|
||||
*(int *)(code+wrpos) = 0x00100ff2; // movsd xmm0, [rax]
|
||||
wrpos += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
// movsd xmm0, [r12+offs]
|
||||
code[wrpos++] = 0xf2;
|
||||
code[wrpos++] = 0x41;
|
||||
code[wrpos++] = 0x0f;
|
||||
code[wrpos++] = 0x10;
|
||||
code[wrpos++] = 0x84;
|
||||
code[wrpos++] = 0x24;
|
||||
*(int *)(code+wrpos) = (int)c2offs;
|
||||
wrpos += 4;
|
||||
}
|
||||
|
||||
if (!is_sse_op)
|
||||
{
|
||||
// load xmm1 from rdi/c1offs
|
||||
if (!PTR_32_OK(c1offs))
|
||||
{
|
||||
*(int *)(code+wrpos) = 0x0f100ff2; // movsd xmm1, [rdi]
|
||||
wrpos += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
// movsd xmm1, [r12+offs]
|
||||
code[wrpos++] = 0xf2;
|
||||
code[wrpos++] = 0x41;
|
||||
code[wrpos++] = 0x0f;
|
||||
code[wrpos++] = 0x10;
|
||||
code[wrpos++] = 0x8c;
|
||||
code[wrpos++] = 0x24;
|
||||
*(int *)(code+wrpos) = (int)c1offs;
|
||||
wrpos += 4;
|
||||
}
|
||||
if (wrpos<0) memmove(code+wrpos,code,right_size);
|
||||
return wrpos;
|
||||
}
|
||||
|
||||
// fuse to sse op
|
||||
if (!PTR_32_OK(c1offs))
|
||||
{
|
||||
memcpy(code+wrpos,opc,3);
|
||||
code[wrpos+3] = 0x07; // [rdi]
|
||||
wrpos += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
// mul/add/sub/min/max/sd xmm0, [r12+offs]
|
||||
code[wrpos++] = opc[0]; // 0xf2
|
||||
code[wrpos++] = 0x41;
|
||||
code[wrpos++] = opc[1]; // 0x0f
|
||||
code[wrpos++] = opc[2]; // 0x58 etc
|
||||
code[wrpos++] = 0x84;
|
||||
code[wrpos++] = 0x24;
|
||||
*(int *)(code+wrpos) = (int)c1offs;
|
||||
wrpos += 4;
|
||||
}
|
||||
return wrpos - right_size;
|
||||
}
|
||||
}
|
||||
if ((fuse_flags&1) && left_size >= 14)
|
||||
{
|
||||
if (code[-14] == 0x48 && code[-13] == 0xb8 && // mov rax, const64_2
|
||||
*(int *)(code - 4) == 0x00100ff2) // movsd xmm0, [rax]
|
||||
{
|
||||
INT_PTR c1;
|
||||
memcpy(&c1,code-12,8);
|
||||
c1 -= base;
|
||||
if (PTR_32_OK(c1))
|
||||
{
|
||||
// movsd xmm0, [r12+offs]
|
||||
int wrpos = -14;
|
||||
code[wrpos++] = 0xf2;
|
||||
code[wrpos++] = 0x41;
|
||||
code[wrpos++] = 0x0f;
|
||||
code[wrpos++] = 0x10;
|
||||
code[wrpos++] = 0x84;
|
||||
code[wrpos++] = 0x24;
|
||||
*(int *)(code+wrpos) = (int)c1;
|
||||
wrpos += 4;
|
||||
if (wrpos<0) memmove(code+wrpos,code,right_size);
|
||||
return wrpos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (left_size == 20 && right_size == 9 &&
|
||||
code[-20]==0x48 && code[-19] == 0xbf && // mov rdi, const64_1
|
||||
code[-10]==0x48 && code[-9] == 0xb8 // mov rax, const64_2
|
||||
)
|
||||
{
|
||||
static unsigned char assign_copy[9] = { 0x48, 0x8b, 0x10, // mov rdx, [rax]
|
||||
0x48, 0x89, 0x17, // mov [rdi], rdx
|
||||
0x48, 0x89, 0xf8, // mov rax, rdi
|
||||
};
|
||||
if (!memcmp(code,assign_copy,9))
|
||||
{
|
||||
int wrpos = -20;
|
||||
INT_PTR c1,c2; // c1 is dest, c2 is src
|
||||
memcpy(&c1,code-18,8);
|
||||
memcpy(&c2,code-8,8);
|
||||
|
||||
if (!PTR_32_OK(c2-base))
|
||||
{
|
||||
code[wrpos++] = 0x48; // mov rdi, src
|
||||
code[wrpos++] = 0xbf;
|
||||
memcpy(code+wrpos,&c2,8);
|
||||
wrpos +=8;
|
||||
}
|
||||
|
||||
code[wrpos++] = 0x48; // mov rax, dest
|
||||
code[wrpos++] = 0xb8;
|
||||
memcpy(code+wrpos,&c1,8);
|
||||
wrpos +=8;
|
||||
|
||||
if (PTR_32_OK(c2-base))
|
||||
{
|
||||
// mov rdx, [r12+offs]
|
||||
code[wrpos++] = 0x49;
|
||||
code[wrpos++] = 0x8b;
|
||||
code[wrpos++] = 0x94;
|
||||
code[wrpos++] = 0x24;
|
||||
*(int *)(code+wrpos) = (int)(c2-base);
|
||||
wrpos += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
code[wrpos++] = 0x48; // mov rdx, [rdi]
|
||||
code[wrpos++] = 0x8b;
|
||||
code[wrpos++] = 0x17;
|
||||
}
|
||||
|
||||
code[wrpos++] = 0x48; // mov [rax], rdx
|
||||
code[wrpos++] = 0x89;
|
||||
code[wrpos++] = 0x10;
|
||||
|
||||
return wrpos - right_size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
165
oversampling/WDL/eel2/loose_eel.cpp
Normal file
165
oversampling/WDL/eel2/loose_eel.cpp
Normal file
@@ -0,0 +1,165 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include "../mutex.h"
|
||||
|
||||
int g_verbose, g_interactive;
|
||||
|
||||
static void writeToStandardError(const char *fmt, ...)
|
||||
{
|
||||
va_list arglist;
|
||||
va_start(arglist, fmt);
|
||||
vfprintf(stderr,fmt,arglist);
|
||||
fprintf(stderr,"\n");
|
||||
fflush(stderr);
|
||||
va_end(arglist);
|
||||
}
|
||||
#define EEL_STRING_DEBUGOUT writeToStandardError // no parameters, since it takes varargs
|
||||
|
||||
#ifndef EEL_LICE_WANT_STANDALONE
|
||||
#define EELSCRIPT_NO_LICE
|
||||
#endif
|
||||
|
||||
#include "eelscript.h"
|
||||
|
||||
|
||||
void NSEEL_HOSTSTUB_EnterMutex() { }
|
||||
void NSEEL_HOSTSTUB_LeaveMutex() { }
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
bool want_args = true;
|
||||
int argpos = 1;
|
||||
const char *scriptfn = argv[0];
|
||||
while (argpos < argc && argv[argpos][0] == '-' && argv[argpos][1])
|
||||
{
|
||||
if (!strcmp(argv[argpos],"-v")) g_verbose++;
|
||||
else if (!strcmp(argv[argpos],"-i")) g_interactive++;
|
||||
else if (!strcmp(argv[argpos],"--no-args")) want_args=false;
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"Usage: %s [-v] [--no-args] [-i | scriptfile | -]\n",argv[0]);
|
||||
return -1;
|
||||
}
|
||||
argpos++;
|
||||
}
|
||||
if (argpos < argc && !g_interactive)
|
||||
{
|
||||
scriptfn = argv[argpos++];
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef _WIN32
|
||||
if (!g_interactive && isatty(0))
|
||||
#else
|
||||
if (1)
|
||||
#endif
|
||||
g_interactive=1;
|
||||
}
|
||||
|
||||
if (eelScriptInst::init())
|
||||
{
|
||||
fprintf(stderr,"NSEEL_init(): error initializing\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#ifndef EELSCRIPT_NO_LICE
|
||||
#ifdef __APPLE__
|
||||
SWELL_InitAutoRelease();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
WDL_FastString code,t;
|
||||
|
||||
eelScriptInst inst;
|
||||
if (want_args)
|
||||
{
|
||||
#ifndef EELSCRIPT_DO_DISASSEMBLE
|
||||
const int argv_offs = 1<<22;
|
||||
code.SetFormatted(64,"argc=0; argv=%d;\n",argv_offs);
|
||||
int x;
|
||||
for (x=argpos-1;x<argc;x++)
|
||||
{
|
||||
code.AppendFormatted(64,"argv[argc]=%d; argc+=1;\n",
|
||||
inst.m_string_context->AddString(new WDL_FastString(x<argpos ? scriptfn : argv[x])));
|
||||
}
|
||||
inst.runcode(code.Get(),2,"__cmdline__",true,true,true);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (g_interactive)
|
||||
{
|
||||
#ifndef EELSCRIPT_NO_LICE
|
||||
if (inst.m_gfx_state && inst.m_gfx_state->m_gfx_clear) inst.m_gfx_state->m_gfx_clear[0] = -1;
|
||||
#endif
|
||||
|
||||
printf("EEL interactive mode, type quit to quit, abort to abort multiline entry\n");
|
||||
EEL_F *resultVar = NSEEL_VM_regvar(inst.m_vm,"__result");
|
||||
code.Set("");
|
||||
char line[4096];
|
||||
for (;;)
|
||||
{
|
||||
#ifndef EELSCRIPT_NO_LICE
|
||||
_gfx_update(&inst,NULL);
|
||||
#endif
|
||||
if (!code.Get()[0]) printf("EEL> ");
|
||||
else printf("> ");
|
||||
fflush(stdout);
|
||||
line[0]=0;
|
||||
fgets(line,sizeof(line),stdin);
|
||||
if (!line[0]) break;
|
||||
code.Append(line);
|
||||
while (line[0] && (
|
||||
line[strlen(line)-1] == '\r' ||
|
||||
line[strlen(line)-1] == '\n' ||
|
||||
line[strlen(line)-1] == '\t' ||
|
||||
line[strlen(line)-1] == ' '
|
||||
)) line[strlen(line)-1]=0;
|
||||
|
||||
if (!strcmp(line,"quit")) break;
|
||||
if (!strcmp(line,"abort")) code.Set("");
|
||||
|
||||
#ifndef EELSCRIPT_DO_DISASSEMBLE
|
||||
t.Set("__result = (");
|
||||
#else
|
||||
t.Set("");
|
||||
#endif
|
||||
t.Append(code.Get());
|
||||
#ifndef EELSCRIPT_DO_DISASSEMBLE
|
||||
t.Append(");");
|
||||
#endif
|
||||
int res=inst.runcode(t.Get(),false,"",true,true,true); // allow free, since functions can't be defined locally
|
||||
if (!res)
|
||||
{
|
||||
if (resultVar) printf("=%g ",*resultVar);
|
||||
code.Set("");
|
||||
}
|
||||
else // try compiling again allowing function definitions (and not allowing free)
|
||||
// but show errors if not continuation
|
||||
{
|
||||
res=inst.runcode(code.Get(),true,"(stdin)", false,false,true);
|
||||
if (res<=0) code.Set("");
|
||||
// res>0 means need more lines
|
||||
}
|
||||
while (inst.run_deferred());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
inst.loadfile(scriptfn,NULL,true);
|
||||
while (inst.run_deferred());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
INT_PTR SWELLAppMain(int msg, INT_PTR parm1, INT_PTR parm2)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
194
oversampling/WDL/eel2/loose_eel.dsp
Normal file
194
oversampling/WDL/eel2/loose_eel.dsp
Normal file
@@ -0,0 +1,194 @@
|
||||
# Microsoft Developer Studio Project File - Name="loose_eel" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=loose_eel - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "loose_eel.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "loose_eel.mak" CFG="loose_eel - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "loose_eel - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "loose_eel - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "loose_eel - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D WDL_FFT_REALSIZE=8 /D NSEEL_LOOPFUNC_SUPPORT_MAXLEN=0 /D "EEL_LICE_WANT_STANDALONE" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "loose_eel - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D WDL_FFT_REALSIZE=8 /D NSEEL_LOOPFUNC_SUPPORT_MAXLEN=0 /D "EEL_LICE_WANT_STANDALONE" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "loose_eel - Win32 Release"
|
||||
# Name "loose_eel - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Group "eel2"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\ns-eel-addfuncs.h"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\ns-eel-int.h"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\ns-eel.h"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\nseel-caltab.c"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\nseel-cfunc.c"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\nseel-compiler.c"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\nseel-eval.c"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\nseel-lextab.c"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\nseel-ram.c"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\nseel-yylex.c"
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "lice"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\lice\lice.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\lice\lice_arc.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\lice\lice_bmp.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\lice\lice_ico.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\lice\lice_image.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\lice\lice_line.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\lice\lice_lvg.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\lice\lice_pcx.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\lice\lice_text.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\lice\lice_textnew.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\fft.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\loose_eel.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
29
oversampling/WDL/eel2/loose_eel.dsw
Normal file
29
oversampling/WDL/eel2/loose_eel.dsw
Normal file
@@ -0,0 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "loose_eel"=.\loose_eel.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
28
oversampling/WDL/eel2/loose_eel.sln
Normal file
28
oversampling/WDL/eel2/loose_eel.sln
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Express 2013 for Windows Desktop
|
||||
VisualStudioVersion = 12.0.30110.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "loose_eel", "loose_eel.vcxproj", "{893B9C0E-73CA-4843-A3BC-8A3FF9055FA8}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{893B9C0E-73CA-4843-A3BC-8A3FF9055FA8}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{893B9C0E-73CA-4843-A3BC-8A3FF9055FA8}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{893B9C0E-73CA-4843-A3BC-8A3FF9055FA8}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{893B9C0E-73CA-4843-A3BC-8A3FF9055FA8}.Debug|x64.Build.0 = Debug|x64
|
||||
{893B9C0E-73CA-4843-A3BC-8A3FF9055FA8}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{893B9C0E-73CA-4843-A3BC-8A3FF9055FA8}.Release|Win32.Build.0 = Release|Win32
|
||||
{893B9C0E-73CA-4843-A3BC-8A3FF9055FA8}.Release|x64.ActiveCfg = Release|x64
|
||||
{893B9C0E-73CA-4843-A3BC-8A3FF9055FA8}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
190
oversampling/WDL/eel2/loose_eel.vcxproj
Normal file
190
oversampling/WDL/eel2/loose_eel.vcxproj
Normal file
@@ -0,0 +1,190 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Object Include="asm-nseel-x64.obj">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</Object>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include=".\nseel-caltab.c" />
|
||||
<ClCompile Include=".\nseel-cfunc.c" />
|
||||
<ClCompile Include=".\nseel-compiler.c" />
|
||||
<ClCompile Include=".\nseel-eval.c" />
|
||||
<ClCompile Include=".\nseel-lextab.c" />
|
||||
<ClCompile Include=".\nseel-ram.c" />
|
||||
<ClCompile Include=".\nseel-yylex.c" />
|
||||
<ClCompile Include="..\lice\lice.cpp" />
|
||||
<ClCompile Include="..\lice\lice_arc.cpp" />
|
||||
<ClCompile Include="..\lice\lice_bmp.cpp" />
|
||||
<ClCompile Include="..\lice\lice_ico.cpp" />
|
||||
<ClCompile Include="..\lice\lice_image.cpp" />
|
||||
<ClCompile Include="..\lice\lice_line.cpp" />
|
||||
<ClCompile Include="..\lice\lice_lvg.cpp" />
|
||||
<ClCompile Include="..\lice\lice_pcx.cpp" />
|
||||
<ClCompile Include="..\lice\lice_text.cpp" />
|
||||
<ClCompile Include="..\lice\lice_textnew.cpp" />
|
||||
<ClCompile Include="..\fft.c" />
|
||||
<ClCompile Include=".\loose_eel.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include=".\ns-eel-addfuncs.h" />
|
||||
<ClInclude Include=".\ns-eel-int.h" />
|
||||
<ClInclude Include=".\ns-eel.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{893B9C0E-73CA-4843-A3BC-8A3FF9055FA8}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>loose_eel</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IntDir>$(Configuration)_new\</IntDir>
|
||||
<OutDir>$(SolutionDir)$(Configuration)_new\</OutDir>
|
||||
<TargetExt>.exe</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<TargetExt>.exe</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IntDir>$(Configuration)_new\</IntDir>
|
||||
<OutDir>$(SolutionDir)$(Configuration)_new\</OutDir>
|
||||
<TargetExt>.exe</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetExt>.exe</TargetExt>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;BUILD_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WDL_FFT_REALSIZE=8;EEL_LICE_WANT_STANDALONE;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;wsock32.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;BUILD_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WDL_FFT_REALSIZE=8;EEL_LICE_WANT_STANDALONE;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;wsock32.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;BUILD_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WDL_FFT_REALSIZE=8;EEL_LICE_WANT_STANDALONE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;wsock32.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;BUILD_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WDL_FFT_REALSIZE=8;EEL_LICE_WANT_STANDALONE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;wsock32.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
95
oversampling/WDL/eel2/loose_eel.vcxproj.filters
Normal file
95
oversampling/WDL/eel2/loose_eel.vcxproj.filters
Normal file
@@ -0,0 +1,95 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\lice">
|
||||
<UniqueIdentifier>{3A983C0A-E7C1-449D-B869-8CC1CE792C2F}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include=".\nseel-caltab.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\nseel-cfunc.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\nseel-compiler.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\nseel-eval.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\nseel-lextab.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\nseel-ram.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\nseel-yylex.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lice\lice.cpp">
|
||||
<Filter>Source Files\lice</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lice\lice_arc.cpp">
|
||||
<Filter>Source Files\lice</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lice\lice_bmp.cpp">
|
||||
<Filter>Source Files\lice</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lice\lice_ico.cpp">
|
||||
<Filter>Source Files\lice</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lice\lice_image.cpp">
|
||||
<Filter>Source Files\lice</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lice\lice_line.cpp">
|
||||
<Filter>Source Files\lice</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lice\lice_lvg.cpp">
|
||||
<Filter>Source Files\lice</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lice\lice_pcx.cpp">
|
||||
<Filter>Source Files\lice</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lice\lice_text.cpp">
|
||||
<Filter>Source Files\lice</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lice\lice_textnew.cpp">
|
||||
<Filter>Source Files\lice</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\fft.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\loose_eel.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include=".\ns-eel-addfuncs.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\ns-eel-int.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\ns-eel.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Object Include="asm-nseel-x64.obj">
|
||||
<Filter>Source Files</Filter>
|
||||
</Object>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
63
oversampling/WDL/eel2/makefile.vc
Normal file
63
oversampling/WDL/eel2/makefile.vc
Normal file
@@ -0,0 +1,63 @@
|
||||
|
||||
EEL_SOURCE = nseel-caltab.c nseel-cfunc.c nseel-compiler.c nseel-eval.c nseel-lextab.c nseel-ram.c nseel-yylex.c
|
||||
|
||||
LICE_SOURCE = ../lice/lice.cpp ../lice/lice_image.cpp ../lice/lice_line.cpp ../lice/lice_ico.cpp ../lice/lice_bmp.cpp ../lice/lice_textnew.cpp ../lice/lice_text.cpp ../lice/lice_arc.cpp
|
||||
|
||||
FFT_SOURCE = ../fft.c
|
||||
CFLAGS = /DWDL_FFT_REALSIZE=8 /DEEL_LICE_WANT_STANDALONE
|
||||
|
||||
CFLAGS = $(CFLAGS) -DNSEEL_LOOPFUNC_SUPPORT_MAXLEN=0
|
||||
|
||||
LFLAGS = shell32.lib user32.lib comdlg32.lib
|
||||
|
||||
!ifndef VC6
|
||||
CFLAGS = $(CFLAGS) /MT
|
||||
!else
|
||||
CFLAGS = $(CFLAGS) /MD
|
||||
LFLAGS = $(LFLAGS) /OPT:NOWIN98
|
||||
!endif
|
||||
|
||||
!ifdef x64
|
||||
!ifndef PORTABLE
|
||||
EEL_SOURCE = $(EEL_SOURCE) asm-nseel-x64.obj
|
||||
!endif
|
||||
!endif
|
||||
|
||||
!ifdef arm64
|
||||
!ifndef PORTABLE
|
||||
EEL_SOURCE = $(EEL_SOURCE) asm-nseel-aarch64-msvc.obj
|
||||
!endif
|
||||
!endif
|
||||
|
||||
!ifdef arm64ec
|
||||
!ifndef PORTABLE
|
||||
EEL_SOURCE = $(EEL_SOURCE) asm-nseel-arm64ec.obj
|
||||
!endif
|
||||
!endif
|
||||
|
||||
|
||||
default: loose_eel.exe
|
||||
|
||||
!ifdef PORTABLE
|
||||
CFLAGS = $(CFLAGS) -DEEL_TARGET_PORTABLE
|
||||
!endif
|
||||
|
||||
loose_eel.cpp: eel*.h ns-eel*.h
|
||||
|
||||
$(EEL_SOURCE): ns-eel*.h
|
||||
|
||||
|
||||
loose_eel.exe: loose_eel.cpp $(EEL_SOURCE) $(FFT_SOURCE) $(LICE_SOURCE) ..\win32_utf8.c
|
||||
cl $(CFLAGS) $** /link wsock32.lib user32.lib gdi32.lib advapi32.lib $(LFLAGS) /out:$@
|
||||
|
||||
eel_disasm.exe: eel_disasm.cpp $(EEL_SOURCE)
|
||||
cl $(CFLAGS) $** /link wsock32.lib user32.lib gdi32.lib advapi32.lib $(LFLAGS) /out:$@
|
||||
|
||||
asm-nseel-aarch64-msvc.obj: asm-nseel-aarch64-msvc.asm
|
||||
armasm64 asm-nseel-aarch64-msvc.asm
|
||||
|
||||
asm-nseel-arm64ec.obj: asm-nseel-arm64ec.asm
|
||||
armasm64 /machine arm64EC asm-nseel-arm64ec.asm
|
||||
|
||||
test: eel_disasm.exe
|
||||
eel_disasm "buf[a] = x*y"
|
||||
63
oversampling/WDL/eel2/ns-eel-addfuncs.h
Normal file
63
oversampling/WDL/eel2/ns-eel-addfuncs.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
Nullsoft Expression Evaluator Library (NS-EEL)
|
||||
Copyright (C) 1999-2003 Nullsoft, Inc.
|
||||
|
||||
ns-eel-addfuncs.h: defines macros useful for adding functions to the compiler
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef __NS_EEL_ADDFUNCS_H__
|
||||
#define __NS_EEL_ADDFUNCS_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct _compileContext;
|
||||
|
||||
void *NSEEL_PProc_RAM(void *data, int data_size, struct _compileContext *ctx);
|
||||
void *NSEEL_PProc_THIS(void *data, int data_size, struct _compileContext *ctx);
|
||||
|
||||
|
||||
#ifdef EEL_TARGET_PORTABLE
|
||||
|
||||
extern EEL_BC_TYPE _asm_generic3parm[]; // 3 double * parms, returning double *
|
||||
extern EEL_BC_TYPE _asm_generic3parm_retd[]; // 3 double * parms, returning double
|
||||
extern EEL_BC_TYPE _asm_generic2parm[]; // 2 double * parms, returning double *
|
||||
extern EEL_BC_TYPE _asm_generic2parm_retd[]; // 2 double * parms, returning double
|
||||
extern EEL_BC_TYPE _asm_generic2xparm_retd[]; // 2 double * parms, returning double
|
||||
extern EEL_BC_TYPE _asm_generic1parm[]; // 1 double * parms, returning double *
|
||||
extern EEL_BC_TYPE _asm_generic1parm_retd[]; // 1 double * parms, returning double
|
||||
|
||||
#else
|
||||
|
||||
void _asm_generic3parm(void); // 3 double * parms, returning double *
|
||||
void _asm_generic3parm_retd(void); // 3 double * parms, returning double
|
||||
void _asm_generic2parm(void); // 2 double * parms, returning double *
|
||||
void _asm_generic2parm_retd(void); // 2 double * parms, returning double
|
||||
void _asm_generic2xparm_retd(void); // 2 double * parms, returning double
|
||||
void _asm_generic1parm(void); // 1 double * parms, returning double *
|
||||
void _asm_generic1parm_retd(void); // 1 double * parms, returning double
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif//__NS_EEL_ADDFUNCS_H__
|
||||
64
oversampling/WDL/eel2/ns-eel-func-ref.h
Normal file
64
oversampling/WDL/eel2/ns-eel-func-ref.h
Normal file
@@ -0,0 +1,64 @@
|
||||
#ifndef _NSEEL_FUNC_REF_H_
|
||||
#define _NSEEL_FUNC_REF_H_
|
||||
|
||||
#include "ns-eel.h"
|
||||
#define TMP_MKSTR2(x) #x
|
||||
#define TMP_MKSTR(x) TMP_MKSTR2(x)
|
||||
|
||||
const char *nseel_builtin_function_reference=
|
||||
"while\texpression\tExecutes expression until expression evaluates to zero"
|
||||
#if NSEEL_LOOPFUNC_SUPPORT_MAXLEN
|
||||
", or until " TMP_MKSTR(NSEEL_LOOPFUNC_SUPPORT_MAXLEN) "iterations occur"
|
||||
#endif
|
||||
". An alternate and more useful syntax is while (expression) ( statements ), which evaluates statements after "
|
||||
"every non-zero evaluation of expression.\0"
|
||||
"loop\tcount,expression\tEvaluates count once, and then executes expression count"
|
||||
#if NSEEL_LOOPFUNC_SUPPORT_MAXLEN
|
||||
", but not more than " TMP_MKSTR(NSEEL_LOOPFUNC_SUPPORT_MAXLEN) ","
|
||||
#endif
|
||||
" times.\0"
|
||||
"sin\tangle\tReturns the sine of the angle specified (specified in radians -- to convert from degrees to radians, multiply by $pi/180, or 0.017453).\0"
|
||||
"cos\tangle\tReturns the cosine of the angle specified (specified in radians).\0"
|
||||
"tan\tangle\tReturns the tangent of the angle specified (specified in radians).\0"
|
||||
"sqrt\tvalue\tReturns the square root of the parameter. If the parameter is negative, the return value is undefined.\0"
|
||||
"log\tvalue\tReturns the natural logarithm (base e) of the parameter. If the value is not greater than 0, the return value is undefined.\0"
|
||||
"log10\tvalue\tReturns the base-10 logarithm of the parameter. If the value is not greater than 0, the return value is undefined.\0"
|
||||
"asin\tvalue\tReturns the arc sine of the value specified (return value is in radians). If the parameter is not between -1.0 and 1.0 inclusive, the return value is undefined.\0"
|
||||
"acos\tvalue\tReturns the arc cosine of the value specified (return value is in radians). If the parameter is not between -1.0 and 1.0 inclusive, the return value is undefined.\0"
|
||||
"atan\tvalue\tReturns the arc tangent of the value specified (return value is in radians). If the parameter is not between -1.0 and 1.0 inclusive, the return value is undefined.\0"
|
||||
"atan2\tnumerator,denominator\tReturns the arc tangent of the numerator divided by the denominator, allowing the denominator to be 0, and using their signs to produce a more meaningful result.\0"
|
||||
"exp\texponent\tReturns the number e ($e, approximately 2.718) raised to the parameter-th power. This function is significantly faster than pow() or the ^ operator.\0"
|
||||
"abs\tvalue\tReturns the absolute value of the parameter.\0"
|
||||
"sqr\tvalue\tReturns the square of the parameter (similar to value*value, but only evaluating value once).\0"
|
||||
"min\t&value,&value\tReturns (by reference) the minimum value of the two parameters. Since min() returns by reference, expressions such as min(x,y) = 5 are possible.\0"
|
||||
"max\t&value,&value\tReturns (by reference) the maximum value of the two parameters. Since max() returns by reference, expressions such as max(x,y) = 5 are possible.\0"
|
||||
"sign\tvalue\tReturns 1.0 if the parameter is greater than 0, -1.0 if the parameter is less than 0, or 0 if the parameter is 0.\0"
|
||||
"floor\tvalue\tReturns the value rounded to the next lowest integer (floor(3.9)==3, floor(-3.1)==-4).\0"
|
||||
"ceil\tvalue\tReturns the value rounded to the next highest integer (ceil(3.1)==4, ceil(-3.9)==-3).\0"
|
||||
"invsqrt\tvalue\tReturns a fast inverse square root (1/sqrt(x)) approximation of the parameter.\0"
|
||||
"freembuf\taddress\tHints the runtime that memory above the address specified may no longer be used. The runtime may, at its leisure, choose to lose the contents of memory above the address specified.\0"
|
||||
"memcpy\tdest,src,length\tCopies length items of memory from src to dest. Regions are permitted to overlap.\0"
|
||||
"memset\toffset,value,length\tSets length items of memory at offset to value.\0"
|
||||
"mem_get_values\toffset, ...\tReads values from memory starting at offset into variables specified. Slower than regular memory reads for less than a few variables, faster for more than a few. Undefined behavior if used with more than 32767 variables.\0"
|
||||
"mem_set_values\toffset, ...\tWrites values to memory starting at offset from variables specified. Slower than regular memory writes for less than a few variables, faster for more than a few. Undefined behavior if used with more than 32767 variables.\0"
|
||||
"mem_multiply_sum\tsrc1,src2,length\tCalculates the sum of the products of values pointed to by src1 and src2. If src2 is -1, then calculates the sum of squares of src1, if -2, the sum of the absolute values of src, if -3, calculates the sum of the values of src1. Other negative values are undefined.\0"
|
||||
"mem_insert_shuffle\tbuf,len,value\tShuffles contents of buf right by 1, inserts value at buf[0], returns previous buf[len-1].\0"
|
||||
"stack_push\t&value\tPushes value onto the user stack, returns a reference to the parameter.\0"
|
||||
"stack_pop\t&value\tPops a value from the user stack into value, or into a temporary buffer if value is not specified, and returns a reference to where the stack was popped. Note that no checking is done to determine if the stack is empty, and as such stack_pop() will never fail.\0"
|
||||
"stack_peek\tindex\tReturns a reference to the item on the top of the stack (if index is 0), or to the Nth item on the stack if index is greater than 0. \0"
|
||||
"stack_exch\t&value\tExchanges a value with the top of the stack, and returns a reference to the parameter (with the new value).\0"
|
||||
#ifdef NSEEL_EEL1_COMPAT_MODE
|
||||
"rand\tmax\tReturns a pseudorandom non-negative integer number less than the parameter.\0"
|
||||
"sigmoid\tvalue,constraint\tReturns 1.0/(1+exp(-x * (constraint))), or 0 if a divide by 0 would occur.\0"
|
||||
"band\tx,y\tReturns 1 if both x and y evaluate to nonzero, 0 if otherwise. Both parameters are always evaluated.\0"
|
||||
"bor\tx,y\tReturns 1 if either x or y evaluate to nonzero, 0 if otherwise. Both parameters are always evaluated.\0"
|
||||
"exec2\tx,y\tEvaluates x, then evaluates and returns y.\0"
|
||||
"exec3\tx,y,z\tEvaluates x, evaluates y, then evaluates and returns z.\0"
|
||||
#else
|
||||
"rand\t[max]\tReturns a pseudorandom real number between 0 and the parameter, inclusive. If the parameter is omitted or less than 1.0, 1.0 is used as a maximum instead.\0"
|
||||
|
||||
#endif
|
||||
;
|
||||
#undef TMP_MKSTR
|
||||
|
||||
#endif
|
||||
331
oversampling/WDL/eel2/ns-eel-int.h
Normal file
331
oversampling/WDL/eel2/ns-eel-int.h
Normal file
@@ -0,0 +1,331 @@
|
||||
/*
|
||||
Nullsoft Expression Evaluator Library (NS-EEL)
|
||||
Copyright (C) 1999-2003 Nullsoft, Inc.
|
||||
|
||||
ns-eel-int.h: internal code definition header.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef __NS_EELINT_H__
|
||||
#define __NS_EELINT_H__
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include "../wdltypes.h"
|
||||
#endif
|
||||
|
||||
#include "ns-eel.h"
|
||||
#include "ns-eel-addfuncs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
enum {
|
||||
|
||||
// these ignore fn in opcodes, just use fntype to determine function
|
||||
FN_MULTIPLY=0,
|
||||
FN_DIVIDE,
|
||||
FN_JOIN_STATEMENTS,
|
||||
FN_DENORMAL_LIKELY,
|
||||
FN_DENORMAL_UNLIKELY,
|
||||
FN_ADD,
|
||||
FN_SUB,
|
||||
FN_AND,
|
||||
FN_OR,
|
||||
FN_UMINUS,
|
||||
FN_NOT,
|
||||
FN_NOTNOT,
|
||||
FN_XOR,
|
||||
FN_SHL,
|
||||
FN_SHR,
|
||||
FN_MOD,
|
||||
FN_POW,
|
||||
FN_LT,
|
||||
FN_GT,
|
||||
FN_LTE,
|
||||
FN_GTE,
|
||||
FN_EQ,
|
||||
FN_EQ_EXACT,
|
||||
FN_NE,
|
||||
FN_NE_EXACT,
|
||||
FN_LOGICAL_AND,
|
||||
FN_LOGICAL_OR,
|
||||
FN_IF_ELSE,
|
||||
FN_MEMORY,
|
||||
FN_GMEMORY,
|
||||
FN_NONCONST_BEGIN,
|
||||
FN_ASSIGN=FN_NONCONST_BEGIN,
|
||||
|
||||
FN_ADD_OP,
|
||||
FN_SUB_OP,
|
||||
FN_MOD_OP,
|
||||
FN_OR_OP,
|
||||
FN_AND_OP,
|
||||
FN_XOR_OP,
|
||||
FN_DIV_OP,
|
||||
FN_MUL_OP,
|
||||
FN_POW_OP,
|
||||
|
||||
FN_WHILE,
|
||||
FN_LOOP,
|
||||
|
||||
FUNCTYPE_SIMPLEMAX,
|
||||
|
||||
|
||||
FUNCTYPE_FUNCTIONTYPEREC=1000, // fn is a functionType *
|
||||
FUNCTYPE_EELFUNC, // fn is a _codeHandleFunctionRec *
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define YYSTYPE opcodeRec *
|
||||
|
||||
#define NSEEL_CLOSEFACTOR 0.00001
|
||||
|
||||
|
||||
typedef struct opcodeRec opcodeRec;
|
||||
|
||||
typedef struct _codeHandleFunctionRec
|
||||
{
|
||||
struct _codeHandleFunctionRec *next; // main linked list (only used for high level functions)
|
||||
struct _codeHandleFunctionRec *derivedCopies; // separate linked list, head being the main function, other copies being derived versions
|
||||
|
||||
void *startptr; // compiled code (may be cleared + recompiled when shared)
|
||||
opcodeRec *opcodes;
|
||||
|
||||
int startptr_size; // 0=no code. -1 = needs calculation. >0 = size.
|
||||
int startptr_base_size; // initially calculated size of root function
|
||||
int tmpspace_req;
|
||||
|
||||
int num_params;
|
||||
|
||||
int rvMode; // RETURNVALUE_*
|
||||
int fpStackUsage; // 0-8, usually
|
||||
int canHaveDenormalOutput;
|
||||
|
||||
// local storage's first items are the parameters, then locals. Note that the opcodes will reference localstorage[] via VARPTRPTR, but
|
||||
// the values localstorage[x] points are reallocated from context-to-context, if it is a common function.
|
||||
|
||||
// separately allocated list of pointers, the contents of the list should be zeroed on context changes if a common function
|
||||
// note that when making variations on a function (context), it is shared, but since it is zeroed on context changes, it is context-local
|
||||
int localstorage_size;
|
||||
EEL_F **localstorage;
|
||||
|
||||
int isCommonFunction;
|
||||
int usesNamespaces;
|
||||
unsigned int parameterAsNamespaceMask;
|
||||
|
||||
char fname[NSEEL_MAX_FUNCSIG_NAME+1];
|
||||
} _codeHandleFunctionRec;
|
||||
|
||||
typedef struct _llBlock {
|
||||
struct _llBlock *next;
|
||||
int sizeused;
|
||||
int sizealloc;
|
||||
// data follows
|
||||
} llBlock;
|
||||
|
||||
typedef struct {
|
||||
llBlock *blocks_code, *blocks_data;
|
||||
void *workTable; // references a chunk in blocks_data
|
||||
|
||||
void *code;
|
||||
int code_size; // in case the caller wants to write it out
|
||||
int code_stats[4];
|
||||
|
||||
int want_stack;
|
||||
void *stack; // references a chunk in blocks_data, somewhere within the complete NSEEL_STACK_SIZE aligned at NSEEL_STACK_SIZE
|
||||
|
||||
void *ramPtr;
|
||||
|
||||
int workTable_size; // size (minus padding/extra space) of workTable -- only used if EEL_VALIDATE_WORKTABLE_USE set, but might be handy to have around too
|
||||
int compile_flags;
|
||||
} codeHandleType;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
EEL_F *value;
|
||||
int refcnt;
|
||||
char isreg;
|
||||
char str[1];
|
||||
} varNameRec;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *ptr;
|
||||
int size, alloc;
|
||||
} eel_growbuf;
|
||||
#define EEL_GROWBUF(type) union { eel_growbuf _growbuf; type *_tval; }
|
||||
#define EEL_GROWBUF_RESIZE(gb, newsz) __growbuf_resize(&(gb)->_growbuf, (newsz)*(int)sizeof((gb)->_tval[0])) // <0 to free, does not realloc down otherwise
|
||||
#define EEL_GROWBUF_GET(gb) ((gb)->_tval)
|
||||
#define EEL_GROWBUF_GET_SIZE(gb) ((gb)->_growbuf.size/(int)sizeof((gb)->_tval[0]))
|
||||
|
||||
typedef struct _compileContext
|
||||
{
|
||||
eel_function_table *registered_func_tab;
|
||||
const char *(*func_check)(const char *fn_name, void *user); // return error message if not permitted
|
||||
void *func_check_user;
|
||||
|
||||
EEL_GROWBUF(varNameRec *) varNameList;
|
||||
EEL_F *varValueStore;
|
||||
int varValueStore_left;
|
||||
|
||||
int errVar,gotEndOfInput;
|
||||
opcodeRec *result;
|
||||
char last_error_string[256];
|
||||
|
||||
void *scanner;
|
||||
const char *rdbuf_start, *rdbuf, *rdbuf_end;
|
||||
|
||||
llBlock *tmpblocks, // used while compiling, and freed after compiling
|
||||
|
||||
*blocks_head_code, // used while compiling, transferred to code context (whole pages marked as executable)
|
||||
*blocks_head_data, // used while compiling, transferred to code context
|
||||
|
||||
*ctx_pblocks; // persistent blocks, stores data used by varTable_Names, varTable_Values, etc.
|
||||
|
||||
int l_stats[4]; // source bytes, static code bytes, call code bytes, data bytes
|
||||
int has_used_global_vars;
|
||||
|
||||
_codeHandleFunctionRec *functions_local, *functions_common;
|
||||
|
||||
// state used while generating functions
|
||||
int optimizeDisableFlags;
|
||||
int current_compile_flags;
|
||||
struct opcodeRec *directValueCache; // linked list using fn as next
|
||||
|
||||
int isSharedFunctions;
|
||||
int isGeneratingCommonFunction;
|
||||
int function_usesNamespaces;
|
||||
int function_globalFlag; // set if restrict globals to function_localTable_Names[2]
|
||||
// [0] is parameter+local symbols (combined space)
|
||||
// [1] is symbols which get implied "this." if used
|
||||
// [2] is globals permitted
|
||||
int function_localTable_Size[3]; // for parameters only
|
||||
char **function_localTable_Names[3]; // lists of pointers
|
||||
EEL_F **function_localTable_ValuePtrs;
|
||||
const char *function_curName; // name of current function
|
||||
|
||||
EEL_F (*onString)(void *caller_this, struct eelStringSegmentRec *list);
|
||||
EEL_F (*onNamedString)(void *caller_this, const char *name);
|
||||
|
||||
EEL_F *(*getVariable)(void *userctx, const char *name);
|
||||
void *getVariable_userctx;
|
||||
|
||||
codeHandleType *tmpCodeHandle;
|
||||
|
||||
struct
|
||||
{
|
||||
WDL_UINT64 sign_mask[2];
|
||||
WDL_UINT64 abs_mask[2];
|
||||
int needfree;
|
||||
int maxblocks;
|
||||
double closefact;
|
||||
EEL_F *blocks[NSEEL_RAM_BLOCKS];
|
||||
} *ram_state; // allocated from blocks with 16 byte alignment
|
||||
|
||||
void *gram_blocks;
|
||||
|
||||
void *caller_this;
|
||||
}
|
||||
compileContext;
|
||||
|
||||
#define NSEEL_NPARAMS_FLAG_CONST 0x80000
|
||||
typedef struct functionType {
|
||||
const char *name;
|
||||
void *afunc;
|
||||
int nParams;
|
||||
void *replptrs[4];
|
||||
NSEEL_PPPROC pProc;
|
||||
} functionType;
|
||||
|
||||
functionType *nseel_getFunctionByName(compileContext *ctx, const char *name, int *mchk); // sets mchk (if non-NULL) to how far allowed to scan forward for duplicate names
|
||||
functionType *nseel_enumFunctions(compileContext *ctx, int idx);
|
||||
|
||||
opcodeRec *nseel_createCompiledValue(compileContext *ctx, EEL_F value);
|
||||
opcodeRec *nseel_createCompiledValuePtr(compileContext *ctx, EEL_F *addrValue, const char *namestr);
|
||||
|
||||
opcodeRec *nseel_createMoreParametersOpcode(compileContext *ctx, opcodeRec *code1, opcodeRec *code2);
|
||||
opcodeRec *nseel_createSimpleCompiledFunction(compileContext *ctx, int fn, int np, opcodeRec *code1, opcodeRec *code2);
|
||||
opcodeRec *nseel_createMemoryAccess(compileContext *ctx, opcodeRec *code1, opcodeRec *code2);
|
||||
opcodeRec *nseel_createIfElse(compileContext *ctx, opcodeRec *code1, opcodeRec *code2, opcodeRec *code3);
|
||||
opcodeRec *nseel_createFunctionByName(compileContext *ctx, const char *name, int np, opcodeRec *code1, opcodeRec *code2, opcodeRec *code3);
|
||||
|
||||
// converts a generic identifier (VARPTR) opcode into either an actual variable reference (parmcnt = -1),
|
||||
// or if parmcnt >= 0, to a function call (see nseel_setCompiledFunctionCallParameters())
|
||||
opcodeRec *nseel_resolve_named_symbol(compileContext *ctx, opcodeRec *rec, int parmcnt, int *errOut);
|
||||
|
||||
// sets parameters and calculates parameter count for opcode, and calls nseel_resolve_named_symbol() with the right
|
||||
// parameter count
|
||||
opcodeRec *nseel_setCompiledFunctionCallParameters(compileContext *ctx, opcodeRec *fn, opcodeRec *code1, opcodeRec *code2, opcodeRec *code3, opcodeRec *postCode, int *errOut);
|
||||
// errOut will be set if return NULL:
|
||||
// -1 if postCode set when not wanted (i.e. not while())
|
||||
// 0 if func not found,
|
||||
// 1 if function requires 2+ parameters but was given more
|
||||
// 2 if function needs more parameters
|
||||
// 4 if function requires 1 parameter but was given more
|
||||
|
||||
|
||||
|
||||
struct eelStringSegmentRec *nseel_createStringSegmentRec(compileContext *ctx, const char *str, int len);
|
||||
opcodeRec *nseel_eelMakeOpcodeFromStringSegments(compileContext *ctx, struct eelStringSegmentRec *rec);
|
||||
|
||||
EEL_F *nseel_int_register_var(compileContext *ctx, const char *name, int isReg, const char **namePtrOut);
|
||||
_codeHandleFunctionRec *eel_createFunctionNamespacedInstance(compileContext *ctx, _codeHandleFunctionRec *fr, const char *nameptr);
|
||||
|
||||
typedef struct nseel_globalVarItem
|
||||
{
|
||||
EEL_F data;
|
||||
struct nseel_globalVarItem *_next;
|
||||
char name[1]; // varlen, does not include _global. prefix
|
||||
} nseel_globalVarItem;
|
||||
|
||||
extern nseel_globalVarItem *nseel_globalreg_list; // if NSEEL_EEL1_COMPAT_MODE, must use NSEEL_getglobalregs() for regxx values
|
||||
|
||||
#include "y.tab.h"
|
||||
|
||||
// nseel_simple_tokenizer will return comments as tokens if state is non-NULL
|
||||
const char *nseel_simple_tokenizer(const char **ptr, const char *endptr, int *lenOut, int *state);
|
||||
int nseel_filter_escaped_string(char *outbuf, int outbuf_sz, const char *rdptr, size_t rdptr_size, char delim_char); // returns length used, minus NUL char
|
||||
|
||||
opcodeRec *nseel_translate(compileContext *ctx, const char *tmp, size_t tmplen); // tmplen=0 for nul-term
|
||||
int nseel_lookup(compileContext *ctx, opcodeRec **opOut, const char *sname);
|
||||
|
||||
EEL_F * NSEEL_CGEN_CALL __NSEEL_RAMAlloc(EEL_F **blocks, unsigned int w);
|
||||
EEL_F * NSEEL_CGEN_CALL __NSEEL_RAMAllocGMEM(EEL_F ***blocks, unsigned int w);
|
||||
EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemSet(EEL_F **blocks,EEL_F *dest, EEL_F *v, EEL_F *lenptr);
|
||||
EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemFree(void *blocks, EEL_F *which);
|
||||
EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemTop(void *blocks, EEL_F *which);
|
||||
EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemCpy(EEL_F **blocks,EEL_F *dest, EEL_F *src, EEL_F *lenptr);
|
||||
EEL_F NSEEL_CGEN_CALL __NSEEL_RAM_MemSumProducts(EEL_F **blocks,EEL_F *dest, EEL_F *src, EEL_F *lenptr);
|
||||
EEL_F NSEEL_CGEN_CALL __NSEEL_RAM_MemInsertShuffle(EEL_F **blocks,EEL_F *buf, EEL_F *len, EEL_F *value);
|
||||
EEL_F NSEEL_CGEN_CALL __NSEEL_RAM_Mem_SetValues(EEL_F **blocks, INT_PTR np, EEL_F **parms);
|
||||
EEL_F NSEEL_CGEN_CALL __NSEEL_RAM_Mem_GetValues(EEL_F **blocks, INT_PTR np, EEL_F **parms);
|
||||
|
||||
extern EEL_F nseel_ramalloc_onfail; // address returned by __NSEEL_RAMAlloc et al on failure
|
||||
extern EEL_F * volatile nseel_gmembuf_default; // can free/zero this on DLL unload if needed
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif//__NS_EELINT_H__
|
||||
264
oversampling/WDL/eel2/ns-eel.h
Normal file
264
oversampling/WDL/eel2/ns-eel.h
Normal file
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
Nullsoft Expression Evaluator Library (NS-EEL)
|
||||
Copyright (C) 1999-2003 Nullsoft, Inc.
|
||||
|
||||
ns-eel.h: main application interface header
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __NS_EEL_H__
|
||||
#define __NS_EEL_H__
|
||||
|
||||
// put standard includes here
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef EEL_F_SIZE
|
||||
#define EEL_F_SIZE 8
|
||||
#endif
|
||||
|
||||
#include "../wdltypes.h"
|
||||
|
||||
typedef double EEL_F WDL_FIXALIGN;
|
||||
typedef double *EEL_F_PTR;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define NSEEL_CGEN_CALL __cdecl
|
||||
#else
|
||||
#define NSEEL_CGEN_CALL
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// host should implement these (can be empty stub functions if no VM will execute code in multiple threads at once)
|
||||
|
||||
// implement if you will be running the code in same VM from multiple threads,
|
||||
// or VMs that have the same GRAM pointer from different threads, or multiple
|
||||
// VMs that have a NULL GRAM pointer from multiple threads.
|
||||
// if you give each VM it's own unique GRAM and only run each VM in one thread, then you can leave it blank.
|
||||
|
||||
// or if you're daring....
|
||||
|
||||
void NSEEL_HOSTSTUB_EnterMutex();
|
||||
void NSEEL_HOSTSTUB_LeaveMutex();
|
||||
|
||||
|
||||
int NSEEL_init(); // returns nonzero on failure (only if EEL_VALIDATE_FSTUBS defined), otherwise the same as NSEEL_quit(), and completely optional
|
||||
void NSEEL_quit(); // clears any added functions
|
||||
|
||||
|
||||
// adds a function that returns a value (EEL_F)
|
||||
#define NSEEL_addfunc_retval(name,np,pproc,fptr) \
|
||||
NSEEL_addfunc_ret_type(name,np,1,pproc,(void *)(fptr),NSEEL_ADDFUNC_DESTINATION)
|
||||
|
||||
// adds a function that returns a pointer (EEL_F*)
|
||||
#define NSEEL_addfunc_retptr(name,np,pproc,fptr) \
|
||||
NSEEL_addfunc_ret_type(name,np,0,pproc,(void *)(fptr),NSEEL_ADDFUNC_DESTINATION)
|
||||
|
||||
// adds a void or bool function
|
||||
#define NSEEL_addfunc_retbool(name,np,pproc,fptr) \
|
||||
NSEEL_addfunc_ret_type(name,np,-1,pproc,(void *)(fptr),NSEEL_ADDFUNC_DESTINATION)
|
||||
|
||||
// adds a function that takes min_np or more parameters (func sig needs to be EEL_F func(void *ctx, INT_PTR np, EEL_F **parms)
|
||||
#define NSEEL_addfunc_varparm(name, min_np, pproc, fptr) \
|
||||
NSEEL_addfunc_varparm_ex(name,min_np,0,pproc,fptr,NSEEL_ADDFUNC_DESTINATION)
|
||||
|
||||
// adds a function that takes np parameters via func: sig needs to be EEL_F func(void *ctx, INT_PTR np, EEL_F **parms)
|
||||
#define NSEEL_addfunc_exparms(name, np, pproc, fptr) \
|
||||
NSEEL_addfunc_varparm_ex(name,np,1,pproc,fptr,NSEEL_ADDFUNC_DESTINATION)
|
||||
|
||||
|
||||
// deprecated
|
||||
#define NSEEL_addfunction(name,nparms,code,len) NSEEL_addfunctionex((name),(nparms),(code),(len),0,0)
|
||||
#define NSEEL_addfunctionex(name,nparms,code,len,pproc,fptr) NSEEL_addfunctionex2((name),(nparms),(code),(len),(pproc),(fptr),0, NSEEL_ADDFUNC_DESTINATION)
|
||||
|
||||
#ifndef NSEEL_ADDFUNC_DESTINATION
|
||||
#define NSEEL_ADDFUNC_DESTINATION (NULL)
|
||||
#endif
|
||||
|
||||
struct functionType;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct functionType *list;
|
||||
int list_size;
|
||||
} eel_function_table;
|
||||
|
||||
struct _compileContext;
|
||||
typedef void *(*NSEEL_PPPROC)(void *data, int data_size, struct _compileContext *userfunc_data);
|
||||
void NSEEL_addfunctionex2(const char *name, int nparms, char *code_startaddr, int code_len, NSEEL_PPPROC pproc, void *fptr, void *fptr2, eel_function_table *destination);
|
||||
|
||||
void NSEEL_addfunc_ret_type(const char *name, int np, int ret_type, NSEEL_PPPROC pproc, void *fptr, eel_function_table *destination); // ret_type=-1 for bool, 1 for value, 0 for ptr
|
||||
void NSEEL_addfunc_varparm_ex(const char *name, int min_np, int want_exact, NSEEL_PPPROC pproc, EEL_F (NSEEL_CGEN_CALL *fptr)(void *, INT_PTR, EEL_F **), eel_function_table *destination);
|
||||
void NSEEL_addfunc_varparm_ctxptr(const char *name, int min_np, int want_exact, void *ctxptr, EEL_F (NSEEL_CGEN_CALL *fptr)(void *, INT_PTR, EEL_F **), eel_function_table *destination);
|
||||
void NSEEL_addfunc_varparm_ctxptr2(const char *name, int min_np, int want_exact, NSEEL_PPPROC pproc, void *ctx, EEL_F (NSEEL_CGEN_CALL *fptr)(void *, void *,INT_PTR, EEL_F **), eel_function_table *destination);
|
||||
|
||||
int *NSEEL_getstats(); // returns a pointer to 5 ints... source bytes, static code bytes, call code bytes, data bytes, number of code handles
|
||||
|
||||
typedef void *NSEEL_VMCTX;
|
||||
typedef void *NSEEL_CODEHANDLE;
|
||||
|
||||
NSEEL_VMCTX NSEEL_VM_alloc(); // return a handle
|
||||
void NSEEL_VM_free(NSEEL_VMCTX ctx); // free when done with a VM and ALL of its code have been freed, as well
|
||||
|
||||
void NSEEL_VM_SetFunctionTable(NSEEL_VMCTX, eel_function_table *tab); // use NULL to use default (global) table
|
||||
|
||||
// validateFunc can return error message if not permitted
|
||||
void NSEEL_VM_SetFunctionValidator(NSEEL_VMCTX, const char * (*validateFunc)(const char *fn_name, void *user), void *user);
|
||||
|
||||
void NSEEL_VM_remove_unused_vars(NSEEL_VMCTX _ctx);
|
||||
void NSEEL_VM_clear_var_refcnts(NSEEL_VMCTX _ctx);
|
||||
void NSEEL_VM_remove_all_nonreg_vars(NSEEL_VMCTX _ctx);
|
||||
void NSEEL_VM_enumallvars(NSEEL_VMCTX ctx, int (*func)(const char *name, EEL_F *val, void *ctx), void *userctx); // return false from func to stop
|
||||
|
||||
EEL_F *NSEEL_VM_regvar(NSEEL_VMCTX ctx, const char *name); // register a variable (before compilation)
|
||||
EEL_F *NSEEL_VM_getvar(NSEEL_VMCTX ctx, const char *name); // get a variable (if registered or created by code)
|
||||
int NSEEL_VM_get_var_refcnt(NSEEL_VMCTX _ctx, const char *name); // returns -1 if not registered, or >=0
|
||||
void NSEEL_VM_set_var_resolver(NSEEL_VMCTX ctx, EEL_F *(*res)(void *userctx, const char *name), void *userctx);
|
||||
|
||||
void NSEEL_VM_freeRAM(NSEEL_VMCTX ctx); // clears and frees all (VM) RAM used
|
||||
void NSEEL_VM_freeRAMIfCodeRequested(NSEEL_VMCTX); // call after code to free the script-requested memory
|
||||
int NSEEL_VM_wantfreeRAM(NSEEL_VMCTX ctx); // want NSEEL_VM_freeRAMIfCodeRequested?
|
||||
|
||||
// if you set this, it uses a local GMEM context.
|
||||
// Must be set before compilation.
|
||||
// void *p=NULL;
|
||||
// NSEEL_VM_SetGRAM(ctx,&p);
|
||||
// .. do stuff
|
||||
// NSEEL_VM_FreeGRAM(&p);
|
||||
void NSEEL_VM_SetGRAM(NSEEL_VMCTX ctx, void **gram);
|
||||
void NSEEL_VM_FreeGRAM(void **ufd); // frees a gmem context.
|
||||
void NSEEL_VM_SetCustomFuncThis(NSEEL_VMCTX ctx, void *thisptr);
|
||||
|
||||
EEL_F *NSEEL_VM_getramptr(NSEEL_VMCTX ctx, unsigned int offs, int *validCount);
|
||||
EEL_F *NSEEL_VM_getramptr_noalloc(NSEEL_VMCTX ctx, unsigned int offs, int *validCount);
|
||||
|
||||
|
||||
// set 0 to query. returns actual value used (limits, granularity apply -- see NSEEL_RAM_BLOCKS)
|
||||
int NSEEL_VM_setramsize(NSEEL_VMCTX ctx, int maxent);
|
||||
void NSEEL_VM_preallocram(NSEEL_VMCTX ctx, int maxent); // maxent=-1 for all allocated
|
||||
|
||||
|
||||
struct eelStringSegmentRec {
|
||||
struct eelStringSegmentRec *_next;
|
||||
const char *str_start; // escaped characters, including opening/trailing characters
|
||||
int str_len;
|
||||
};
|
||||
void NSEEL_VM_SetStringFunc(NSEEL_VMCTX ctx,
|
||||
EEL_F (*onString)(void *caller_this, struct eelStringSegmentRec *list),
|
||||
EEL_F (*onNamedString)(void *caller_this, const char *name));
|
||||
|
||||
// call with NULL to calculate size, or non-null to generate to buffer (returning size used -- will not null terminate, caller responsibility)
|
||||
int nseel_stringsegments_tobuf(char *bufOut, int bufout_sz, struct eelStringSegmentRec *list);
|
||||
|
||||
|
||||
NSEEL_CODEHANDLE NSEEL_code_compile(NSEEL_VMCTX ctx, const char *code, int lineoffs);
|
||||
#define NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS 1 // allows that code's functions to be used in other code (note you shouldn't destroy that codehandle without destroying others first if used)
|
||||
#define NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS_RESET 2 // resets common code functions
|
||||
#define NSEEL_CODE_COMPILE_FLAG_NOFPSTATE 4 // hint that the FPU/SSE state should be good-to-go
|
||||
#define NSEEL_CODE_COMPILE_FLAG_ONLY_BUILTIN_FUNCTIONS 8 // very restrictive mode (only math functions really)
|
||||
|
||||
NSEEL_CODEHANDLE NSEEL_code_compile_ex(NSEEL_VMCTX ctx, const char *code, int lineoffs, int flags);
|
||||
|
||||
char *NSEEL_code_getcodeerror(NSEEL_VMCTX ctx);
|
||||
int NSEEL_code_geterror_flag(NSEEL_VMCTX ctx);
|
||||
void NSEEL_code_execute(NSEEL_CODEHANDLE code);
|
||||
void NSEEL_code_free(NSEEL_CODEHANDLE code);
|
||||
int *NSEEL_code_getstats(NSEEL_CODEHANDLE code); // 4 ints...source bytes, static code bytes, call code bytes, data bytes
|
||||
|
||||
|
||||
// global memory control/view
|
||||
extern unsigned int NSEEL_RAM_limitmem; // if nonzero, memory limit for user data, in bytes
|
||||
extern unsigned int NSEEL_RAM_memused;
|
||||
extern int NSEEL_RAM_memused_errors;
|
||||
|
||||
|
||||
|
||||
// configuration:
|
||||
|
||||
// use the handwritten lexer -- the flex (eel2.l generated) lexer mostly works, but doesn't support string parsing at the moment
|
||||
// this mode is faster and uses less ram than eel2.l anyway, so leave it on
|
||||
#define NSEEL_SUPER_MINIMAL_LEXER
|
||||
|
||||
// #define NSEEL_EEL1_COMPAT_MODE // supports old behaviors (continue after failed compile), old functions _bnot etc. disables string support (strings were used as comments in eel1 etc)
|
||||
|
||||
#define NSEEL_MAX_VARIABLE_NAMELEN 128 // define this to override the max variable length
|
||||
#define NSEEL_MAX_EELFUNC_PARAMETERS 40
|
||||
#define NSEEL_MAX_FUNCSIG_NAME 2048 // longer than variable maxlen, due to multiple namespaces
|
||||
|
||||
// maximum loop length (0 for unlimited)
|
||||
#ifndef NSEEL_LOOPFUNC_SUPPORT_MAXLEN
|
||||
#define NSEEL_LOOPFUNC_SUPPORT_MAXLEN 1048576
|
||||
#endif
|
||||
|
||||
#define NSEEL_MAX_FUNCTION_SIZE_FOR_INLINE 2048
|
||||
|
||||
// when a VM ctx doesn't have a GRAM context set, make the global one this big
|
||||
#define NSEEL_SHARED_GRAM_SIZE (1<<20)
|
||||
|
||||
//#define EEL_DUMP_OPS // used for testing frontend parser/logic changes
|
||||
|
||||
// note: if you wish to change NSEEL_RAM_*, and your target is x86-64, you will
|
||||
// need to edit asm-nseel-x64-sse.asm to match
|
||||
|
||||
// 512 * 65536 = 32 million entries maximum (256MB RAM)
|
||||
// default is limited to 128 * 65536 = 8 million entries (64MB RAM)
|
||||
|
||||
// default to 8 million entries, use NSEEL_VM_setramsize() to change at runtime
|
||||
#define NSEEL_RAM_BLOCKS_DEFAULTMAX 128
|
||||
|
||||
// 512 entry block table maximum (2k/4k per VM)
|
||||
#define NSEEL_RAM_BLOCKS_LOG2 9
|
||||
|
||||
// 65536 items per block (512KB)
|
||||
#define NSEEL_RAM_ITEMSPERBLOCK_LOG2 16
|
||||
|
||||
#define NSEEL_RAM_BLOCKS (1 << NSEEL_RAM_BLOCKS_LOG2)
|
||||
#define NSEEL_RAM_ITEMSPERBLOCK (1<<NSEEL_RAM_ITEMSPERBLOCK_LOG2)
|
||||
|
||||
#define NSEEL_STACK_SIZE 4096 // about 64k overhead if the stack functions are used in a given code handle
|
||||
|
||||
// arch neutral mode, runs about 1/8th speed or so
|
||||
//#define EEL_TARGET_PORTABLE
|
||||
|
||||
#ifdef EEL_TARGET_PORTABLE
|
||||
#ifdef EEL_PORTABLE_TAILCALL
|
||||
typedef void (*EEL_BC_TYPE)(void *next_inst, void *state);
|
||||
#else
|
||||
#define EEL_BC_TYPE int
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef NSEEL_EEL1_COMPAT_MODE
|
||||
double *NSEEL_getglobalregs();
|
||||
#endif
|
||||
|
||||
void eel_enterfp(int s[2]);
|
||||
void eel_leavefp(int s[2]);
|
||||
|
||||
extern void *(*nseel_gmem_calloc)(size_t,size_t); // set this to the calloc() implementation used by the context that will call NSEEL_VM_FreeGRAM()
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif//__NS_EEL_H__
|
||||
1
oversampling/WDL/eel2/nseel-caltab.c
Normal file
1
oversampling/WDL/eel2/nseel-caltab.c
Normal file
@@ -0,0 +1 @@
|
||||
// no longer used
|
||||
147
oversampling/WDL/eel2/nseel-cfunc.c
Normal file
147
oversampling/WDL/eel2/nseel-cfunc.c
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
Expression Evaluator Library (NS-EEL) v2
|
||||
Copyright (C) 2004-2013 Cockos Incorporated
|
||||
Copyright (C) 1999-2003 Nullsoft, Inc.
|
||||
|
||||
nseel-cfunc.c: assembly/C implementation of operator/function templates
|
||||
This file should be ideally compiled with optimizations towards "minimize size"
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#include "ns-eel-int.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
|
||||
// these are used by our assembly code
|
||||
|
||||
|
||||
#define N 624
|
||||
#define M 397
|
||||
#define MATRIX_A 0x9908b0dfUL /* constant vector a */
|
||||
#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
|
||||
#define LOWER_MASK 0x7fffffffUL /* least significant r bits */
|
||||
|
||||
static unsigned int genrand_int32(void)
|
||||
{
|
||||
|
||||
unsigned int y;
|
||||
static unsigned int mag01[2]={0x0UL, MATRIX_A};
|
||||
/* mag01[x] = x * MATRIX_A for x=0,1 */
|
||||
|
||||
static unsigned int mt[N]; /* the array for the state vector */
|
||||
static unsigned int __idx;
|
||||
|
||||
unsigned int mti = __idx;
|
||||
|
||||
if (!mti)
|
||||
{
|
||||
unsigned int s=0x4141f00d;
|
||||
mt[0]= s & 0xffffffffUL;
|
||||
for (mti=1; mti<N; mti++)
|
||||
{
|
||||
mt[mti] =
|
||||
(1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
|
||||
/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
|
||||
/* In the previous versions, MSBs of the seed affect */
|
||||
/* only MSBs of the array mt[]. */
|
||||
/* 2002/01/09 modified by Makoto Matsumoto */
|
||||
mt[mti] &= 0xffffffffUL;
|
||||
/* for >32 bit machines */
|
||||
}
|
||||
__idx = N; // mti = N (from loop)
|
||||
}
|
||||
|
||||
if (mti >= N) { /* generate N words at one time */
|
||||
int kk;
|
||||
__idx = 1;
|
||||
|
||||
for (kk=0;kk<N-M;kk++) {
|
||||
y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
|
||||
mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
|
||||
}
|
||||
for (;kk<N-1;kk++) {
|
||||
y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
|
||||
mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
|
||||
}
|
||||
y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
|
||||
mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
|
||||
|
||||
mti = 0;
|
||||
}
|
||||
else
|
||||
__idx++;
|
||||
|
||||
y = mt[mti];
|
||||
|
||||
/* Tempering */
|
||||
y ^= (y >> 11);
|
||||
y ^= (y << 7) & 0x9d2c5680UL;
|
||||
y ^= (y << 15) & 0xefc60000UL;
|
||||
y ^= (y >> 18);
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
EEL_F NSEEL_CGEN_CALL nseel_int_rand(EEL_F f)
|
||||
{
|
||||
EEL_F x=floor(f);
|
||||
if (x < 1.0) x=1.0;
|
||||
|
||||
#ifdef NSEEL_EEL1_COMPAT_MODE
|
||||
return (EEL_F)(genrand_int32()%(int)x);
|
||||
#else
|
||||
return (EEL_F) (genrand_int32()*(1.0/(double)0xFFFFFFFF)*x);
|
||||
#endif
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef EEL_TARGET_PORTABLE
|
||||
|
||||
#ifdef __ppc__
|
||||
#include "asm-nseel-ppc-gcc.c"
|
||||
#elif defined(__aarch64__)
|
||||
#include "asm-nseel-aarch64-gcc.c"
|
||||
#elif defined(_M_ARM64) || defined(_M_ARM64EC)
|
||||
// add asm-nseel-aarch64-msvc.obj / asm-nseel-arm64ec.obj to project
|
||||
#elif defined(__arm__)
|
||||
#include "asm-nseel-arm-gcc.c"
|
||||
#elif defined (_M_ARM) && _M_ARM == 7
|
||||
// vc on ARM, tbd
|
||||
#else
|
||||
#ifdef _MSC_VER
|
||||
#ifdef _WIN64
|
||||
//nasm
|
||||
#else
|
||||
#include "asm-nseel-x86-msvc.c"
|
||||
#endif
|
||||
#elif !defined(__LP64__) && !defined(_WIN64)
|
||||
#define EEL_F_SUFFIX "l"
|
||||
#define FUNCTION_MARKER "\n.byte 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90\n"
|
||||
#include "asm-nseel-x86-gcc.c"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
5819
oversampling/WDL/eel2/nseel-compiler.c
Normal file
5819
oversampling/WDL/eel2/nseel-compiler.c
Normal file
File diff suppressed because it is too large
Load Diff
469
oversampling/WDL/eel2/nseel-eval.c
Normal file
469
oversampling/WDL/eel2/nseel-eval.c
Normal file
@@ -0,0 +1,469 @@
|
||||
/*
|
||||
Expression Evaluator Library (NS-EEL) v2
|
||||
Copyright (C) 2004-2013 Cockos Incorporated
|
||||
Copyright (C) 1999-2003 Nullsoft, Inc.
|
||||
|
||||
nseel-eval.c
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "ns-eel-int.h"
|
||||
#include "../wdlcstring.h"
|
||||
|
||||
|
||||
static const char *nseel_skip_space_and_comments(const char *p, const char *endptr)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
while (p < endptr && isspace((unsigned char)p[0])) p++;
|
||||
if (p >= endptr-1 || *p != '/') return p;
|
||||
|
||||
if (p[1]=='/')
|
||||
{
|
||||
while (p < endptr && *p != '\r' && *p != '\n') p++;
|
||||
}
|
||||
else if (p[1] == '*')
|
||||
{
|
||||
p+=2;
|
||||
while (p < endptr-1 && (p[0] != '*' || p[1] != '/')) p++;
|
||||
p+=2;
|
||||
if (p>=endptr) return endptr;
|
||||
}
|
||||
else return p;
|
||||
}
|
||||
}
|
||||
|
||||
// removes any escaped characters, also will convert pairs delim_char into single delim_chars
|
||||
int nseel_filter_escaped_string(char *outbuf, int outbuf_sz, const char *rdptr, size_t rdptr_size, char delim_char)
|
||||
{
|
||||
int outpos = 0;
|
||||
const char *rdptr_end = rdptr + rdptr_size;
|
||||
while (rdptr < rdptr_end && outpos < outbuf_sz-1)
|
||||
{
|
||||
char thisc=*rdptr;
|
||||
if (thisc == '\\' && rdptr < rdptr_end-1)
|
||||
{
|
||||
const char nc = rdptr[1];
|
||||
if (nc == 'r' || nc == 'R') { thisc = '\r'; }
|
||||
else if (nc == 'n' || nc == 'N') { thisc = '\n'; }
|
||||
else if (nc == 't' || nc == 'T') { thisc = '\t'; }
|
||||
else if (nc == 'b' || nc == 'B') { thisc = '\b'; }
|
||||
else if ((nc >= '0' && nc <= '9') || nc == 'x' || nc == 'X')
|
||||
{
|
||||
unsigned char c=0;
|
||||
char base_shift = 3;
|
||||
char num_top = '7';
|
||||
|
||||
rdptr++; // skip backslash
|
||||
if (nc > '9') // implies xX
|
||||
{
|
||||
base_shift = 4;
|
||||
num_top = '9';
|
||||
rdptr ++; // skip x
|
||||
}
|
||||
|
||||
while (rdptr < rdptr_end)
|
||||
{
|
||||
char tc=*rdptr;
|
||||
if (tc >= '0' && tc <= num_top)
|
||||
{
|
||||
c = (c<<base_shift) + tc - '0';
|
||||
}
|
||||
else if (base_shift==4)
|
||||
{
|
||||
if (tc >= 'a' && tc <= 'f')
|
||||
{
|
||||
c = (c<<base_shift) + (tc - 'a' + 10);
|
||||
}
|
||||
else if (tc >= 'A' && tc <= 'F')
|
||||
{
|
||||
c = (c<<base_shift) + (tc - 'A' + 10);
|
||||
}
|
||||
else break;
|
||||
}
|
||||
else break;
|
||||
|
||||
rdptr++;
|
||||
}
|
||||
outbuf[outpos++] = (char)c;
|
||||
continue;
|
||||
}
|
||||
else // \c where c is an unknown character drops the backslash -- works for \, ', ", etc
|
||||
{
|
||||
thisc = nc;
|
||||
}
|
||||
rdptr+=2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (thisc == delim_char) break;
|
||||
rdptr++;
|
||||
}
|
||||
outbuf[outpos++] = thisc;
|
||||
}
|
||||
outbuf[outpos]=0;
|
||||
return outpos;
|
||||
}
|
||||
|
||||
int nseel_stringsegments_tobuf(char *bufOut, int bufout_sz, struct eelStringSegmentRec *list) // call with NULL to calculate size, or non-null to generate to buffer (returning size used)
|
||||
{
|
||||
int pos=0;
|
||||
while (list)
|
||||
{
|
||||
if (!bufOut)
|
||||
{
|
||||
pos += list->str_len;
|
||||
}
|
||||
else if (list->str_len > 1)
|
||||
{
|
||||
if (pos >= bufout_sz) break;
|
||||
pos += nseel_filter_escaped_string(bufOut + pos, bufout_sz-pos, list->str_start+1, list->str_len-1, list->str_start[0]);
|
||||
}
|
||||
list = list->_next;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// state can be NULL, it will be set if finished with unterminated thing: 1 for multiline comment, ' or " for string
|
||||
const char *nseel_simple_tokenizer(const char **ptr, const char *endptr, int *lenOut, int *state)
|
||||
{
|
||||
const char *p = *ptr;
|
||||
const char *rv = p;
|
||||
char delim;
|
||||
|
||||
if (state) // if state set, returns comments as tokens
|
||||
{
|
||||
if (*state == 1) goto in_comment;
|
||||
|
||||
#ifndef NSEEL_EEL1_COMPAT_MODE
|
||||
if (*state == '\'' || *state == '\"')
|
||||
{
|
||||
delim = (char)*state;
|
||||
goto in_string;
|
||||
}
|
||||
#endif
|
||||
|
||||
// skip any whitespace
|
||||
while (p < endptr && isspace((unsigned char)p[0])) p++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// state not passed, skip comments (do not return them as tokens)
|
||||
p = nseel_skip_space_and_comments(p,endptr);
|
||||
}
|
||||
|
||||
if (p >= endptr)
|
||||
{
|
||||
*ptr = endptr;
|
||||
*lenOut = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rv=p;
|
||||
|
||||
if (*p == '$' && p+3 < endptr && p[1] == '\'' && p[3] == '\'')
|
||||
{
|
||||
p+=4;
|
||||
}
|
||||
else if (state && *p == '/' && p < endptr-1 && (p[1] == '/' || p[1] == '*'))
|
||||
{
|
||||
if (p[1] == '/')
|
||||
{
|
||||
while (p < endptr && *p != '\r' && *p != '\n') p++; // advance to end of line
|
||||
}
|
||||
else
|
||||
{
|
||||
if (state) *state=1;
|
||||
p+=2;
|
||||
in_comment:
|
||||
while (p < endptr)
|
||||
{
|
||||
const char c = *p++;
|
||||
if (c == '*' && p < endptr && *p == '/')
|
||||
{
|
||||
p++;
|
||||
if (state) *state=0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else if (isalnum((unsigned char)*p) || *p == '_' || *p == '#' || *p == '$' || (*p == '.' && p < endptr-1 && p[1] >= '0' && p[1] <= '9'))
|
||||
{
|
||||
if (*p == '$' && p < endptr-1 && p[1] == '~') p++;
|
||||
p++;
|
||||
while (p < endptr && (isalnum((unsigned char)*p) || *p == '_' || *p == '.')) p++;
|
||||
}
|
||||
#ifndef NSEEL_EEL1_COMPAT_MODE
|
||||
else if (*p == '\'' || *p == '\"')
|
||||
{
|
||||
delim = *p++;
|
||||
if (state) *state=delim;
|
||||
in_string:
|
||||
|
||||
while (p < endptr)
|
||||
{
|
||||
const char c = *p++;
|
||||
if (p < endptr && c == '\\') p++; // skip escaped characters
|
||||
else if (c == delim)
|
||||
{
|
||||
if (state) *state=0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
p++;
|
||||
}
|
||||
*ptr = p;
|
||||
*lenOut = (int) (p - rv);
|
||||
return p>rv ? rv : NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef NSEEL_SUPER_MINIMAL_LEXER
|
||||
|
||||
int nseellex(opcodeRec **output, YYLTYPE * yylloc_param, compileContext *scctx)
|
||||
{
|
||||
int rv=0,toklen=0;
|
||||
const char *rdptr = scctx->rdbuf;
|
||||
const char *endptr = scctx->rdbuf_end;
|
||||
const char *tok = nseel_simple_tokenizer(&rdptr,endptr,&toklen,NULL);
|
||||
*output = 0;
|
||||
if (tok)
|
||||
{
|
||||
rv = tok[0];
|
||||
if ((rv == '0' || rv == '$') && toklen > 1 && (tok[1] == 'x' || tok[1] == 'X')) // 0xf00 or $xf00
|
||||
{
|
||||
int x;
|
||||
for (x = 2; x < toklen; x ++)
|
||||
if (!((tok[x] >= '0' && tok[x] <= '9') ||
|
||||
(tok[x] >= 'a' && tok[x] <= 'f') ||
|
||||
(tok[x] >= 'A' && tok[x] <= 'F')))
|
||||
{
|
||||
tok += x;
|
||||
break;
|
||||
}
|
||||
|
||||
*output = x == toklen && toklen > 2 ? nseel_translate(scctx,tok,toklen) : NULL;
|
||||
if (*output) rv=VALUE;
|
||||
}
|
||||
#ifndef NSEEL_EEL1_COMPAT_MODE
|
||||
else if (rv == '#' && scctx->onNamedString)
|
||||
{
|
||||
*output = nseel_translate(scctx,tok,toklen);
|
||||
if (*output) rv=STRING_IDENTIFIER;
|
||||
}
|
||||
else if (rv == '\'')
|
||||
{
|
||||
if (toklen > 1 && tok[toklen-1] == '\'')
|
||||
{
|
||||
*output = nseel_translate(scctx, tok, toklen);
|
||||
if (*output) rv = VALUE;
|
||||
}
|
||||
else scctx->gotEndOfInput|=8;
|
||||
}
|
||||
else if (rv == '\"' && scctx->onString)
|
||||
{
|
||||
if (toklen > 1 && tok[toklen-1] == '\"')
|
||||
{
|
||||
*output = (opcodeRec *)nseel_createStringSegmentRec(scctx,tok,toklen);
|
||||
if (*output) rv = STRING_LITERAL;
|
||||
}
|
||||
else scctx->gotEndOfInput|=16;
|
||||
}
|
||||
#endif
|
||||
else if (isalpha((unsigned char)rv) || rv == '_')
|
||||
{
|
||||
char buf[NSEEL_MAX_VARIABLE_NAMELEN*2];
|
||||
if (toklen > sizeof(buf) - 1) toklen=sizeof(buf) - 1;
|
||||
memcpy(buf,tok,toklen);
|
||||
buf[toklen]=0;
|
||||
*output = nseel_createCompiledValuePtr(scctx, NULL, buf);
|
||||
if (*output) rv = IDENTIFIER;
|
||||
}
|
||||
else if ((rv >= '0' && rv <= '9') || (rv == '.' && toklen > 1 && tok[1] >= '0' && tok[1] <= '9')) // 123.45 or .45
|
||||
{
|
||||
int x, pcnt = 0;
|
||||
for (x = 0; x < toklen; x ++)
|
||||
{
|
||||
if (tok[x] == '.' ? (++pcnt > 1) : (tok[x] < '0' || tok[x] > '9'))
|
||||
{
|
||||
tok += x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*output = x == toklen ? nseel_translate(scctx,tok,toklen) : NULL;
|
||||
if (*output) rv=VALUE;
|
||||
}
|
||||
else if (rv == '$' && toklen > 1)
|
||||
{
|
||||
if (tok[1] == '~')
|
||||
{
|
||||
int x;
|
||||
for (x = 2; x < toklen; x ++)
|
||||
if (tok[x] < '0' || tok[x] > '9')
|
||||
{
|
||||
tok += x;
|
||||
break;
|
||||
}
|
||||
|
||||
if (x<toklen || toklen == 2) toklen = 0;
|
||||
}
|
||||
|
||||
*output = toklen > 1 ? nseel_translate(scctx,tok,toklen) : NULL;
|
||||
if (*output) rv=VALUE;
|
||||
}
|
||||
else if (rv == '<')
|
||||
{
|
||||
const char nc=*rdptr;
|
||||
if (nc == '<')
|
||||
{
|
||||
rdptr++;
|
||||
rv=TOKEN_SHL;
|
||||
}
|
||||
else if (nc == '=')
|
||||
{
|
||||
rdptr++;
|
||||
rv=TOKEN_LTE;
|
||||
}
|
||||
}
|
||||
else if (rv == '>')
|
||||
{
|
||||
const char nc=*rdptr;
|
||||
if (nc == '>')
|
||||
{
|
||||
rdptr++;
|
||||
rv=TOKEN_SHR;
|
||||
}
|
||||
else if (nc == '=')
|
||||
{
|
||||
rdptr++;
|
||||
rv=TOKEN_GTE;
|
||||
}
|
||||
}
|
||||
else if (rv == '&' && *rdptr == '&')
|
||||
{
|
||||
rdptr++;
|
||||
rv = TOKEN_LOGICAL_AND;
|
||||
}
|
||||
else if (rv == '|' && *rdptr == '|')
|
||||
{
|
||||
rdptr++;
|
||||
rv = TOKEN_LOGICAL_OR;
|
||||
}
|
||||
else if (*rdptr == '=')
|
||||
{
|
||||
switch (rv)
|
||||
{
|
||||
case '+': rv=TOKEN_ADD_OP; rdptr++; break;
|
||||
case '-': rv=TOKEN_SUB_OP; rdptr++; break;
|
||||
case '%': rv=TOKEN_MOD_OP; rdptr++; break;
|
||||
case '|': rv=TOKEN_OR_OP; rdptr++; break;
|
||||
case '&': rv=TOKEN_AND_OP; rdptr++; break;
|
||||
case '~': rv=TOKEN_XOR_OP; rdptr++; break;
|
||||
case '/': rv=TOKEN_DIV_OP; rdptr++; break;
|
||||
case '*': rv=TOKEN_MUL_OP; rdptr++; break;
|
||||
case '^': rv=TOKEN_POW_OP; rdptr++; break;
|
||||
case '!':
|
||||
rdptr++;
|
||||
if (rdptr < endptr && *rdptr == '=')
|
||||
{
|
||||
rdptr++;
|
||||
rv=TOKEN_NE_EXACT;
|
||||
}
|
||||
else
|
||||
rv=TOKEN_NE;
|
||||
break;
|
||||
case '=':
|
||||
rdptr++;
|
||||
if (rdptr < endptr && *rdptr == '=')
|
||||
{
|
||||
rdptr++;
|
||||
rv=TOKEN_EQ_EXACT;
|
||||
}
|
||||
else
|
||||
rv=TOKEN_EQ;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scctx->rdbuf = rdptr;
|
||||
yylloc_param->first_column = (int)(tok - scctx->rdbuf_start);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
void nseelerror(YYLTYPE *pos,compileContext *ctx, const char *str)
|
||||
{
|
||||
ctx->errVar=pos->first_column>0?pos->first_column:(int)(ctx->rdbuf_end - ctx->rdbuf_start);
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
int nseel_gets(compileContext *ctx, char *buf, size_t sz)
|
||||
{
|
||||
int n=0;
|
||||
const char *endptr = ctx->rdbuf_end;
|
||||
const char *rdptr = ctx->rdbuf;
|
||||
if (!rdptr) return 0;
|
||||
|
||||
while (n < sz && rdptr < endptr) buf[n++] = *rdptr++;
|
||||
ctx->rdbuf=rdptr;
|
||||
return n;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//#define EEL_TRACE_LEX
|
||||
|
||||
#ifdef EEL_TRACE_LEX
|
||||
#define nseellex nseellex2
|
||||
|
||||
#endif
|
||||
#include "lex.nseel.c"
|
||||
|
||||
#ifdef EEL_TRACE_LEX
|
||||
|
||||
#undef nseellex
|
||||
|
||||
int nseellex(YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
|
||||
{
|
||||
int a=nseellex2(yylval_param,yylloc_param,yyscanner);
|
||||
|
||||
wdl_log("tok: %c (%d)\n",a,a);
|
||||
return a;
|
||||
}
|
||||
#endif//EEL_TRACE_LEX
|
||||
|
||||
|
||||
void nseelerror(YYLTYPE *pos,compileContext *ctx, const char *str)
|
||||
{
|
||||
ctx->errVar=pos->first_column>0?pos->first_column:(int)(ctx->rdbuf_end - ctx->rdbuf_start);
|
||||
}
|
||||
#endif // !NSEEL_SUPER_MINIMAL_LEXER
|
||||
1
oversampling/WDL/eel2/nseel-lextab.c
Normal file
1
oversampling/WDL/eel2/nseel-lextab.c
Normal file
@@ -0,0 +1 @@
|
||||
// no longer used
|
||||
580
oversampling/WDL/eel2/nseel-ram.c
Normal file
580
oversampling/WDL/eel2/nseel-ram.c
Normal file
@@ -0,0 +1,580 @@
|
||||
/*
|
||||
Expression Evaluator Library (NS-EEL) v2
|
||||
Copyright (C) 2004-2013 Cockos Incorporated
|
||||
Copyright (C) 1999-2003 Nullsoft, Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "ns-eel.h"
|
||||
#include "ns-eel-int.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <malloc.h>
|
||||
#ifdef _MSC_VER
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
unsigned int NSEEL_RAM_limitmem=0;
|
||||
unsigned int NSEEL_RAM_memused=0;
|
||||
int NSEEL_RAM_memused_errors=0;
|
||||
|
||||
|
||||
|
||||
int NSEEL_VM_wantfreeRAM(NSEEL_VMCTX ctx)
|
||||
{
|
||||
if (ctx)
|
||||
{
|
||||
compileContext *c=(compileContext*)ctx;
|
||||
if (c->ram_state->needfree)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void NSEEL_VM_freeRAMIfCodeRequested(NSEEL_VMCTX ctx) // check to see if our free flag was set
|
||||
{
|
||||
if (ctx)
|
||||
{
|
||||
compileContext *c=(compileContext*)ctx;
|
||||
if (c->ram_state->needfree)
|
||||
{
|
||||
NSEEL_HOSTSTUB_EnterMutex();
|
||||
{
|
||||
INT_PTR startpos=((INT_PTR)c->ram_state->needfree)-1;
|
||||
EEL_F **blocks = c->ram_state->blocks;
|
||||
INT_PTR pos=0;
|
||||
int x;
|
||||
for (x = 0; x < NSEEL_RAM_BLOCKS; x ++)
|
||||
{
|
||||
if (pos >= startpos)
|
||||
{
|
||||
if (blocks[x])
|
||||
{
|
||||
if (NSEEL_RAM_memused >= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK)
|
||||
NSEEL_RAM_memused -= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK;
|
||||
else NSEEL_RAM_memused_errors++;
|
||||
free(blocks[x]);
|
||||
blocks[x]=0;
|
||||
}
|
||||
}
|
||||
pos+=NSEEL_RAM_ITEMSPERBLOCK;
|
||||
}
|
||||
c->ram_state->needfree=0;
|
||||
}
|
||||
NSEEL_HOSTSTUB_LeaveMutex();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
EEL_F nseel_ramalloc_onfail;
|
||||
EEL_F * volatile nseel_gmembuf_default;
|
||||
|
||||
|
||||
void *(*nseel_gmem_calloc)(size_t a, size_t b);
|
||||
|
||||
EEL_F * NSEEL_CGEN_CALL __NSEEL_RAMAllocGMEM(EEL_F ***blocks, unsigned int w)
|
||||
{
|
||||
if (blocks)
|
||||
{
|
||||
EEL_F **pblocks=*blocks;
|
||||
|
||||
if (w < NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK)
|
||||
{
|
||||
const unsigned int whichblock = w/NSEEL_RAM_ITEMSPERBLOCK;
|
||||
EEL_F *p=NULL;
|
||||
if (!pblocks || !(p=pblocks[whichblock]))
|
||||
{
|
||||
NSEEL_HOSTSTUB_EnterMutex();
|
||||
if (!nseel_gmem_calloc) nseel_gmem_calloc=calloc;
|
||||
|
||||
if (!(pblocks=*blocks)) pblocks = *blocks = (EEL_F **)nseel_gmem_calloc(sizeof(EEL_F *),NSEEL_RAM_BLOCKS);
|
||||
else p = pblocks[whichblock];
|
||||
|
||||
if (!p && pblocks)
|
||||
{
|
||||
p=pblocks[whichblock]=(EEL_F *)nseel_gmem_calloc(sizeof(EEL_F),NSEEL_RAM_ITEMSPERBLOCK);
|
||||
}
|
||||
NSEEL_HOSTSTUB_LeaveMutex();
|
||||
}
|
||||
if (p) return p + (w&(NSEEL_RAM_ITEMSPERBLOCK-1));
|
||||
}
|
||||
return &nseel_ramalloc_onfail;
|
||||
}
|
||||
|
||||
if (!nseel_gmembuf_default)
|
||||
{
|
||||
NSEEL_HOSTSTUB_EnterMutex();
|
||||
if (!nseel_gmembuf_default) nseel_gmembuf_default=(EEL_F*)calloc(sizeof(EEL_F),NSEEL_SHARED_GRAM_SIZE);
|
||||
NSEEL_HOSTSTUB_LeaveMutex();
|
||||
if (!nseel_gmembuf_default) return &nseel_ramalloc_onfail;
|
||||
}
|
||||
|
||||
return nseel_gmembuf_default+(((unsigned int)w)&((NSEEL_SHARED_GRAM_SIZE)-1));
|
||||
}
|
||||
|
||||
|
||||
EEL_F * NSEEL_CGEN_CALL __NSEEL_RAMAlloc(EEL_F **pblocks, unsigned int w)
|
||||
{
|
||||
// fprintf(stderr,"got request at %d, %d\n",w/NSEEL_RAM_ITEMSPERBLOCK, w&(NSEEL_RAM_ITEMSPERBLOCK-1));
|
||||
if (w < NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK)
|
||||
{
|
||||
unsigned int whichblock = w/NSEEL_RAM_ITEMSPERBLOCK;
|
||||
EEL_F *p=pblocks[whichblock];
|
||||
if (!p && whichblock < ((unsigned int *)pblocks)[-3]) // pblocks -1/-2 are closefact, -3 is maxblocks
|
||||
{
|
||||
NSEEL_HOSTSTUB_EnterMutex();
|
||||
|
||||
if (!(p=pblocks[whichblock]))
|
||||
{
|
||||
|
||||
const int msize=sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK;
|
||||
if (!NSEEL_RAM_limitmem || NSEEL_RAM_memused+msize < NSEEL_RAM_limitmem)
|
||||
{
|
||||
p=pblocks[whichblock]=(EEL_F *)calloc(sizeof(EEL_F),NSEEL_RAM_ITEMSPERBLOCK);
|
||||
if (p) NSEEL_RAM_memused+=msize;
|
||||
}
|
||||
}
|
||||
NSEEL_HOSTSTUB_LeaveMutex();
|
||||
}
|
||||
if (p) return p + (w&(NSEEL_RAM_ITEMSPERBLOCK-1));
|
||||
}
|
||||
// fprintf(stderr,"ret 0\n");
|
||||
return &nseel_ramalloc_onfail;
|
||||
}
|
||||
|
||||
|
||||
EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemFree(void *blocks, EEL_F *which)
|
||||
{
|
||||
// blocks points to ram_state->blocks, so back it up past closefact and maxblocks to needfree
|
||||
int *flag = (int *)((char *)blocks - sizeof(double) - 2*sizeof(int));
|
||||
int d=(int)(*which);
|
||||
if (d < 0) d=0;
|
||||
if (d < flag[1]*NSEEL_RAM_ITEMSPERBLOCK) flag[0]=1+d;
|
||||
return which;
|
||||
}
|
||||
|
||||
EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemTop(void *blocks, EEL_F *which)
|
||||
{
|
||||
// blocks points to ram_state->blocks, so back it up past closefact to maxblocks
|
||||
const int *flag = (int *)((char *)blocks - sizeof(double) - sizeof(int));
|
||||
*which = flag[0]*NSEEL_RAM_ITEMSPERBLOCK;
|
||||
return which;
|
||||
}
|
||||
|
||||
|
||||
EEL_F NSEEL_CGEN_CALL __NSEEL_RAM_MemInsertShuffle(EEL_F **blocks,EEL_F *buf, EEL_F *lenptr, EEL_F *value)
|
||||
{
|
||||
int src_offs = (int)*buf;
|
||||
int len = (int)*lenptr;
|
||||
int copy_len;
|
||||
|
||||
EEL_F ret = *value;
|
||||
|
||||
unsigned int sbidx = (unsigned int)src_offs / NSEEL_RAM_ITEMSPERBLOCK;
|
||||
|
||||
if (len < 1 || src_offs < 0) return 0.0;
|
||||
|
||||
src_offs = src_offs&(NSEEL_RAM_ITEMSPERBLOCK-1);
|
||||
copy_len = wdl_min(len,NSEEL_RAM_ITEMSPERBLOCK - src_offs);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
EEL_F *srcptr;
|
||||
if (sbidx >= NSEEL_RAM_BLOCKS) break;
|
||||
|
||||
srcptr = blocks[sbidx];
|
||||
|
||||
if (WDL_unlikely(!srcptr))
|
||||
{
|
||||
srcptr = __NSEEL_RAMAlloc(blocks,sbidx * NSEEL_RAM_ITEMSPERBLOCK);
|
||||
if (srcptr==&nseel_ramalloc_onfail) break;
|
||||
}
|
||||
|
||||
len-=copy_len;
|
||||
srcptr += src_offs;
|
||||
while (copy_len-- > 0)
|
||||
{
|
||||
EEL_F v = *srcptr;
|
||||
*srcptr++ = ret;
|
||||
ret = v;
|
||||
}
|
||||
if (!len) break;
|
||||
|
||||
sbidx++;
|
||||
src_offs=0;
|
||||
copy_len = wdl_min(len,NSEEL_RAM_ITEMSPERBLOCK);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
EEL_F NSEEL_CGEN_CALL __NSEEL_RAM_MemSumProducts(EEL_F **blocks,EEL_F *dest, EEL_F *src, EEL_F *lenptr)
|
||||
{
|
||||
int src_offs = (int)*src;
|
||||
int len = (int)*lenptr;
|
||||
|
||||
EEL_F sum = 0.0;
|
||||
|
||||
if (len < 1 || src_offs < 0) return 0.0;
|
||||
|
||||
if (*dest < 0.0)
|
||||
{
|
||||
int copy_len;
|
||||
unsigned int sbidx = (unsigned int)src_offs / NSEEL_RAM_ITEMSPERBLOCK;
|
||||
src_offs = src_offs&(NSEEL_RAM_ITEMSPERBLOCK-1);
|
||||
copy_len = wdl_min(len,NSEEL_RAM_ITEMSPERBLOCK - src_offs);
|
||||
for (;;)
|
||||
{
|
||||
const EEL_F *srcptr;
|
||||
if (sbidx >= NSEEL_RAM_BLOCKS) break;
|
||||
|
||||
srcptr = blocks[sbidx];
|
||||
|
||||
if (WDL_likely(srcptr))
|
||||
{
|
||||
int i;
|
||||
srcptr += src_offs;
|
||||
if (*dest == -1.0)
|
||||
for (i = 0; i < copy_len; i ++) sum += srcptr[i] * srcptr[i];
|
||||
else if (*dest == -2.0)
|
||||
for (i = 0; i < copy_len; i ++) sum += fabs(srcptr[i]);
|
||||
else
|
||||
for (i = 0; i < copy_len; i ++) sum += srcptr[i];
|
||||
}
|
||||
len-=copy_len;
|
||||
if (!len) break;
|
||||
|
||||
sbidx++;
|
||||
src_offs=0;
|
||||
copy_len = wdl_min(len,NSEEL_RAM_ITEMSPERBLOCK);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int dest_offs = (unsigned int) (int)*dest;
|
||||
for (;;)
|
||||
{
|
||||
unsigned int sbidx = (unsigned int)src_offs / NSEEL_RAM_ITEMSPERBLOCK;
|
||||
const int sbo = (src_offs&(NSEEL_RAM_ITEMSPERBLOCK-1));
|
||||
unsigned int dbidx = dest_offs / NSEEL_RAM_ITEMSPERBLOCK;
|
||||
const int dbo = (dest_offs&(NSEEL_RAM_ITEMSPERBLOCK-1));
|
||||
|
||||
const int copy_len = wdl_min(len,NSEEL_RAM_ITEMSPERBLOCK - wdl_max(dbo,sbo));
|
||||
|
||||
const EEL_F *srcptr, *destptr;
|
||||
|
||||
if (sbidx >= NSEEL_RAM_BLOCKS || dbidx >= NSEEL_RAM_BLOCKS) break;
|
||||
srcptr = blocks[sbidx];
|
||||
destptr = blocks[dbidx];
|
||||
if (WDL_likely(srcptr && destptr))
|
||||
{
|
||||
int i;
|
||||
srcptr += sbo;
|
||||
destptr += dbo;
|
||||
for (i = 0; i < copy_len; i ++) sum += destptr[i] * srcptr[i];
|
||||
}
|
||||
len-=copy_len;
|
||||
if (!len) break;
|
||||
|
||||
src_offs += copy_len;
|
||||
dest_offs += copy_len;
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
||||
EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemCpy(EEL_F **blocks,EEL_F *dest, EEL_F *src, EEL_F *lenptr)
|
||||
{
|
||||
const int mem_size=NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK;
|
||||
int dest_offs = (int)(*dest + 0.0001);
|
||||
int src_offs = (int)(*src + 0.0001);
|
||||
int len = (int)(*lenptr + 0.0001);
|
||||
int want_mmove=0;
|
||||
|
||||
// trim to front
|
||||
if (src_offs<0)
|
||||
{
|
||||
len += src_offs;
|
||||
dest_offs -= src_offs;
|
||||
src_offs=0;
|
||||
}
|
||||
if (dest_offs<0)
|
||||
{
|
||||
len += dest_offs;
|
||||
src_offs -= dest_offs;
|
||||
dest_offs=0;
|
||||
}
|
||||
if (src_offs + len > mem_size) len = mem_size-src_offs;
|
||||
if (dest_offs + len > mem_size) len = mem_size-dest_offs;
|
||||
|
||||
if (src_offs == dest_offs || len < 1) return dest;
|
||||
|
||||
if (src_offs < dest_offs && src_offs+len > dest_offs)
|
||||
{
|
||||
// if src_offs < dest_offs and overlapping, must copy right to left
|
||||
if ((dest_offs - src_offs) < NSEEL_RAM_ITEMSPERBLOCK) want_mmove = 1;
|
||||
src_offs += len;
|
||||
dest_offs += len;
|
||||
while (len > 0)
|
||||
{
|
||||
const int maxdlen=((dest_offs-1)&(NSEEL_RAM_ITEMSPERBLOCK-1)) + 1;
|
||||
const int maxslen=((src_offs-1)&(NSEEL_RAM_ITEMSPERBLOCK-1)) + 1;
|
||||
int copy_len = len;
|
||||
EEL_F *srcptr,*destptr;
|
||||
|
||||
if (copy_len > maxdlen) copy_len=maxdlen;
|
||||
if (copy_len > maxslen) copy_len=maxslen;
|
||||
|
||||
srcptr = __NSEEL_RAMAlloc(blocks,src_offs - copy_len);
|
||||
destptr = __NSEEL_RAMAlloc(blocks,dest_offs - copy_len);
|
||||
if (srcptr==&nseel_ramalloc_onfail || destptr==&nseel_ramalloc_onfail) break;
|
||||
|
||||
if (want_mmove) memmove(destptr,srcptr,sizeof(EEL_F)*copy_len);
|
||||
else memcpy(destptr,srcptr,sizeof(EEL_F)*copy_len);
|
||||
src_offs-=copy_len;
|
||||
dest_offs-=copy_len;
|
||||
len-=copy_len;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
if (dest_offs < src_offs && dest_offs+len > src_offs)
|
||||
{
|
||||
// if dest_offs < src_offs and overlapping, and less than NSEEL_RAM_ITEMSPERBLOCK apart, use memmove()
|
||||
if ((src_offs-dest_offs) < NSEEL_RAM_ITEMSPERBLOCK) want_mmove = 1;
|
||||
}
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
const int maxdlen=NSEEL_RAM_ITEMSPERBLOCK - (dest_offs&(NSEEL_RAM_ITEMSPERBLOCK-1));
|
||||
const int maxslen=NSEEL_RAM_ITEMSPERBLOCK - (src_offs&(NSEEL_RAM_ITEMSPERBLOCK-1));
|
||||
int copy_len = len;
|
||||
EEL_F *srcptr,*destptr;
|
||||
|
||||
if (copy_len > maxdlen) copy_len=maxdlen;
|
||||
if (copy_len > maxslen) copy_len=maxslen;
|
||||
|
||||
srcptr = __NSEEL_RAMAlloc(blocks,src_offs);
|
||||
destptr = __NSEEL_RAMAlloc(blocks,dest_offs);
|
||||
if (srcptr==&nseel_ramalloc_onfail || destptr==&nseel_ramalloc_onfail) break;
|
||||
|
||||
if (want_mmove) memmove(destptr,srcptr,sizeof(EEL_F)*copy_len);
|
||||
else memcpy(destptr,srcptr,sizeof(EEL_F)*copy_len);
|
||||
src_offs+=copy_len;
|
||||
dest_offs+=copy_len;
|
||||
len-=copy_len;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemSet(EEL_F **blocks,EEL_F *dest, EEL_F *v, EEL_F *lenptr)
|
||||
{
|
||||
int offs = (int)(*dest + 0.0001);
|
||||
int len = (int)(*lenptr + 0.0001);
|
||||
EEL_F t;
|
||||
if (offs<0)
|
||||
{
|
||||
len += offs;
|
||||
offs=0;
|
||||
}
|
||||
if (offs >= NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK) return dest;
|
||||
|
||||
if (offs+len > NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK) len = NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK - offs;
|
||||
|
||||
if (len < 1) return dest;
|
||||
|
||||
|
||||
t=*v; // set value
|
||||
|
||||
// int lastBlock=-1;
|
||||
while (len > 0)
|
||||
{
|
||||
int lcnt;
|
||||
EEL_F *ptr=__NSEEL_RAMAlloc(blocks,offs);
|
||||
if (ptr==&nseel_ramalloc_onfail) break;
|
||||
|
||||
lcnt=NSEEL_RAM_ITEMSPERBLOCK-(offs&(NSEEL_RAM_ITEMSPERBLOCK-1));
|
||||
if (lcnt > len) lcnt=len;
|
||||
|
||||
len -= lcnt;
|
||||
offs += lcnt;
|
||||
|
||||
while (lcnt--)
|
||||
{
|
||||
*ptr++=t;
|
||||
}
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
static inline int __getset_values(EEL_F **blocks, int isset, int len, EEL_F **parms)
|
||||
{
|
||||
int offs, lout=0;
|
||||
unsigned int pageidx, sub_offs;
|
||||
if (--len < 1) return 0;
|
||||
offs = (int)(parms++[0][0] + 0.0001);
|
||||
|
||||
if (offs<=0)
|
||||
{
|
||||
len += offs;
|
||||
parms -= offs;
|
||||
offs=0;
|
||||
pageidx=sub_offs=0;
|
||||
if (len<1) return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
sub_offs = ((unsigned int)offs) & (NSEEL_RAM_ITEMSPERBLOCK-1);
|
||||
pageidx = ((unsigned int)offs)>>NSEEL_RAM_ITEMSPERBLOCK_LOG2;
|
||||
if (pageidx>=NSEEL_RAM_BLOCKS) return 0;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int lcnt=NSEEL_RAM_ITEMSPERBLOCK-sub_offs;
|
||||
EEL_F *ptr=blocks[pageidx];
|
||||
if (!ptr)
|
||||
{
|
||||
ptr = __NSEEL_RAMAlloc(blocks,offs + lout);
|
||||
if (ptr==&nseel_ramalloc_onfail) return lout;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr += sub_offs;
|
||||
}
|
||||
|
||||
if (lcnt >= len)
|
||||
{
|
||||
// this page satisfies the request (normal behavior)
|
||||
lout += len;
|
||||
if (isset) while (len--) *ptr++=parms++[0][0];
|
||||
else while (len--) parms++[0][0] = *ptr++;
|
||||
return lout;
|
||||
}
|
||||
|
||||
// crossing a page boundary
|
||||
len -= lcnt;
|
||||
lout += lcnt;
|
||||
if (isset) while (lcnt--) *ptr++=parms++[0][0];
|
||||
else while (lcnt--) parms++[0][0] = *ptr++;
|
||||
|
||||
if (len <= 0 || ++pageidx >= NSEEL_RAM_BLOCKS) return lout;
|
||||
sub_offs=0;
|
||||
}
|
||||
}
|
||||
|
||||
EEL_F NSEEL_CGEN_CALL __NSEEL_RAM_Mem_SetValues(EEL_F **blocks, INT_PTR np, EEL_F **parms)
|
||||
{
|
||||
return __getset_values(blocks,1,(int)np,parms);
|
||||
}
|
||||
|
||||
EEL_F NSEEL_CGEN_CALL __NSEEL_RAM_Mem_GetValues(EEL_F **blocks, INT_PTR np, EEL_F **parms)
|
||||
{
|
||||
return __getset_values(blocks,0,(int)np,parms);
|
||||
}
|
||||
|
||||
void NSEEL_VM_SetGRAM(NSEEL_VMCTX ctx, void **gram)
|
||||
{
|
||||
if (ctx)
|
||||
{
|
||||
compileContext *c=(compileContext*)ctx;
|
||||
c->gram_blocks = gram;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void NSEEL_VM_freeRAM(NSEEL_VMCTX ctx)
|
||||
{
|
||||
if (ctx)
|
||||
{
|
||||
int x;
|
||||
compileContext *c=(compileContext*)ctx;
|
||||
EEL_F **blocks = c->ram_state->blocks;
|
||||
for (x = 0; x < NSEEL_RAM_BLOCKS; x ++)
|
||||
{
|
||||
if (blocks[x])
|
||||
{
|
||||
if (NSEEL_RAM_memused >= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK)
|
||||
NSEEL_RAM_memused -= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK;
|
||||
else NSEEL_RAM_memused_errors++;
|
||||
free(blocks[x]);
|
||||
blocks[x]=0;
|
||||
}
|
||||
}
|
||||
c->ram_state->needfree=0; // no need to free anymore
|
||||
}
|
||||
}
|
||||
|
||||
void NSEEL_VM_FreeGRAM(void **ufd)
|
||||
{
|
||||
if (ufd[0])
|
||||
{
|
||||
EEL_F **blocks = (EEL_F **)ufd[0];
|
||||
int x;
|
||||
for (x = 0; x < NSEEL_RAM_BLOCKS; x ++)
|
||||
{
|
||||
if (blocks[x])
|
||||
{
|
||||
if (NSEEL_RAM_memused >= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK)
|
||||
NSEEL_RAM_memused -= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK;
|
||||
else NSEEL_RAM_memused_errors++;
|
||||
}
|
||||
free(blocks[x]);
|
||||
blocks[x]=0;
|
||||
}
|
||||
free(blocks);
|
||||
ufd[0]=0;
|
||||
}
|
||||
}
|
||||
|
||||
EEL_F *NSEEL_VM_getramptr(NSEEL_VMCTX ctx, unsigned int offs, int *validCount)
|
||||
{
|
||||
EEL_F *d=__NSEEL_RAMAlloc(ctx ? ((compileContext*)ctx)->ram_state->blocks : 0,offs);
|
||||
if (!d || d == &nseel_ramalloc_onfail) return NULL;
|
||||
if (validCount) *validCount = NSEEL_RAM_ITEMSPERBLOCK - (offs%NSEEL_RAM_ITEMSPERBLOCK);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
EEL_F *NSEEL_VM_getramptr_noalloc(NSEEL_VMCTX ctx, unsigned int offs, int *validCount)
|
||||
{
|
||||
EEL_F *d;
|
||||
compileContext *cc = (compileContext *)ctx;
|
||||
|
||||
if (!cc ||
|
||||
offs >= NSEEL_RAM_ITEMSPERBLOCK*NSEEL_RAM_BLOCKS ||
|
||||
NULL == (d = cc->ram_state->blocks[offs/NSEEL_RAM_ITEMSPERBLOCK])
|
||||
)
|
||||
{
|
||||
if (validCount) *validCount = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
offs %= NSEEL_RAM_ITEMSPERBLOCK;
|
||||
if (validCount) *validCount = NSEEL_RAM_ITEMSPERBLOCK - offs;
|
||||
return d + offs;
|
||||
}
|
||||
43
oversampling/WDL/eel2/nseel-yylex.c
Normal file
43
oversampling/WDL/eel2/nseel-yylex.c
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
Expression Evaluator Library (NS-EEL)
|
||||
Copyright (C) 2004-2013 Cockos Incorporated
|
||||
Copyright (C) 1999-2003 Nullsoft, Inc.
|
||||
|
||||
nseel-yylex.c
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#include "ns-eel-int.h"
|
||||
|
||||
|
||||
|
||||
# define YYMALLOC malloc
|
||||
# define YYFREE free
|
||||
|
||||
int nseellex(void * yylval_param,void * yylloc_param ,void *yyscanner);
|
||||
void nseelerror(void *pos,compileContext *ctx, const char *str);
|
||||
|
||||
// inhibit a warning:
|
||||
static void WDL_STATICFUNC_UNUSED yydestruct(const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, compileContext* context);
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "y.tab.c"
|
||||
|
||||
8
oversampling/WDL/eel2/regenerate-x64-objects.sh
Normal file
8
oversampling/WDL/eel2/regenerate-x64-objects.sh
Normal file
@@ -0,0 +1,8 @@
|
||||
# regenerates x86_64 objects
|
||||
rm -f asm-nseel-x64-macho.o asm-nseel-x64.obj foo.o
|
||||
nasm -f win64 asm-nseel-x64-sse.asm -o asm-nseel-x64.obj || echo "error assembling win64 object"
|
||||
nasm -D AMD64ABI -f macho64 --prefix _ asm-nseel-x64-sse.asm -o asm-nseel-x64-macho.o || echo "error assembling macOS x86_64"
|
||||
echo > foo.c
|
||||
clang -arch arm64 -c -o foo.o foo.c || echo "error compiling arm64 stub"
|
||||
lipo foo.o asm-nseel-x64-macho.o -create -output asm-nseel-multi-macho.o || echo "error making asm-nseel-multi-macho.o"
|
||||
rm -f -- foo.c foo.o
|
||||
50
oversampling/WDL/eel2/scripts/circle.eel
Normal file
50
oversampling/WDL/eel2/scripts/circle.eel
Normal file
@@ -0,0 +1,50 @@
|
||||
gfx_init("vis",1024,768);
|
||||
|
||||
zp=-0.84;
|
||||
fill=0;
|
||||
radj=1;
|
||||
while ((c=gfx_getchar())!=27 && c >= 0)
|
||||
(
|
||||
c == 'f' ? fill=!fill;
|
||||
c == 'j' ? jitter=!jitter;
|
||||
c == 'm' ? radj = !radj;
|
||||
|
||||
gfx_r=gfx_g=gfx_b=1;
|
||||
gfx_a=1;
|
||||
gfx_x=gfx_y=0;
|
||||
gfx_printf("[f]ill=%s, [j]itter=%s, [m]ove=%s [%f] %d,%d",fill?"on":"off",jitter?"on":"off",radj?"on":"off",zp,mouse_x,mouse_y);
|
||||
gfx_a=0.25;
|
||||
|
||||
|
||||
radj ? zp+=0.03;
|
||||
gfx_getchar('up') ? zp+=0.03;
|
||||
gfx_getchar('down') ? zp-=0.03;
|
||||
zp2+=0.1;
|
||||
rd = (1+sin(zp*1.3))*(gfx_w/8-16) + 3;
|
||||
jitter ? (
|
||||
xoffs=0.5+sin(zp2*6.7)*0.5;
|
||||
yoffs=0.5+sin(zp2*7.7)*0.5;
|
||||
rd|=0;
|
||||
rd += 0.5+sin(zp2*3.1)*0.5
|
||||
) : ( xoffs=yoffs=0; rd|= 0;);
|
||||
|
||||
|
||||
gfx_circle(xoffs+(gfx_w/4)|0,yoffs+(gfx_h/2)|0,rd, fill,0);
|
||||
gfx_circle(xoffs+(gfx_w*3/4)|0,yoffs+(gfx_h/2)|0,rd, fill,1);
|
||||
|
||||
gfx_mode=4+(1<<4); // filtering off, additive
|
||||
gfx_a=1;
|
||||
zsz=20;
|
||||
outsz=gfx_w/4;
|
||||
gfx_blit(-1,0,0,
|
||||
gfx_w/4-zsz, gfx_h/2-zsz, zsz*2,zsz*2,
|
||||
0,gfx_h-outsz,outsz,outsz);
|
||||
|
||||
gfx_blit(-1,0,0,
|
||||
gfx_w*3/4-zsz, gfx_h/2-zsz, zsz*2,zsz*2,
|
||||
gfx_w-outsz,gfx_h-outsz,outsz,outsz);
|
||||
gfx_mode=0;
|
||||
|
||||
gfx_update();
|
||||
sleep(30);
|
||||
);
|
||||
20
oversampling/WDL/eel2/scripts/eval_test.eel
Normal file
20
oversampling/WDL/eel2/scripts/eval_test.eel
Normal file
@@ -0,0 +1,20 @@
|
||||
argc < 2 ? (
|
||||
printf("Usage: %s [script]\n",argv[0]);
|
||||
|
||||
) : (
|
||||
printf("loading '%s'\n",argv[1]);
|
||||
x = fopen(argv[1],"r");
|
||||
!x ? (
|
||||
printf("Error opening '%s'\n",argv[1])
|
||||
) : (
|
||||
#str="";
|
||||
while (fgets(x,#line)) ( #str += #line; );
|
||||
fclose(x);
|
||||
loop(30,
|
||||
start_t = time_precise();
|
||||
eval(#str) || printf("error evaluating script\n");
|
||||
start_t = time_precise()-start_t;
|
||||
printf("finished in %f milliseconds\n",start_t*1000.0);
|
||||
);
|
||||
);
|
||||
);
|
||||
24
oversampling/WDL/eel2/scripts/gfx_test.eel
Normal file
24
oversampling/WDL/eel2/scripts/gfx_test.eel
Normal file
@@ -0,0 +1,24 @@
|
||||
gfx_init("vis",1024,768);
|
||||
|
||||
gfx_clear=-1;
|
||||
while ((c=gfx_getchar())!=27 && c >= 0)
|
||||
(
|
||||
c == ' ' ? (mode += 1) >= 2 ? mode=0;
|
||||
t=time_precise();
|
||||
zsc = 0.01*cos(t*0.73);
|
||||
// gfx_x=gfx_y=0; gfx_blurto(gfx_w,gfx_h);
|
||||
gfx_blit(-1,0,0.3*(sin(t*0.3)^2),gfx_w*zsc,gfx_h*zsc, gfx_w*(1-2*zsc),gfx_h*(1-2*zsc), 0,0,gfx_w,gfx_h);
|
||||
gfx_r=(cos(t)+1.0)*0.5;
|
||||
gfx_g=(cos(t*1.74)+1.0)*0.5;
|
||||
gfx_b=(cos(t*1.2+0.56)+1.0)*0.5;
|
||||
gfx_a=0.15;
|
||||
sz=gfx_w*0.03;
|
||||
loop(20,
|
||||
mode == 1 ?
|
||||
gfx_circle(rand(gfx_w-sz),rand(gfx_h-sz),sz,1) :
|
||||
gfx_rect(rand(gfx_w-sz),rand(gfx_h-sz),sz,sz);
|
||||
);
|
||||
|
||||
|
||||
gfx_update();
|
||||
);
|
||||
29
oversampling/WDL/eel2/scripts/gfx_test_defer.eel
Normal file
29
oversampling/WDL/eel2/scripts/gfx_test_defer.eel
Normal file
@@ -0,0 +1,29 @@
|
||||
gfx_init("vis",1024,768);
|
||||
|
||||
gfx_clear=-1;
|
||||
|
||||
function frame()
|
||||
(
|
||||
c=gfx_getchar();
|
||||
c == ' ' ? (mode += 1) >= 2 ? mode=0;
|
||||
t=time_precise();
|
||||
zsc = 0.01*cos(t*0.73);
|
||||
// gfx_x=gfx_y=0; gfx_blurto(gfx_w,gfx_h);
|
||||
gfx_blit(-1,0,0.3*(sin(t*0.3)^2),gfx_w*zsc,gfx_h*zsc, gfx_w*(1-2*zsc),gfx_h*(1-2*zsc), 0,0,gfx_w,gfx_h);
|
||||
gfx_r=(cos(t)+1.0)*0.5;
|
||||
gfx_g=(cos(t*1.74)+1.0)*0.5;
|
||||
gfx_b=(cos(t*1.2+0.56)+1.0)*0.5;
|
||||
gfx_a=0.15;
|
||||
sz=gfx_w*0.03;
|
||||
loop(20,
|
||||
mode == 1 ?
|
||||
gfx_circle(rand(gfx_w-sz),rand(gfx_h-sz),sz,1) :
|
||||
gfx_rect(rand(gfx_w-sz),rand(gfx_h-sz),sz,sz);
|
||||
);
|
||||
|
||||
|
||||
gfx_update();
|
||||
c>=0 && c != 27 ? defer("frame()");
|
||||
);
|
||||
|
||||
frame();
|
||||
208
oversampling/WDL/eel2/scripts/gpx_edit.eel
Normal file
208
oversampling/WDL/eel2/scripts/gpx_edit.eel
Normal file
@@ -0,0 +1,208 @@
|
||||
// does not work for all .gpx files
|
||||
// writes to output on every mouseup after edit
|
||||
// move points with mouse, alt+click to delete
|
||||
// click/drag to pan
|
||||
// mousewheel to zoom
|
||||
|
||||
tab = 10000;
|
||||
tabsz = 0;
|
||||
|
||||
is_dirty = 0;
|
||||
circle_size = 5;
|
||||
|
||||
function scale(v) global() ( (v - this.min) / (this.max-this.min) );
|
||||
function unscale(v) global() ( v * (this.max-this.min) + this.min);
|
||||
function zoom(sc) global() local(c h) (
|
||||
h = (this.max - this.min) * sc;
|
||||
c = (this.max + this.min) * .5;
|
||||
this.max = c + h*.5;
|
||||
this.min = c - h*.5;
|
||||
);
|
||||
function include(v) global() ( this.min = min(v,this.min); this.max = max(v,this.max); );
|
||||
|
||||
function scroll(amt) global() ( amt *= (this.max-this.min); this.max += amt; this.min += amt; );
|
||||
function zoom_view(sc) ( v_lon.zoom(sc); v_lat.zoom(sc); );
|
||||
function scroll_view(dx, dy) ( v_lat.scroll(-dy/gfx_h); v_lon.scroll(-dx/gfx_w); );
|
||||
|
||||
function hit_test(x,y,p) global(tab tabsz circle_size gfx_w gfx_h v_lat.scale v_lon.scale) local(p hit) (
|
||||
hit = -1;
|
||||
while (p < tabsz && hit < 0) (
|
||||
sqr(v_lat.scale(tab[p*2+1])*gfx_h-y)+sqr(v_lon.scale(tab[p*2])*gfx_w-x) < circle_size*circle_size ? hit = p;
|
||||
p += 1;
|
||||
);
|
||||
hit
|
||||
);
|
||||
|
||||
function linearize(p,sz, slon, slat, elon, elat, rev) local(x) global()
|
||||
(
|
||||
rev ? ( x=slon; slon=elon; elon=x; x=slat; slat=elat; elat=x; );
|
||||
elon = (elon - slon) / sz;
|
||||
elat = (elat - slat) / sz;
|
||||
loop(sz,
|
||||
p[0] = slon;
|
||||
p[1] = slat;
|
||||
slon += elon;
|
||||
slat += elat;
|
||||
p += 2;
|
||||
);
|
||||
);
|
||||
|
||||
function make_lowpass(f filtsize filtpos) global() local(windowpos sincpos x)
|
||||
(
|
||||
x = 0;
|
||||
loop(filtsize,
|
||||
x == filtsize/2 ? (
|
||||
f[x] = 1.0;
|
||||
) : (
|
||||
windowpos = 2 * x * $pi / filtsize;
|
||||
sincpos = filtpos * $pi * (x - filtsize/2);
|
||||
|
||||
// blackman-harris * window
|
||||
f[x] = (0.35875 - 0.48829 * cos(windowpos) + 0.14128 * cos(2*windowpos) - 0.01168 * cos(3*windowpos)) * sin(sincpos) / sincpos;
|
||||
);
|
||||
x+=1;
|
||||
);
|
||||
);
|
||||
|
||||
function lowpass() local(src sz i j lpf_pos v sx sy filt p) global(tab tabsz)
|
||||
(
|
||||
lpf_pos>0.001 ? lpf_pos *= 0.95 : lpf_pos = 0.9;
|
||||
sz = 64;
|
||||
src = tab+tabsz*2 + sz*4 + 1024;
|
||||
filt = src + tabsz*2 + sz*4 + 1024;
|
||||
make_lowpass(filt, sz, lpf_pos);
|
||||
memcpy(src, tab, tabsz*2);
|
||||
i = src;
|
||||
j = src + tabsz*2;
|
||||
loop(sz/2,
|
||||
memcpy(i-2,i,2);
|
||||
memcpy(j,j-2,2);
|
||||
j+=2;
|
||||
i-=2;
|
||||
);
|
||||
i = 0;
|
||||
loop(tabsz,
|
||||
tab[i*2] != 10000 ? (
|
||||
p = j = sx = sy = 0;
|
||||
loop(sz,
|
||||
v = src[(i+j-sz/2)*2];
|
||||
v != 10000 ? (
|
||||
p += filt[j];
|
||||
sx += v * filt[j];
|
||||
sy += src[(i+j-sz/2)*2 + 1] * filt[j];
|
||||
);
|
||||
j+=1;
|
||||
);
|
||||
tab[i*2] = sx/p;
|
||||
tab[i*2+1] = sy/p;
|
||||
);
|
||||
i+=1;
|
||||
);
|
||||
|
||||
);
|
||||
|
||||
function do_file(srcfn, destfn) local(fp fpout p lat lon skipping) (
|
||||
(fp = fopen(srcfn,"r")) > 0 ? (
|
||||
destfn < 0 || (fpout = fopen(destfn,"w")) > 0 ? (
|
||||
p = tab;
|
||||
skipping = 0;
|
||||
while (fgets(fp,#line)) (
|
||||
match("%s<trkpt lat=\"%f\" lon=\"%f\">%s",#line,#lead,lat,lon,#trail) ? (
|
||||
destfn < 0 ? ( tabsz+=1; v_lat.include(p[1] = -lat); v_lon.include(p[0] = lon);) :
|
||||
( !(skipping = p[0] == 10000) ? fprintf(fpout,"%s<trkpt lat=\"%.7f\" lon=\"%.7f\">%s",#lead,-p[1],p[0],#trail); );
|
||||
p += 2;
|
||||
) : destfn >= 0 ? ( skipping ? ( match("*</trkpt>*",#line) ? skipping = 0; ) : fwrite(fpout,#line,0) );
|
||||
);
|
||||
destfn >= 0 ? fclose(fpout);
|
||||
);
|
||||
fclose(fp);
|
||||
);
|
||||
);
|
||||
|
||||
|
||||
function run() (
|
||||
mouse_wheel ? ( zoom_view(mouse_wheel < 0 ? 1.1 : 1/1.1); mouse_wheel = 0;);
|
||||
(mouse_cap&1)? (
|
||||
!(last_mouse_cap & 1) ? (
|
||||
cap_mode >= 0 && (mouse_cap&4) ? (
|
||||
tmp = hit_test(mouse_x,mouse_y,0);
|
||||
tmp >= 0 ? (
|
||||
tmp < cap_mode ? (
|
||||
cap_cnt = cap_mode+cap_cnt - tmp;
|
||||
cap_mode = tmp;
|
||||
) : (
|
||||
cap_cnt = max(cap_mode+cap_cnt, tmp) - cap_mode;
|
||||
);
|
||||
) : cap_mode = tmp;
|
||||
) : (
|
||||
cap_mode = hit_test(mouse_x,mouse_y,0);
|
||||
cap_mode >= 0 ? (
|
||||
cap_cnt = 1;
|
||||
while (hit_test(mouse_x,mouse_y,cap_mode+cap_cnt) >= 0) ( cap_cnt += 1; );
|
||||
);
|
||||
);
|
||||
cap_start_lon = v_lon.unscale(mouse_x/gfx_w);
|
||||
cap_start_lat = v_lat.unscale(mouse_y/gfx_h);
|
||||
) : cap_mode >= 0 ? (
|
||||
cap_cnt > 1 && (mouse_cap&4) ? (
|
||||
linearize(tab + cap_mode*2,cap_cnt, cap_start_lon, cap_start_lat,
|
||||
v_lon.unscale(mouse_x/gfx_w), v_lat.unscale(mouse_y/gfx_h),
|
||||
mouse_cap&8);
|
||||
) : (
|
||||
tab[cap_mode*2] = v_lon.unscale(mouse_x/gfx_w);
|
||||
tab[cap_mode*2+1] = v_lat.unscale(mouse_y/gfx_h);
|
||||
);
|
||||
is_dirty = 1;
|
||||
) : scroll_view(mouse_x-last_mouse_x,mouse_y-last_mouse_y);
|
||||
) : (
|
||||
(last_mouse_cap & 1) && (last_mouse_cap & 16) && cap_mode >= 0 ? (
|
||||
tab[cap_mode*2] = 10000;
|
||||
is_dirty = 1;
|
||||
);
|
||||
is_dirty ? ( do_file(argv[1], argv[2]); is_dirty = 0; );
|
||||
);
|
||||
last_mouse_cap = mouse_cap;
|
||||
last_mouse_x = mouse_x;
|
||||
last_mouse_y = mouse_y;
|
||||
|
||||
p = tab;
|
||||
hadprev = dist = 0;
|
||||
loop(tabsz,
|
||||
p[0] != 10000 ? (
|
||||
x = v_lon.scale(p[0])*gfx_w;
|
||||
y = v_lat.scale(p[1])*gfx_h;
|
||||
hadprev ? (
|
||||
gfx_set(0,.5,.7);
|
||||
gfx_line(v_lon.scale(llon)*gfx_w,v_lat.scale(llat)*gfx_h,x,y);
|
||||
dist += sqrt(sqr((p[0] - llon) * cos(llat*$pi/180.0)*69.172) + sqr((p[1] - llat)*60));
|
||||
);
|
||||
cap_mode == (p-tab)/2 ? gfx_set(1,0,1) : gfx_set(0,1,0);
|
||||
gfx_circle(x,y,circle_size);
|
||||
llon = p[0];
|
||||
llat = p[1];
|
||||
hadprev = 1;
|
||||
);
|
||||
p += 2;
|
||||
);
|
||||
|
||||
gfx_x=gfx_y=0;
|
||||
gfx_set(1,1,0);
|
||||
gfx_printf("distance (approx) %.2f mi\n",dist);
|
||||
|
||||
gfx_update();
|
||||
c = gfx_getchar();
|
||||
c == 'l' ? ( lowpass(); is_dirty = 1; );
|
||||
c >= 0 && c != 27 ? defer("run()");
|
||||
);
|
||||
|
||||
argc < 2 ? printf("Usage: %s file.gpx output.gpx\n",argv[0]) : (
|
||||
v_lat.min = v_lon.min = 100000;
|
||||
v_lat.max = v_lon.max = -100000;
|
||||
do_file(argv[1],-1);
|
||||
tabsz > 0 ? (
|
||||
zoom_view(1.3);
|
||||
gfx_init("gpx edit",1024,768);
|
||||
defer("run()");
|
||||
) : printf("Error: %s has no <trkpt lines matching\n",argv[1]);
|
||||
);
|
||||
|
||||
180
oversampling/WDL/eel2/scripts/httpd.eel
Normal file
180
oversampling/WDL/eel2/scripts/httpd.eel
Normal file
@@ -0,0 +1,180 @@
|
||||
// asynchronous HTTP server in EEL
|
||||
|
||||
|
||||
function httpd.init(port, maxcon, table, stringoffs, wwwroot) global()
|
||||
(
|
||||
this.maxcon = maxcon;
|
||||
this.tab = table;
|
||||
this.port = port;
|
||||
this.stringtab = stringoffs;
|
||||
this.string_recsz = 2;
|
||||
this.recsz = 3;
|
||||
#this.wwwroot = wwwroot;
|
||||
);
|
||||
|
||||
function httpd.getrecval(conid, parm) global()
|
||||
(
|
||||
conid >= 0 && conid < this.maxcon ? (
|
||||
parm == 'sock' ? this.tab + conid*this.recsz + 0 : // socket
|
||||
parm == 'st' ? this.tab + conid*this.recsz + 1 : // state
|
||||
parm == 'fh' ? this.tab + conid*this.recsz + 2 : // file handle
|
||||
0)
|
||||
: 0
|
||||
);
|
||||
|
||||
function httpd.set(conid, parm, value) local(x) global()
|
||||
(
|
||||
x = httpd.getrecval(conid,parm);
|
||||
x>=0 ? x[]=value;
|
||||
);
|
||||
function httpd.get(conid, parm) local(x) global()
|
||||
(
|
||||
x=httpd.getrecval(conid,parm);
|
||||
x>=0?x[];
|
||||
);
|
||||
function httpd.getbuf(conid, w) global()
|
||||
(
|
||||
conid >=0 && conid < this.maxcon ? this.stringtab + this.string_recsz*conid + w : -1;
|
||||
);
|
||||
function httpd.close(conid) global()
|
||||
(
|
||||
conid >=0 && conid < this.maxcon ?
|
||||
(
|
||||
tcp_close(httpd.get(conid,'sock'));
|
||||
fclose(httpd.get(conid,'fh'));
|
||||
httpd.set(conid,'sock',0);
|
||||
httpd.set(conid,'fh',0);
|
||||
);
|
||||
);
|
||||
function httpd.file_for_req(req, response) local(fn,fp) global() (
|
||||
!strcmp(req,"") || !strcmp(req,"/") ? req = "/index.html";
|
||||
|
||||
str_getchar(req,0) == '/' &&
|
||||
!match("*..*",req) &&
|
||||
(fp=fopen(fn = strcat(#=#this.wwwroot,req),"rb")) > 0 ?
|
||||
(
|
||||
fseek(fp,0,1);
|
||||
printf("GET %s -- 200: %s\n",req,fn);
|
||||
strcat(response,sprintf(#, "HTTP/1.1 200 OK\r\n"
|
||||
"Content-length: %d\r\n"
|
||||
"Content-type: text/html\r\n"
|
||||
"\r\n",
|
||||
ftell(fp)));
|
||||
fseek(fp,0,-1);
|
||||
fp;
|
||||
) : (
|
||||
printf("GET %s -- 404\n",req);
|
||||
|
||||
fn = "The file specified could not be found.";
|
||||
strcat(response,sprintf(#, "HTTP/1.1 404 NOT FOUND\r\n"
|
||||
"Content-length: %d\r\n"
|
||||
"Content-type: text/plain\r\n"
|
||||
"\r\n"
|
||||
"%s", strlen(fn),fn));
|
||||
0;
|
||||
);
|
||||
);
|
||||
|
||||
// run input and output buffers
|
||||
function httpd.runcon(idx) local(sock,x,str,rv,buffers) global() (
|
||||
rv=0;
|
||||
sock = httpd.get(idx,'sock');
|
||||
sock > 0 ?
|
||||
(
|
||||
x=tcp_recv(sock,str=#);
|
||||
x<0 ? (
|
||||
httpd.close(idx);
|
||||
) : (
|
||||
buffers=httpd.getbuf(idx,0);
|
||||
x>0 ? strcat(buffers,str);
|
||||
rv+=x;
|
||||
|
||||
strlen(buffers+1)>0 ?
|
||||
(
|
||||
(x=tcp_send(sock,buffers+1)) > 0 ?
|
||||
(
|
||||
rv+=1;
|
||||
str_delsub(buffers+1.1,0,x);
|
||||
);
|
||||
);
|
||||
);
|
||||
);
|
||||
rv;
|
||||
);
|
||||
|
||||
|
||||
function httpd.run() local(sock, x, i, str, rv, t,hdrs,httpdver) global() (
|
||||
str=#;
|
||||
hdrs=#;
|
||||
rv=0;
|
||||
sock=tcp_listen(this.port,"",str);
|
||||
sock > 0 ?
|
||||
(
|
||||
i=0;
|
||||
while (i < this.maxcon && httpd.get(i,'sock')) ( i += 1; );
|
||||
i < this.maxcon ? (
|
||||
tcp_set_block(sock,0);
|
||||
httpd.set(i,'sock',sock);
|
||||
httpd.set(i,'st',0);
|
||||
|
||||
x=0;
|
||||
loop(this.string_recsz, strcpy(httpd.getbuf(i,x), ""); x+=1; );
|
||||
printf("httpd.run(): connection from '%s'\n",str);
|
||||
rv+=1;
|
||||
|
||||
) : (
|
||||
printf("httpd.run(): dropping connect from '%s', slots full\n",str);
|
||||
tcp_close(x);
|
||||
);
|
||||
);
|
||||
|
||||
i=0;
|
||||
while (i < this.maxcon)
|
||||
(
|
||||
this.httpd.runcon(i) ?
|
||||
(
|
||||
t = httpd.getbuf(i,0);
|
||||
this.httpd.get(i,'st') == 0 ?
|
||||
(
|
||||
match("GET %S HTTP/1.%1d%S",t,str,httpdver,hdrs) &&
|
||||
str_getchar(hdrs,0)=='\r' && str_getchar(hdrs,1)=='\n' &&
|
||||
!strcmp(strcpy_substr(#,hdrs,-4),"\r\n\r\n")
|
||||
?
|
||||
(
|
||||
httpd.set(i,'st',1 |
|
||||
((httpdver==0 || matchi("\r\nConnection:*close\r\n",hdrs))?2:0)
|
||||
);
|
||||
|
||||
httpd.set(i,'fh',httpd.file_for_req(str,t+1));
|
||||
);
|
||||
);
|
||||
|
||||
httpd.get(i,'fh') && !strlen(t+1) ? fread(httpd.get(i,'fh'),t+1,4096);
|
||||
|
||||
httpd.get(i,'st') == 3 ? (
|
||||
strlen(t+1) == 0 ? (
|
||||
httpd.close(i);
|
||||
printf("sent data, closing\n");
|
||||
);
|
||||
);
|
||||
|
||||
rv+=1;
|
||||
);
|
||||
i+=1;
|
||||
);
|
||||
|
||||
|
||||
rv;
|
||||
);
|
||||
|
||||
argc != 3 || strlen(argv[1])<1 || !match("%d",argv[2],port) ? (
|
||||
printf("Usage: \n\t%s www_root port\n",argv[0]);
|
||||
) : (
|
||||
srv.httpd.init(port, 100, 100000, 10000, argv[1]);
|
||||
// string [conidx] = send buffe
|
||||
while(1)
|
||||
(
|
||||
srv.httpd.run() || Sleep(10);
|
||||
);
|
||||
);
|
||||
|
||||
10
oversampling/WDL/eel2/scripts/pproc_test.eel
Normal file
10
oversampling/WDL/eel2/scripts/pproc_test.eel
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
<? x=37; ?>
|
||||
<? printf("y=%d;",x); ?>
|
||||
|
||||
<? _suppress += 1; ?>
|
||||
|
||||
printf("this will not get compiled\n");
|
||||
|
||||
<? _suppress -= 1; ?>
|
||||
printf("apparently y is now %d but x is %d\n",y,x);
|
||||
17
oversampling/WDL/eel2/scripts/sinewave_text.eel
Normal file
17
oversampling/WDL/eel2/scripts/sinewave_text.eel
Normal file
@@ -0,0 +1,17 @@
|
||||
width = 80;
|
||||
lx=-1;
|
||||
loop(1000000,
|
||||
x = ((1+sin(pos))*0.5 * width)|0;
|
||||
lx >= -1 && lx!=x ? (
|
||||
loop(min(x,lx), printf(" "));
|
||||
loop(abs(x-lx), printf("*"));
|
||||
loop(width-max(x,lx), printf(" "));
|
||||
) : (
|
||||
loop(x, printf(" "));
|
||||
printf("*");
|
||||
loop(width-1-x, printf(" "));
|
||||
);
|
||||
lx=x;
|
||||
printf("\n");
|
||||
pos += 0.25 + sin(pos*0.32)*0.2;
|
||||
);
|
||||
73
oversampling/WDL/eel2/scripts/space.eel
Normal file
73
oversampling/WDL/eel2/scripts/space.eel
Normal file
@@ -0,0 +1,73 @@
|
||||
|
||||
|
||||
gfx_init("space",640,480);
|
||||
|
||||
function enemylist.init(buf, rows, cols, maxwid) global()
|
||||
(
|
||||
this.buf = buf;
|
||||
this.rows=rows;
|
||||
this.cols=cols;
|
||||
this.maxwid = maxwid;
|
||||
loop(rows*cols, buf[]=1; buf += 1; );
|
||||
);
|
||||
|
||||
|
||||
function enemylist.draw(pos, vpos, destextent*)
|
||||
local(rad,buf,xpos,ypos,dxpos)
|
||||
global(gfx_w,gfx_h,gfx_r,gfx_g,gfx_b,gfx_a)
|
||||
(
|
||||
gfx_r=gfx_a=1;
|
||||
gfx_g=gfx_b=0;
|
||||
dxpos = this.maxwid/this.cols*gfx_w;
|
||||
buf=this.buf;
|
||||
rad = dxpos*0.3;
|
||||
destextent.right = 0;
|
||||
destextent.bottom = 0;
|
||||
destextent.left=2^20;
|
||||
destextent.top=2^20;
|
||||
|
||||
ypos=dxpos*0.5 + gfx_h*vpos;
|
||||
loop(this.rows,
|
||||
xpos=pos*gfx_w + dxpos*0.5;
|
||||
loop(this.cols,
|
||||
buf[] ? (
|
||||
destextent.left = min(destextent.left,xpos-rad);
|
||||
destextent.right = max(destextent.right,xpos+rad);
|
||||
destextent.top = min(destextent.top,ypos-rad);
|
||||
destextent.bottom = max(destextent.bottom,ypos+rad);
|
||||
gfx_circle(xpos,ypos,rad);
|
||||
);
|
||||
xpos += dxpos;
|
||||
buf += 1;
|
||||
);
|
||||
ypos += dxpos;
|
||||
);
|
||||
);
|
||||
|
||||
|
||||
enemylist.init(0, 4, 8, 0.8);
|
||||
|
||||
|
||||
last_time = time_precise();
|
||||
enemy_pos = 0;
|
||||
enemy_vpos = 0;
|
||||
enemy_vel = 0.05;
|
||||
while ((curchar = gfx_getchar()) != 27)
|
||||
(
|
||||
now = time_precise();
|
||||
enemylist.draw(enemy_pos, enemy_vpos, area);
|
||||
enemy_vel > 0 ? (
|
||||
area.right >= gfx_w ? ( enemy_vel = -enemy_vel; enemy_vpos += abs(enemy_vel); enemy_vel *= 1.3; );
|
||||
) : (
|
||||
area.left <= 0 ? ( enemy_vel = -enemy_vel; enemy_vpos += abs(enemy_vel); enemy_vel *= 1.3; );
|
||||
);
|
||||
|
||||
enemy_pos += (now-last_time)*enemy_vel;
|
||||
|
||||
|
||||
|
||||
|
||||
last_time = now;
|
||||
sleep(33);
|
||||
gfx_update();
|
||||
);
|
||||
22
oversampling/WDL/eel2/scripts/test_a.eel
Normal file
22
oversampling/WDL/eel2/scripts/test_a.eel
Normal file
@@ -0,0 +1,22 @@
|
||||
sum=0;
|
||||
a= 1;
|
||||
b = .1;
|
||||
c= .2;
|
||||
d = .5;
|
||||
e = 4;
|
||||
f = -0.2;
|
||||
g = 0.3;
|
||||
h = .37;
|
||||
|
||||
loop(62000,
|
||||
i = 0;
|
||||
sum=0.0;
|
||||
loop(8192,
|
||||
sum += i*(3+ a * b + c*d + e * (f - b*(-c) + g*(e-g*(-g)*g)) );
|
||||
sum2 += (a*b)+(a*b)+((a*b)*((b*c)*((h*i)*(f*g))));
|
||||
i += 0.001;
|
||||
i2+=1;
|
||||
);
|
||||
);
|
||||
printf("sum error %.18f %.18f\n", sum - 245333.476966294896556064, sum2 - 101488440.519564077258110046);
|
||||
printf("sum error per inst %.18f %.18f\n", (sum - 245333.476966294896556064) / i, (sum2 - 101488440.519564077258110046)/i2);
|
||||
35
oversampling/WDL/eel2/scripts/test_or64.eel
Normal file
35
oversampling/WDL/eel2/scripts/test_or64.eel
Normal file
@@ -0,0 +1,35 @@
|
||||
v1 = 2^50;
|
||||
v2 = 2^50;
|
||||
z=0;
|
||||
|
||||
(floor(v1)/v2) !== 1 ? printf("fail test floor\n");
|
||||
(floor(v1)/(2^50)) !== 1 ? printf("fail test floor/const\n");
|
||||
(floor(2^50)/v2) !== 1 ? printf("fail test floor-const\n");
|
||||
(floor(2^50)/(2^50)) !== 1 ? printf("fail test floor-const/const\n");
|
||||
(floor(v1+1)/(v2+1)) !== 1 ? printf("fail test floor+1\n");
|
||||
(floor(v1+1)/(2^50+1)) !== 1 ? printf("fail test floor+1/const\n");
|
||||
(floor(2^50 + 1)/(v2+1)) !== 1 ? printf("fail test floor-const+1");
|
||||
(floor(2^50 + 1)/(2^50 + 1)) !== 1 ? printf("fail test floor-const+1/const\n");
|
||||
|
||||
((v1|0)/v2) !== 1 ? printf("fail test |0\n");
|
||||
((v1|0)/(2^50)) !== 1 ? printf("fail test |0/const\n");
|
||||
(((2^50)|0)/v2) !== 1 ? printf("fail test const|0\n");
|
||||
(((2^50)|0)/(2^50)) !== 1 ? printf("fail test const|0/const\n");
|
||||
((v1|1)/(v2+1)) !== 1 ? printf("fail test |1\n");
|
||||
((v1|1)/(2^50+1)) !== 1 ? printf("fail test |1/const\n");
|
||||
(((2^50)|1)/(v2 + 1)) !== 1 ? printf("fail test const|1\n");
|
||||
(((2^50)|1)/(2^50 + 1)) !== 1 ? printf("fail test const|1/const\n");
|
||||
|
||||
((v1~1)/(v2+1)) !== 1 ? printf("fail test ~1\n");
|
||||
((v1~1)/(2^50+1)) !== 1 ? printf("fail test ~1/const\n");
|
||||
(((2^50)~1)/(v2 + 1)) !== 1 ? printf("fail test const~1\n");
|
||||
(((2^50)~1)/(2^50 + 1)) !== 1 ? printf("fail test const~1/const\n");
|
||||
|
||||
c = v1; c |= v1;
|
||||
c !== v1 ? printf("fail test |= \n");
|
||||
c = v1; c |= 0;
|
||||
c !== v1 ? printf("fail test |= 0\n");
|
||||
c = v1; c &= v1;
|
||||
c !== v1 ? printf("fail test &=\n");
|
||||
c = v1; c ~= z;
|
||||
c !== v1 ? printf("fail test ~= \n");
|
||||
2186
oversampling/WDL/eel2/y.tab.c
Normal file
2186
oversampling/WDL/eel2/y.tab.c
Normal file
File diff suppressed because it is too large
Load Diff
117
oversampling/WDL/eel2/y.tab.h
Normal file
117
oversampling/WDL/eel2/y.tab.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/* A Bison parser, made by GNU Bison 2.3. */
|
||||
|
||||
/* Skeleton interface for Bison's Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
/* Tokens. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
/* Put the tokens into the symbol table, so that GDB and other debuggers
|
||||
know about them. */
|
||||
enum yytokentype {
|
||||
VALUE = 258,
|
||||
IDENTIFIER = 259,
|
||||
TOKEN_SHL = 260,
|
||||
TOKEN_SHR = 261,
|
||||
TOKEN_LTE = 262,
|
||||
TOKEN_GTE = 263,
|
||||
TOKEN_EQ = 264,
|
||||
TOKEN_EQ_EXACT = 265,
|
||||
TOKEN_NE = 266,
|
||||
TOKEN_NE_EXACT = 267,
|
||||
TOKEN_LOGICAL_AND = 268,
|
||||
TOKEN_LOGICAL_OR = 269,
|
||||
TOKEN_ADD_OP = 270,
|
||||
TOKEN_SUB_OP = 271,
|
||||
TOKEN_MOD_OP = 272,
|
||||
TOKEN_OR_OP = 273,
|
||||
TOKEN_AND_OP = 274,
|
||||
TOKEN_XOR_OP = 275,
|
||||
TOKEN_DIV_OP = 276,
|
||||
TOKEN_MUL_OP = 277,
|
||||
TOKEN_POW_OP = 278,
|
||||
STRING_LITERAL = 279,
|
||||
STRING_IDENTIFIER = 280
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
#define VALUE 258
|
||||
#define IDENTIFIER 259
|
||||
#define TOKEN_SHL 260
|
||||
#define TOKEN_SHR 261
|
||||
#define TOKEN_LTE 262
|
||||
#define TOKEN_GTE 263
|
||||
#define TOKEN_EQ 264
|
||||
#define TOKEN_EQ_EXACT 265
|
||||
#define TOKEN_NE 266
|
||||
#define TOKEN_NE_EXACT 267
|
||||
#define TOKEN_LOGICAL_AND 268
|
||||
#define TOKEN_LOGICAL_OR 269
|
||||
#define TOKEN_ADD_OP 270
|
||||
#define TOKEN_SUB_OP 271
|
||||
#define TOKEN_MOD_OP 272
|
||||
#define TOKEN_OR_OP 273
|
||||
#define TOKEN_AND_OP 274
|
||||
#define TOKEN_XOR_OP 275
|
||||
#define TOKEN_DIV_OP 276
|
||||
#define TOKEN_MUL_OP 277
|
||||
#define TOKEN_POW_OP 278
|
||||
#define STRING_LITERAL 279
|
||||
#define STRING_IDENTIFIER 280
|
||||
|
||||
|
||||
|
||||
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
typedef int YYSTYPE;
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
|
||||
typedef struct YYLTYPE
|
||||
{
|
||||
int first_line;
|
||||
int first_column;
|
||||
int last_line;
|
||||
int last_column;
|
||||
} YYLTYPE;
|
||||
# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYLTYPE_IS_DECLARED 1
|
||||
# define YYLTYPE_IS_TRIVIAL 1
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user