Skip to content

Commit

Permalink
MMIX 2009 — Release 2013-10-07.
Browse files Browse the repository at this point in the history
  • Loading branch information
Andreas Scherer committed Oct 7, 2013
1 parent bc6460a commit e6ad300
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 43 deletions.
3 changes: 3 additions & 0 deletions mmix-arith.w
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
@s ff TeX
@s bool normal @q unreserve a C++ keyword @>
@s xor normal @q unreserve a C++ keyword @>
@s bignum int

@* Introduction. The subroutines below are used to simulate 64-bit \MMIX\
arithmetic on an old-fashioned 32-bit computer---like the one the author
Expand Down Expand Up @@ -487,6 +488,8 @@ it is tiny and either (i)~it is inexact or (ii)~the underflow trap is enabled.
The |fpack| routine sets |U_BIT| in |exceptions| if and only if the result is
tiny, |X_BIT| if and only if the result is inexact.
@^underflow@>
@^tininess@>
@^accuracy loss@>

@d X_BIT (1<<8) /* floating inexact */
@d Z_BIT (1<<9) /* floating division by zero */
Expand Down
2 changes: 1 addition & 1 deletion mmix-config.w
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,7 @@ int_stages[ld]=int_stages[st]=int_stages[frem]=2;
for (j=0;j<256;j++) stages[j]=int_stages[int_op[j]];

@ The |int_op| conversion table is similar to the |internal_op| array of
the \\{MMIX\_pipe} routine, but it replaces |divu| by |div|,
the \\{MMIX\_run} routine, but it replaces |divu| by |div|,
|fsub| by |fadd|, etc.

@<Glob...@>=
Expand Down
14 changes: 7 additions & 7 deletions mmix-doc.w
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ have made significant contributions.
@^Hennessy, John LeRoy@>
@^Sites, Richard Lee@>

@ A programmer's introduction to \MMIX\ appears in ``Volume~1 Fascicle~1,''
@ A programmer's introduction to \MMIX\ appears in ``Volume~1, Fascicle~1,''
@^Fascicle 1@>
a booklet containing tutorial material that will ultimately appear in the
fourth edition of {\sl The Art of Computer Programming}.
Expand Down Expand Up @@ -344,7 +344,7 @@ into $\mm_8[\$2+17]$.
@.STB@>
The least significant byte of register~X is stored into
byte $\mm[\rY+\rZ]$ or $\mm[\rY+\zz]$. An integer overflow exception occurs if
@.overflow@>
@^overflow@>
\$X is not between $-128$ and $+127$. (We will discuss overflow and other
kinds of exceptions later.)

Expand Down Expand Up @@ -411,7 +411,7 @@ The sum $\rY+\rZ$ or $\rY+\zz$ is placed into register~X using signed,
two's complement arithmetic.
An integer overflow exception occurs if the sum is $\ge2^{63}$ or $<-2^{63}$.
(We will discuss overflow and other kinds of exceptions later.)
@.overflow@>
@^overflow@>

\bull\<ADDU \$X,\$Y,\0 `add unsigned'.\>
@.ADDU@>
Expand Down Expand Up @@ -705,7 +705,7 @@ exclusive-or is used to combine the bits. Thus we obtain a matrix
product over the field of two elements instead of a Boolean matrix product.
This operation can be used to construct hash functions, among many other things.
(The hash functions aren't bad, but they are not ``universal'' in the
sense of exercise 6.4--72.)
sense of {\sl Sorting and Searching}, exercise 6.4--72.)
@^matrices of bits@>
@^Boolean multiplication@>

Expand Down Expand Up @@ -2239,7 +2239,7 @@ and place the result in~rZZ\null. A~subsequent

When a forced trap occurs on a store instruction because of memory protection
failure, the settings of rYY and rZZ are undefined. They do not necessarily
correspond to the virtual address rY and octabyte to be stored rZ
correspond to the virtual address rY and the octabyte to be stored rZ
that are supplied to a trip handler after a tripped store instruction,
because a forced trap aborts its instruction as soon as possible.

Expand Down Expand Up @@ -2661,7 +2661,7 @@ by Advanced Micro Devices, in the processors of their Am29000 series---a
family of computers whose instructions have essentially the
format `OP~X~Y~Z' used by~\MMIX.]
@^Ditzel, David Roger@>
@^McClellan, Hubert Rae, Jr.@>
@^McLellan, Hubert Rae, Jr.@>

Limited versions of\/ \MMIX, having fewer registers, can also be envisioned. For
example, we might have only 32 local registers $\l[0]$, $\l[1]$,
Expand Down Expand Up @@ -2710,7 +2710,7 @@ of the current value and the new value. (A~program should say
\<SETL \$99,0 instead of \<PUT rL,100 when rL is known to be less than~100.)

Impermissible \.{PUT} commands cause an illegal instruction interrupt,
or (in the case of rI, rK, rQ, rT, rU, rV, and~rTT) a privileged
or (in the case of rC, rI, rK, rQ, rT, rU, rV, and~rTT) a privileged
operation interrupt.
@^illegal instructions@>
@^privileged operations@>
Expand Down
18 changes: 10 additions & 8 deletions mmix-pipe.w
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@ A lot of subtle things can happen when instructions are executed in parallel.
Therefore this simulator ranks among the most interesting and instructive
programs in the author's experience. The author has tried his best to make
everything correct \dots\ but the chances for error are great. Anyone who
discovers a bug is therefore urged to report it as soon as possible to
\.{knuth-bug@@cs.stanford.edu}; then the program will be as useful as
possible. Rewards will be paid to bug-finders! (Except for bugs in version~0.)
discovers a bug is therefore urged to report it as soon as possible;
please see \.{http:/\kern-.1em/mmix.cs.hm.edu/bugs/} for instructions.

It sort of boggles the mind when one realizes that the present program might
someday be translated by a \CEE/~compiler for \MMIX\ and used to simulate
Expand All @@ -35,6 +34,8 @@ someday be translated by a \CEE/~compiler for \MMIX\ and used to simulate
@ This high-performance prototype of \MMIX\ achieves its efficiency by
means of ``pipelining,'' a technique of overlapping that is explained
for the related \.{DLX} computer in Chapter~3 of Hennessy \char`\&\ Patterson's
@^Hennessy, John LeRoy@>
@^Patterson, David Andrew@>
book {\sl Computer Architecture\/} (second edition). Other techniques
such as ``dynamic scheduling'' and ``multiple issue,'' explained in
Chapter~4 of that book, are used too.
Expand Down Expand Up @@ -202,7 +203,7 @@ bypass the library names here.

@ The |MMIX_init()| routine should be called exactly once, after
|MMIX_config()| has done its work but before the simulator starts to execute
any programs. Then |MMIX_run| can be called as often as the user likes.
any programs. Then |MMIX_run()| can be called as often as the user likes.

@s octa int

Expand Down Expand Up @@ -3849,6 +3850,7 @@ fact does help us: We know that the flusher coroutine will not be
aborted until it has run to completion.

Some machines, such as the Alpha 21164, have an additional cache between
@^Alpha computers@>
the S-cache and memory, called the B-cache (the ``backup cache''). A B-cache
could be simulated by extending the logic used here; but such extensions
of the present program are left to the interested reader.
Expand Down Expand Up @@ -4347,7 +4349,7 @@ static octa phys_addr @,@,@[ARGS((octa,octa))@];
static octa phys_addr(virt,trans)
octa virt,trans;
{@+octa t;
t=oandn(trans,page_mask); /* zero out the |ynp| fields of a PTE */
t=oandn(trans,page_mask); /* zero out the \\{ynp} fields of a PTE */
return oplus(t,oand(virt,page_mask));
}

Expand Down Expand Up @@ -4993,7 +4995,7 @@ data->state=ld_ready;
if (data->i==preld || data->i==prest) goto fin_ex;@+else sleep;

@ If a |prest| instruction makes it to the hot seat,
we have been assured by the user of |PREST| that the current
we have been assured by the user of \.{PREST} that the current
values of bytes in virtual addresses |data->y.o-(data->xx&-Dcache->bb)| through
|data->y.o+(data->xx&(Dcache->bb-1))|
are irrelevant. Hence we can pretend that we know they are zero. This
Expand Down Expand Up @@ -5419,7 +5421,7 @@ tail->noted=false;
if (inst_ptr.o.l==breakpoint.l && inst_ptr.o.h==breakpoint.h)
breakpoint_hit=true;

@ The commands |RESUME|, |SAVE|, |UNSAVE|, and |SYNC| should not have
@ The commands \.{RESUME}, \.{SAVE}, \.{UNSAVE}, and \.{SYNC} should not have
nonzero bits in the positions defined here.

@<Global...@>=
Expand Down Expand Up @@ -5652,7 +5654,7 @@ if (verbose&issue_bit) {

@d RESUME_AGAIN 0 /* repeat the command in rX as if in location $\rm rW-4$ */
@d RESUME_CONT 1 /* same, but substitute rY and rZ for operands */
@d RESUME_SET 2 /* set r[X] to rZ */
@d RESUME_SET 2 /* set register \$X to rZ */
@d RESUME_TRANS 3 /* install $\rm(rY,rZ)$ into IT-cache or DT-cache,
then |RESUME_AGAIN| */
@d pack_bytes(a,b,c,d) ((((((unsigned)(a)<<8)+(b))<<8)+(c))<<8)+(d)
Expand Down
46 changes: 24 additions & 22 deletions mmix-sim.w
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ count field of~rU may increase by~1 (modulo~$2^{47}$) for each instruction.
@ To run this simulator, assuming \UNIX/ conventions, you say
`\.{mmix} \<options> \.{progfile} \.{args...}',
where \.{progfile} is an output of the \.{MMIXAL} assembler,
\.{args...} is a sequence of optional command-line arguments passed
\.{args...} is a sequence of optional command line arguments passed
to the simulated program, and \<options> is any subset of the following:
@^command line arguments@>

Expand Down Expand Up @@ -121,7 +121,7 @@ end of file when standard input has been defined in any other way.
simulators, instead of actually doing a simulation.

\bull \.{-?}\quad Print the ``\.{Usage}'' message, which summarizes
the command-line options.
the command line options.

\smallskip\noindent
The author recommends \.{-t2} \.{-l} \.{-L} for initial offline debugging.
Expand All @@ -134,7 +134,7 @@ even if \.{-i} and \.{-I} were not specified on the command line.

@ In interactive mode, the user is prompted `\.{mmix>}' and a variety of
@.mmix>@>
commands can be typed online. Any command-line option can be given
commands can be typed online. Any command line option can be given
in response to such a prompt (including the `\.-' that begins the option),
and the following operations are also available:

Expand Down Expand Up @@ -436,13 +436,13 @@ example below.)
the global registers are initialized according to the \.{GREG}
statements in the \.{MMIXAL} program, and \$255 is set to the
numeric equivalent of~\.{Main}. Local register~\$0 is
initially set to the number of {\it command-line arguments\/}; and
initially set to the number of {\it command line arguments\/}; and
@^command line arguments@>
local register~\$1 points to the first such argument, which
is always a pointer to the program name. Each command-line argument is a
is always a pointer to the program name. Each command line argument is a
pointer to a string; the last such pointer is M$_8[\$0\ll3+\$1]$, and
M$_8[\$0\ll3+\$1+8]$ is zero. (Register~\$1 will point to an octabyte in
\.{Pool\_Segment}, and the command-line strings will be in that segment
\.{Pool\_Segment}, and the command line strings will be in that segment
too.) Location M[\.{Pool\_Segment}] will be the address of the first
unused octabyte of the pool segment.

Expand Down Expand Up @@ -753,7 +753,7 @@ mem_node* new_mem()
}

@ Initially we start with a chunk for the pool segment, since
the simulator will be putting command-line information there before
the simulator will be putting command line information there before
it runs the program.

@<Initialize...@>=
Expand Down Expand Up @@ -1055,7 +1055,7 @@ G=zbyte;@+ L=0;
for (j=G+G;j<256+256;j++,ll++,aux.l+=4) read_tet(), ll->tet=tet;
inst_ptr.h=(ll-2)->tet, inst_ptr.l=(ll-1)->tet; /* \.{Main} */
(ll+2*12)->tet=G<<24;
g[255]=incr(aux,12*8); /* we will |UNSAVE| from here, to get going */
g[255]=incr(aux,12*8); /* we will \.{UNSAVE} from here, to get going */

@* Loading and printing source lines.
The loaded program generally contains cross references to the lines
Expand Down Expand Up @@ -1819,10 +1819,10 @@ if (!l) panic("No room for the local registers");
@.No room...@>
cur_round=ROUND_NEAR;

@ In operations like |INCH|, we want |z| to be the |yz| field,
@ In operations like \.{INCH}, we want |z| to be the |yz| field,
shifted left 48 bits. We also want |y| to be register~X, which has
previously been placed in |b|; then |INCH| can be simulated as if
it were |ADDU|.
previously been placed in |b|; then \.{INCH} can be simulated as if
it were \.{ADDU}.

@<Set |z| as an immediate wyde@>=
{
Expand Down Expand Up @@ -2193,7 +2193,7 @@ case CSWAP: case CSWAPI: w.l&=-8;@+ll=mem_find(w);
}
goto check_ld;

@ The |GET| command is permissive, but |PUT| is restrictive.
@ The \.{GET} command is permissive, but \.{PUT} is restrictive.

@<Cases for ind...@>=
case GET:@+if (yy!=0 || zz>=32) goto illegal_inst;
Expand Down Expand Up @@ -2267,7 +2267,7 @@ case POP:@+if (xx!=0 && xx<=L) y=l[(O+xx-1)&lring_mask];
goto sync_L;

@ To complete our simulation of \MMIX's register stack, we need
to implement |SAVE| and |UNSAVE|.
to implement \.{SAVE} and \.{UNSAVE}.

@<Cases for ind...@>=
case SAVE:@+if (xx<G || yy!=0 || zz!=0) goto illegal_inst;
Expand Down Expand Up @@ -2620,7 +2620,7 @@ If so, the ropcode will actually be obeyed on the next fetch phase.

@d RESUME_AGAIN 0 /* repeat the command in rX as if in location $\rm rW-4$ */
@d RESUME_CONT 1 /* same, but substitute rY and rZ for operands */
@d RESUME_SET 2 /* set r[X] to rZ */
@d RESUME_SET 2 /* set register \$X to rZ */

@<Prepare to perform a ropcode@>=
{
Expand Down Expand Up @@ -2648,7 +2648,7 @@ if (rop==RESUME_SET) {
z=g[rZ];
}

@ We don't want to count the |UNSAVE| that bootstraps the whole process.
@ We don't want to count the \.{UNSAVE} that bootstraps the whole process.

@<Update the clocks@>=
if (sclock.l || sclock.h || !resuming) {
Expand Down Expand Up @@ -2916,7 +2916,7 @@ int main(argc,argv)
return g[255].l; /* provide rudimentary feedback for non-interactive runs */
}

@ Here we process the command-line options; when we finish, |*cur_arg|
@ Here we process the command line options; when we finish, |*cur_arg|
should be the name of the object file to be loaded and simulated.

We assume that |argv[0]| is never null. (The author believes strongly that
Expand Down Expand Up @@ -2945,7 +2945,7 @@ are harmless while interacting.
@<Subr...@>=
void scan_option @,@,@[ARGS((char*,bool))@];@+@t}\6{@>
void scan_option(arg,usage)
char *arg; /* command-line argument (without the `\.-') */
char *arg; /* command line argument (without the `\.-') */
bool usage; /* should we exit with usage note if unrecognized? */
{
register int k;
Expand Down Expand Up @@ -2982,7 +2982,7 @@ void scan_option(arg,usage)
case 'D': @<Open a file for dumping binary output@>;@+return;
default:@+if (usage) {
fprintf(stderr,
"Usage: %s <options> progfile command-line-args...\n",myself);
"Usage: %s <options> progfile command line-args...\n",myself);
@.Usage: ...@>
for (k=0;usage_help[k][0];k++) fprintf(stderr,usage_help[k]);
exit(-1);
Expand Down Expand Up @@ -3253,8 +3253,8 @@ switch (cur_disp_mode) {
}@+break;
}

@ Here we essentially simulate a |PUT| command, but we simply |break|
if the |PUT| is illegal or privileged.
@ Here we essentially simulate a \.{PUT} command, but we simply |break|
if the \.{PUT} is illegal or privileged.

@<Set |g[k]=val| only if permissible@>=
if (k>=9 && k!=rI) {
Expand Down Expand Up @@ -3362,7 +3362,7 @@ void show_breaks(p)
if (p->right) show_breaks(p->right);
}

@ We put pointers to the command-line strings in
@ We put pointers to the command line strings in
M$_8[\.{Pool\_Segment}+8*(k+1)]$ for $0\le k<|argc|$;
the strings themselves are octabyte-aligned, starting at
M$_8[\.{Pool\_Segment}+8*(|argc|+2)]$. The location of the first free
Expand Down Expand Up @@ -3399,7 +3399,9 @@ if (dump_file) {
}

@ The special option `\.{-D<filename>}' can be used to prepare binary files
needed by the \MMIX-in-\MMIX\ simulator of Section 1.4.3\'{}. This option
needed by the \MMIX-in-\MMIX\ simulator of Section 1.4.3\'{}. (See
{\sl The Art of Computer Programming}, Volume~1, Fascicle~1.) This option
@^Fascicle 1@>
puts big-endian octa\-bytes into a given file; a location~$l$ is followed
by one or more nonzero octabytes M$_8[l]$, M$_8[l+8]$, M$_8[l+16]$, \dots,
followed by zero. The simulated simulator knows how to load programs
Expand Down
6 changes: 3 additions & 3 deletions mmixal.w
Original file line number Diff line number Diff line change
Expand Up @@ -681,10 +681,10 @@ data assembled for each byte position; but the general rule ``do not load
two things into the same byte'' is safest.)
All locations that do not receive assembled data are initially zero,
except that the loading routine will put register stack data into
segment~3, and the operating system may put command-line data and
segment~3, and the operating system may put command line data and
debugger data into segment~2.
(The rudimentary \MMIX\ operating system starts a program
with the number of command-line arguments in~\$0, and a pointer to
with the number of command line arguments in~\$0, and a pointer to
the beginning of an array of argument pointers in~\$1.)
Segments 2 and 3 should not get assembled data, unless the
user is a true hacker who is willing to take the risk that such data
Expand Down Expand Up @@ -1129,7 +1129,7 @@ register Char *p,*q; /* the place where we're currently scanning */

@ The next several subroutines are useful for preparing a listing of
the assembled results. In such a listing, which the user can request
with a command-line option, we fill the leftmost 19 columns with
with a command line option, we fill the leftmost 19 columns with
a representation of the output that has been assembled from the
input in the buffer. Sometimes the assembled output requires
more than one line, because we have room to output only a tetrabyte per line.
Expand Down
6 changes: 4 additions & 2 deletions mmmix.w
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,12 @@ FILE *prog_file;

@* Binary input to memory.
When the program file was dumped by {\mc MMIX-SIM}, it
has the simple format discussed in exercise 1.4.3$'$--20 of the \MMIX\ fascicle.
has the simple format discussed in exercise 1.4.3$'$--20 of the \MMIX\ fascicle
[{\sl The Art of Computer Programming}, Volume~1, Fascicle~1].
@^Fascicle 1@>
@^binary files@>
@^segments@>
In this case we assume that the user's program has text, data, pool, and stack
We assume that such a program has text, data, pool, and stack
segments, as in the conventions of that book.
We load it into four
$2^{32}$-byte pages of physical memory, one for each segment; page zero of
Expand Down

0 comments on commit e6ad300

Please sign in to comment.