Add the vvp engine to cvs.
This commit is contained in:
parent
debe707097
commit
cb65ee5e00
|
|
@ -16,7 +16,7 @@
|
|||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.91 2001/02/10 20:29:39 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.92 2001/03/11 00:29:38 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
|
@ -27,6 +27,8 @@ prefix = @prefix@
|
|||
exec_prefix = @exec_prefix@
|
||||
srcdir = @srcdir@
|
||||
|
||||
SUBDIRS = @subdirs@
|
||||
|
||||
VPATH = $(srcdir)
|
||||
|
||||
bindir = @bindir@
|
||||
|
|
|
|||
|
|
@ -148,5 +148,6 @@ AC_SUBST(shared)
|
|||
AC_MSG_RESULT($shared)
|
||||
|
||||
|
||||
AC_CONFIG_SUBDIRS(vvp)
|
||||
|
||||
AC_OUTPUT(Makefile vpi/Makefile ivlpp/Makefile vvm/Makefile driver/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
configure
|
||||
config.log
|
||||
config.status
|
||||
config.h
|
||||
dep
|
||||
Makefile
|
||||
lexor.cc
|
||||
parse.cc
|
||||
parse.cc.output
|
||||
parse.h
|
||||
vvp
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
#
|
||||
# This source code is free software; you can redistribute it
|
||||
# and/or modify it in source code form under the terms of the GNU
|
||||
# Library 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 Library General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library 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
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.1 2001/03/11 00:29:38 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
srcdir = @srcdir@
|
||||
|
||||
VPATH = $(srcdir)
|
||||
|
||||
bindir = @bindir@
|
||||
libdir = @libdir@
|
||||
includedir = @includedir@
|
||||
|
||||
CC = @CC@
|
||||
CXX = @CXX@ -Wall
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
STRIP = @STRIP@
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@ @DEFS@
|
||||
CXXFLAGS = @CXXFLAGS@ -I. -I$(srcdir)
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
all: vvp
|
||||
|
||||
clean:
|
||||
rm -rf vvp *.o *~ parse.cc parse.cc.output parse.h lexor.cc dep
|
||||
|
||||
distclean: clean
|
||||
rm -f config.h Makefile config.cache config.log config.status
|
||||
|
||||
O = main.o parse.o parse_misc.o lexor.o compile.o functor.o symbols.o \
|
||||
codes.o vthread.o schedule.o
|
||||
|
||||
vvp: $O
|
||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o vvp $O
|
||||
|
||||
|
||||
%.o: %.cc
|
||||
@[ -d dep ] || mkdir dep
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o
|
||||
mv $*.d dep/$*.d
|
||||
|
||||
|
||||
lexor.o: lexor.cc parse.h
|
||||
|
||||
parse.o: parse.cc
|
||||
|
||||
parse.h parse.cc: $(srcdir)/parse.y
|
||||
bison --verbose -t -d $(srcdir)/parse.y -o parse.cc
|
||||
mv parse.cc.h parse.h
|
||||
|
||||
lexor.cc: $(srcdir)/lexor.lex
|
||||
flex -s -olexor.cc $(srcdir)/lexor.lex
|
||||
|
||||
|
||||
-include $(patsubst %.o, dep/%.d, $O)
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
|
||||
VVP SIMULATION ENGINE
|
||||
|
||||
The VVP simulator takes as input source code not unlike assembly
|
||||
language for a conventional processor. It is intended to be machine
|
||||
generated code emitted by other tools, including the Icarus Verilog
|
||||
compiler, so the syntax, though readable, is not necessarily
|
||||
convenient for humans.
|
||||
|
||||
|
||||
GENERAL FORMAT
|
||||
|
||||
The source file is a collection of statements. Each statement may have
|
||||
a label, an opcode, and operands that depend on the opcode. For some
|
||||
opcodes, the label is optional (or meaningless) and for others it is
|
||||
required.
|
||||
|
||||
Every statement is terminated by a semicolon. The semicolon is also
|
||||
the start of a comment line, so you can put comment text after the
|
||||
semicolon that terminates a statement. Like so:
|
||||
|
||||
Label .functor and, x, y ; This is a comment.
|
||||
|
||||
The semicolon is required, whether the comment is there or not.
|
||||
|
||||
Statements may span multiple lines, as long as there is no text (other
|
||||
then the first character of a label) in the first column of hte
|
||||
continuation line.
|
||||
|
||||
|
||||
LABELS AND SYMBOLS
|
||||
|
||||
Labels and symbols consist of the characters:
|
||||
|
||||
a-z
|
||||
A-Z
|
||||
0-9
|
||||
.$_
|
||||
|
||||
Labels and symbols may not start with a digit or a '.', so that they
|
||||
are easily distinguished from keywords and numbers. A Label is a
|
||||
symbol that starts a statement. If a label is present in a statement,
|
||||
it must start in the first text column. This is how the lexical
|
||||
analyzer distinguishes a label from a symbol. If a symbol is present
|
||||
in a statement, it is in the operand. Opcodes of statements must be a
|
||||
keyword.
|
||||
|
||||
Symbols are references to labels. It is not necessary for a label to
|
||||
be declared before its use in a symbol, but it must be declared
|
||||
eventually.
|
||||
|
||||
|
||||
FUNCTOR STATEMENTS:
|
||||
|
||||
A functor statement is a statement that uses the ``.functor''
|
||||
opcode. Functors are the basic structural units of a simulation, and
|
||||
include a type (in the form of a truth table) and up to four inputs. A
|
||||
label is required for functors.
|
||||
|
||||
The general syntax of a functor is:
|
||||
|
||||
<label> .functor <type> [, symbol_list]
|
||||
|
||||
The symbol list is 0-4 names of labels of other functors. These
|
||||
connect inputs of the functor of the statement to the output of other
|
||||
functors. The type is the label of a .ftype statement elsewhere in the
|
||||
program. The references .ftype describes the behavoir of the functor.
|
||||
|
||||
Almost all of the structural aspects of a simulation can be
|
||||
represented by functors.
|
||||
|
||||
VARIABLE STATEMENTS:
|
||||
|
||||
A variable is a bit that can be written by behavioral code (so has no
|
||||
structural input) and propagates its output to a functor. The general
|
||||
syntax of a variable is:
|
||||
|
||||
<label> .var
|
||||
|
||||
A variable does not take inputs, since its value is set behaviorally
|
||||
by assignment events. It does have an output, though, and its output
|
||||
is propagated into the net of functors in the usual way.
|
||||
|
||||
Therefore, the .var statement implicitly also creates a .functor of
|
||||
the same name as the variable. It is in fact the functor that
|
||||
behavioral code reads when the value of the variable (or net) is read
|
||||
by behavioral code.
|
||||
|
||||
The variable .functor implicitly has three inputs. The first is the
|
||||
value that gets set by assignments or procedural continuous
|
||||
assignments. The second is a forced value that can be connected to a
|
||||
force expression (as a functor) when a value is being forced. And the
|
||||
third input selects the source to use. The default is to select the
|
||||
assignment input.
|
||||
|
||||
Note that nets in a design do not necessarily have a specific functor
|
||||
or object allocated to them. Nets are just something that behavioral
|
||||
code can read, so it is enough to give to the behavioral code the
|
||||
vvp_ipoint_t object of the .functor that drives the net.
|
||||
|
||||
|
||||
THREAD STATEMENTS:
|
||||
|
||||
Thread statements create the initial threads for a simulation. These
|
||||
represent the initial and always blocks, and possibly other causes to
|
||||
create threads at startup.
|
||||
|
||||
.thread <symbol>
|
||||
|
||||
This statement creates a thread with a starting address at the
|
||||
instruction given by <symbol>.
|
||||
|
||||
|
||||
EXECUTABLE INSTRUCTIONS
|
||||
|
||||
Threads run executable code, much like a processor executes machine
|
||||
code. VVP has a variety of opcodes for executable instructions. All of
|
||||
those instructions start with '%' and go into a single address
|
||||
space. Labels attached to executable instructions get assigned the
|
||||
address of the instruction, and can be the target of %jmp instructions
|
||||
and starting points for threads.
|
||||
|
||||
|
||||
HOW TO GET FROM THERE TO HERE
|
||||
|
||||
The vvp simulation engine is designed to be able to take as input a
|
||||
compiled form of Verilog. That implies that there is a compiler that
|
||||
compiles Verilog into a form that the vvp engine can read.
|
||||
|
||||
|
||||
* Boolean logic gates
|
||||
|
||||
Gates like AND, OR and NAND are implemented simply and obviously by
|
||||
functor statements. Any logic up to 4 inputs can be implemented with a
|
||||
single functor. For example:
|
||||
|
||||
and gate (out, i1, i2, i3);
|
||||
|
||||
becomes:
|
||||
|
||||
gate .functor and, i1, i2, i3;
|
||||
|
||||
Notice the first parameter of the .functor is the type. The type
|
||||
includes a truth table that describes the output with a given
|
||||
input. If the gate is wider then four inputs, then cascade
|
||||
functors. For example:
|
||||
|
||||
and gate (out, i1, i2, i3, i4, i5, i6, i7, i8);
|
||||
|
||||
becomes:
|
||||
|
||||
gate.0 .functor and, i1, i2, i3, i4;
|
||||
gate.1 .functor and, i5, i6, i7, i8;
|
||||
gate .functor and, gate.0, gate.1;
|
||||
|
||||
|
||||
* reg and other variables
|
||||
|
||||
Reg and integer are cases of what Verilog calls ``variables.''
|
||||
Variables are, simply put, things that behavioral code can assign
|
||||
to. These are not the same as ``nets,'' which include wires and the
|
||||
like.
|
||||
|
||||
Each bit of a variable is created by a ``.var'' statement. For example:
|
||||
|
||||
reg a;
|
||||
|
||||
becomes:
|
||||
|
||||
a .var;
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form 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
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: codes.cc,v 1.1 2001/03/11 00:29:38 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "codes.h"
|
||||
# include <string.h>
|
||||
# include <assert.h>
|
||||
|
||||
|
||||
const unsigned code_index0_size = 2 << 9;
|
||||
const unsigned code_index1_size = 2 << 11;
|
||||
const unsigned code_index2_size = 2 << 10;
|
||||
|
||||
struct code_index0 {
|
||||
struct vvp_code_s table[code_index0_size];
|
||||
};
|
||||
|
||||
struct code_index1 {
|
||||
struct code_index0* table[code_index1_size];
|
||||
};
|
||||
|
||||
static vvp_cpoint_t code_count = 0;
|
||||
static struct code_index1*code_table[code_index2_size] = { 0 };
|
||||
|
||||
|
||||
void codespace_init(void)
|
||||
{
|
||||
code_table[0] = 0;
|
||||
code_count = 1;
|
||||
}
|
||||
|
||||
vvp_cpoint_t codespace_allocate(void)
|
||||
{
|
||||
vvp_cpoint_t idx = code_count;
|
||||
|
||||
idx /= code_index0_size;
|
||||
|
||||
unsigned index1 = idx % code_index1_size;
|
||||
idx /= code_index1_size;
|
||||
|
||||
assert(idx < code_index2_size);
|
||||
|
||||
if (code_table[idx] == 0) {
|
||||
code_table[idx] = new struct code_index1;
|
||||
memset(code_table[idx], 0, sizeof code_table[idx]);
|
||||
}
|
||||
|
||||
if (code_table[idx]->table[index1] == 0) {
|
||||
code_table[idx]->table[index1] = new struct code_index0;
|
||||
memset(code_table[idx]->table[index1],
|
||||
0, sizeof(struct code_index0));
|
||||
}
|
||||
|
||||
vvp_cpoint_t res = code_count;
|
||||
code_count += 1;
|
||||
return res;
|
||||
}
|
||||
|
||||
vvp_code_t codespace_index(vvp_cpoint_t point)
|
||||
{
|
||||
assert(point < code_count);
|
||||
|
||||
unsigned index0 = point % code_index0_size;
|
||||
point /= code_index0_size;
|
||||
|
||||
unsigned index1 = point % code_index1_size;
|
||||
point /= code_index1_size;
|
||||
|
||||
return code_table[point]->table[index1]->table + index0;
|
||||
}
|
||||
|
||||
void codespace_dump(FILE*fd)
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < code_count ; idx += 1) {
|
||||
fprintf(fd, " %8x: ", idx);
|
||||
vvp_code_t cop = codespace_index(idx);
|
||||
|
||||
if (cop->opcode == &of_ASSIGN) {
|
||||
fprintf(fd, "%%assign 0x%u, %lu, %u\n",
|
||||
cop->iptr, cop->number, cop->bit_idx);
|
||||
|
||||
} else if (cop->opcode == &of_DELAY) {
|
||||
fprintf(fd, "%%delay %lu\n", cop->number);
|
||||
|
||||
} else if (cop->opcode == &of_END) {
|
||||
fprintf(fd, "%%end\n");
|
||||
|
||||
} else if (cop->opcode == &of_SET) {
|
||||
fprintf(fd, "%%set 0x%lu, %u\n",
|
||||
cop->iptr, cop->bit_idx);
|
||||
|
||||
} else {
|
||||
fprintf(fd, "opcode %p\n", cop->opcode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: codes.cc,v $
|
||||
* Revision 1.1 2001/03/11 00:29:38 steve
|
||||
* Add the vvp engine to cvs.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
#ifndef __codes_H
|
||||
#define __codes_H
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form 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
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: codes.h,v 1.1 2001/03/11 00:29:38 steve Exp $"
|
||||
#endif
|
||||
|
||||
|
||||
# include "pointers.h"
|
||||
# include "vthread.h"
|
||||
# include <stdio.h>
|
||||
|
||||
typedef struct vvp_code_s *vvp_code_t;
|
||||
typedef bool (*vvp_code_fun)(vthread_t thr, vvp_code_t code);
|
||||
|
||||
/*
|
||||
* These functions are implementations of executable op-codes. The
|
||||
* implementation lives in the vthread.cc file so that they have
|
||||
* access to the thread context.
|
||||
*/
|
||||
extern bool of_ASSIGN(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_DELAY(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_END(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SET(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_NOOP(vthread_t thr, vvp_code_t code);
|
||||
|
||||
/*
|
||||
* This is the format of a machine code instruction.
|
||||
*/
|
||||
struct vvp_code_s {
|
||||
vvp_code_fun opcode;
|
||||
|
||||
unsigned short bit_idx;
|
||||
unsigned long number;
|
||||
union {
|
||||
vvp_ipoint_t iptr;
|
||||
vvp_cpoint_t cptr;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* This function clears the code space, ready for initialization. This
|
||||
* needs to be done exactly once before any instructions are created.
|
||||
*/
|
||||
extern void codespace_init(void);
|
||||
|
||||
/*
|
||||
* This function returns a pointer to the next free instruction in the
|
||||
* code address space.
|
||||
*/
|
||||
extern vvp_cpoint_t codespace_allocate(void);
|
||||
|
||||
/*
|
||||
* Return a pointer to the indexed instruction in the codespace. The
|
||||
* ptr must be a value returned from codespace_allocate. The compiler
|
||||
* can use this to get a handle on the instruction to be created, and
|
||||
* the runtime uses this to get the instruction addressed by the PC or
|
||||
* by a branch instruction.
|
||||
*/
|
||||
extern vvp_code_t codespace_index(vvp_cpoint_t ptr);
|
||||
|
||||
extern void codespace_dump(FILE*fd);
|
||||
|
||||
/*
|
||||
* $Log: codes.h,v $
|
||||
* Revision 1.1 2001/03/11 00:29:38 steve
|
||||
* Add the vvp engine to cvs.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
|
@ -0,0 +1,360 @@
|
|||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form 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
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: compile.cc,v 1.1 2001/03/11 00:29:38 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "compile.h"
|
||||
# include "functor.h"
|
||||
# include "symbols.h"
|
||||
# include "codes.h"
|
||||
# include "schedule.h"
|
||||
# include "vthread.h"
|
||||
# include "parse_misc.h"
|
||||
# include <malloc.h>
|
||||
# include <stdlib.h>
|
||||
# include <assert.h>
|
||||
|
||||
|
||||
/*
|
||||
* The opcode table lists all the code mnemonics, along with their
|
||||
* opcode and operand types. The table is written sorted by mnemonic
|
||||
* so that it can be searched by binary search. The opcode_compare
|
||||
* function is a helper function for that lookup.
|
||||
*/
|
||||
|
||||
enum operand_e {
|
||||
/* Place holder for unused operand */
|
||||
OA_NONE,
|
||||
/* The operand is a number, an immediate unsigned long integer */
|
||||
OA_NUMBER,
|
||||
/* The operand is a thread bit index */
|
||||
OA_BIT,
|
||||
/* The operand is a pointer to code space */
|
||||
OA_CODE_PTR,
|
||||
/* The operand is a variable or net pointer */
|
||||
OA_FUNC_PTR
|
||||
};
|
||||
|
||||
struct opcode_table_s {
|
||||
const char*mnemonic;
|
||||
vvp_code_fun opcode;
|
||||
|
||||
unsigned argc;
|
||||
enum operand_e argt[OPERAND_MAX];
|
||||
};
|
||||
|
||||
const static struct opcode_table_s opcode_table[] = {
|
||||
{ "%assign", of_ASSIGN, 3, {OA_FUNC_PTR, OA_NUMBER, OA_BIT} },
|
||||
{ "%delay", of_DELAY, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
|
||||
{ "%end", of_END, 0, {OA_NONE, OA_NONE, OA_NONE} },
|
||||
{ "%set", of_SET, 2, {OA_FUNC_PTR, OA_BIT, OA_NONE} },
|
||||
{ 0, of_NOOP, 0, {OA_NONE, OA_NONE, OA_NONE} }
|
||||
};
|
||||
|
||||
static unsigned opcode_count = 0;
|
||||
|
||||
static int opcode_compare(const void*k, const void*r)
|
||||
{
|
||||
const char*kp = (const char*)k;
|
||||
const struct opcode_table_s*rp = (const struct opcode_table_s*)r;
|
||||
return strcmp(kp, rp->mnemonic);
|
||||
}
|
||||
|
||||
/*
|
||||
* Keep a symbol table of addresses within code space. Labels on
|
||||
* executable opcodes are mapped to their address here.
|
||||
*/
|
||||
static symbol_table_t sym_codespace = 0;
|
||||
|
||||
/*
|
||||
* Keep a symbol table of functors mentioned in the source. This table
|
||||
* is used to resolve references as they come.
|
||||
*/
|
||||
static symbol_table_t sym_functors = 0;
|
||||
|
||||
/*
|
||||
* If a functor parameter makes a forward reference to a functor, then
|
||||
* I need to save that reference and resolve it after the functors are
|
||||
* created. Use this structure to keep the unresolved references in an
|
||||
* unsorted singly linked list.
|
||||
*/
|
||||
struct resolv_list_s {
|
||||
struct resolv_list_s*next;
|
||||
vvp_ipoint_t port;
|
||||
char*source;
|
||||
};
|
||||
|
||||
static struct resolv_list_s*resolv_list = 0;
|
||||
|
||||
|
||||
/*
|
||||
* Initialize the compiler by allocation empty symbol tables and
|
||||
* initializing the various address spaces.
|
||||
*/
|
||||
void compile_init(void)
|
||||
{
|
||||
sym_functors = new_symbol_table();
|
||||
functor_init();
|
||||
sym_codespace = new_symbol_table();
|
||||
codespace_init();
|
||||
|
||||
opcode_count = 0;
|
||||
while (opcode_table[opcode_count].mnemonic)
|
||||
opcode_count += 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The parser calls this function to create a functor. I allocate a
|
||||
* functor, and map the name to the vvp_ipoint_t address for the
|
||||
* functor. Also resolve the inputs to the functor.
|
||||
*/
|
||||
void compile_functor(char*label, char*type, unsigned argc, char**argv)
|
||||
{
|
||||
vvp_ipoint_t fdx = functor_allocate();
|
||||
functor_t obj = functor_index(fdx);
|
||||
sym_set_value(sym_functors, label, fdx);
|
||||
|
||||
assert(argc <= 4);
|
||||
|
||||
/* Run through the arguments looking for the functors that are
|
||||
connected to my input ports. For each source functor that I
|
||||
find, connect the output of that functor to the indexed
|
||||
input by inserting myself (complete with the port number in
|
||||
the vvp_ipoint_t) into the list that the source heads.
|
||||
|
||||
If the source functor is not declared yet, then don't do
|
||||
the link yet. Save the reference to be resolved later. */
|
||||
|
||||
for (unsigned idx = 0 ; idx < argc ; idx += 1) {
|
||||
vvp_ipoint_t tmp = sym_get_value(sym_functors, argv[idx]);
|
||||
|
||||
if (tmp) {
|
||||
functor_t fport = functor_index(tmp);
|
||||
obj->port[idx] = fport->out;
|
||||
fport->out = ipoint_make(fdx, idx);
|
||||
|
||||
free(argv[idx]);
|
||||
|
||||
} else {
|
||||
struct resolv_list_s*res = (struct resolv_list_s*)
|
||||
calloc(1, sizeof(struct resolv_list_s));
|
||||
|
||||
res->port = ipoint_make(fdx, idx);
|
||||
res->source = argv[idx];
|
||||
res->next = resolv_list;
|
||||
resolv_list = res;
|
||||
}
|
||||
}
|
||||
|
||||
free(argv);
|
||||
free(label);
|
||||
free(type);
|
||||
}
|
||||
|
||||
/*
|
||||
* The parser uses this function to compile an link an executable
|
||||
* opcode. I do this by looking up the opcode in the opcode_table. The
|
||||
* table gives the operand structure that is acceptible, so I can
|
||||
* process the operands here as well.
|
||||
*/
|
||||
void compile_code(char*label, char*mnem, comp_operands_t opa)
|
||||
{
|
||||
vvp_cpoint_t ptr = codespace_allocate();
|
||||
|
||||
/* First, I can give the label a value that is the current
|
||||
codespace pointer. Don't need the text of the label after
|
||||
this is done. */
|
||||
if (label) {
|
||||
sym_set_value(sym_codespace, label, ptr);
|
||||
free(label);
|
||||
}
|
||||
|
||||
/* Lookup the opcode in the opcode table. */
|
||||
struct opcode_table_s*op = (struct opcode_table_s*)
|
||||
bsearch(mnem, opcode_table, opcode_count,
|
||||
sizeof(struct opcode_table_s), &opcode_compare);
|
||||
if (op == 0) {
|
||||
yyerror("Invalid opcode");
|
||||
return;
|
||||
}
|
||||
|
||||
assert(op);
|
||||
|
||||
/* Build up the code from the information about the opcode and
|
||||
the information from the comiler. */
|
||||
vvp_code_t code = codespace_index(ptr);
|
||||
code->opcode = op->opcode;
|
||||
|
||||
if (op->argc != (opa? opa->argc : 0)) {
|
||||
yyerror("operand count");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Pull the operands that the instruction expects from the
|
||||
list that the parser supplied. */
|
||||
|
||||
for (unsigned idx = 0 ; idx < op->argc ; idx += 1) {
|
||||
switch (op->argt[idx]) {
|
||||
case OA_NONE:
|
||||
break;
|
||||
|
||||
case OA_BIT:
|
||||
if (opa->argv[idx].ltype != L_NUMB) {
|
||||
yyerror("operand format");
|
||||
break;
|
||||
}
|
||||
|
||||
code->bit_idx = opa->argv[idx].numb;
|
||||
break;
|
||||
|
||||
case OA_CODE_PTR:
|
||||
if (opa->argv[idx].ltype != L_TEXT) {
|
||||
yyerror("operand format");
|
||||
break;
|
||||
}
|
||||
|
||||
code->cptr = sym_get_value(sym_codespace,
|
||||
opa->argv[idx].text);
|
||||
if (code->cptr == 0) {
|
||||
yyerror("functor undefined");
|
||||
break;
|
||||
}
|
||||
|
||||
free(opa->argv[idx].text);
|
||||
break;
|
||||
|
||||
case OA_FUNC_PTR:
|
||||
if (opa->argv[idx].ltype != L_TEXT) {
|
||||
yyerror("operand format");
|
||||
break;
|
||||
}
|
||||
|
||||
code->iptr = sym_get_value(sym_functors,
|
||||
opa->argv[idx].text);
|
||||
if (code->iptr == 0) {
|
||||
yyerror("functor undefined");
|
||||
break;
|
||||
}
|
||||
|
||||
free(opa->argv[idx].text);
|
||||
break;
|
||||
|
||||
case OA_NUMBER:
|
||||
if (opa->argv[idx].ltype != L_NUMB) {
|
||||
yyerror("operand format");
|
||||
break;
|
||||
}
|
||||
|
||||
code->number = opa->argv[idx].numb;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (opa) free(opa);
|
||||
|
||||
free(mnem);
|
||||
}
|
||||
|
||||
/*
|
||||
* When the parser finds a thread statement, I create a new thread
|
||||
* with the start address referenced by the program symbol passed to
|
||||
* me.
|
||||
*/
|
||||
void compile_thread(char*start_sym)
|
||||
{
|
||||
vvp_cpoint_t pc = sym_get_value(sym_codespace, start_sym);
|
||||
if (pc == 0) {
|
||||
yyerror("unresolved address");
|
||||
return;
|
||||
}
|
||||
|
||||
vthread_t thr = v_newthread(pc);
|
||||
schedule_vthread(thr, 0);
|
||||
free(start_sym);
|
||||
}
|
||||
|
||||
/*
|
||||
* A variable is a special functor, so we allocate that functor and
|
||||
* write the label into the symbol table.
|
||||
*/
|
||||
void compile_variable(char*label)
|
||||
{
|
||||
vvp_ipoint_t fdx = functor_allocate();
|
||||
functor_t obj = functor_index(fdx);
|
||||
sym_set_value(sym_functors, label, fdx);
|
||||
|
||||
free(label);
|
||||
}
|
||||
|
||||
void compile_cleanup(void)
|
||||
{
|
||||
struct resolv_list_s*tmp_list = resolv_list;
|
||||
resolv_list = 0;
|
||||
|
||||
while (tmp_list) {
|
||||
struct resolv_list_s*res = tmp_list;
|
||||
tmp_list = res->next;
|
||||
|
||||
functor_t obj = functor_index(res->port);
|
||||
unsigned idx = ipoint_port(res->port);
|
||||
|
||||
vvp_ipoint_t tmp = sym_get_value(sym_functors, res->source);
|
||||
|
||||
if (tmp != 0) {
|
||||
functor_t fport = functor_index(tmp);
|
||||
obj->port[idx] = fport->out;
|
||||
fport->out = res->port;
|
||||
|
||||
free(res->source);
|
||||
free(res);
|
||||
|
||||
} else {
|
||||
/* Still not resolved. put back into the list. */
|
||||
res->next = resolv_list;
|
||||
resolv_list = res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void compile_dump(FILE*fd)
|
||||
{
|
||||
fprintf(fd, "FUNCTOR SYMBOL TABLE:\n");
|
||||
sym_dump(sym_functors, fd);
|
||||
fprintf(fd, "FUNCTORS:\n");
|
||||
functor_dump(fd);
|
||||
fprintf(fd, "UNRESOLVED PORT INPUTS:\n");
|
||||
for (struct resolv_list_s*cur = resolv_list ; cur ; cur = cur->next)
|
||||
fprintf(fd, " %p: %s\n", cur->port, cur->source);
|
||||
|
||||
fprintf(fd, "CODE SPACE SYMBOL TABLE:\n");
|
||||
sym_dump(sym_codespace, fd);
|
||||
|
||||
fprintf(fd, "CODE SPACE DISASSEMBLY:\n");
|
||||
codespace_dump(fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: compile.cc,v $
|
||||
* Revision 1.1 2001/03/11 00:29:38 steve
|
||||
* Add the vvp engine to cvs.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
#ifndef __compile_H
|
||||
#define __compile_H
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form 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
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: compile.h,v 1.1 2001/03/11 00:29:38 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <stdio.h>
|
||||
|
||||
/*
|
||||
* The functions described here are the compile time support
|
||||
* functions. Various bits of the compile process are taken care of
|
||||
* here. What is called when is mostly controlled by the parser.
|
||||
*
|
||||
* Before compilation takes place, the compile_init function must be
|
||||
* called once to set stuff up.
|
||||
*/
|
||||
|
||||
extern void compile_init(void);
|
||||
|
||||
extern void compile_cleanup(void);
|
||||
|
||||
/*
|
||||
* This function is called by the parser to compile a functor
|
||||
* statement. The strings passed in are allocated by the lexor, but
|
||||
* this function will free them. (Or save them permanently.) This
|
||||
* includes the argv array and the strings it references.
|
||||
*
|
||||
* The argc and argv are a list of char* that are the port paramters
|
||||
* of the functor. The compile should match those port parameters up
|
||||
* to existing functors to manage the linking.
|
||||
*/
|
||||
extern void compile_functor(char*label, char*type,
|
||||
unsigned argc, char**argv);
|
||||
|
||||
|
||||
/*
|
||||
* A code statement is a label, an opcode and up to 3 operands. There
|
||||
* are a few lexical types that the parser recognizes of the operands,
|
||||
* given by the ltype_e enumeration. The compile_code function takes
|
||||
* the label, mnemonic and parsed operands and writes a properly
|
||||
* formed instruction into the code space. The label is set into the
|
||||
* symbol table with the address of the instruction.
|
||||
*/
|
||||
|
||||
#define OPERAND_MAX 3
|
||||
enum ltype_e { L_NUMB, L_TEXT };
|
||||
|
||||
struct comp_operands_s {
|
||||
unsigned argc;
|
||||
struct {
|
||||
enum ltype_e ltype;
|
||||
union {
|
||||
unsigned long numb;
|
||||
char*text;
|
||||
};
|
||||
} argv[OPERAND_MAX];
|
||||
};
|
||||
|
||||
typedef struct comp_operands_s*comp_operands_t;
|
||||
|
||||
extern void compile_code(char*label, char*mnem, comp_operands_t opa);
|
||||
|
||||
/*
|
||||
* The parser uses this function to declare a thread. The start_sym is
|
||||
* the start instruction, and must already be defined.
|
||||
*/
|
||||
extern void compile_thread(char*start_sym);
|
||||
|
||||
/*
|
||||
* This function is called to create a var bit with the given name.
|
||||
*/
|
||||
extern void compile_variable(char*label);
|
||||
|
||||
/*
|
||||
* This is a diagnostic aid. Dump all the compiler tables to the file
|
||||
* descriptor in a readable form.
|
||||
*/
|
||||
extern void compile_dump(FILE*fd);
|
||||
|
||||
/*
|
||||
* $Log: compile.h,v $
|
||||
* Revision 1.1 2001/03/11 00:29:38 steve
|
||||
* Add the vvp engine to cvs.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
|
@ -0,0 +1,912 @@
|
|||
#! /bin/sh
|
||||
# Attempt to guess a canonical system name.
|
||||
# Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file 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.
|
||||
#
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# Written by Per Bothner <bothner@cygnus.com>.
|
||||
# The master version of this file is at the FSF in /home/gd/gnu/lib.
|
||||
#
|
||||
# This script attempts to guess a canonical system name similar to
|
||||
# config.sub. If it succeeds, it prints the system name on stdout, and
|
||||
# exits with 0. Otherwise, it exits with 1.
|
||||
#
|
||||
# The plan is that this can be called by configure scripts if you
|
||||
# don't specify an explicit system type (host/target name).
|
||||
#
|
||||
# Only a few systems have been added to this list; please add others
|
||||
# (but try to keep the structure clean).
|
||||
#
|
||||
|
||||
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
|
||||
# (ghazi@noc.rutgers.edu 8/24/94.)
|
||||
if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
|
||||
PATH=$PATH:/.attbin ; export PATH
|
||||
fi
|
||||
|
||||
UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
|
||||
UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
|
||||
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
|
||||
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
|
||||
|
||||
trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
|
||||
|
||||
# Note: order is significant - the case branches are not exclusive.
|
||||
|
||||
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
alpha:OSF1:*:*)
|
||||
if test $UNAME_RELEASE = "V4.0"; then
|
||||
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
|
||||
fi
|
||||
# A Vn.n version is a released version.
|
||||
# A Tn.n version is a released field test version.
|
||||
# A Xn.n version is an unreleased experimental baselevel.
|
||||
# 1.2 uses "1.2" for uname -r.
|
||||
cat <<EOF >dummy.s
|
||||
.globl main
|
||||
.ent main
|
||||
main:
|
||||
.frame \$30,0,\$26,0
|
||||
.prologue 0
|
||||
.long 0x47e03d80 # implver $0
|
||||
lda \$2,259
|
||||
.long 0x47e20c21 # amask $2,$1
|
||||
srl \$1,8,\$2
|
||||
sll \$2,2,\$2
|
||||
sll \$0,3,\$0
|
||||
addl \$1,\$0,\$0
|
||||
addl \$2,\$0,\$0
|
||||
ret \$31,(\$26),1
|
||||
.end main
|
||||
EOF
|
||||
${CC-cc} dummy.s -o dummy 2>/dev/null
|
||||
if test "$?" = 0 ; then
|
||||
./dummy
|
||||
case "$?" in
|
||||
7)
|
||||
UNAME_MACHINE="alpha"
|
||||
;;
|
||||
15)
|
||||
UNAME_MACHINE="alphaev5"
|
||||
;;
|
||||
14)
|
||||
UNAME_MACHINE="alphaev56"
|
||||
;;
|
||||
10)
|
||||
UNAME_MACHINE="alphapca56"
|
||||
;;
|
||||
16)
|
||||
UNAME_MACHINE="alphaev6"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
rm -f dummy.s dummy
|
||||
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]`
|
||||
exit 0 ;;
|
||||
21064:Windows_NT:50:3)
|
||||
echo alpha-dec-winnt3.5
|
||||
exit 0 ;;
|
||||
Amiga*:UNIX_System_V:4.0:*)
|
||||
echo m68k-cbm-sysv4
|
||||
exit 0;;
|
||||
amiga:NetBSD:*:*)
|
||||
echo m68k-cbm-netbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
amiga:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
arc64:OpenBSD:*:*)
|
||||
echo mips64el-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
arc:OpenBSD:*:*)
|
||||
echo mipsel-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
hkmips:OpenBSD:*:*)
|
||||
echo mips-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
pmax:OpenBSD:*:*)
|
||||
echo mipsel-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
sgi:OpenBSD:*:*)
|
||||
echo mips-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
wgrisc:OpenBSD:*:*)
|
||||
echo mipsel-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
|
||||
echo arm-acorn-riscix${UNAME_RELEASE}
|
||||
exit 0;;
|
||||
arm32:NetBSD:*:*)
|
||||
echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
|
||||
exit 0 ;;
|
||||
SR2?01:HI-UX/MPP:*:*)
|
||||
echo hppa1.1-hitachi-hiuxmpp
|
||||
exit 0;;
|
||||
Pyramid*:OSx*:*:*|MIS*:OSx*:*:*)
|
||||
# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
|
||||
if test "`(/bin/universe) 2>/dev/null`" = att ; then
|
||||
echo pyramid-pyramid-sysv3
|
||||
else
|
||||
echo pyramid-pyramid-bsd
|
||||
fi
|
||||
exit 0 ;;
|
||||
NILE:*:*:dcosx)
|
||||
echo pyramid-pyramid-svr4
|
||||
exit 0 ;;
|
||||
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
|
||||
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit 0 ;;
|
||||
i86pc:SunOS:5.*:*)
|
||||
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit 0 ;;
|
||||
sun4*:SunOS:6*:*)
|
||||
# According to config.sub, this is the proper way to canonicalize
|
||||
# SunOS6. Hard to guess exactly what SunOS6 will be like, but
|
||||
# it's likely to be more like Solaris than SunOS4.
|
||||
echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit 0 ;;
|
||||
sun4*:SunOS:*:*)
|
||||
case "`/usr/bin/arch -k`" in
|
||||
Series*|S4*)
|
||||
UNAME_RELEASE=`uname -v`
|
||||
;;
|
||||
esac
|
||||
# Japanese Language versions have a version number like `4.1.3-JL'.
|
||||
echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
|
||||
exit 0 ;;
|
||||
sun3*:SunOS:*:*)
|
||||
echo m68k-sun-sunos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
sun*:*:4.2BSD:*)
|
||||
UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
|
||||
test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
|
||||
case "`/bin/arch`" in
|
||||
sun3)
|
||||
echo m68k-sun-sunos${UNAME_RELEASE}
|
||||
;;
|
||||
sun4)
|
||||
echo sparc-sun-sunos${UNAME_RELEASE}
|
||||
;;
|
||||
esac
|
||||
exit 0 ;;
|
||||
aushp:SunOS:*:*)
|
||||
echo sparc-auspex-sunos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
atari*:NetBSD:*:*)
|
||||
echo m68k-atari-netbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
atari*:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
sun3*:NetBSD:*:*)
|
||||
echo m68k-sun-netbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
sun3*:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mac68k:NetBSD:*:*)
|
||||
echo m68k-apple-netbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mac68k:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mvme68k:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mvme88k:OpenBSD:*:*)
|
||||
echo m88k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
powerpc:machten:*:*)
|
||||
echo powerpc-apple-machten${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
RISC*:Mach:*:*)
|
||||
echo mips-dec-mach_bsd4.3
|
||||
exit 0 ;;
|
||||
RISC*:ULTRIX:*:*)
|
||||
echo mips-dec-ultrix${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
VAX*:ULTRIX*:*:*)
|
||||
echo vax-dec-ultrix${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
2020:CLIX:*:*)
|
||||
echo clipper-intergraph-clix${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mips:*:*:UMIPS | mips:*:*:RISCos)
|
||||
sed 's/^ //' << EOF >dummy.c
|
||||
int main (argc, argv) int argc; char **argv; {
|
||||
#if defined (host_mips) && defined (MIPSEB)
|
||||
#if defined (SYSTYPE_SYSV)
|
||||
printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
|
||||
#endif
|
||||
#if defined (SYSTYPE_SVR4)
|
||||
printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
|
||||
#endif
|
||||
#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
|
||||
printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
|
||||
#endif
|
||||
#endif
|
||||
exit (-1);
|
||||
}
|
||||
EOF
|
||||
${CC-cc} dummy.c -o dummy \
|
||||
&& ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
|
||||
&& rm dummy.c dummy && exit 0
|
||||
rm -f dummy.c dummy
|
||||
echo mips-mips-riscos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
Night_Hawk:Power_UNIX:*:*)
|
||||
echo powerpc-harris-powerunix
|
||||
exit 0 ;;
|
||||
m88k:CX/UX:7*:*)
|
||||
echo m88k-harris-cxux7
|
||||
exit 0 ;;
|
||||
m88k:*:4*:R4*)
|
||||
echo m88k-motorola-sysv4
|
||||
exit 0 ;;
|
||||
m88k:*:3*:R3*)
|
||||
echo m88k-motorola-sysv3
|
||||
exit 0 ;;
|
||||
AViiON:dgux:*:*)
|
||||
# DG/UX returns AViiON for all architectures
|
||||
UNAME_PROCESSOR=`/usr/bin/uname -p`
|
||||
if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
|
||||
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
|
||||
-o ${TARGET_BINARY_INTERFACE}x = x ] ; then
|
||||
echo m88k-dg-dgux${UNAME_RELEASE}
|
||||
else
|
||||
echo m88k-dg-dguxbcs${UNAME_RELEASE}
|
||||
fi
|
||||
else echo i586-dg-dgux${UNAME_RELEASE}
|
||||
fi
|
||||
exit 0 ;;
|
||||
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
|
||||
echo m88k-dolphin-sysv3
|
||||
exit 0 ;;
|
||||
M88*:*:R3*:*)
|
||||
# Delta 88k system running SVR3
|
||||
echo m88k-motorola-sysv3
|
||||
exit 0 ;;
|
||||
XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
|
||||
echo m88k-tektronix-sysv3
|
||||
exit 0 ;;
|
||||
Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
|
||||
echo m68k-tektronix-bsd
|
||||
exit 0 ;;
|
||||
*:IRIX*:*:*)
|
||||
echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
|
||||
exit 0 ;;
|
||||
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
|
||||
echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
|
||||
exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
|
||||
i?86:AIX:*:*)
|
||||
echo i386-ibm-aix
|
||||
exit 0 ;;
|
||||
*:AIX:2:3)
|
||||
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
|
||||
sed 's/^ //' << EOF >dummy.c
|
||||
#include <sys/systemcfg.h>
|
||||
|
||||
main()
|
||||
{
|
||||
if (!__power_pc())
|
||||
exit(1);
|
||||
puts("powerpc-ibm-aix3.2.5");
|
||||
exit(0);
|
||||
}
|
||||
EOF
|
||||
${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
|
||||
rm -f dummy.c dummy
|
||||
echo rs6000-ibm-aix3.2.5
|
||||
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
|
||||
echo rs6000-ibm-aix3.2.4
|
||||
else
|
||||
echo rs6000-ibm-aix3.2
|
||||
fi
|
||||
exit 0 ;;
|
||||
*:AIX:*:4)
|
||||
if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then
|
||||
IBM_ARCH=rs6000
|
||||
else
|
||||
IBM_ARCH=powerpc
|
||||
fi
|
||||
if [ -x /usr/bin/oslevel ] ; then
|
||||
IBM_REV=`/usr/bin/oslevel`
|
||||
else
|
||||
IBM_REV=4.${UNAME_RELEASE}
|
||||
fi
|
||||
echo ${IBM_ARCH}-ibm-aix${IBM_REV}
|
||||
exit 0 ;;
|
||||
*:AIX:*:*)
|
||||
echo rs6000-ibm-aix
|
||||
exit 0 ;;
|
||||
ibmrt:4.4BSD:*|romp-ibm:BSD:*)
|
||||
echo romp-ibm-bsd4.4
|
||||
exit 0 ;;
|
||||
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and
|
||||
echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
|
||||
exit 0 ;; # report: romp-ibm BSD 4.3
|
||||
*:BOSX:*:*)
|
||||
echo rs6000-bull-bosx
|
||||
exit 0 ;;
|
||||
DPX/2?00:B.O.S.:*:*)
|
||||
echo m68k-bull-sysv3
|
||||
exit 0 ;;
|
||||
9000/[34]??:4.3bsd:1.*:*)
|
||||
echo m68k-hp-bsd
|
||||
exit 0 ;;
|
||||
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
|
||||
echo m68k-hp-bsd4.4
|
||||
exit 0 ;;
|
||||
9000/[3478]??:HP-UX:*:*)
|
||||
case "${UNAME_MACHINE}" in
|
||||
9000/31? ) HP_ARCH=m68000 ;;
|
||||
9000/[34]?? ) HP_ARCH=m68k ;;
|
||||
9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1 ;;
|
||||
9000/8?? ) HP_ARCH=hppa1.0 ;;
|
||||
esac
|
||||
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
|
||||
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
|
||||
exit 0 ;;
|
||||
3050*:HI-UX:*:*)
|
||||
sed 's/^ //' << EOF >dummy.c
|
||||
#include <unistd.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
long cpu = sysconf (_SC_CPU_VERSION);
|
||||
/* The order matters, because CPU_IS_HP_MC68K erroneously returns
|
||||
true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
|
||||
results, however. */
|
||||
if (CPU_IS_PA_RISC (cpu))
|
||||
{
|
||||
switch (cpu)
|
||||
{
|
||||
case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
|
||||
case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
|
||||
case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
|
||||
default: puts ("hppa-hitachi-hiuxwe2"); break;
|
||||
}
|
||||
}
|
||||
else if (CPU_IS_HP_MC68K (cpu))
|
||||
puts ("m68k-hitachi-hiuxwe2");
|
||||
else puts ("unknown-hitachi-hiuxwe2");
|
||||
exit (0);
|
||||
}
|
||||
EOF
|
||||
${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
|
||||
rm -f dummy.c dummy
|
||||
echo unknown-hitachi-hiuxwe2
|
||||
exit 0 ;;
|
||||
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
|
||||
echo hppa1.1-hp-bsd
|
||||
exit 0 ;;
|
||||
9000/8??:4.3bsd:*:*)
|
||||
echo hppa1.0-hp-bsd
|
||||
exit 0 ;;
|
||||
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
|
||||
echo hppa1.1-hp-osf
|
||||
exit 0 ;;
|
||||
hp8??:OSF1:*:*)
|
||||
echo hppa1.0-hp-osf
|
||||
exit 0 ;;
|
||||
i?86:OSF1:*:*)
|
||||
if [ -x /usr/sbin/sysversion ] ; then
|
||||
echo ${UNAME_MACHINE}-unknown-osf1mk
|
||||
else
|
||||
echo ${UNAME_MACHINE}-unknown-osf1
|
||||
fi
|
||||
exit 0 ;;
|
||||
parisc*:Lites*:*:*)
|
||||
echo hppa1.1-hp-lites
|
||||
exit 0 ;;
|
||||
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
|
||||
echo c1-convex-bsd
|
||||
exit 0 ;;
|
||||
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
|
||||
if getsysinfo -f scalar_acc
|
||||
then echo c32-convex-bsd
|
||||
else echo c2-convex-bsd
|
||||
fi
|
||||
exit 0 ;;
|
||||
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
|
||||
echo c34-convex-bsd
|
||||
exit 0 ;;
|
||||
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
|
||||
echo c38-convex-bsd
|
||||
exit 0 ;;
|
||||
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
|
||||
echo c4-convex-bsd
|
||||
exit 0 ;;
|
||||
CRAY*X-MP:*:*:*)
|
||||
echo xmp-cray-unicos
|
||||
exit 0 ;;
|
||||
CRAY*Y-MP:*:*:*)
|
||||
echo ymp-cray-unicos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
CRAY*[A-Z]90:*:*:*)
|
||||
echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
|
||||
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
|
||||
-e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
|
||||
exit 0 ;;
|
||||
CRAY*TS:*:*:*)
|
||||
echo t90-cray-unicos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
CRAY-2:*:*:*)
|
||||
echo cray2-cray-unicos
|
||||
exit 0 ;;
|
||||
F300:UNIX_System_V:*:*)
|
||||
FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
|
||||
echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
exit 0 ;;
|
||||
F301:UNIX_System_V:*:*)
|
||||
echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
|
||||
exit 0 ;;
|
||||
hp3[0-9][05]:NetBSD:*:*)
|
||||
echo m68k-hp-netbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
hp300:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
i?86:BSD/386:*:* | *:BSD/OS:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:FreeBSD:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
|
||||
exit 0 ;;
|
||||
*:NetBSD:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
|
||||
exit 0 ;;
|
||||
*:OpenBSD:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
|
||||
exit 0 ;;
|
||||
i*:CYGWIN*:*)
|
||||
echo i386-pc-cygwin32
|
||||
exit 0 ;;
|
||||
i*:MINGW*:*)
|
||||
echo i386-pc-mingw32
|
||||
exit 0 ;;
|
||||
p*:CYGWIN*:*)
|
||||
echo powerpcle-unknown-cygwin32
|
||||
exit 0 ;;
|
||||
prep*:SunOS:5.*:*)
|
||||
echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit 0 ;;
|
||||
*:GNU:*:*)
|
||||
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
|
||||
exit 0 ;;
|
||||
*:Linux:*:*)
|
||||
# The BFD linker knows what the default object file format is, so
|
||||
# first see if it will tell us.
|
||||
ld_help_string=`ld --help 2>&1`
|
||||
ld_supported_emulations=`echo $ld_help_string \
|
||||
| sed -ne '/supported emulations:/!d
|
||||
s/[ ][ ]*/ /g
|
||||
s/.*supported emulations: *//
|
||||
s/ .*//
|
||||
p'`
|
||||
case "$ld_supported_emulations" in
|
||||
i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;;
|
||||
i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;;
|
||||
sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
|
||||
m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
|
||||
elf32ppc)
|
||||
# Determine Lib Version
|
||||
cat >dummy.c <<EOF
|
||||
#include <features.h>
|
||||
#if defined(__GLIBC__)
|
||||
extern char __libc_version[];
|
||||
extern char __libc_release[];
|
||||
#endif
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
#if defined(__GLIBC__)
|
||||
printf("%s %s\n", __libc_version, __libc_release);
|
||||
#else
|
||||
printf("unkown\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
LIBC=""
|
||||
${CC-cc} dummy.c -o dummy 2>/dev/null
|
||||
if test "$?" = 0 ; then
|
||||
./dummy | grep 1\.99 > /dev/null
|
||||
if test "$?" = 0 ; then
|
||||
LIBC="libc1"
|
||||
fi
|
||||
fi
|
||||
rm -f dummy.c dummy
|
||||
echo powerpc-unknown-linux-gnu${LIBC} ; exit 0 ;;
|
||||
esac
|
||||
|
||||
if test "${UNAME_MACHINE}" = "alpha" ; then
|
||||
sed 's/^ //' <<EOF >dummy.s
|
||||
.globl main
|
||||
.ent main
|
||||
main:
|
||||
.frame \$30,0,\$26,0
|
||||
.prologue 0
|
||||
.long 0x47e03d80 # implver $0
|
||||
lda \$2,259
|
||||
.long 0x47e20c21 # amask $2,$1
|
||||
srl \$1,8,\$2
|
||||
sll \$2,2,\$2
|
||||
sll \$0,3,\$0
|
||||
addl \$1,\$0,\$0
|
||||
addl \$2,\$0,\$0
|
||||
ret \$31,(\$26),1
|
||||
.end main
|
||||
EOF
|
||||
LIBC=""
|
||||
${CC-cc} dummy.s -o dummy 2>/dev/null
|
||||
if test "$?" = 0 ; then
|
||||
./dummy
|
||||
case "$?" in
|
||||
7)
|
||||
UNAME_MACHINE="alpha"
|
||||
;;
|
||||
15)
|
||||
UNAME_MACHINE="alphaev5"
|
||||
;;
|
||||
14)
|
||||
UNAME_MACHINE="alphaev56"
|
||||
;;
|
||||
10)
|
||||
UNAME_MACHINE="alphapca56"
|
||||
;;
|
||||
16)
|
||||
UNAME_MACHINE="alphaev6"
|
||||
;;
|
||||
esac
|
||||
|
||||
objdump --private-headers dummy | \
|
||||
grep ld.so.1 > /dev/null
|
||||
if test "$?" = 0 ; then
|
||||
LIBC="libc1"
|
||||
fi
|
||||
fi
|
||||
rm -f dummy.s dummy
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
|
||||
elif test "${UNAME_MACHINE}" = "mips" ; then
|
||||
cat >dummy.c <<EOF
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
#ifdef __MIPSEB__
|
||||
printf ("%s-unknown-linux-gnu\n", argv[1]);
|
||||
#endif
|
||||
#ifdef __MIPSEL__
|
||||
printf ("%sel-unknown-linux-gnu\n", argv[1]);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
|
||||
rm -f dummy.c dummy
|
||||
else
|
||||
# Either a pre-BFD a.out linker (linux-gnuoldld)
|
||||
# or one that does not give us useful --help.
|
||||
# GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
|
||||
# If ld does not provide *any* "supported emulations:"
|
||||
# that means it is gnuoldld.
|
||||
echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:"
|
||||
test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
|
||||
|
||||
case "${UNAME_MACHINE}" in
|
||||
i?86)
|
||||
VENDOR=pc;
|
||||
;;
|
||||
*)
|
||||
VENDOR=unknown;
|
||||
;;
|
||||
esac
|
||||
# Determine whether the default compiler is a.out or elf
|
||||
cat >dummy.c <<EOF
|
||||
#include <features.h>
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
#ifdef __ELF__
|
||||
# ifdef __GLIBC__
|
||||
# if __GLIBC__ >= 2
|
||||
printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
|
||||
# else
|
||||
printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
|
||||
# endif
|
||||
# else
|
||||
printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
|
||||
# endif
|
||||
#else
|
||||
printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
|
||||
rm -f dummy.c dummy
|
||||
fi ;;
|
||||
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
|
||||
# are messed up and put the nodename in both sysname and nodename.
|
||||
i?86:DYNIX/ptx:4*:*)
|
||||
echo i386-sequent-sysv4
|
||||
exit 0 ;;
|
||||
i?86:UNIX_SV:4.2MP:2.*)
|
||||
# Unixware is an offshoot of SVR4, but it has its own version
|
||||
# number series starting with 2...
|
||||
# I am not positive that other SVR4 systems won't match this,
|
||||
# I just have to hope. -- rms.
|
||||
# Use sysv4.2uw... so that sysv4* matches it.
|
||||
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
|
||||
exit 0 ;;
|
||||
i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
|
||||
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
|
||||
echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
|
||||
else
|
||||
echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
|
||||
fi
|
||||
exit 0 ;;
|
||||
i?86:*:3.2:*)
|
||||
if test -f /usr/options/cb.name; then
|
||||
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
|
||||
echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
|
||||
elif /bin/uname -X 2>/dev/null >/dev/null ; then
|
||||
UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
|
||||
(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
|
||||
(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
|
||||
&& UNAME_MACHINE=i586
|
||||
echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
|
||||
else
|
||||
echo ${UNAME_MACHINE}-pc-sysv32
|
||||
fi
|
||||
exit 0 ;;
|
||||
pc:*:*:*)
|
||||
# uname -m prints for DJGPP always 'pc', but it prints nothing about
|
||||
# the processor, so we play safe by assuming i386.
|
||||
echo i386-pc-msdosdjgpp
|
||||
exit 0 ;;
|
||||
Intel:Mach:3*:*)
|
||||
echo i386-pc-mach3
|
||||
exit 0 ;;
|
||||
paragon:*:*:*)
|
||||
echo i860-intel-osf1
|
||||
exit 0 ;;
|
||||
i860:*:4.*:*) # i860-SVR4
|
||||
if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
|
||||
echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
|
||||
else # Add other i860-SVR4 vendors below as they are discovered.
|
||||
echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
|
||||
fi
|
||||
exit 0 ;;
|
||||
mini*:CTIX:SYS*5:*)
|
||||
# "miniframe"
|
||||
echo m68010-convergent-sysv
|
||||
exit 0 ;;
|
||||
M68*:*:R3V[567]*:*)
|
||||
test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
|
||||
3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
|
||||
OS_REL=''
|
||||
test -r /etc/.relid \
|
||||
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
|
||||
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||
&& echo i486-ncr-sysv4.3${OS_REL} && exit 0
|
||||
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
|
||||
&& echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
|
||||
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
|
||||
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||
&& echo i486-ncr-sysv4 && exit 0 ;;
|
||||
m68*:LynxOS:2.*:*)
|
||||
echo m68k-unknown-lynxos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mc68030:UNIX_System_V:4.*:*)
|
||||
echo m68k-atari-sysv4
|
||||
exit 0 ;;
|
||||
i?86:LynxOS:2.*:*)
|
||||
echo i386-unknown-lynxos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
TSUNAMI:LynxOS:2.*:*)
|
||||
echo sparc-unknown-lynxos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
|
||||
echo rs6000-unknown-lynxos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
SM[BE]S:UNIX_SV:*:*)
|
||||
echo mips-dde-sysv${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
RM*:SINIX-*:*:*)
|
||||
echo mips-sni-sysv4
|
||||
exit 0 ;;
|
||||
*:SINIX-*:*:*)
|
||||
if uname -p 2>/dev/null >/dev/null ; then
|
||||
UNAME_MACHINE=`(uname -p) 2>/dev/null`
|
||||
echo ${UNAME_MACHINE}-sni-sysv4
|
||||
else
|
||||
echo ns32k-sni-sysv
|
||||
fi
|
||||
exit 0 ;;
|
||||
PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
|
||||
# says <Richard.M.Bartel@ccMail.Census.GOV>
|
||||
echo i586-unisys-sysv4
|
||||
exit 0 ;;
|
||||
*:UNIX_System_V:4*:FTX*)
|
||||
# From Gerald Hewes <hewes@openmarket.com>.
|
||||
# How about differentiating between stratus architectures? -djm
|
||||
echo hppa1.1-stratus-sysv4
|
||||
exit 0 ;;
|
||||
*:*:*:FTX*)
|
||||
# From seanf@swdc.stratus.com.
|
||||
echo i860-stratus-sysv4
|
||||
exit 0 ;;
|
||||
mc68*:A/UX:*:*)
|
||||
echo m68k-apple-aux${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
news*:NEWS-OS:*:6*)
|
||||
echo mips-sony-newsos6
|
||||
exit 0 ;;
|
||||
R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*)
|
||||
if [ -d /usr/nec ]; then
|
||||
echo mips-nec-sysv${UNAME_RELEASE}
|
||||
else
|
||||
echo mips-unknown-sysv${UNAME_RELEASE}
|
||||
fi
|
||||
exit 0 ;;
|
||||
esac
|
||||
|
||||
#echo '(No uname command or uname output not recognized.)' 1>&2
|
||||
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
|
||||
|
||||
cat >dummy.c <<EOF
|
||||
#ifdef _SEQUENT_
|
||||
# include <sys/types.h>
|
||||
# include <sys/utsname.h>
|
||||
#endif
|
||||
main ()
|
||||
{
|
||||
#if defined (sony)
|
||||
#if defined (MIPSEB)
|
||||
/* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
|
||||
I don't know.... */
|
||||
printf ("mips-sony-bsd\n"); exit (0);
|
||||
#else
|
||||
#include <sys/param.h>
|
||||
printf ("m68k-sony-newsos%s\n",
|
||||
#ifdef NEWSOS4
|
||||
"4"
|
||||
#else
|
||||
""
|
||||
#endif
|
||||
); exit (0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined (__arm) && defined (__acorn) && defined (__unix)
|
||||
printf ("arm-acorn-riscix"); exit (0);
|
||||
#endif
|
||||
|
||||
#if defined (hp300) && !defined (hpux)
|
||||
printf ("m68k-hp-bsd\n"); exit (0);
|
||||
#endif
|
||||
|
||||
#if defined (NeXT)
|
||||
#if !defined (__ARCHITECTURE__)
|
||||
#define __ARCHITECTURE__ "m68k"
|
||||
#endif
|
||||
int version;
|
||||
version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
|
||||
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
|
||||
exit (0);
|
||||
#endif
|
||||
|
||||
#if defined (MULTIMAX) || defined (n16)
|
||||
#if defined (UMAXV)
|
||||
printf ("ns32k-encore-sysv\n"); exit (0);
|
||||
#else
|
||||
#if defined (CMU)
|
||||
printf ("ns32k-encore-mach\n"); exit (0);
|
||||
#else
|
||||
printf ("ns32k-encore-bsd\n"); exit (0);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined (__386BSD__)
|
||||
printf ("i386-pc-bsd\n"); exit (0);
|
||||
#endif
|
||||
|
||||
#if defined (sequent)
|
||||
#if defined (i386)
|
||||
printf ("i386-sequent-dynix\n"); exit (0);
|
||||
#endif
|
||||
#if defined (ns32000)
|
||||
printf ("ns32k-sequent-dynix\n"); exit (0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined (_SEQUENT_)
|
||||
struct utsname un;
|
||||
|
||||
uname(&un);
|
||||
|
||||
if (strncmp(un.version, "V2", 2) == 0) {
|
||||
printf ("i386-sequent-ptx2\n"); exit (0);
|
||||
}
|
||||
if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
|
||||
printf ("i386-sequent-ptx1\n"); exit (0);
|
||||
}
|
||||
printf ("i386-sequent-ptx\n"); exit (0);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined (vax)
|
||||
#if !defined (ultrix)
|
||||
printf ("vax-dec-bsd\n"); exit (0);
|
||||
#else
|
||||
printf ("vax-dec-ultrix\n"); exit (0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined (alliant) && defined (i860)
|
||||
printf ("i860-alliant-bsd\n"); exit (0);
|
||||
#endif
|
||||
|
||||
exit (1);
|
||||
}
|
||||
EOF
|
||||
|
||||
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0
|
||||
rm -f dummy.c dummy
|
||||
|
||||
# Apollos put the system type in the environment.
|
||||
|
||||
test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
|
||||
|
||||
# Convex versions that predate uname can use getsysinfo(1)
|
||||
|
||||
if [ -x /usr/convex/getsysinfo ]
|
||||
then
|
||||
case `getsysinfo -f cpu_type` in
|
||||
c1*)
|
||||
echo c1-convex-bsd
|
||||
exit 0 ;;
|
||||
c2*)
|
||||
if getsysinfo -f scalar_acc
|
||||
then echo c32-convex-bsd
|
||||
else echo c2-convex-bsd
|
||||
fi
|
||||
exit 0 ;;
|
||||
c34*)
|
||||
echo c34-convex-bsd
|
||||
exit 0 ;;
|
||||
c38*)
|
||||
echo c38-convex-bsd
|
||||
exit 0 ;;
|
||||
c4*)
|
||||
echo c4-convex-bsd
|
||||
exit 0 ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
#echo '(Unable to guess system type)' 1>&2
|
||||
|
||||
exit 1
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
#ifndef __config_H
|
||||
#define __config_H
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form 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
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: config.h.in,v 1.1 2001/03/11 00:29:38 steve Exp $"
|
||||
#endif
|
||||
|
||||
# define SIZEOF_UNSIGNED_LONG 0
|
||||
# define SIZEOF_UNSIGNED 0
|
||||
|
||||
|
||||
/*
|
||||
* $Log: config.h.in,v $
|
||||
* Revision 1.1 2001/03/11 00:29:38 steve
|
||||
* Add the vvp engine to cvs.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,13 @@
|
|||
AC_INIT(Makefile.in)
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AC_CHECK_TOOL(STRIP, strip, true)
|
||||
|
||||
AC_PROG_INSTALL
|
||||
|
||||
AC_CHECK_SIZEOF(unsigned long)
|
||||
AC_CHECK_SIZEOF(unsigned)
|
||||
|
||||
AC_OUTPUT(Makefile)
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form 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
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: functor.cc,v 1.1 2001/03/11 00:29:38 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "functor.h"
|
||||
# include <assert.h>
|
||||
|
||||
/*
|
||||
* Functors are created as the source design is read in. Each is
|
||||
* assigned an ipoint_t address starting from 1. The design is
|
||||
* expected to have a create many functors, so it makes sense to
|
||||
* allocate the functors in chunks. This structure describes a chunk
|
||||
* of functors.
|
||||
*
|
||||
* The 32bit vvp_ipoint_t allows for 2**30 functors in the
|
||||
* design. (2 bits are used to select the input of the functor.) The
|
||||
* functor address is, for the purpose of lookup up addresses, divided
|
||||
* into three parts, the index within a chunk, the index of the chunk
|
||||
* within an index1 table, and the index of the index1 within the root
|
||||
* table. There is a single root table. The index1 tables and chunk
|
||||
* tables are allocated as needed.
|
||||
*/
|
||||
|
||||
const unsigned functor_index0_size = 2 << 9;
|
||||
const unsigned functor_index1_size = 2 << 11;
|
||||
const unsigned functor_index2_size = 2 << 10;
|
||||
|
||||
struct functor_index0 {
|
||||
struct functor_s table[functor_index0_size];
|
||||
};
|
||||
|
||||
struct functor_index1 {
|
||||
struct functor_index0* table[functor_index1_size];
|
||||
};
|
||||
|
||||
static vvp_ipoint_t functor_count = 0;
|
||||
static struct functor_index1*functor_table[functor_index2_size] = { 0 };
|
||||
|
||||
|
||||
/*
|
||||
* This function initializes the functor address space by creating the
|
||||
* zero functor. This means creating a functor_index1 and a
|
||||
* functor_index0, and initializing the count to 1.
|
||||
*/
|
||||
void functor_init(void)
|
||||
{
|
||||
functor_table[0] = new struct functor_index1;
|
||||
functor_table[0]->table[0] = new struct functor_index0;
|
||||
functor_count = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate normall is just a matter of incrementing the functor_count
|
||||
* and returning a pointer to the next unallocated functor. However,
|
||||
* if we overrun a chunk or an index, we need to allocate the needed
|
||||
* bits first.
|
||||
*/
|
||||
vvp_ipoint_t functor_allocate(void)
|
||||
{
|
||||
vvp_ipoint_t idx = functor_count;
|
||||
|
||||
idx /= functor_index0_size;
|
||||
|
||||
unsigned index1 = idx % functor_index1_size;
|
||||
idx /= functor_index1_size;
|
||||
|
||||
assert( idx < functor_index2_size);
|
||||
|
||||
if (functor_table[idx] == 0)
|
||||
functor_table[idx] = new struct functor_index1;
|
||||
|
||||
if (functor_table[idx]->table[index1] == 0)
|
||||
functor_table[idx]->table[index1] = new struct functor_index0;
|
||||
|
||||
vvp_ipoint_t res = functor_count;
|
||||
functor_count += 1;
|
||||
return res * 4;
|
||||
}
|
||||
|
||||
|
||||
functor_t functor_index(vvp_ipoint_t point)
|
||||
{
|
||||
point /= 4;
|
||||
|
||||
assert(point < functor_count);
|
||||
assert(point > 0);
|
||||
|
||||
unsigned index0 = point % functor_index0_size;
|
||||
point /= functor_index0_size;
|
||||
|
||||
unsigned index1 = point % functor_index1_size;
|
||||
point /= functor_index1_size;
|
||||
|
||||
return functor_table[point]->table[index1]->table + index0;
|
||||
}
|
||||
|
||||
|
||||
void functor_dump(FILE*fd)
|
||||
{
|
||||
for (unsigned idx = 1 ; idx < functor_count ; idx += 1) {
|
||||
functor_t cur = functor_index(idx*4);
|
||||
fprintf(fd, "%10p: out=%x port={%x %x %x %x}\n", idx*4,
|
||||
cur->out, cur->port[0], cur->port[1],
|
||||
cur->port[2], cur->port[3]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: functor.cc,v $
|
||||
* Revision 1.1 2001/03/11 00:29:38 steve
|
||||
* Add the vvp engine to cvs.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
#ifndef __functor_H
|
||||
#define __functor_H
|
||||
/*
|
||||
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form 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
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: functor.h,v 1.1 2001/03/11 00:29:38 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "pointers.h"
|
||||
# include <stdio.h>
|
||||
|
||||
typedef struct vvp_truth_s*vvp_truth_t;
|
||||
|
||||
/*
|
||||
* The vvp_ipoint_t is an integral type that is 32bits. The low 2 bits
|
||||
* select the port of the referenced functor, and the remaining 30
|
||||
* index the functor itself. All together, the 32 bits can completely
|
||||
* identify any input of any functor.
|
||||
*
|
||||
* Outputs of functors are the heads of a linked list of all the
|
||||
* inputs that it is connected to. The vvp_ipoint_t in .out points to
|
||||
* the first port in the list. The .port[x] in turn points to the next
|
||||
* port, and so on. The last .port[x] contains the null vvp_ipoint_t
|
||||
* value zero (0). In this way, an output can fan out as wide as the
|
||||
* original design requires.
|
||||
*/
|
||||
|
||||
struct functor_s {
|
||||
/* This is the truth table for the device */
|
||||
vvp_truth_t table;
|
||||
/* This is the output for the device. */
|
||||
vvp_ipoint_t out;
|
||||
/* These are the input ports. */
|
||||
vvp_ipoint_t port[4];
|
||||
};
|
||||
|
||||
typedef struct functor_s *functor_t;
|
||||
|
||||
/*
|
||||
* Initialize the functors address space. This function must be called
|
||||
* exactly once before any of the other functor functions may be
|
||||
* called.
|
||||
*/
|
||||
extern void functor_init(void);
|
||||
|
||||
/*
|
||||
* This function allocates a functor and returns the vvp_ipoint_t
|
||||
* address for it. Every call to functor_allocate is guaranteed to
|
||||
* return a different vvp_ipoint_t address. The ipoint port bits are 0.
|
||||
*/
|
||||
extern vvp_ipoint_t functor_allocate(void);
|
||||
|
||||
/*
|
||||
* Given an ipoint_t pointer, return a C pointer to the functor. This
|
||||
* is like a pointer dereference. The point parameter must have been
|
||||
* returned from a previous call to functor_allocate.
|
||||
*/
|
||||
extern functor_t functor_index(vvp_ipoint_t point);
|
||||
|
||||
/*
|
||||
* Dump a readable version of the functor address space to the file.
|
||||
*/
|
||||
extern void functor_dump(FILE*fd);
|
||||
|
||||
/*
|
||||
* $Log: functor.h,v $
|
||||
* Revision 1.1 2001/03/11 00:29:38 steve
|
||||
* Add the vvp engine to cvs.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
|
@ -0,0 +1,238 @@
|
|||
#! /bin/sh
|
||||
#
|
||||
# install - install a program, script, or datafile
|
||||
# This comes from X11R5.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# `make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch.
|
||||
#
|
||||
|
||||
|
||||
# set DOITPROG to echo to test this script
|
||||
|
||||
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||
doit="${DOITPROG-}"
|
||||
|
||||
|
||||
# put in absolute paths if you don't have them in your path; or use env. vars.
|
||||
|
||||
mvprog="${MVPROG-mv}"
|
||||
cpprog="${CPPROG-cp}"
|
||||
chmodprog="${CHMODPROG-chmod}"
|
||||
chownprog="${CHOWNPROG-chown}"
|
||||
chgrpprog="${CHGRPPROG-chgrp}"
|
||||
stripprog="${STRIPPROG-strip}"
|
||||
rmprog="${RMPROG-rm}"
|
||||
mkdirprog="${MKDIRPROG-mkdir}"
|
||||
|
||||
transformbasename=""
|
||||
transform_arg=""
|
||||
instcmd="$mvprog"
|
||||
chmodcmd="$chmodprog 0755"
|
||||
chowncmd=""
|
||||
chgrpcmd=""
|
||||
stripcmd=""
|
||||
rmcmd="$rmprog -f"
|
||||
mvcmd="$mvprog"
|
||||
src=""
|
||||
dst=""
|
||||
dir_arg=""
|
||||
|
||||
while [ x"$1" != x ]; do
|
||||
case $1 in
|
||||
-c) instcmd="$cpprog"
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-d) dir_arg=true
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-m) chmodcmd="$chmodprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-s) stripcmd="$stripprog"
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
|
||||
shift
|
||||
continue;;
|
||||
|
||||
*) if [ x"$src" = x ]
|
||||
then
|
||||
src=$1
|
||||
else
|
||||
# this colon is to work around a 386BSD /bin/sh bug
|
||||
:
|
||||
dst=$1
|
||||
fi
|
||||
shift
|
||||
continue;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ x"$src" = x ]
|
||||
then
|
||||
echo "install: no input file specified"
|
||||
exit 1
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
if [ x"$dir_arg" != x ]; then
|
||||
dst=$src
|
||||
src=""
|
||||
|
||||
if [ -d $dst ]; then
|
||||
instcmd=:
|
||||
else
|
||||
instcmd=mkdir
|
||||
fi
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
|
||||
if [ -f $src -o -d $src ]
|
||||
then
|
||||
true
|
||||
else
|
||||
echo "install: $src does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ x"$dst" = x ]
|
||||
then
|
||||
echo "install: no destination specified"
|
||||
exit 1
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
# If destination is a directory, append the input filename; if your system
|
||||
# does not like double slashes in filenames, you may need to add some logic
|
||||
|
||||
if [ -d $dst ]
|
||||
then
|
||||
dst="$dst"/`basename $src`
|
||||
else
|
||||
true
|
||||
fi
|
||||
fi
|
||||
|
||||
## this sed command emulates the dirname command
|
||||
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
|
||||
|
||||
# Make sure that the destination directory exists.
|
||||
# this part is taken from Noah Friedman's mkinstalldirs script
|
||||
|
||||
# Skip lots of stat calls in the usual case.
|
||||
if [ ! -d "$dstdir" ]; then
|
||||
defaultIFS='
|
||||
'
|
||||
IFS="${IFS-${defaultIFS}}"
|
||||
|
||||
oIFS="${IFS}"
|
||||
# Some sh's can't handle IFS=/ for some reason.
|
||||
IFS='%'
|
||||
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
|
||||
IFS="${oIFS}"
|
||||
|
||||
pathcomp=''
|
||||
|
||||
while [ $# -ne 0 ] ; do
|
||||
pathcomp="${pathcomp}${1}"
|
||||
shift
|
||||
|
||||
if [ ! -d "${pathcomp}" ] ;
|
||||
then
|
||||
$mkdirprog "${pathcomp}"
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
pathcomp="${pathcomp}/"
|
||||
done
|
||||
fi
|
||||
|
||||
if [ x"$dir_arg" != x ]
|
||||
then
|
||||
$doit $instcmd $dst &&
|
||||
|
||||
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
|
||||
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
|
||||
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
|
||||
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
|
||||
else
|
||||
|
||||
# If we're going to rename the final executable, determine the name now.
|
||||
|
||||
if [ x"$transformarg" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
dstfile=`basename $dst $transformbasename |
|
||||
sed $transformarg`$transformbasename
|
||||
fi
|
||||
|
||||
# don't allow the sed command to completely eliminate the filename
|
||||
|
||||
if [ x"$dstfile" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
# Make a temp file name in the proper directory.
|
||||
|
||||
dsttmp=$dstdir/#inst.$$#
|
||||
|
||||
# Move or copy the file name to the temp name
|
||||
|
||||
$doit $instcmd $src $dsttmp &&
|
||||
|
||||
trap "rm -f ${dsttmp}" 0 &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits
|
||||
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $instcmd $src $dsttmp" command.
|
||||
|
||||
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
|
||||
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
|
||||
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
|
||||
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
|
||||
$doit $rmcmd -f $dstdir/$dstfile &&
|
||||
$doit $mvcmd $dsttmp $dstdir/$dstfile
|
||||
|
||||
fi &&
|
||||
|
||||
|
||||
exit 0
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
|
||||
%{
|
||||
# include "parse_misc.h"
|
||||
# include "compile.h"
|
||||
# include "parse.h"
|
||||
# include <string.h>
|
||||
%}
|
||||
|
||||
%%
|
||||
|
||||
/* A label is any non-blank text that appears left justified. */
|
||||
^[.$_a-zA-Z][.$_a-zA-Z0-9]* {
|
||||
yylval.text = strdup(yytext);
|
||||
return T_LABEL; }
|
||||
|
||||
|
||||
/* These are some keywords that are recognized. */
|
||||
".functor" { return K_FUNCTOR; }
|
||||
".thread" { return K_THREAD; }
|
||||
".var" { return K_VAR; }
|
||||
|
||||
|
||||
/* instructions start with a % character. The compiler decides what
|
||||
kind of instruction this really is. */
|
||||
"%"[.$_/a-zA-Z0-9]+ {
|
||||
yylval.text = strdup(yytext);
|
||||
return T_INSTR; }
|
||||
|
||||
[0-9][0-9]* {
|
||||
yylval.numb = strtoul(yytext, 0, 0);
|
||||
return T_NUMBER; }
|
||||
|
||||
"0x"[0-9a-fA-F]+ {
|
||||
yylval.numb = strtoul(yytext, 0, 0);
|
||||
return T_NUMBER; }
|
||||
|
||||
|
||||
/* Symbols are pretty much what is left. They are used to refer to
|
||||
labels so the rule must match a string that a label would match. */
|
||||
[.$_a-zA-Z][.$_a-zA-Z0-9]* {
|
||||
yylval.text = strdup(yytext);
|
||||
return T_SYMBOL; }
|
||||
|
||||
|
||||
/* Accept the common assembler style comments, treat them as white
|
||||
space. Of course, also skip white space. The semi-colon is
|
||||
special, though, in that it is also a statement terminator. */
|
||||
";".* { return ';'; }
|
||||
"#".* { ; }
|
||||
|
||||
[ \t\b] { ; }
|
||||
|
||||
\n { yyline += 1; }
|
||||
|
||||
. { return yytext[0]; }
|
||||
|
||||
%%
|
||||
|
||||
int yywrap()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form 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
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: main.cc,v 1.1 2001/03/11 00:29:38 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
# include "parse_misc.h"
|
||||
# include "compile.h"
|
||||
# include "schedule.h"
|
||||
# include <stdio.h>
|
||||
# include <getopt.h>
|
||||
|
||||
|
||||
int main(int argc, char*argv[])
|
||||
{
|
||||
int opt;
|
||||
unsigned flag_errors = 0;
|
||||
const char*dump_path = 0;
|
||||
const char*design_path = 0;
|
||||
|
||||
while ((opt = getopt(argc, argv, "D:")) != EOF) switch (opt) {
|
||||
case 'D':
|
||||
dump_path = optarg;
|
||||
break;
|
||||
default:
|
||||
flag_errors += 1;
|
||||
}
|
||||
|
||||
if (flag_errors)
|
||||
return flag_errors;
|
||||
|
||||
if (optind == argc) {
|
||||
fprintf(stderr, "%s: no input file.\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
design_path = argv[optind];
|
||||
|
||||
compile_init();
|
||||
compile_design(design_path);
|
||||
compile_cleanup();
|
||||
|
||||
if (dump_path) {
|
||||
FILE*fd = fopen(dump_path, "w");
|
||||
compile_dump(fd);
|
||||
}
|
||||
|
||||
schedule_simulate();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: main.cc,v $
|
||||
* Revision 1.1 2001/03/11 00:29:38 steve
|
||||
* Add the vvp engine to cvs.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
|
||||
EXECUTABLE INSTRUCTION OPCODES
|
||||
|
||||
Instruction opcodes all start with a % character and have 0 or more
|
||||
operands. In no case are there more then 3 operands.
|
||||
|
||||
|
||||
* %assign <var-label>, <delay>, <bit>
|
||||
|
||||
This does a non-blocking assignment to a variable. The <label>
|
||||
identifies the affected variable, and the <delay> gives the delay when
|
||||
the assignment takes place. The delay may be 0. For blocking
|
||||
assignments, see %set. The <bit> is the address of the thread register
|
||||
that contains the bit value to assign.
|
||||
|
||||
* %delay <delay>
|
||||
|
||||
This opcode pauses the thread, and causes it to be rescheduled for a
|
||||
time in the future. The <amount> is the number of the ticks in the
|
||||
future to reschedule, and is >= 0. If the %delay is zero, then the
|
||||
thread yields the processor for another thread, but will be resumed in
|
||||
the current time step.
|
||||
|
||||
* %load <bit>, <functor-label>
|
||||
|
||||
This instruction loads a value from the given functor output into the
|
||||
specified thread register bit.
|
||||
|
||||
* %set <var-label>, <bit>
|
||||
|
||||
This sets a bit of a variable, and is used to implement blocking
|
||||
assignments. The <label> identifies the variable to receive the new
|
||||
value. Once the set completes, the value is immediately available to
|
||||
be read out of the variable. The <bit> is the address of the thread
|
||||
register that contains the bit value to assign.
|
||||
|
||||
* %waitfor <functor-label>
|
||||
|
||||
XXXX
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
|
||||
%{
|
||||
# include "parse_misc.h"
|
||||
# include "compile.h"
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <assert.h>
|
||||
|
||||
/*
|
||||
* These are bits in the lexor.
|
||||
*/
|
||||
extern FILE*yyin;
|
||||
|
||||
%}
|
||||
|
||||
%union {
|
||||
char*text;
|
||||
unsigned long numb;
|
||||
struct textv_s textv;
|
||||
comp_operands_t opa;
|
||||
};
|
||||
|
||||
|
||||
%token K_FUNCTOR K_THREAD K_VAR
|
||||
|
||||
%token <text> T_INSTR
|
||||
%token <text> T_LABEL
|
||||
%token <numb> T_NUMBER
|
||||
%token <text> T_SYMBOL
|
||||
|
||||
%type <textv> symbols
|
||||
%type <opa> operand operands operands_opt
|
||||
|
||||
%%
|
||||
|
||||
/* A program is simply a list of statements. No other structure. */
|
||||
program
|
||||
: statement
|
||||
| program statement
|
||||
;
|
||||
|
||||
|
||||
/* A statement can be any of the following. In all cases, the
|
||||
statment is terminated by a semi-colon. In general, a statement
|
||||
has a label, an opcode of some source, and operands. The
|
||||
structure of the operands depends on the opcode. */
|
||||
|
||||
statement
|
||||
|
||||
/* Functor statements define functors. The functor must have a
|
||||
label and a type name, and may have operands. */
|
||||
|
||||
: T_LABEL K_FUNCTOR T_SYMBOL ',' symbols ';'
|
||||
{ struct textv_s obj = $5;
|
||||
compile_functor($1, $3, obj.cnt, obj.text);
|
||||
}
|
||||
| T_LABEL K_FUNCTOR T_SYMBOL ';'
|
||||
{ compile_functor($1, $3, 0, 0); }
|
||||
|
||||
/* Instructions may have a label, and have zero or more
|
||||
operands. The meaning of and restrictions on the operands depends
|
||||
on the specific instruction. */
|
||||
|
||||
| T_LABEL T_INSTR operands_opt ';'
|
||||
{ compile_code($1, $2, $3);
|
||||
}
|
||||
|
||||
| T_INSTR operands_opt ';'
|
||||
{ compile_code(0, $1, $2);
|
||||
}
|
||||
|
||||
/* Thread statements declare a thread with its starting address. The
|
||||
starting address must already be defined. */
|
||||
|
||||
| K_THREAD T_SYMBOL ';'
|
||||
{ compile_thread($2); }
|
||||
|
||||
/* Var statements declare a bit of a variable. This also implicitly
|
||||
creates a functor with the same name that acts as the output of
|
||||
the variable in the netlist. */
|
||||
|
||||
| T_LABEL K_VAR ';'
|
||||
{ compile_variable($1); }
|
||||
;
|
||||
|
||||
|
||||
operands_opt
|
||||
: operands { $$ = $1; }
|
||||
| { $$ = 0; }
|
||||
;
|
||||
|
||||
operands
|
||||
: operands ',' operand
|
||||
{ comp_operands_t opa = $1;
|
||||
assert(opa->argc < 3);
|
||||
assert($3->argc == 1);
|
||||
opa->argv[opa->argc] = $3->argv[0];
|
||||
opa->argc += 1;
|
||||
free($3);
|
||||
$$ = opa;
|
||||
}
|
||||
| operand
|
||||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
operand
|
||||
: T_SYMBOL
|
||||
{ comp_operands_t opa = (comp_operands_t)
|
||||
calloc(1, sizeof(struct comp_operands_s));
|
||||
opa->argc = 1;
|
||||
opa->argv[0].ltype = L_TEXT;
|
||||
opa->argv[0].text = $1;
|
||||
$$ = opa;
|
||||
}
|
||||
| T_NUMBER
|
||||
{ comp_operands_t opa = (comp_operands_t)
|
||||
calloc(1, sizeof(struct comp_operands_s));
|
||||
opa->argc = 1;
|
||||
opa->argv[0].ltype = L_NUMB;
|
||||
opa->argv[0].numb = $1;
|
||||
$$ = opa;
|
||||
}
|
||||
;
|
||||
|
||||
/* functor operands can only be a list of symbols. */
|
||||
symbols
|
||||
: T_SYMBOL
|
||||
{ struct textv_s obj;
|
||||
textv_init(&obj);
|
||||
textv_add(&obj, $1);
|
||||
$$ = obj;
|
||||
}
|
||||
| symbols ',' T_SYMBOL
|
||||
{ struct textv_s obj = $1;
|
||||
textv_add(&obj, $3);
|
||||
$$ = obj;
|
||||
}
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
int compile_design(const char*path)
|
||||
{
|
||||
yypath = path;
|
||||
yyline = 1;
|
||||
yyin = fopen(path, "r");
|
||||
int rc = yyparse();
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form 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
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: parse_misc.cc,v 1.1 2001/03/11 00:29:39 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "parse_misc.h"
|
||||
# include <stdio.h>
|
||||
# include <malloc.h>
|
||||
|
||||
const char*yypath;
|
||||
unsigned yyline;
|
||||
|
||||
void yyerror(const char*msg)
|
||||
{
|
||||
fprintf(stderr, "%s:%u: %s\n", yypath, yyline, msg);
|
||||
}
|
||||
|
||||
void textv_init(struct textv_s*obj)
|
||||
{
|
||||
obj->cnt = 0;
|
||||
obj->text = 0;
|
||||
}
|
||||
|
||||
void textv_add(struct textv_s*obj, char*item)
|
||||
{
|
||||
obj->text = realloc(obj->text, (obj->cnt+1) * sizeof(char*));
|
||||
obj->text[obj->cnt] = item;
|
||||
obj->cnt += 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: parse_misc.cc,v $
|
||||
* Revision 1.1 2001/03/11 00:29:39 steve
|
||||
* Add the vvp engine to cvs.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
#ifndef __parse_misc_H
|
||||
#define __parse_misc_H
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form 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
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: parse_misc.h,v 1.1 2001/03/11 00:29:39 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This method is called to compile the design file. The input is read
|
||||
* and a list of statements is created.
|
||||
*/
|
||||
extern int compile_design(const char*path);
|
||||
|
||||
/*
|
||||
* various functions shared by the lexor and the parser.
|
||||
*/
|
||||
extern int yylex(void);
|
||||
extern void yyerror(const char*msg);
|
||||
|
||||
/*
|
||||
* This is the path of the current source file.
|
||||
*/
|
||||
extern const char*yypath;
|
||||
extern unsigned yyline;
|
||||
|
||||
struct textv_s {
|
||||
unsigned cnt;
|
||||
char**text;
|
||||
};
|
||||
|
||||
extern void textv_init(struct textv_s*obj);
|
||||
extern void textv_add(struct textv_s*obj, char*item);
|
||||
|
||||
/*
|
||||
* $Log: parse_misc.h,v $
|
||||
* Revision 1.1 2001/03/11 00:29:39 steve
|
||||
* Add the vvp engine to cvs.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
#ifndef __pointers_H
|
||||
#define __pointers_H
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form 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
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: pointers.h,v 1.1 2001/03/11 00:29:39 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This header file describes the various "pointer" integral types
|
||||
* that are used in vvp, along with functions that can be used to
|
||||
* manipulate those pointers.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
||||
/*
|
||||
* The vvp_ipoint_t is a 32bit integer that encodes the address of a
|
||||
* functor input port.
|
||||
*
|
||||
* The typedef below gets the type properly declared as an integral
|
||||
* type that is big enough. The config.h header file has the defines
|
||||
* needed for the following pre-processor magic to work.
|
||||
*/
|
||||
# if SIZEOF_UNSIGNED >= 4
|
||||
typedef unsigned vvp_ipoint_t;
|
||||
#elif SIZEOF_UNSIGNED_LONG >= 4
|
||||
typedef unsigned long vvp_ipoint_t;
|
||||
#else
|
||||
#error "I need an unsigned type that is 32 bits!"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Given a functor generic address and a desired port, this function
|
||||
* makes a complete vvp_ipoint_t that points to the port of the given
|
||||
* functor. The The result points to the same functor as the input
|
||||
* pointer, but addresses the supplied port instead.
|
||||
*/
|
||||
inline vvp_ipoint_t ipoint_make(vvp_ipoint_t func, unsigned port)
|
||||
{
|
||||
return (func & ~3) | (port & 3);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function returns the port index of a functor given a complete
|
||||
* vvp_ipoint_t pointer.
|
||||
*/
|
||||
inline unsigned ipoint_port(vvp_ipoint_t func)
|
||||
{
|
||||
return func & 3;
|
||||
}
|
||||
|
||||
typedef unsigned vvp_cpoint_t;
|
||||
|
||||
/*
|
||||
* $Log: pointers.h,v $
|
||||
* Revision 1.1 2001/03/11 00:29:39 steve
|
||||
* Add the vvp engine to cvs.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form 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
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: schedule.cc,v 1.1 2001/03/11 00:29:39 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "schedule.h"
|
||||
# include "vthread.h"
|
||||
# include <malloc.h>
|
||||
# include <assert.h>
|
||||
|
||||
struct event_s {
|
||||
unsigned delay;
|
||||
|
||||
vthread_t thr;
|
||||
vvp_ipoint_t fun;
|
||||
|
||||
struct event_s*next;
|
||||
struct event_s*last;
|
||||
};
|
||||
|
||||
static struct event_s* list = 0;
|
||||
|
||||
static void schedule_event_(struct event_s*cur)
|
||||
{
|
||||
cur->last = cur;
|
||||
|
||||
if (list == 0) {
|
||||
list = cur;
|
||||
cur->next = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
struct event_s*idx = list;
|
||||
if (cur->delay < idx->delay) {
|
||||
idx->delay -= cur->delay;
|
||||
cur->next = idx;
|
||||
list = cur;
|
||||
|
||||
} else {
|
||||
struct event_s*prev = idx;
|
||||
|
||||
while (cur->delay > idx->delay) {
|
||||
cur->delay -= idx->delay;
|
||||
prev = idx->last;
|
||||
if (prev->next == 0) {
|
||||
cur->next = 0;
|
||||
prev->next = cur;
|
||||
return;
|
||||
}
|
||||
idx = prev->next;
|
||||
}
|
||||
|
||||
if (cur->delay < idx->delay) {
|
||||
idx->delay -= cur->delay;
|
||||
cur->last = cur;
|
||||
cur->next = idx;
|
||||
prev->next = cur;
|
||||
|
||||
} else {
|
||||
assert(cur->delay == idx->delay);
|
||||
cur->delay = 0;
|
||||
cur->last = cur;
|
||||
cur->next = idx->last->next;
|
||||
idx->last->next = cur;
|
||||
idx->last = cur;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void schedule_vthread(vthread_t thr, unsigned delay)
|
||||
{
|
||||
struct event_s*cur = (struct event_s*)
|
||||
calloc(1, sizeof(struct event_s));
|
||||
|
||||
cur->delay = delay;
|
||||
cur->thr = thr;
|
||||
|
||||
schedule_event_(cur);
|
||||
}
|
||||
|
||||
void schedule_functor(vvp_ipoint_t fun, unsigned delay)
|
||||
{
|
||||
struct event_s*cur = (struct event_s*)
|
||||
calloc(1, sizeof(struct event_s));
|
||||
|
||||
cur->delay = delay;
|
||||
cur->fun = fun;
|
||||
|
||||
schedule_event_(cur);
|
||||
}
|
||||
|
||||
static unsigned long schedule_time;
|
||||
|
||||
void schedule_simulate(void)
|
||||
{
|
||||
schedule_time = 0;
|
||||
|
||||
while (list) {
|
||||
|
||||
/* Pull the first item off the list. Fixup the last
|
||||
pointer in the next cell, if necessary. */
|
||||
struct event_s*cur = list;
|
||||
list = cur->next;
|
||||
if (cur->last != cur) {
|
||||
assert(list->delay == 0);
|
||||
list->last = cur->last;
|
||||
|
||||
} else {
|
||||
schedule_time += cur->delay;
|
||||
printf("TIME: %u\n", schedule_time);
|
||||
}
|
||||
|
||||
if (cur->thr) {
|
||||
vthread_run(cur->thr);
|
||||
|
||||
} else if (cur->fun) {
|
||||
/* XXXX not implemented yet */
|
||||
|
||||
}
|
||||
|
||||
free(cur);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: schedule.cc,v $
|
||||
* Revision 1.1 2001/03/11 00:29:39 steve
|
||||
* Add the vvp engine to cvs.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef __schedule_H
|
||||
#define __schedule_H
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form 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
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: schedule.h,v 1.1 2001/03/11 00:29:39 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vthread.h"
|
||||
# include "pointers.h"
|
||||
|
||||
extern void schedule_vthread(vthread_t thr, unsigned delay);
|
||||
|
||||
extern void schedule_functor(vvp_ipoint_t fun, unsigned delay);
|
||||
|
||||
extern void schedule_simulate(void);
|
||||
|
||||
/*
|
||||
* $Log: schedule.h,v $
|
||||
* Revision 1.1 2001/03/11 00:29:39 steve
|
||||
* Add the vvp engine to cvs.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
|
@ -0,0 +1,295 @@
|
|||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form 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
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: symbols.cc,v 1.1 2001/03/11 00:29:39 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "symbols.h"
|
||||
# include <string.h>
|
||||
# include <assert.h>
|
||||
|
||||
struct symbol_table_s {
|
||||
struct tree_node_*root;
|
||||
};
|
||||
|
||||
/*
|
||||
* This is a B-Tree data structure, where there are nodes and
|
||||
* leaves.
|
||||
*
|
||||
* Nodes have a bunch of pointers to children. Each child pointer has
|
||||
* associated with it a key that is the largest key referenced by that
|
||||
* child. So, if the key being searched for has a value <= the first
|
||||
* key of a node, then the value is in the first child.
|
||||
*
|
||||
* leaves have a sorted table of key-value pairs. The search can use a
|
||||
* simple binary search to find an item. Each key represents an item.
|
||||
*/
|
||||
|
||||
const unsigned leaf_width = 511;
|
||||
const unsigned node_width = 511;
|
||||
|
||||
struct tree_node_ {
|
||||
bool leaf_flag;
|
||||
unsigned count;
|
||||
struct tree_node_*parent;
|
||||
|
||||
union {
|
||||
struct {
|
||||
char*key;
|
||||
unsigned long val;
|
||||
} leaf[leaf_width];
|
||||
|
||||
struct tree_node_*child[node_width];
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
static inline char* node_last_key(struct tree_node_*node)
|
||||
{
|
||||
while (node->leaf_flag == false)
|
||||
node = node->child[node->count-1];
|
||||
|
||||
return node->leaf[node->count-1].key;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a new symbol table means creating the table structure and
|
||||
* a root node, and initializing the pointers and members of the root
|
||||
* node.
|
||||
*/
|
||||
symbol_table_t new_symbol_table(void)
|
||||
{
|
||||
symbol_table_t tbl = new struct symbol_table_s;
|
||||
tbl->root = new struct tree_node_;
|
||||
tbl->root->leaf_flag = false;
|
||||
tbl->root->count = 0;
|
||||
tbl->root->parent = 0;
|
||||
return tbl;
|
||||
}
|
||||
|
||||
static void split_node_(struct tree_node_*cur)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function takes a leaf node and splits in into two. Move half
|
||||
* the leaf keys into the new node, and add the new leaf into the
|
||||
* parent node.
|
||||
*/
|
||||
static struct tree_node_* split_leaf_(struct tree_node_*cur)
|
||||
{
|
||||
assert(cur->leaf_flag);
|
||||
assert(cur->parent);
|
||||
assert(! cur->parent->leaf_flag);
|
||||
|
||||
/* Create a new leaf to hold half the data from the old leaf. */
|
||||
struct tree_node_*new_leaf = new struct tree_node_;
|
||||
new_leaf->leaf_flag = true;
|
||||
new_leaf->count = cur->count / 2;
|
||||
new_leaf->parent = cur->parent;
|
||||
|
||||
/* Move the last half of the data from the end of the old leaf
|
||||
to the beggining of the new leaf. At the same time, reduce
|
||||
the size of the old leaf. */
|
||||
unsigned idx1 = new_leaf->count;
|
||||
unsigned idx2 = cur->count;
|
||||
while (idx1 > 0) {
|
||||
idx1 -= 1;
|
||||
idx2 -= 1;
|
||||
new_leaf->leaf[idx1] = cur->leaf[idx2];
|
||||
cur->count -= 1;
|
||||
}
|
||||
|
||||
assert(new_leaf->count > 0);
|
||||
assert(cur->count > 0);
|
||||
|
||||
unsigned idx = 0;
|
||||
while (cur->parent->child[idx] != cur) {
|
||||
assert(idx < cur->parent->count);
|
||||
idx += 1;
|
||||
}
|
||||
|
||||
idx += 1;
|
||||
|
||||
for (unsigned tmp = cur->parent->count ; tmp > idx ; tmp -= 1)
|
||||
cur->parent->child[tmp] = cur->parent->child[tmp-1];
|
||||
|
||||
cur->parent->child[idx] = new_leaf;
|
||||
cur->parent->count += 1;
|
||||
|
||||
if (cur->parent->count == node_width)
|
||||
split_node_(cur->parent);
|
||||
|
||||
return new_leaf;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Thid function searches tree recursively for the key. If the value
|
||||
* is not found (and we are at a leaf) then set the key with the given
|
||||
* value. If the key is found, set the value only if the force_flag is
|
||||
* true.
|
||||
*/
|
||||
|
||||
static unsigned long find_value_(symbol_table_t tbl, struct tree_node_*cur,
|
||||
const char*key, unsigned long val,
|
||||
bool force_flag)
|
||||
{
|
||||
if (cur->leaf_flag) {
|
||||
|
||||
unsigned idx = 0;
|
||||
for (;;) {
|
||||
/* If we run out of keys in the leaf, then add
|
||||
this at the end of the leaf. */
|
||||
if (idx == cur->count) {
|
||||
cur->leaf[idx].key = strdup(key);
|
||||
cur->leaf[idx].val = val;
|
||||
cur->count += 1;
|
||||
if (cur->count == leaf_width)
|
||||
split_leaf_(cur);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
int rc = strcmp(key, cur->leaf[idx].key);
|
||||
|
||||
/* If we found the key already in the table, then
|
||||
set the new value and break. */
|
||||
if (rc == 0) {
|
||||
if (force_flag)
|
||||
cur->leaf[idx].val = val;
|
||||
return cur->leaf[idx].val;
|
||||
}
|
||||
|
||||
/* If this key goes before the current key, then
|
||||
push all the following entries back and add
|
||||
this key here. */
|
||||
if (rc < 0) {
|
||||
for (unsigned tmp = cur->count; tmp > idx; tmp -= 1)
|
||||
cur->leaf[tmp] = cur->leaf[tmp-1];
|
||||
|
||||
cur->leaf[idx].key = strdup(key);
|
||||
cur->leaf[idx].val = val;
|
||||
cur->count += 1;
|
||||
if (cur->count == leaf_width)
|
||||
split_leaf_(cur);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
idx += 1;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
unsigned idx = 0;
|
||||
for (;;) {
|
||||
if (idx == cur->count) {
|
||||
idx -= 1;
|
||||
return find_value_(tbl, cur->child[idx],
|
||||
key, val, force_flag);
|
||||
}
|
||||
|
||||
int rc = strcmp(key, node_last_key(cur->child[idx]));
|
||||
if (rc <= 0) {
|
||||
return find_value_(tbl, cur->child[idx],
|
||||
key, val, force_flag);
|
||||
}
|
||||
|
||||
idx += 1;
|
||||
}
|
||||
}
|
||||
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sym_set_value(symbol_table_t tbl, const char*key, unsigned long val)
|
||||
{
|
||||
if (tbl->root->count == 0) {
|
||||
/* Handle the special case that this is the very first
|
||||
value in the symbol table. Create the first leaf node
|
||||
and initialize the pointers. */
|
||||
struct tree_node_*cur = new struct tree_node_;
|
||||
cur->leaf_flag = true;
|
||||
cur->parent = tbl->root;
|
||||
cur->count = 1;
|
||||
cur->leaf[0].key = strdup(key);
|
||||
cur->leaf[0].val = val;
|
||||
|
||||
tbl->root->count = 1;
|
||||
tbl->root->child[0] = cur;
|
||||
} else {
|
||||
find_value_(tbl, tbl->root, key, val, true);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long sym_get_value(symbol_table_t tbl, const char*key)
|
||||
{
|
||||
if (tbl->root->count == 0) {
|
||||
/* Handle the special case that this is the very first
|
||||
value in the symbol table. Create the first leaf node
|
||||
and initialize the pointers. */
|
||||
struct tree_node_*cur = new struct tree_node_;
|
||||
cur->leaf_flag = true;
|
||||
cur->parent = tbl->root;
|
||||
cur->count = 1;
|
||||
cur->leaf[0].key = strdup(key);
|
||||
cur->leaf[0].val = 0;
|
||||
|
||||
tbl->root->count = 1;
|
||||
tbl->root->child[0] = cur;
|
||||
return 0;
|
||||
} else {
|
||||
return find_value_(tbl, tbl->root, key, 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void dump_tree(struct tree_node_*cur, unsigned ind, FILE*fd)
|
||||
{
|
||||
if (cur->leaf_flag) {
|
||||
|
||||
fprintf(fd, "%*s%p: %u keys\n", ind, "", cur, cur->count);
|
||||
for (unsigned idx = 0 ; idx < cur->count ; idx += 1) {
|
||||
fprintf(fd, "%*s %3d: key=%s, val=0x%lx\n", ind, "",
|
||||
idx, cur->leaf[idx].key, cur->leaf[idx].val);
|
||||
}
|
||||
|
||||
} else {
|
||||
fprintf(fd, "%*s%p: %u children\n", ind, "", cur, cur->count);
|
||||
for (unsigned idx = 0 ; idx < cur->count ; idx += 1) {
|
||||
dump_tree(cur->child[idx], ind+4, fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sym_dump(symbol_table_t tbl, FILE*fd)
|
||||
{
|
||||
dump_tree(tbl->root, 0, fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: symbols.cc,v $
|
||||
* Revision 1.1 2001/03/11 00:29:39 steve
|
||||
* Add the vvp engine to cvs.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
#ifndef __symbols_H
|
||||
#define __symbols_H
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form 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
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: symbols.h,v 1.1 2001/03/11 00:29:39 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The symbol_table_t is intended as a means to hold and quickly index
|
||||
* large symbol tables with small symbol values. That is, the value
|
||||
* should fit in a 32bit unsigned integer (not even necessarily a
|
||||
* pointer.)
|
||||
*
|
||||
* The key is an unstructured ASCII string, terminated by a
|
||||
* null. Items added to the table are not removed, unless the entire
|
||||
* table is deleted.
|
||||
*
|
||||
* The compiler uses symbol tables to help match up operands to
|
||||
* referenced objects in the source. The compiler knows by the context
|
||||
* that the symbol appears what kind of thing is referenced, and so
|
||||
* what symbol table to look in.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
# include <stdio.h>
|
||||
|
||||
/*
|
||||
* This is the basic type of a symbol table. It is opaque. Don't even
|
||||
* try to look inside. The actual implementation is given in the
|
||||
* symbols.cc source file.
|
||||
*/
|
||||
typedef struct symbol_table_s *symbol_table_t;
|
||||
|
||||
/*
|
||||
* Create a new symbol table or release an existing one. A new symbol
|
||||
* table has no keys and no values. As a symbol table is built up, it
|
||||
* consumes more and more memory. When the table is no longer needed,
|
||||
* the delete_symbol_table method will delete the table, including all
|
||||
* the space for the keys.
|
||||
*/
|
||||
extern symbol_table_t new_symbol_table(void);
|
||||
extern void delete_symbol_table(symbol_table_t tbl);
|
||||
|
||||
/*
|
||||
* This method locates the value in the symbol table and sets its
|
||||
* value. If the key doesn't yet exist, create it.
|
||||
*/
|
||||
void sym_set_value(symbol_table_t tbl, const char*key, unsigned long val);
|
||||
|
||||
/*
|
||||
* This method locates the value in the symbol table and returns
|
||||
* it. If the value does not exist, create it, initialize it with
|
||||
* zero and return the zero value.
|
||||
*/
|
||||
unsigned long sym_get_value(symbol_table_t tbl, const char*key);
|
||||
|
||||
/*
|
||||
* Diagnostic dump of the symbol table.
|
||||
*/
|
||||
extern void sym_dump(symbol_table_t tbl, FILE*fd);
|
||||
|
||||
/*
|
||||
* $Log: symbols.h,v $
|
||||
* Revision 1.1 2001/03/11 00:29:39 steve
|
||||
* Add the vvp engine to cvs.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form 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
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: vthread.cc,v 1.1 2001/03/11 00:29:39 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vthread.h"
|
||||
# include "codes.h"
|
||||
# include "schedule.h"
|
||||
|
||||
struct vthread_s {
|
||||
/* This is the program counter. */
|
||||
unsigned long pc;
|
||||
};
|
||||
|
||||
/*
|
||||
* Create a new thread with the given start address.
|
||||
*/
|
||||
vthread_t v_newthread(unsigned long pc)
|
||||
{
|
||||
vthread_t thr = new struct vthread_s;
|
||||
thr->pc = pc;
|
||||
|
||||
return thr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function runs a thread by fetching an instruction,
|
||||
* incrementing the PC, and executing the instruction.
|
||||
*/
|
||||
void vthread_run(vthread_t thr)
|
||||
{
|
||||
for (;;) {
|
||||
vvp_code_t cp = codespace_index(thr->pc);
|
||||
thr->pc += 1;
|
||||
|
||||
bool rc = (cp->opcode)(thr, cp);
|
||||
if (rc == false)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool of_ASSIGN(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
printf("thread %p: %%assign\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_DELAY(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
printf("thread %p: %%delay %u\n", thr, cp->number);
|
||||
schedule_vthread(thr, cp->number);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool of_END(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
printf("thread %p: %%end\n", thr);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool of_NOOP(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_SET(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
printf("thread %p: %%set\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: vthread.cc,v $
|
||||
* Revision 1.1 2001/03/11 00:29:39 steve
|
||||
* Add the vvp engine to cvs.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
#ifndef __vthread_H
|
||||
#define __vthread_H
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form 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
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: vthread.h,v 1.1 2001/03/11 00:29:39 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* A vthread is a simulation thread that executes instructions when
|
||||
* they are scheduled. This structure contains all the thread specific
|
||||
* context needed to run an instruction.
|
||||
*
|
||||
* Included in a thread are its program counter, local bits and
|
||||
* members needed for tracking the thread. The thread runs by fetching
|
||||
* instructions from code space, interpreting the instruction, then
|
||||
* fetching the next instruction.
|
||||
*/
|
||||
|
||||
typedef struct vthread_s*vthread_t;
|
||||
|
||||
/*
|
||||
* This creates a new simulation thread, with the given start
|
||||
* address. The generated thread is ready to run, but is not yet
|
||||
* scheduled.
|
||||
*/
|
||||
extern vthread_t v_newthread(unsigned long sa);
|
||||
|
||||
/*
|
||||
* Cause this thread to execute instructions until in is put to sleep
|
||||
* by executing some sort of delay or wait instruction.
|
||||
*/
|
||||
extern void vthread_run(vthread_t thr);
|
||||
|
||||
/*
|
||||
* $Log: vthread.h,v $
|
||||
* Revision 1.1 2001/03/11 00:29:39 steve
|
||||
* Add the vvp engine to cvs.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
Loading…
Reference in New Issue