mirror of https://github.com/ademakov/libjit
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
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
|
|
|