Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 5 commits
  • 10 files changed
  • 0 comments
  • 1 contributor
Dec 28, 2011
Werner Almesberger 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 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 compiler/file2h: produce valid empty string if the file is empty 6970e27
Werner Almesberger compiler/ptest: dump registers and code 20c17d7
Werner Almesberger compiler/ptest/eval.pl: experimental PFPU code evaluator c48e4c9
10  src/compiler/compiler.c
@@ -62,7 +62,7 @@ static void comp_report(struct compiler_sc *sc, const char *format, ...)
62 62
 /* PER-FRAME VARIABLES                                          */
63 63
 /****************************************************************/
64 64
 
65  
-static const char pfv_names[COMP_PFV_COUNT][FPVM_MAXSYMLEN] = {
  65
+const char pfv_names[COMP_PFV_COUNT][FPVM_MAXSYMLEN] = {
66 66
 	"sx",
67 67
 	"sy",
68 68
 	"cx",
@@ -332,7 +332,7 @@ static bool schedule_pfv(struct compiler_sc *sc)
332 332
 /* PER-VERTEX VARIABLES                                         */
333 333
 /****************************************************************/
334 334
 
335  
-static const char pvv_names[COMP_PVV_COUNT][FPVM_MAXSYMLEN] = {
  335
+const char pvv_names[COMP_PVV_COUNT][FPVM_MAXSYMLEN] = {
336 336
 	/* System */
337 337
 	"_texsize",
338 338
 	"_hmeshsize",
@@ -549,6 +549,7 @@ static const char *assign_per_vertex(struct parser_comm *comm,
549 549
 static const char *assign_image_name(struct parser_comm *comm,
550 550
     int number, const char *name)
551 551
 {
  552
+#ifndef STANDALONE
552 553
 	struct compiler_sc *sc = comm->u.sc;
553 554
 	char *totalname;
554 555
 
@@ -568,6 +569,7 @@ static const char *assign_image_name(struct parser_comm *comm,
568 569
 	pixbuf_dec_ref(sc->p->images[number]);
569 570
 	sc->p->images[number] = pixbuf_get(totalname);
570 571
 	free(totalname);
  572
+#endif /* STANDALONE */
571 573
 	return NULL;
572 574
 }
573 575
 
@@ -660,6 +662,8 @@ struct patch *patch_compile_filename(const char *filename,
660 662
 	return p;
661 663
 }
662 664
 
  665
+#ifndef STANDALONE
  666
+
663 667
 struct patch *patch_copy(struct patch *p)
664 668
 {
665 669
 	struct patch *new_patch;
@@ -683,3 +687,5 @@ void patch_free(struct patch *p)
683 687
 		pixbuf_dec_ref(p->images[i]);
684 688
 	free(p);
685 689
 }
  690
+
  691
+#endif
7  src/compiler/compiler.h
@@ -18,8 +18,12 @@
18 18
 #ifndef __COMPILER_H
19 19
 #define __COMPILER_H
20 20
 
  21
+#ifndef STANDALONE
21 22
 #include <rtems.h>
22 23
 #include <bsp/milkymist_pfpu.h>
  24
+#else
  25
+#include STANDALONE
  26
+#endif /* STANDALONE */
23 27
 
24 28
 #include "../renderer/framedescriptor.h"
25 29
 #include "../pixbuf/pixbuf.h"
@@ -230,6 +234,9 @@ struct patch {
230 234
 
231 235
 typedef void (*report_message)(const char *);
232 236
 
  237
+extern const char pfv_names[COMP_PFV_COUNT][FPVM_MAXSYMLEN];
  238
+extern const char pvv_names[COMP_PVV_COUNT][FPVM_MAXSYMLEN];
  239
+
233 240
 struct patch *patch_compile(const char *basedir, const char *patch_code, report_message rmc);
234 241
 struct patch *patch_compile_filename(const char *filename, const char *patch_code, report_message rmc);
235 242
 struct patch *patch_copy(struct patch *p);
2  src/compiler/file2h
@@ -2,7 +2,7 @@
2 2
 while [ "$1" ]; do
3 3
 	echo -n "#define "
4 4
 	basename $1 | sed 's/[^a-zA-Z0-9]/_/g' | tr a-z A-Z | tr -d '\n'
5  
-	echo ' \'
  5
+	echo ' "" \'
6 6
 	sed 's/\\/\\\\/g;s/"/\\"/g;s/.*/    "&\\n" \\/' <$1
7 7
 	echo
8 8
 	shift
19  src/compiler/ptest/Makefile
@@ -3,8 +3,13 @@ RTEMS_MAKEFILE_PATH ?= \
3 3
     /opt/rtems-$(RTEMS_VERSION)/lm32-rtems$(RTEMS_VERSION)/milkymist/
4 4
 RTEMS_FPVM_H = $(RTEMS_MAKEFILE_PATH)/lib/include/fpvm
5 5
 
6  
-CFLAGS = -Wall -g -I.. -I.
7  
-OBJS = ptest.o scanner.o parser.o parser_helper.o unique.o
  6
+MMDIR ?= /opt/milkymist/milkymist.git
  7
+LIBFPVM_X86 = $(MMDIR)/software/libfpvm/x86-linux
  8
+
  9
+CFLAGS_STANDALONE = -DSTANDALONE=\"standalone.h\"
  10
+CFLAGS = -Wall -g -I.. -I. $(CFLAGS_STANDALONE)
  11
+OBJS = ptest.o scanner.o parser.o parser_helper.o unique.o compiler.o fpvm.o \
  12
+       libfpvm.a
8 13
 
9 14
 # ----- Verbosity control -----------------------------------------------------
10 15
 
@@ -45,6 +50,13 @@ ptest:		$(OBJS)
45 50
 %.h %.inc:	%.ids
46 51
 		$(GEN) cd .. && ./idgen `basename $<`
47 52
 
  53
+../infra-fnp.h:	../finish-pfv.fnp ../init-pvv.fnp ../finish-pvv.fnp
  54
+		$(GEN) ../file2h $^ >$@ || { rm -f $@; }
  55
+
  56
+libfpvm.a:
  57
+		$(MAKE) -C $(LIBFPVM_X86)
  58
+		cp $(LIBFPVM_X86)/$@ .
  59
+
48 60
 # ----- Dependencies ----------------------------------------------------------
49 61
 
50 62
 ../parser.h:	../parser.c
@@ -52,12 +64,15 @@ scanner.o:	../parser.h
52 64
 parser_helper.o: ../parser.h
53 65
 ptest.o:	../parser.h
54 66
 unique.o:	../fnp.inc
  67
+compiler.o:	../infra-fnp.h
55 68
 
56 69
 # ----- Cleanup ---------------------------------------------------------------
57 70
 
58 71
 clean:
  72
+		$(MAKE) -C $(LIBFPVM_X86) clean
59 73
 		rm -f $(OBJS)
60 74
 		rm -f ../scanner.c
61 75
 		rm -f ../parser.c ../parser.h ../parser.out
62 76
 		rm -f ../fnp.h ../fnp.inc
  77
+		rm -f ../infra-fnp.h libfpvm.a
63 78
 		rm -f fpvm
98  src/compiler/ptest/eval.pl
... ...
@@ -0,0 +1,98 @@
  1
+#!/usr/bin/perl
  2
+#
  3
+# eval.pl - PFPU code evaluator (experimental)
  4
+#
  5
+# Copyright 2011 by Werner Almesberger
  6
+#
  7
+# This program is free software: you can redistribute it and/or modify
  8
+# it under the terms of the GNU General Public License as published by
  9
+# the Free Software Foundation, version 3 of the License.
  10
+#
  11
+
  12
+
  13
+sub flush
  14
+{
  15
+	if ($nregs) {
  16
+		print 0+keys %reg, "/", (sort { $b cmp $a } keys %reg)[0],
  17
+		     "\n";
  18
+		return;
  19
+	}
  20
+	for (sort keys %use) {
  21
+		print defined $alias{$_} ? $alias{$_} : $_;
  22
+		print " = ".$reg{$_}."\n";
  23
+	}
  24
+	print $res;
  25
+}
  26
+
  27
+
  28
+if ($ARGV[0] eq "-r") {
  29
+	shift @ARGV;
  30
+	$nregs = 1;
  31
+}
  32
+
  33
+
  34
+while (<>) {
  35
+#	if (/FPVM fragment:/) {
  36
+#		&flush if $i;
  37
+#		undef %tmp;
  38
+#		undef $i;
  39
+#	}
  40
+	if (/PFPU fragment:/) {
  41
+		%use = %tmp;
  42
+		&flush if defined $i;
  43
+		print "\n" if defined $i;
  44
+		%init = %reg unless defined $i;
  45
+		undef $res;
  46
+		%reg = %init;
  47
+		undef @val;
  48
+		undef %tmp;
  49
+		$i = 0;
  50
+	}
  51
+
  52
+	$reg{$1} = sprintf("%g", $2) if /^(R\d+) = ([-0-9.]+)$/;
  53
+	if (/^(R\d+) = ([-0-9.]+) (\S+)/) {
  54
+		$reg{$1} = sprintf("$3=%g", $2);
  55
+		$alias{$1} = $3;
  56
+	}
  57
+
  58
+	$tmp{"R$1"} = 1 if /^\d+:.*-> R(\d+)/;
  59
+	next unless defined $i;
  60
+
  61
+	next unless
  62
+	    /^(\d+):\s+(\S+)\s+(R\d+)?(,(R\d+))?.*?(->\s+(R\d+))?\s*$/;
  63
+	#     1        2       3      4 5          6     7
  64
+	($c, $op, $a, $b, $d) = ($1, $2, $3, $5, $7);
  65
+	undef $e;
  66
+	$e = $1 if /E=(\d+)>/;
  67
+	die "($i) $_" if $c != $i;
  68
+
  69
+	$reg{$a} = 1 if $nregs && defined $a;
  70
+	$reg{$b} = 1 if $nregs && defined $b;
  71
+
  72
+	print STDERR "$i: concurrent read/write on $a (A)\n"
  73
+	    if defined $d && $a eq $d;
  74
+	print STDERR "$i: concurrent read/write on $b (B)\n"
  75
+	    if defined $d && $b eq $d;
  76
+
  77
+	$a = $reg{$a} if defined $reg{$a};
  78
+	$b = $reg{$b} if defined $reg{$b};
  79
+
  80
+	if ($op eq "IF<R2>") {
  81
+		$expr = "(IF ".$reg{"R002"}." $a $b)";
  82
+		$reg{"R002"} = 1 if $nregs;
  83
+	} elsif ($op eq "VECTOUT") {
  84
+		$res = "A = $a\nB = $b\n";
  85
+	} elsif (defined $b) {
  86
+		$expr = "($op $a $b)";
  87
+	} elsif (defined $a) {
  88
+		$expr = "($op $a)";
  89
+	} else {
  90
+		$expr = "($op)";
  91
+	}
  92
+
  93
+	$val[$e] = $expr if defined $e;
  94
+	$reg{$d} = $val[$i] if defined $d;
  95
+	$i++;
  96
+}
  97
+%use = %tmp;
  98
+&flush;
116  src/compiler/ptest/ptest.c
@@ -14,9 +14,12 @@
14 14
 #include <unistd.h>
15 15
 #include <string.h>
16 16
 
  17
+#include "fpvm/pfpu.h"
  18
+
17 19
 #include "../fpvm.h"
18 20
 #include "../parser_helper.h"
19 21
 #include "../parser.h"
  22
+#include "../compiler.h"
20 23
 
21 24
 
22 25
 static int quiet = 0;
@@ -135,12 +138,6 @@ static void dump_ast(const struct ast_node *ast)
135 138
 }
136 139
 
137 140
 
138  
-const char *fpvm_get_last_error(struct fpvm_fragment *fragment)
139  
-{
140  
-	return fragment->last_error;
141  
-}
142  
-
143  
-
144 141
 static const char *assign_default(struct parser_comm *comm,
145 142
     const char *label, struct ast_node *node)
146 143
 {
@@ -187,6 +184,14 @@ static const char *assign_image_name(struct parser_comm *comm,
187 184
 	return NULL;
188 185
 }
189 186
 
  187
+
  188
+static void report(const char *s)
  189
+{
  190
+	fprintf(stderr, "%s\n", s);
  191
+	exit(1);
  192
+}
  193
+
  194
+
190 195
 static const char *read_stdin(void)
191 196
 {
192 197
 	char *buf = NULL;
@@ -217,17 +222,8 @@ static const char *read_stdin(void)
217 222
 }
218 223
 
219 224
 
220  
-static void usage(const char *name)
221  
-{
222  
-	fprintf(stderr, "usage: %s [-f error] [-q] [expr]\n", name);
223  
-	exit(1);
224  
-}
225  
-
226  
-
227  
-int main(int argc, char **argv)
  225
+static void parse_only(const char *pgm)
228 226
 {
229  
-	int c;
230  
-	const char *buf;
231 227
 	struct fpvm_fragment fragment;
232 228
 	struct parser_comm comm = {
233 229
 		.u.fragment = &fragment,
@@ -238,8 +234,82 @@ int main(int argc, char **argv)
238 234
 	 };
239 235
 	const char *error;
240 236
 
241  
-	while ((c = getopt(argc, argv, "f:q")) != EOF)
  237
+	error = fpvm_parse(pgm, TOK_START_ASSIGN, &comm);
  238
+	if (!error)
  239
+		return;
  240
+	fflush(stdout);
  241
+	fprintf(stderr, "%s\n", error);
  242
+	free((void *) error);
  243
+	exit(1);
  244
+}
  245
+
  246
+
  247
+static void dump_regs(const int *alloc, const char (*names)[FPVM_MAXSYMLEN],
  248
+    const float *values, int n)
  249
+{
  250
+	const char *mapped[n];
  251
+	int i;
  252
+
  253
+	for (i = 0; i != n; i++)
  254
+		mapped[i] = NULL;
  255
+	for (i = 0; i != n; i++)
  256
+		if (alloc[i] != -1)
  257
+			mapped[alloc[i]] = names[i];
  258
+	for (i = 0; i != n; i++) {
  259
+		if (!values[i] && !mapped[i])
  260
+			continue;
  261
+		printf("R%03d = %f", i, values[i]);
  262
+		if (mapped[i])
  263
+			printf(" %s", mapped[i]);
  264
+		printf("\n");
  265
+	}
  266
+}
  267
+
  268
+
  269
+static void compile(const char *pgm)
  270
+{
  271
+	struct patch *patch;
  272
+	int i;
  273
+
  274
+	patch = patch_compile("/", pgm, report);
  275
+	if (!patch)
  276
+		exit(1);
  277
+	if (quiet)
  278
+		return;
  279
+	printf("global:\n");
  280
+	for (i = 0; i != COMP_PFV_COUNT; i++)
  281
+		if (patch->pfv_initial[i])
  282
+			printf("R%03d = %f %s\n", i, patch->pfv_initial[i],
  283
+			    pfv_names[i]);
  284
+	printf("per-frame PFPU fragment:\n");
  285
+	dump_regs(patch->pfv_allocation, pfv_names, patch->perframe_regs,
  286
+	    COMP_PFV_COUNT);
  287
+	pfpu_dump(patch->perframe_prog, patch->perframe_prog_length);
  288
+	printf("per-vertex PFPU fragment:\n");
  289
+	dump_regs(patch->pvv_allocation, pvv_names, patch->pervertex_regs,
  290
+	    COMP_PVV_COUNT);
  291
+	pfpu_dump(patch->pervertex_prog, patch->pervertex_prog_length);
  292
+}
  293
+
  294
+
  295
+static void usage(const char *name)
  296
+{
  297
+	fprintf(stderr, "usage: %s [-c] [-f error] [-q] [expr]\n", name);
  298
+	exit(1);
  299
+}
  300
+
  301
+
  302
+int main(int argc, char **argv)
  303
+{
  304
+	int c;
  305
+	const char *buf;
  306
+	int codegen = 0;
  307
+
  308
+	while ((c = getopt(argc, argv, "cf:q")) != EOF)
242 309
 		switch (c) {
  310
+		case 'c':
  311
+			codegen = 1;
  312
+			break;
243 313
 		case 'f':
244 314
 			fail = optarg;
245 315
 			break;
@@ -260,11 +330,9 @@ int main(int argc, char **argv)
260 330
 		usage(*argv);
261 331
 	}
262 332
 
263  
-	error = fpvm_parse(buf, TOK_START_ASSIGN, &comm);
264  
-	if (!error)
265  
-		return 0;
266  
-	fflush(stdout);
267  
-	fprintf(stderr, "%s\n", error);
268  
-	free((void *)error);
269  
-	return 1;
  333
+	if (codegen)
  334
+		compile(buf);
  335
+	else
  336
+		parse_only(buf);
  337
+	return 0;
270 338
 }
12  src/compiler/ptest/standalone.h
... ...
@@ -0,0 +1,12 @@
  1
+#ifndef STANDALONE_H
  2
+#define	STANDALONE_H
  3
+
  4
+/*
  5
+ * From
  6
+ * /opt/rtems-4.11/lm32-rtems4.11/milkymist/lib/include/bsp/milkymist_pfpu.h
  7
+ */
  8
+
  9
+#define PFPU_PROGSIZE	2048
  10
+#define PFPU_REG_COUNT	128
  11
+
  12
+#endif /* !STANDALONE_H */
30  src/compiler/test/codegen
... ...
@@ -0,0 +1,30 @@
  1
+#!/bin/sh
  2
+. ./Common
  3
+
  4
+###############################################################################
  5
+
  6
+ptest "codegen: global wave_a = 1" -c -q <<EOF
  7
+wave_a = 1
  8
+EOF
  9
+expect <<EOF
  10
+EOF
  11
+
  12
+#------------------------------------------------------------------------------
  13
+
  14
+ptest_fail "codegen: global foo = 1" -c -q <<EOF
  15
+foo = 1
  16
+EOF
  17
+expect <<EOF
  18
+FPVM, line 1: unknown parameter near ''
  19
+EOF
  20
+
  21
+#------------------------------------------------------------------------------
  22
+
  23
+ptest_fail "codegen: wave_a = bar" -c -q <<EOF
  24
+wave_a = bar
  25
+EOF
  26
+expect <<EOF
  27
+FPVM, line 1: value must be a constant near 'bar'
  28
+EOF
  29
+
  30
+###############################################################################
2  src/compiler/test/patches
@@ -71,7 +71,7 @@ for n in \
71 71
     "Zylot - The Inner Workings of my New Computer.fnp" \
72 72
     "bmelgren - Godhead (Video mix).fnp" \
73 73
     "nil - Cid and Lucy.fnp"; do
74  
-	ptest "patch: $n" -q <"$PATCHDIR/$n"
  74
+	ptest "patch: $n" -c -q <"$PATCHDIR/$n"
75 75
 	expect </dev/null
76 76
 done
77 77
 
4  src/renderer/framedescriptor.h
@@ -18,8 +18,12 @@
18 18
 #ifndef __FRAMEDESCRIPTOR_H
19 19
 #define __FRAMEDESCRIPTOR_H
20 20
 
  21
+#ifndef STANDALONE
21 22
 #include <rtems.h>
22 23
 #include <bsp/milkymist_ac97.h>
  24
+#else 
  25
+#include STANDALONE
  26
+#endif /* STANDALONE */
23 27
 
24 28
 #include "../pixbuf/pixbuf.h"
25 29
 

No commit comments for this range

Something went wrong with that request. Please try again.