aboutsummaryrefslogtreecommitdiff
path: root/scaf/system
diff options
context:
space:
mode:
Diffstat (limited to 'scaf/system')
-rw-r--r--scaf/system/Makefile21
-rw-r--r--scaf/system/kernel.scaf130
-rw-r--r--scaf/system/optim.rules74
-rw-r--r--scaf/system/scaf_feeder.s49
-rw-r--r--scaf/system/scaf_feeder_test.c30
-rwxr-xr-xscaf/system/scafc.pl269
-rw-r--r--scaf/system/scafmacro.s487
7 files changed, 1060 insertions, 0 deletions
diff --git a/scaf/system/Makefile b/scaf/system/Makefile
new file mode 100644
index 0000000..2a07f4f
--- /dev/null
+++ b/scaf/system/Makefile
@@ -0,0 +1,21 @@
+all: scaf_feeder.o
+
+test: scaf_feeder_test
+
+OBJ = scaf_feeder_test.o scaf_feeder.o
+
+
+scaf_feeder_test: $(OBJ)
+ gcc -o scaf_feeder_test *.o -g -ldl
+
+.s.o:
+ as -o $*.o $*.s
+
+.c.o:
+ gcc -c $*.c -o $*.o -g
+
+clean:
+ rm -f *~
+ rm -f *.o
+ rm -f scaf_feeder_test
+
diff --git a/scaf/system/kernel.scaf b/scaf/system/kernel.scaf
new file mode 100644
index 0000000..0bc2788
--- /dev/null
+++ b/scaf/system/kernel.scaf
@@ -0,0 +1,130 @@
+( Pure Data Packet - scaforth kernel. )
+( Copyright (c) by Tom Schouten <pdp@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 ;
+
diff --git a/scaf/system/optim.rules b/scaf/system/optim.rules
new file mode 100644
index 0000000..282caf4
--- /dev/null
+++ b/scaf/system/optim.rules
@@ -0,0 +1,74 @@
+# Pure Data Packet - scaf optimization rules.
+# Copyright (c) by Tom Schouten <pdp@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"
diff --git a/scaf/system/scaf_feeder.s b/scaf/system/scaf_feeder.s
new file mode 100644
index 0000000..1cd8fd3
--- /dev/null
+++ b/scaf/system/scaf_feeder.s
@@ -0,0 +1,49 @@
+# Pure Data Packet - scaf feeder routine.
+# Copyright (c) by Tom Schouten <pdp@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.
+#
+
+.include "scafmacro.s"
+
+
+# *rg is only used for returning the stack pointer
+# the 4 bit counter is using registers mm4-mm7 now
+# long long scaf_feeder(void *tos, void *rg, *void() ca_rule, void *env)
+.globl scaf_feeder
+.type scaf_feeder, @function
+scaf_feeder:
+ pushl %ebp
+ movl %esp, %ebp
+ push %esi
+ push %edi
+
+ movl 20(%ebp), %edi # load env ptr
+ movl 8(%ebp), %esi # load TOS2 ptr
+ movl 16(%ebp), %eax # address of ca routine
+ pcmpeqw %mm3, %mm3 # load 1 reg
+
+ call *%eax # TOS = 32x2 cell result
+ dup # push %mm0 to memory
+ movl (%esi), %eax
+ movl 4(%esi), %edx
+ lea 16(%esi), %esi # discard stack
+ movl %esi, (%edi) # store for stack underflow check
+
+ emms
+ pop %edi
+ pop %esi
+ leave
+ ret
diff --git a/scaf/system/scaf_feeder_test.c b/scaf/system/scaf_feeder_test.c
new file mode 100644
index 0000000..23a2661
--- /dev/null
+++ b/scaf/system/scaf_feeder_test.c
@@ -0,0 +1,30 @@
+#include <dlfcn.h>
+
+void scaf_feeder_asm (void *tos, void *reg, void (*ca_rule)(), void *env);
+
+void ca_test() {}
+
+main()
+{
+ int stack[256];
+ int reg[8];
+ int env[8];
+
+ void *libhandle;
+ void *ca_routine;
+
+
+ if (!(libhandle = dlopen("../modules/test.scafo", RTLD_NOW))){
+ printf("error: %s\n", dlerror());
+ exit(1);
+ }
+
+ if (!(ca_routine = dlsym(libhandle, "carule_1"))){
+ printf("error: %s\n", dlerror());
+ exit(1);
+ }
+
+ scaf_feeder_asm(stack+254, reg, ca_routine, env);
+
+ dlclose(libhandle);
+}
diff --git a/scaf/system/scafc.pl b/scaf/system/scafc.pl
new file mode 100755
index 0000000..ee6b969
--- /dev/null
+++ b/scaf/system/scafc.pl
@@ -0,0 +1,269 @@
+#!/usr/bin/perl
+
+# Pure Data Packet - scafc: scaf compiler.
+# Copyright (c) by Tom Schouten <pdp@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;
+
diff --git a/scaf/system/scafmacro.s b/scaf/system/scafmacro.s
new file mode 100644
index 0000000..04e6537
--- /dev/null
+++ b/scaf/system/scafmacro.s
@@ -0,0 +1,487 @@
+ # Pure Data Packet - scaf assembler macros.
+ # Copyright (c) by Tom Schouten <pdp@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