You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

298 lines
11 KiB

#!/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