--- /dev/null
+#!/bin/sh
+#
+# mklabel.sh - Make label tables for computed goto's.
+#
+# Copyright (C) 2002, 2004 Southern Storm Software, Pty Ltd.
+#
+# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Usage: mklabel.sh awk jit-opcode.h jit-interp.h >jit-interp-labels.h
+
+# Validate the parameters.
+if test "x$1" = "x" ; then
+ echo "Usage: $0 awk jit-opcode.h jit-interp.h >jit-interp-labels.h" 1>&2
+ exit 1
+fi
+if test "x$2" = "x" ; then
+ echo "Usage: $0 awk jit-opcode.h jit-interp.h >jit-interp-labels.h" 1>&2
+ exit 1
+fi
+if test "x$3" = "x" ; then
+ echo "Usage: $0 awk jit-opcode.h jit-interp.h >jit-interp-labels.h" 1>&2
+ exit 1
+fi
+
+# Output the "do not edit" header.
+echo '/* This file is automatically generated - do not edit */'
+echo ''
+
+# Define a null assembly statement. This is a trick to stop gcc doing
+# tail-end combination on the cases within the switch statements.
+echo '#if defined(__GNUC__)'
+echo '#define VMNULLASM() __asm__("")'
+echo '#else'
+echo '#define VMNULLASM()'
+echo '#endif'
+echo '#define VMFETCH(pc) ((int)*((jit_nint *)(pc)))'
+echo ''
+
+# Are we compiling an interpreter that uses PIC computed goto's?
+echo '#if defined(JIT_INTERP_TOKEN_PIC)'
+echo ''
+
+# Output a table of PIC labels, based on an incoming stream
+# of #define's for opcodes. Some awks don't support hex
+# string to number conversion, which is why we have to convert
+# the opcode value the hard way.
+pic_table()
+{
+ "$1" 'BEGIN{
+ nextval=0
+ }
+ {
+ currval=0;
+ hexval=$3
+ ch=substr(hexval,1,1);
+ if(ch == "(")
+ hexval=$5
+ ch=substr(hexval,3,1);
+ if(ch == "0") currval=currval+0; else
+ if(ch == "1") currval=currval+1; else
+ if(ch == "2") currval=currval+2; else
+ if(ch == "3") currval=currval+3; else
+ if(ch == "4") currval=currval+4; else
+ if(ch == "5") currval=currval+5; else
+ if(ch == "6") currval=currval+6; else
+ if(ch == "7") currval=currval+7; else
+ if(ch == "8") currval=currval+8; else
+ if(ch == "9") currval=currval+9; else
+ if(ch == "A") currval=currval+10; else
+ if(ch == "B") currval=currval+11; else
+ if(ch == "C") currval=currval+12; else
+ if(ch == "D") currval=currval+13; else
+ if(ch == "E") currval=currval+14; else
+ if(ch == "F") currval=currval+15;
+ currval=currval*16;
+ ch=substr(hexval,4,1);
+ if(ch == "0") currval=currval+0; else
+ if(ch == "1") currval=currval+1; else
+ if(ch == "2") currval=currval+2; else
+ if(ch == "3") currval=currval+3; else
+ if(ch == "4") currval=currval+4; else
+ if(ch == "5") currval=currval+5; else
+ if(ch == "6") currval=currval+6; else
+ if(ch == "7") currval=currval+7; else
+ if(ch == "8") currval=currval+8; else
+ if(ch == "9") currval=currval+9; else
+ if(ch == "A") currval=currval+10; else
+ if(ch == "B") currval=currval+11; else
+ if(ch == "C") currval=currval+12; else
+ if(ch == "D") currval=currval+13; else
+ if(ch == "E") currval=currval+14; else
+ if(ch == "F") currval=currval+15;
+ currval=currval*16;
+ ch=substr(hexval,5,1);
+ if(ch == "0") currval=currval+0; else
+ if(ch == "1") currval=currval+1; else
+ if(ch == "2") currval=currval+2; else
+ if(ch == "3") currval=currval+3; else
+ if(ch == "4") currval=currval+4; else
+ if(ch == "5") currval=currval+5; else
+ if(ch == "6") currval=currval+6; else
+ if(ch == "7") currval=currval+7; else
+ if(ch == "8") currval=currval+8; else
+ if(ch == "9") currval=currval+9; else
+ if(ch == "A") currval=currval+10; else
+ if(ch == "B") currval=currval+11; else
+ if(ch == "C") currval=currval+12; else
+ if(ch == "D") currval=currval+13; else
+ if(ch == "E") currval=currval+14; else
+ if(ch == "F") currval=currval+15;
+ currval=currval*16;
+ ch=substr(hexval,6,1);
+ if(ch == "0") currval=currval+0; else
+ if(ch == "1") currval=currval+1; else
+ if(ch == "2") currval=currval+2; else
+ if(ch == "3") currval=currval+3; else
+ if(ch == "4") currval=currval+4; else
+ if(ch == "5") currval=currval+5; else
+ if(ch == "6") currval=currval+6; else
+ if(ch == "7") currval=currval+7; else
+ if(ch == "8") currval=currval+8; else
+ if(ch == "9") currval=currval+9; else
+ if(ch == "A") currval=currval+10; else
+ if(ch == "B") currval=currval+11; else
+ if(ch == "C") currval=currval+12; else
+ if(ch == "D") currval=currval+13; else
+ if(ch == "E") currval=currval+14; else
+ if(ch == "F") currval=currval+15;
+ while(nextval < currval)
+ {
+ print " &&'"$2"' - &&JIT_OP_NOP_label,"
+ ++nextval
+ }
+ print " &&" $2 "_label - &&JIT_OP_NOP_label,"
+ ++nextval
+ }' -
+ return 0
+}
+
+# Output the label table (PIC version).
+echo 'static int const main_label_table[JIT_OP_END_MARKER] = {'
+grep '^#define[ ]*JIT_OP_' "$2" | grep -v 'JIT_OP_NUM_OPCODES' | \
+ pic_table "$1" JIT_OP_NOP_label
+grep '^#define[ ]*JIT_OP_' "$3" | grep -v 'JIT_OP_NUM_INTERP_OPCODES' | \
+ grep -v 'JIT_OP_END_MARKER' | pic_table "$1" JIT_OP_NOP_label
+echo '};'
+echo ''
+
+# Output the helper macros (PIC).
+echo '#define VMSWITCH(pc) { goto *(&&JIT_OP_NOP_label + main_label_table[VMFETCH((pc))]);'
+echo '#define VMSWITCHEND }'
+echo '#define VMCASE(val) val##_label'
+echo '#define VMBREAK \
+ goto *(&&JIT_OP_NOP_label + main_label_table[VMFETCH((pc))])'
+echo ''
+
+# Now to handle the non-PIC case of using computed goto's.
+echo '#elif defined(JIT_INTERP_TOKEN)'
+echo ''
+
+# Output a table of non-PIC labels, based on an incoming stream
+# of #define's for opcodes. Some awks don't support hex
+# string to number conversion, which is why we have to convert
+# the opcode value the hard way.
+non_pic_table()
+{
+ "$1" 'BEGIN{
+ nextval=0
+ }
+ {
+ currval=0;
+ hexval=$3
+ ch=substr(hexval,1,1);
+ if(ch == "(")
+ hexval=$5
+ ch=substr(hexval,3,1);
+ if(ch == "0") currval=currval+0; else
+ if(ch == "1") currval=currval+1; else
+ if(ch == "2") currval=currval+2; else
+ if(ch == "3") currval=currval+3; else
+ if(ch == "4") currval=currval+4; else
+ if(ch == "5") currval=currval+5; else
+ if(ch == "6") currval=currval+6; else
+ if(ch == "7") currval=currval+7; else
+ if(ch == "8") currval=currval+8; else
+ if(ch == "9") currval=currval+9; else
+ if(ch == "A") currval=currval+10; else
+ if(ch == "B") currval=currval+11; else
+ if(ch == "C") currval=currval+12; else
+ if(ch == "D") currval=currval+13; else
+ if(ch == "E") currval=currval+14; else
+ if(ch == "F") currval=currval+15;
+ currval=currval*16;
+ ch=substr(hexval,4,1);
+ if(ch == "0") currval=currval+0; else
+ if(ch == "1") currval=currval+1; else
+ if(ch == "2") currval=currval+2; else
+ if(ch == "3") currval=currval+3; else
+ if(ch == "4") currval=currval+4; else
+ if(ch == "5") currval=currval+5; else
+ if(ch == "6") currval=currval+6; else
+ if(ch == "7") currval=currval+7; else
+ if(ch == "8") currval=currval+8; else
+ if(ch == "9") currval=currval+9; else
+ if(ch == "A") currval=currval+10; else
+ if(ch == "B") currval=currval+11; else
+ if(ch == "C") currval=currval+12; else
+ if(ch == "D") currval=currval+13; else
+ if(ch == "E") currval=currval+14; else
+ if(ch == "F") currval=currval+15;
+ currval=currval*16;
+ ch=substr(hexval,5,1);
+ if(ch == "0") currval=currval+0; else
+ if(ch == "1") currval=currval+1; else
+ if(ch == "2") currval=currval+2; else
+ if(ch == "3") currval=currval+3; else
+ if(ch == "4") currval=currval+4; else
+ if(ch == "5") currval=currval+5; else
+ if(ch == "6") currval=currval+6; else
+ if(ch == "7") currval=currval+7; else
+ if(ch == "8") currval=currval+8; else
+ if(ch == "9") currval=currval+9; else
+ if(ch == "A") currval=currval+10; else
+ if(ch == "B") currval=currval+11; else
+ if(ch == "C") currval=currval+12; else
+ if(ch == "D") currval=currval+13; else
+ if(ch == "E") currval=currval+14; else
+ if(ch == "F") currval=currval+15;
+ currval=currval*16;
+ ch=substr(hexval,6,1);
+ if(ch == "0") currval=currval+0; else
+ if(ch == "1") currval=currval+1; else
+ if(ch == "2") currval=currval+2; else
+ if(ch == "3") currval=currval+3; else
+ if(ch == "4") currval=currval+4; else
+ if(ch == "5") currval=currval+5; else
+ if(ch == "6") currval=currval+6; else
+ if(ch == "7") currval=currval+7; else
+ if(ch == "8") currval=currval+8; else
+ if(ch == "9") currval=currval+9; else
+ if(ch == "A") currval=currval+10; else
+ if(ch == "B") currval=currval+11; else
+ if(ch == "C") currval=currval+12; else
+ if(ch == "D") currval=currval+13; else
+ if(ch == "E") currval=currval+14; else
+ if(ch == "F") currval=currval+15;
+ while(nextval < currval)
+ {
+ print " &&'"$2"',"
+ ++nextval
+ }
+ print " &&" $2 "_label,"
+ ++nextval
+ }' -
+ return 0
+}
+
+# Output the label table (non-PIC).
+echo 'static void * main_label_table[JIT_OP_END_MARKER] = {'
+grep '^#define[ ]*JIT_OP_' "$2" | grep -v 'JIT_OP_NUM_OPCODES' | \
+ non_pic_table "$1" JIT_OP_NOP_label
+grep '^#define[ ]*JIT_OP_' "$3" | grep -v 'JIT_OP_NUM_INTERP_OPCODES' | \
+ grep -v 'JIT_OP_END_MARKER' | non_pic_table "$1" JIT_OP_NOP_label
+echo '};'
+echo ''
+
+# Output the helper macros (non-PIC).
+echo '#define VMSWITCH(pc) { goto *main_label_table[VMFETCH((pc))];'
+echo '#define VMSWITCHEND }'
+echo '#define VMCASE(val) val##_label'
+echo '#define VMBREAK \
+ goto *main_label_table[VMFETCH((pc))]'
+echo ''
+
+# Output the non-goto case of the helper macros.
+echo '#else /* JIT_INTERP_SWITCH */'
+echo ''
+echo '#define VMSWITCH(pc) for(;;) { switch(VMFETCH((pc)))'
+echo '#define VMSWITCHEND }'
+echo '#define VMCASE(val) case (val)'
+echo '#define VMBREAK VMNULLASM(); break'
+echo ''
+echo '#endif /* JIT_INTERP_SWITCH */'
+
+# Done.
+exit 0