Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

We’re showing branches in this repository, but you can also compare across forks.

base fork: m-labs/flickernoise
base: a5a2866
...
head fork: m-labs/flickernoise
compare: c48e4c9
  • 5 commits
  • 10 files changed
  • 0 commit comments
  • 1 contributor
Commits on Dec 27, 2011
Werner Almesberger wpwrak compiler/ptest: new option -c to run code generation
This patch adds the infrastructure to optionally perform code generation
in ptest and the command-line option -c to enable this feature. Only
small changes were needed in the rest of the system.

This patch needs an up to date version of /opt/milkymist/milkymist.git/
7005527
Werner Almesberger wpwrak compiler/test: test code generation and enable code generation for pa…
…tch pool

"codegen" tests whether enabling code generation adds further checking.
"patches", which iterates over the patch pool, now runs with code
generation enabled.
ed5439e
Werner Almesberger wpwrak compiler/file2h: produce valid empty string if the file is empty 6970e27
Werner Almesberger wpwrak compiler/ptest: dump registers and code 20c17d7
Werner Almesberger wpwrak compiler/ptest/eval.pl: experimental PFPU code evaluator c48e4c9
10 src/compiler/compiler.c
View
@@ -62,7 +62,7 @@ static void comp_report(struct compiler_sc *sc, const char *format, ...)
/* PER-FRAME VARIABLES */
/****************************************************************/
-static const char pfv_names[COMP_PFV_COUNT][FPVM_MAXSYMLEN] = {
+const char pfv_names[COMP_PFV_COUNT][FPVM_MAXSYMLEN] = {
"sx",
"sy",
"cx",
@@ -332,7 +332,7 @@ static bool schedule_pfv(struct compiler_sc *sc)
/* PER-VERTEX VARIABLES */
/****************************************************************/
-static const char pvv_names[COMP_PVV_COUNT][FPVM_MAXSYMLEN] = {
+const char pvv_names[COMP_PVV_COUNT][FPVM_MAXSYMLEN] = {
/* System */
"_texsize",
"_hmeshsize",
@@ -549,6 +549,7 @@ static const char *assign_per_vertex(struct parser_comm *comm,
static const char *assign_image_name(struct parser_comm *comm,
int number, const char *name)
{
+#ifndef STANDALONE
struct compiler_sc *sc = comm->u.sc;
char *totalname;
@@ -568,6 +569,7 @@ static const char *assign_image_name(struct parser_comm *comm,
pixbuf_dec_ref(sc->p->images[number]);
sc->p->images[number] = pixbuf_get(totalname);
free(totalname);
+#endif /* STANDALONE */
return NULL;
}
@@ -660,6 +662,8 @@ struct patch *patch_compile_filename(const char *filename,
return p;
}
+#ifndef STANDALONE
+
struct patch *patch_copy(struct patch *p)
{
struct patch *new_patch;
@@ -683,3 +687,5 @@ void patch_free(struct patch *p)
pixbuf_dec_ref(p->images[i]);
free(p);
}
+
+#endif
7 src/compiler/compiler.h
View
@@ -18,8 +18,12 @@
#ifndef __COMPILER_H
#define __COMPILER_H
+#ifndef STANDALONE
#include <rtems.h>
#include <bsp/milkymist_pfpu.h>
+#else
+#include STANDALONE
+#endif /* STANDALONE */
#include "../renderer/framedescriptor.h"
#include "../pixbuf/pixbuf.h"
@@ -230,6 +234,9 @@ struct patch {
typedef void (*report_message)(const char *);
+extern const char pfv_names[COMP_PFV_COUNT][FPVM_MAXSYMLEN];
+extern const char pvv_names[COMP_PVV_COUNT][FPVM_MAXSYMLEN];
+
struct patch *patch_compile(const char *basedir, const char *patch_code, report_message rmc);
struct patch *patch_compile_filename(const char *filename, const char *patch_code, report_message rmc);
struct patch *patch_copy(struct patch *p);
2  src/compiler/file2h
View
@@ -2,7 +2,7 @@
while [ "$1" ]; do
echo -n "#define "
basename $1 | sed 's/[^a-zA-Z0-9]/_/g' | tr a-z A-Z | tr -d '\n'
- echo ' \'
+ echo ' "" \'
sed 's/\\/\\\\/g;s/"/\\"/g;s/.*/ "&\\n" \\/' <$1
echo
shift
19 src/compiler/ptest/Makefile
View
@@ -3,8 +3,13 @@ RTEMS_MAKEFILE_PATH ?= \
/opt/rtems-$(RTEMS_VERSION)/lm32-rtems$(RTEMS_VERSION)/milkymist/
RTEMS_FPVM_H = $(RTEMS_MAKEFILE_PATH)/lib/include/fpvm
-CFLAGS = -Wall -g -I.. -I.
-OBJS = ptest.o scanner.o parser.o parser_helper.o unique.o
+MMDIR ?= /opt/milkymist/milkymist.git
+LIBFPVM_X86 = $(MMDIR)/software/libfpvm/x86-linux
+
+CFLAGS_STANDALONE = -DSTANDALONE=\"standalone.h\"
+CFLAGS = -Wall -g -I.. -I. $(CFLAGS_STANDALONE)
+OBJS = ptest.o scanner.o parser.o parser_helper.o unique.o compiler.o fpvm.o \
+ libfpvm.a
# ----- Verbosity control -----------------------------------------------------
@@ -45,6 +50,13 @@ ptest: $(OBJS)
%.h %.inc: %.ids
$(GEN) cd .. && ./idgen `basename $<`
+../infra-fnp.h: ../finish-pfv.fnp ../init-pvv.fnp ../finish-pvv.fnp
+ $(GEN) ../file2h $^ >$@ || { rm -f $@; }
+
+libfpvm.a:
+ $(MAKE) -C $(LIBFPVM_X86)
+ cp $(LIBFPVM_X86)/$@ .
+
# ----- Dependencies ----------------------------------------------------------
../parser.h: ../parser.c
@@ -52,12 +64,15 @@ scanner.o: ../parser.h
parser_helper.o: ../parser.h
ptest.o: ../parser.h
unique.o: ../fnp.inc
+compiler.o: ../infra-fnp.h
# ----- Cleanup ---------------------------------------------------------------
clean:
+ $(MAKE) -C $(LIBFPVM_X86) clean
rm -f $(OBJS)
rm -f ../scanner.c
rm -f ../parser.c ../parser.h ../parser.out
rm -f ../fnp.h ../fnp.inc
+ rm -f ../infra-fnp.h libfpvm.a
rm -f fpvm
98 src/compiler/ptest/eval.pl
View
@@ -0,0 +1,98 @@
+#!/usr/bin/perl
+#
+# eval.pl - PFPU code evaluator (experimental)
+#
+# Copyright 2011 by Werner Almesberger
+#
+# 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, version 3 of the License.
+#
+
+
+sub flush
+{
+ if ($nregs) {
+ print 0+keys %reg, "/", (sort { $b cmp $a } keys %reg)[0],
+ "\n";
+ return;
+ }
+ for (sort keys %use) {
+ print defined $alias{$_} ? $alias{$_} : $_;
+ print " = ".$reg{$_}."\n";
+ }
+ print $res;
+}
+
+
+if ($ARGV[0] eq "-r") {
+ shift @ARGV;
+ $nregs = 1;
+}
+
+
+while (<>) {
+# if (/FPVM fragment:/) {
+# &flush if $i;
+# undef %tmp;
+# undef $i;
+# }
+ if (/PFPU fragment:/) {
+ %use = %tmp;
+ &flush if defined $i;
+ print "\n" if defined $i;
+ %init = %reg unless defined $i;
+ undef $res;
+ %reg = %init;
+ undef @val;
+ undef %tmp;
+ $i = 0;
+ }
+
+ $reg{$1} = sprintf("%g", $2) if /^(R\d+) = ([-0-9.]+)$/;
+ if (/^(R\d+) = ([-0-9.]+) (\S+)/) {
+ $reg{$1} = sprintf("$3=%g", $2);
+ $alias{$1} = $3;
+ }
+
+ $tmp{"R$1"} = 1 if /^\d+:.*-> R(\d+)/;
+ next unless defined $i;
+
+ next unless
+ /^(\d+):\s+(\S+)\s+(R\d+)?(,(R\d+))?.*?(->\s+(R\d+))?\s*$/;
+ # 1 2 3 4 5 6 7
+ ($c, $op, $a, $b, $d) = ($1, $2, $3, $5, $7);
+ undef $e;
+ $e = $1 if /E=(\d+)>/;
+ die "($i) $_" if $c != $i;
+
+ $reg{$a} = 1 if $nregs && defined $a;
+ $reg{$b} = 1 if $nregs && defined $b;
+
+ print STDERR "$i: concurrent read/write on $a (A)\n"
+ if defined $d && $a eq $d;
+ print STDERR "$i: concurrent read/write on $b (B)\n"
+ if defined $d && $b eq $d;
+
+ $a = $reg{$a} if defined $reg{$a};
+ $b = $reg{$b} if defined $reg{$b};
+
+ if ($op eq "IF<R2>") {
+ $expr = "(IF ".$reg{"R002"}." $a $b)";
+ $reg{"R002"} = 1 if $nregs;
+ } elsif ($op eq "VECTOUT") {
+ $res = "A = $a\nB = $b\n";
+ } elsif (defined $b) {
+ $expr = "($op $a $b)";
+ } elsif (defined $a) {
+ $expr = "($op $a)";
+ } else {
+ $expr = "($op)";
+ }
+
+ $val[$e] = $expr if defined $e;
+ $reg{$d} = $val[$i] if defined $d;
+ $i++;
+}
+%use = %tmp;
+&flush;
116 src/compiler/ptest/ptest.c
View
@@ -14,9 +14,12 @@
#include <unistd.h>
#include <string.h>
+#include "fpvm/pfpu.h"
+
#include "../fpvm.h"
#include "../parser_helper.h"
#include "../parser.h"
+#include "../compiler.h"
static int quiet = 0;
@@ -135,12 +138,6 @@ static void dump_ast(const struct ast_node *ast)
}
-const char *fpvm_get_last_error(struct fpvm_fragment *fragment)
-{
- return fragment->last_error;
-}
-
-
static const char *assign_default(struct parser_comm *comm,
const char *label, struct ast_node *node)
{
@@ -187,6 +184,14 @@ static const char *assign_image_name(struct parser_comm *comm,
return NULL;
}
+
+static void report(const char *s)
+{
+ fprintf(stderr, "%s\n", s);
+ exit(1);
+}
+
+
static const char *read_stdin(void)
{
char *buf = NULL;
@@ -217,17 +222,8 @@ static const char *read_stdin(void)
}
-static void usage(const char *name)
-{
- fprintf(stderr, "usage: %s [-f error] [-q] [expr]\n", name);
- exit(1);
-}
-
-
-int main(int argc, char **argv)
+static void parse_only(const char *pgm)
{
- int c;
- const char *buf;
struct fpvm_fragment fragment;
struct parser_comm comm = {
.u.fragment = &fragment,
@@ -238,8 +234,82 @@ int main(int argc, char **argv)
};
const char *error;
- while ((c = getopt(argc, argv, "f:q")) != EOF)
+ error = fpvm_parse(pgm, TOK_START_ASSIGN, &comm);
+ if (!error)
+ return;
+ fflush(stdout);
+ fprintf(stderr, "%s\n", error);
+ free((void *) error);
+ exit(1);
+}
+
+
+static void dump_regs(const int *alloc, const char (*names)[FPVM_MAXSYMLEN],
+ const float *values, int n)
+{
+ const char *mapped[n];
+ int i;
+
+ for (i = 0; i != n; i++)
+ mapped[i] = NULL;
+ for (i = 0; i != n; i++)
+ if (alloc[i] != -1)
+ mapped[alloc[i]] = names[i];
+ for (i = 0; i != n; i++) {
+ if (!values[i] && !mapped[i])
+ continue;
+ printf("R%03d = %f", i, values[i]);
+ if (mapped[i])
+ printf(" %s", mapped[i]);
+ printf("\n");
+ }
+}
+
+
+static void compile(const char *pgm)
+{
+ struct patch *patch;
+ int i;
+
+ patch = patch_compile("/", pgm, report);
+ if (!patch)
+ exit(1);
+ if (quiet)
+ return;
+ printf("global:\n");
+ for (i = 0; i != COMP_PFV_COUNT; i++)
+ if (patch->pfv_initial[i])
+ printf("R%03d = %f %s\n", i, patch->pfv_initial[i],
+ pfv_names[i]);
+ printf("per-frame PFPU fragment:\n");
+ dump_regs(patch->pfv_allocation, pfv_names, patch->perframe_regs,
+ COMP_PFV_COUNT);
+ pfpu_dump(patch->perframe_prog, patch->perframe_prog_length);
+ printf("per-vertex PFPU fragment:\n");
+ dump_regs(patch->pvv_allocation, pvv_names, patch->pervertex_regs,
+ COMP_PVV_COUNT);
+ pfpu_dump(patch->pervertex_prog, patch->pervertex_prog_length);
+}
+
+
+static void usage(const char *name)
+{
+ fprintf(stderr, "usage: %s [-c] [-f error] [-q] [expr]\n", name);
+ exit(1);
+}
+
+
+int main(int argc, char **argv)
+{
+ int c;
+ const char *buf;
+ int codegen = 0;
+
+ while ((c = getopt(argc, argv, "cf:q")) != EOF)
switch (c) {
+ case 'c':
+ codegen = 1;
+ break;
case 'f':
fail = optarg;
break;
@@ -260,11 +330,9 @@ int main(int argc, char **argv)
usage(*argv);
}
- error = fpvm_parse(buf, TOK_START_ASSIGN, &comm);
- if (!error)
- return 0;
- fflush(stdout);
- fprintf(stderr, "%s\n", error);
- free((void *)error);
- return 1;
+ if (codegen)
+ compile(buf);
+ else
+ parse_only(buf);
+ return 0;
}
12 src/compiler/ptest/standalone.h
View
@@ -0,0 +1,12 @@
+#ifndef STANDALONE_H
+#define STANDALONE_H
+
+/*
+ * From
+ * /opt/rtems-4.11/lm32-rtems4.11/milkymist/lib/include/bsp/milkymist_pfpu.h
+ */
+
+#define PFPU_PROGSIZE 2048
+#define PFPU_REG_COUNT 128
+
+#endif /* !STANDALONE_H */
30 src/compiler/test/codegen
View
@@ -0,0 +1,30 @@
+#!/bin/sh
+. ./Common
+
+###############################################################################
+
+ptest "codegen: global wave_a = 1" -c -q <<EOF
+wave_a = 1
+EOF
+expect <<EOF
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest_fail "codegen: global foo = 1" -c -q <<EOF
+foo = 1
+EOF
+expect <<EOF
+FPVM, line 1: unknown parameter near ''
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest_fail "codegen: wave_a = bar" -c -q <<EOF
+wave_a = bar
+EOF
+expect <<EOF
+FPVM, line 1: value must be a constant near 'bar'
+EOF
+
+###############################################################################
2  src/compiler/test/patches
View
@@ -71,7 +71,7 @@ for n in \
"Zylot - The Inner Workings of my New Computer.fnp" \
"bmelgren - Godhead (Video mix).fnp" \
"nil - Cid and Lucy.fnp"; do
- ptest "patch: $n" -q <"$PATCHDIR/$n"
+ ptest "patch: $n" -c -q <"$PATCHDIR/$n"
expect </dev/null
done
4 src/renderer/framedescriptor.h
View
@@ -18,8 +18,12 @@
#ifndef __FRAMEDESCRIPTOR_H
#define __FRAMEDESCRIPTOR_H
+#ifndef STANDALONE
#include <rtems.h>
#include <bsp/milkymist_ac97.h>
+#else
+#include STANDALONE
+#endif /* STANDALONE */
#include "../pixbuf/pixbuf.h"

No commit comments for this range

Something went wrong with that request. Please try again.