scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit 09b76524552578f790b8252c9a85bd6128b06953
parent 6e68a7db31e3baab86a0c3ce45c261d740e23b86
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Wed, 27 Sep 2017 14:20:00 +0100

[as] Make gen.awk platform independent

This script may be used by all the platforms. The bad thing of this
change is that all the different types of arguments for all the
architectures must be written here. One possible solution
is to store in a file the allowed arguments and load them
using getline.

Diffstat:
as/target/amd64/target.mk | 10++++------
as/target/gen.awk | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
as/target/i386/target.mk | 5+++--
as/target/x86/gen.awk | 94-------------------------------------------------------------------------------
4 files changed, 101 insertions(+), 102 deletions(-)

diff --git a/as/target/amd64/target.mk b/as/target/amd64/target.mk @@ -1,15 +1,13 @@ -AMD64_TBL = common.dat \ - target/x86/i386.dat \ - target/x86/amd64.dat target/amd64/instbl.o: target/amd64/ins.h -target/amd64/instbl.c: target/x86/gen.awk $(AMD64_TBL) +target/amd64/instbl.c: target/gen.awk target/x86/x86.dat set -e ;\ rm -f $@;\ trap "rm -f $$$$.c" 0 2 3; \ - cat $(AMD64_TBL) |\ - awk -f target/x86/gen.awk > $$$$.c && mv $$$$.c $@ + awk -v bits=BITS32 -v proc=x86 \ + -f target/gen.awk \ + < target/x86/x86.dat > $$$$.c && mv $$$$.c $@ OBJ-amd64 = $(OBJ) \ target/amd64/instbl.o \ diff --git a/as/target/gen.awk b/as/target/gen.awk @@ -0,0 +1,94 @@ + +BEGIN { + FS = "\t" + printf "#include \"../../../inc/scc.h\"\n"\ + "#include \"../../as.h\"\n"\ + "#include \"../" proc "/proc.h\"\n"\ + "#include \"ins.h\"\n\n" + nop = 0; nvar = 0 +} + {sub(/#.*/,"")} + +$6 !~ bits {next} + +/^$/ {next} + + { + if (opstart[$1] == 0) { + opstart[$1] = nvar + opnames[nop++] = $1 + } + opcount[$1]++ + opargs[nvar] = $2 + opsize[nvar] = $3 + opbytes[nvar] = ($4 == "none") ? "" : $4 + opformat[nvar++] = $5 + formats[$5] = 1 +} +END { + for (i in formats) + printf "Format %s;\n", i + + printf "int nr_ins = %d;\n\n", nop + print "struct ins instab[] = {" + for (i = 0; i < nop; i++) { + n = opnames[i] + start = opstart[n] + end = start + opcount[n] + printf "\t{.str = \"%s\", .begin = %d, .end = %d},\n", + n, start, end | "sort" + } + close("sort") + printf "};\n\n" + + print "struct op optab[] = {" + for (i = 0; i < nvar; i++) { + printf "\t{\n" \ + "\t\t.size = %d,\n"\ + "\t\t.format = %s,\n", + opsize[i], opformat[i] + + if (opbytes[i] != "") + printf "\t\t.bytes = (char []) {%s},\n", + opbytes[i] + + a = str2args(opargs[i]) + if (a != "") + printf "\t\t.args = (char []) {%s}\n", a + + print "\t}," + } + print "};" +} + +function str2args(s, args, i, out) +{ + if (split(s, args, /,/) == 0 || args[1] == "none") + return "" + for (i in args) { + a = args[i] + if (match(a, /^imm8/)) { + out = "AIMM8" + } else if (match(a, /^imm16/)) { + out = "AIMM16" + } else if (match(a, /^imm32/)) { + out = "AIMM32" + } else if (match(a, /^imm64/)) { + out = "AIMM64" + } else { + print "wrong arg", a + exit 1 + } + a = substr(a, RLENGTH+1) + if (a ~ /^\+$/) { + return out "|AREP" + } else if (a != "") { + print "wrong arg", a + exit 1 + } + out = out "," + } + out = out "0" + + return out +} diff --git a/as/target/i386/target.mk b/as/target/i386/target.mk @@ -2,11 +2,12 @@ target/i386/ins.o: target/i386/ins.h target/i386/instbl.o: target/i386/ins.h -target/i386/instbl.c: target/x86/gen.awk target/x86/x86.dat +target/i386/instbl.c: target/gen.awk target/x86/x86.dat set -e ;\ rm -f $@;\ trap "rm -f $$$$.c" 0 2 3; \ - awk -v bits=BITS32 -f target/x86/gen.awk \ + awk -v bits=BITS32 -v proc=x86 \ + -f target/gen.awk \ < target/x86/x86.dat > $$$$.c && mv $$$$.c $@ OBJ-i386 = $(OBJ) \ diff --git a/as/target/x86/gen.awk b/as/target/x86/gen.awk @@ -1,94 +0,0 @@ - -BEGIN { - FS = "\t" - printf "#include \"../../../inc/scc.h\"\n"\ - "#include \"../../as.h\"\n"\ - "#include \"../x86/proc.h\"\n"\ - "#include \"ins.h\"\n\n" - nop = 0; nvar = 0 -} - {sub(/#.*/,"")} - -$6 !~ bits {next} - -/^$/ {next} - - { - if (opstart[$1] == 0) { - opstart[$1] = nvar - opnames[nop++] = $1 - } - opcount[$1]++ - opargs[nvar] = $2 - opsize[nvar] = $3 - opbytes[nvar] = ($4 == "none") ? "" : $4 - opformat[nvar++] = $5 - formats[$5] = 1 -} -END { - for (i in formats) - printf "Format %s;\n", i - - printf "int nr_ins = %d;\n\n", nop - print "struct ins instab[] = {" - for (i = 0; i < nop; i++) { - n = opnames[i] - start = opstart[n] - end = start + opcount[n] - printf "\t{.str = \"%s\", .begin = %d, .end = %d},\n", - n, start, end | "sort" - } - close("sort") - printf "};\n\n" - - print "struct op optab[] = {" - for (i = 0; i < nvar; i++) { - printf "\t{\n" \ - "\t\t.size = %d,\n"\ - "\t\t.format = %s,\n", - opsize[i], opformat[i] - - if (opbytes[i] != "") - printf "\t\t.bytes = (char []) {%s},\n", - opbytes[i] - - a = str2args(opargs[i]) - if (a != "") - printf "\t\t.args = (char []) {%s}\n", a - - print "\t}," - } - print "};" -} - -function str2args(s, args, i, out) -{ - if (split(s, args, /,/) == 0 || args[1] == "none") - return "" - for (i in args) { - a = args[i] - if (match(a, /^imm8/)) { - out = "AIMM8" - } else if (match(a, /^imm16/)) { - out = "AIMM16" - } else if (match(a, /^imm32/)) { - out = "AIMM32" - } else if (match(a, /^imm64/)) { - out = "AIMM64" - } else { - print "wrong arg", a - exit 1 - } - a = substr(a, RLENGTH+1) - if (a ~ /^\+$/) { - return out "|AREP" - } else if (a != "") { - print "wrong arg", a - exit 1 - } - out = out "," - } - out = out "0" - - return out -}