[PD-cvs] externals/pdp/scaf/compiler Makefile, 1.2, 1.3 kernel.scaf, 1.2, 1.3 optim.rules, 1.2, 1.3 scafc, 1.2, 1.3 scafc.pl, 1.2, 1.3 scafmacro.s, 1.2, 1.3
Hans-Christoph Steiner
eighthave at users.sourceforge.net
Fri Dec 16 02:05:39 CET 2005
Update of /cvsroot/pure-data/externals/pdp/scaf/compiler
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6756/scaf/compiler
Added Files:
Makefile kernel.scaf optim.rules scafc scafc.pl scafmacro.s
Log Message:
checking in pdp 0.12.4 from http://zwizwa.fartit.com/pd/pdp/pdp-0.12.4.tar.gz
--- NEW FILE: scafmacro.s ---
# Pure Data Packet - scaf assembler macros.
# Copyright (c) by Tom Schouten <pdp at zzz.kotnet.org>
#
# 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 of the License, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# this file contains pure asm macros. it is to be included before assembly
# after scaforth.pl has processed the .scaf file
# *************************** JMP CALL RET **************************************
# j c r
.macro j address
jmp \address
.endm
.macro c address
call \address
.endm
.macro r
ret
.endm
# *************************** CA CELL ACCESS MACROS *****************************
# dropldTL - dropldBR
# shift / load rectangle macros:
# shift rectangle horizontal
# result is in reg1
.macro shift reg1 reg2 count
psllq $(16-\count), \reg1
psrlq $(16+\count), \reg2
psrlq $32, \reg1
psllq $32, \reg2
por \reg2, \reg1
.endm
.macro ldtop reg1 reg2
movq (%edi), \reg1
movq 8(%edi), \reg2
.endm
.macro ldcenter reg1 reg2
movq 8(%edi), \reg1
movq 16(%edi), \reg2
.endm
.macro ldbottom reg1 reg2
movq 16(%edi), \reg1
movq 24(%edi), \reg2
.endm
# dropld from top row
# dropld the top left square
.macro dropldTL
ldtop %mm0, %mm1
shift %mm0, %mm1, -1
.endm
# dropld the top mid square
.macro dropldTM
ldtop %mm0, %mm1
shift %mm0, %mm1, 0
.endm
# dropld the top right square
.macro dropldTR
ldtop %mm0, %mm1
shift %mm0, %mm1, 1
.endm
# dropld from center row
# dropld the mid left square
.macro dropldML
ldcenter %mm0, %mm1
shift %mm0, %mm1, -1
.endm
# dropld the mid mid square
.macro dropldMM
ldcenter %mm0, %mm1
shift %mm0, %mm1, 0
.endm
# dropld the mid right square
.macro dropldMR
ldcenter %mm0, %mm1
shift %mm0, %mm1, 1
.endm
# dropld from bottom row
# dropld the bottom left square
.macro dropldBL
ldbottom %mm0, %mm1
shift %mm0, %mm1, -1
.endm
# dropld the bottom mid square
.macro dropldBM
ldbottom %mm0, %mm1
shift %mm0, %mm1, 0
.endm
# dropld the bottom right square
.macro dropldBR
ldbottom %mm0, %mm1
shift %mm0, %mm1, 1
.endm
# *************************** CA STACK MANIP MACROS *****************************
# these are the only asm macros that have a stack effect other than
# just replacing the TOS
#
# dup drop dropdup swap nip dropover
.macro dup
lea -8(%esi), %esi
movq %mm0, (%esi)
.endm
.macro drop
movq (%esi), %mm0
lea 8(%esi), %esi
.endm
.macro dropdup
movq (%esi), %mm0
.endm
.macro nipdup
movq %mm0, (%esi)
.endm
.macro swap
movq (%esi), %mm1
movq %mm0, (%esi)
movq %mm1, %mm0
.endm
.macro nip
lea 8(%esi), %esi
.endm
.macro dropover
movq 8(%esi), %mm0
.endm
# *************************** CA BOOLEAN LOGIC MACROS *****************************
# overxor overand overor not
.macro overxor
pxor (%esi), %mm0
.endm
.macro overand
pand (%esi), %mm0
.endm
.macro overor
por (%esi), %mm0
.endm
.macro not
pxor %mm3, %mm0
.endm
# *************************** CONSTANTS *****************************
# dropzero dropone
.macro dropzero
pxor %mm0, %mm0
.endm
.macro dropone
pcmpeqw %mm0, %mm0
.endm
# *************************** 4 BIT REG ACCESS ******************************
# dupsta0 - dupsta4 droplda0 - droplda4
# store bit in accumulator
# bit store
.macro dupsta0
movq %mm0, %mm4
.endm
.macro dupsta1
movq %mm0, %mm5
.endm
.macro dupsta2
movq %mm0, %mm6
.endm
.macro dupsta3
movq %mm0, %mm7
.endm
# load bit from accumulator
.macro droplda0
movq %mm4, %mm0
.endm
.macro droplda1
movq %mm5, %mm0
.endm
.macro droplda2
movq %mm6, %mm0
.endm
.macro droplda3
movq %mm7, %mm0
.endm
# *************************** LOAD 4 BIT CONSTANT IN REG ******************************
# a0000 - a1111
.macro ldbit0 value
.ifeq \value
movq %mm1, %mm4
.else
movq %mm3, %mm4
.endif
.endm
.macro ldbit1 value
.ifeq \value
movq %mm1, %mm5
.else
movq %mm3, %mm5
.endif
.endm
.macro ldbit2 value
.ifeq \value
movq %mm1, %mm6
.else
movq %mm3, %mm6
.endif
.endm
.macro ldbit3 value
.ifeq \value
movq %mm1, %mm7
.else
movq %mm3, %mm7
.endif
.endm
.macro ldbin b3 b2 b1 b0
pxor %mm1, %mm1
ldbit0 \b0
ldbit1 \b1
ldbit2 \b2
ldbit3 \b3
.endm
.macro a0000
ldbin 0 0 0 0
.endm
.macro a0001
ldbin 0 0 0 1
.endm
.macro a0010
ldbin 0 0 1 0
.endm
.macro a0011
ldbin 0 0 1 1
.endm
.macro a0100
ldbin 0 1 0 0
.endm
.macro a0101
ldbin 0 1 0 1
.endm
.macro a0110
ldbin 0 1 1 0
.endm
.macro a0111
ldbin 0 1 1 1
.endm
.macro a1000
ldbin 1 0 0 0
.endm
.macro a1001
ldbin 1 0 0 1
.endm
.macro a1010
ldbin 1 0 1 0
.endm
.macro a1011
ldbin 1 0 1 1
.endm
.macro a1100
ldbin 1 1 0 0
.endm
.macro a1101
ldbin 1 1 0 1
.endm
.macro a1110
ldbin 1 1 1 0
.endm
.macro a1111
ldbin 1 1 1 1
.endm
# *************************** 4 BIT COUNTER ******************************
# adds TOS to bit of counter and returns carry in TOS
#
# adb0 - adb3
.macro adb0
movq %mm4, %mm2
pxor %mm0, %mm4
pand %mm2, %mm0
.endm
.macro adb1
movq %mm5, %mm2
pxor %mm0, %mm5
pand %mm2, %mm0
.endm
.macro adb2
movq %mm6, %mm2
pxor %mm0, %mm6
pand %mm2, %mm0
.endm
.macro adb3
movq %mm7, %mm2
pxor %mm0, %mm7
pand %mm2, %mm0
.endm
# *************************** ACCUMULATOR TESTS ***************************
# dropisnonzero4 - dropisnonzero1
.macro dropisnonzero4
movq %mm4, %mm0
por %mm5, %mm0
por %mm6, %mm0
por %mm7, %mm0
.endm
.macro dropisnonzero3
movq %mm4, %mm0
por %mm5, %mm0
por %mm6, %mm0
.endm
.macro dropisnonzero2
movq %mm4, %mm0
por %mm5, %mm0
.endm
.macro dropisnonzero1
movq %mm4, %mm0
.endm
# *************************** REGISTER SHIFT OPERATIONS **********************
# shift and leave shifted out byte on stack
# rotate trough top of stack
.macro dropshiftright
movq %mm4, %mm0
movq %mm5, %mm4
movq %mm6, %mm5
movq %mm7, %mm6
pxor %mm7, %mm7
.endm
.macro dropshiftleft
movq %mm7, %mm0
movq %mm6, %mm7
movq %mm5, %mm6
movq %mm4, %mm5
pxor %mm4, %mm4
.endm
.macro dropshiftrighta
movq %mm4, %mm0
movq %mm5, %mm4
movq %mm6, %mm5
movq %mm7, %mm6
.endm
.macro rotateright
movq %mm4, %mm1
movq %mm5, %mm4
movq %mm6, %mm5
movq %mm7, %mm6
movq %mm1, %mm7
.endm
.macro rotateleft
movq %mm7, %mm1
movq %mm6, %mm7
movq %mm5, %mm6
movq %mm4, %mm5
movq %mm1, %mm4
.endm
.macro rotaterightstack
movq %mm0, %mm1
movq %mm4, %mm0
movq %mm5, %mm4
movq %mm6, %mm5
movq %mm7, %mm6
movq %mm1, %mm7
.endm
.macro rotateleftstack
movq %mm0, %mm1
movq %mm7, %mm0
movq %mm6, %mm7
movq %mm5, %mm6
movq %mm4, %mm5
movq %mm1, %mm4
.endm
# *************************** OTHER REGISTER OPERATIONS **********************
# anot : complement reg (can be used to implement subtraction)
.macro anot
pxor %mm3, %mm4
pxor %mm3, %mm5
pxor %mm3, %mm6
pxor %mm3, %mm7
.endm
--- NEW FILE: kernel.scaf ---
( Pure Data Packet - scaforth kernel. )
( Copyright (c) by Tom Schouten <pdp at zzz.kotnet.org> )
( )
( 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 of the License, 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., 675 Mass Ave, Cambridge, MA 02139, USA. )
( this file contains the inline words in the scaforth kernel. )
( when a file is compiled to asm, it will consist of word )
( definition asm routines, macros and jmp call ret instructions. )
( )
( all words in this file are defined in terms of asm macros )
( defined in scafmacros.s )
( stack manip words )
: over dup dropover ;
( neighbourhood cell fetch words )
: @-+ dup dropldTL ;
: @0+ dup dropldTM ;
: @++ dup dropldTR ;
: @-0 dup dropldML ;
: @00 dup dropldMM ;
: @+0 dup dropldMR ;
: @-- dup dropldBL ;
: @0- dup dropldBM ;
: @+- dup dropldBR ;
( boolean logic )
: or overor nip ;
: xor overxor nip ;
: and overand nip ;
( binary constant loading )
: 1 dup dropone ;
: 0 dup dropzero ;
( 4,3,2,1 bit add stack to register, leave carry on stack )
: ++++ adb0 adb1 adb2 adb3 ;
: +++ adb0 adb1 adb2 ;
: ++ adb0 adb1 ;
: + adb0 ;
( 4,3,2 bit shifted 1 add )
: ++++<<1 adb1 adb2 adb3 ;
: +++<<1 adb1 adb2 ;
: ++<<1 adb1 ;
( 4,3 bit shifted 2 add )
: ++++<<2 adb2 adb3 ;
: +++<<2 adb2 ;
( 4 bit shifted 3 add )
: ++++<<3 adb3 ;
( 4 bit accumulator access )
: !a0 dupsta0 drop ;
: !a1 dupsta1 drop ;
: !a2 dupsta2 drop ;
: !a3 dupsta3 drop ;
: @a0 dup droplda0 ;
: @a1 dup droplda1 ;
: @a2 dup droplda2 ;
: @a3 dup droplda3 ;
( 4,3,2,1 bit accumulator zero tests )
: ?anz dup dropisnonzero4 ;
: ?anz4 dup dropisnonzero4 ;
: ?anz3 dup dropisnonzero3 ;
: ?anz2 dup dropisnonzero2 ;
: ?anz1 dup dropisnonzero1 ;
( load constants into accumulator )
: a0 a0000 ;
: a-0 a0000 ;
: a+0 a0000 ;
: a+1 a0001 ;
: a+2 a0010 ;
: a+3 a0011 ;
: a+4 a0100 ;
: a+5 a0101 ;
: a+6 a0110 ;
: a+7 a0111 ;
: a+8 a1000 ;
: a+9 a1001 ;
: a+10 a1010 ;
: a+11 a1011 ;
: a+12 a1100 ;
: a+13 a1101 ;
: a+14 a1110 ;
: a+15 a1111 ;
: a-8 a1000 ;
: a-7 a1001 ;
: a-6 a1010 ;
: a-5 a1011 ;
: a-4 a1100 ;
: a-3 a1101 ;
: a-2 a1110 ;
: a-1 a1111 ;
--- NEW FILE: scafc ---
#!/bin/sh
#scaf->scafo compiler
if test "xx$1" == "xx"
then
echo
echo "scaf rules compiler"
echo "usage:"
echo " scafc source [dest]"
echo
exit 0
fi
if test "xx$2" == "xx"
then
DEST=$1o
else
DEST=$2
fi
if ! test -f $1
then
echo "source module $1 not found."
exit 1
fi
SCAFDIR=`dirname $0`
if ! test -f $SCAFDIR/scafc.pl;
then
SCAFDIR=`dirname $SCAFDIR`
SCAFDIR="$SCAFDIR/lib/scaf"
if ! test -f $SCAFDIR/scafc.pl
then
echo "scaf library not found in $SCAFDIR"
exit 1
fi
fi
TMP_S=`tempfile -s .s`
$SCAFDIR/scafc.pl -I$SCAFDIR $1 > $TMP_S \
&& gcc -export_dynamic -shared -o $DEST $TMP_S \
&& strip --strip-unneeded $DEST \
&& rm $TMP_S \
|| exit 1
--- NEW FILE: Makefile ---
all:
clean:
rm -f *~
rm -f *.o
--- NEW FILE: scafc.pl ---
#!/usr/bin/perl
# Pure Data Packet - scafc: scaf compiler.
# Copyright (c) by Tom Schouten <pdp at zzz.kotnet.org>
#
# 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 of the License, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# set this if you want to enable/disable optimizing
$optimize = 1;
# this parses a single scaf line
# it is not very intelligent. only looks for 1 def on a line
# todo: change later so it can read multiple lines
sub remove_illegal_characters {
my $line = shift;
$$line =~ s/\+/_PLUS_/g;
$$line =~ s/-/_MINUS_/g;
$$line =~ s/\@/_AT_/g;
$$line =~ s/:/_COLON_/g;
$$line =~ s/\?/_QMARK_/g;
$$line =~ s/<</_SHIFT_/g;
$$line =~ s/</_ST_/g;
$$line =~ s/>/_GT_/g;
$$line =~ s/=/_EQ_/g;
$$line =~ s/\(/_OPEN_/g;
$$line =~ s/\)/_CLOSE_/g;
}
sub parse_scaf_line {
my $word, $def, $sub;
shift;
# this transforms the source into a parsed assembly like form
# a word label: "<word>:<ret>"
# a word definition line "<tab><word><ret>"
# last def = <ret><ret>
# dont process if line doesn't have a def
# first remove comments
s/\(\s+(\S+\s+)*?\)//g;
if (m/:\s+/){
# separate word and definition
m/:\s+(\S+)\s+(.*)/;
$word = $1;
$def = $2;
# remove illegal characters;
remove_illegal_characters \$word;
remove_illegal_characters \$def;
# format definition in asm style
$def =~ s/(\S+)(\s*)/\t$1\n/g;
# replace ; by r
$def =~ s/\s+;\s*/\n\tr\n/;
# put word: def into one string
$sub = "$word:\n$def\n";
# debug
#$sub =~ s/\t/<tab>/g;
#$sub =~ s/\n/<ret>\n/g;
#print "$sub";
return $sub;
}
};
# load and parse scaf source file
sub load_source {
my $filename = shift;
open(SOURCE, $filename) or die "Can't locate source module $filename\n";
my @parsedsource;
while (<SOURCE>){
my $sub = parse_scaf_line $_;
if ($sub) {
push @parsedsource, ($sub);
}
}
close(SOURCE);
return @parsedsource;
}
# this routine parses the optimization rules
sub load_optim {
my $filename = shift;
open(OPTIM, $filename) or die "Can't locate optimization rule file $filename\n";
my @parsedoptim;
while (<OPTIM>){
unless (m/\A\#/){
if (m/\"\s*(.*?)\s*\".*?\"\s*(.*?)\s*\"/)
{
my $source = $1;
my $dest = $2;
$source =~ s/\s+/\n\t/;
$dest =~ s/\s+/\n\t/;
$source = "\t$source\n";
$dest = "\t$dest\n";
remove_illegal_characters \$source;
remove_illegal_characters \$dest;
push @parsedoptim, ("$source:$dest");
}
}
}
close(OPTIM);
return @parsedoptim;
}
# inline one parsed source's definitions into another parsed source's
sub inline_defs {
my $dest = shift;
my $source = shift;
#print @$dest;
#print @$source;
# loop over file with inline defs
foreach (@$source) {
#print "<SUB>$_</SUB>\n";
m/(\S+):\n(.*)\tr\n/s;
my $def = "\t$1\n";
my $body = $2;
#print "<DEF>$def</DEF>\n";
#print "<BODY>$body</BODY>\n";
foreach (@$dest) {
s/$def/$body/g;
}
}
}
# this changes <WORD> to c <WORD> or j <WORD> all defined words
# the undefined words are supposed to be asm macros
sub call_defs {
my $dest = shift;
foreach (@$dest){
m/(\S+):\n/s;
my $word = $1;
foreach (@$dest){
s/\t$word\n\tr\n/\tj $word\n/sg;
s/\t$word\n/\tc $word\n/sg;
}
}
}
# substitue word sequences in dest using optim table
sub subst_optim {
my $dest = shift;
my $optim = shift;
foreach (@$optim){
m/(.*?):(.*)/s;
my $key = $1;
my $subst = $2;
foreach (@$dest){
s/$key/$subst/sg;
}
}
}
# add directives to produce global symbols
# global symbols need to start with carule_
sub global_syms {
my $source = shift;
foreach (@$source){
s/rule_(\S+):\n/.globl\trule_$1\n.type\trule_$1,\@function\nrule_$1:\n/sg;
}
}
# create an array with names for bookkeeping
sub name_array {
my @namearray;
my $source = shift;
push @namearray, (".globl rulenames\nrulenames:\n");
foreach (@$source){
if (m/rule_(\S+):/s){
push @namearray, (".asciz\t\"$1\"\n");
}
}
push @namearray, (".byte\t0\n");
return @namearray;
}
# main program body
$dir=".";
$source = "-";
# parse command line
foreach (@ARGV){
if (m/-I(.*)/) {
$dir = $1;
}
else {
$source = $_;
}
}
$kernel = "$dir/kernel.scaf";
$macro = "$dir/scafmacro.s";
$rules = "$dir/optim.rules";
# load files
@psource = load_source $source;
@pkernel = load_source $kernel;
@poptim = load_optim $rules;
# substitute kernel defs in source
if ($optimize) {subst_optim \@psource, \@poptim;}
inline_defs \@psource, \@pkernel;
if ($optimize) {subst_optim \@psource, \@poptim;}
call_defs \@psource;
global_syms \@psource;
@pnames = name_array \@psource;
# print out asm file
print ".include \"$macro\"\n\n";
print @psource;
print @pnames;
--- NEW FILE: optim.rules ---
# Pure Data Packet - scaf optimization rules.
# Copyright (c) by Tom Schouten <pdp at zzz.kotnet.org>
#
# 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 of the License, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
# this file contains scaf source optimization rules for scaf compiler
# applied after kernel word inlining and before compilation to asm
# one rule that's not in here, and is the responsability for the
# final compilation step: "word ;" is "jmp word" instead of "call word ret"
# TODO: think about order!
# no discrimination between pre inline and post inline optimization ops yet
# pre inline optimizations
"over xor" -> "overxor"
"over and" -> "overand"
"over or" -> "overor"
"drop 1" -> "dropone"
"drop 0" -> "dropzero"
"over add" -> "overadd"
"over addc" -> "overaddc"
"dup !a0" -> "dupsta0"
"dup !a1" -> "dupsta1"
"dup !a2" -> "dupsta2"
"dup !a3" -> "dupsta3"
"drop @a0" -> "droplda0"
"drop @a1" -> "droplda1"
"drop @a2" -> "droplda2"
"drop @a3" -> "droplda3"
"drop ?anz" -> "dropisnonzero4"
"drop ?anz4" -> "dropisnonzero4"
"drop ?anz3" -> "dropisnonzero3"
"drop ?anz2" -> "dropisnonzero2"
"drop ?anz1" -> "dropisnonzero1"
"drop @-+" -> "dropldTL"
"drop @0+" -> "dropldTM"
"drop @++" -> "dropldTR"
"drop @-0" -> "dropldML"
"drop @00" -> "dropldMM"
"drop @+0" -> "dropldMR"
"drop @--" -> "dropldBL"
"drop @0-" -> "dropldBM"
"drop @+-" -> "dropldBR"
# post inline optimizations
"dup drop" -> ""
"swap drop" -> "nip"
"dup swap" -> "dup"
"drop dup" -> "dropdup"
"drop over" -> "dropover"
"nip dup" -> "nipdup"
More information about the Pd-cvs
mailing list