129 lines
2.5 KiB
Plaintext
129 lines
2.5 KiB
Plaintext
|
.so init
|
||
|
.SH
|
||
|
B. IMPLEMENTATION
|
||
|
.SH
|
||
|
B.1. Excerpts from the non-optimized EM_table
|
||
|
.PP
|
||
|
Even though the non-optimized version of the EM_table is relatively
|
||
|
straight-forward, examples have never hurt anybody.
|
||
|
One of the simplest instructions is the \*(Siloc\*(So, which appears in
|
||
|
our EM_table as follows:
|
||
|
.DS
|
||
|
\f6
|
||
|
.TA 8 16 24 32 40 48 56 64
|
||
|
C_loc ==> "set $1, T1";
|
||
|
"dec 4, SP";
|
||
|
"st T1, [SP]".
|
||
|
\f1
|
||
|
.DE
|
||
|
Just as \*(SiSP\*(So is an alias for \*(Si%l0\*(So, \*(SiT1\*(So is
|
||
|
an alias for \*(Si%g1\*(So.
|
||
|
A little more complex is the \*(Siadi\*(So which performs integer
|
||
|
addition.
|
||
|
.DS
|
||
|
\f6
|
||
|
C_adi ==> "ld [SP], T1";
|
||
|
"ld [SP+4], T2";
|
||
|
"add T1, T2, T3";
|
||
|
"st T3, [SP+4];
|
||
|
"inc 4, SP".
|
||
|
\f1
|
||
|
.DE
|
||
|
We could go on with even more complex instructions, but since that would
|
||
|
not contribute to anything the reader is referred to the implementation
|
||
|
for more details.
|
||
|
.SH
|
||
|
B.2. Excerpts from the optimized EM_table
|
||
|
.PP
|
||
|
The optimized EM_table uses the cache primitives mentioned in chapter 4.
|
||
|
This means that the \*(Siloc\*(So this time appears as
|
||
|
.DS
|
||
|
\f6
|
||
|
C_loc ==> push_const($1).
|
||
|
\f1
|
||
|
.DE
|
||
|
The \*(Silol\*(So can now be written as
|
||
|
.DS
|
||
|
\f6
|
||
|
C_lol ==> push_reg(LB);
|
||
|
inc_tos($1);
|
||
|
push_const(4);
|
||
|
C_los(4).
|
||
|
\f1
|
||
|
.DE
|
||
|
Due to the law of conservation of misery somebody has to do the dirty work.
|
||
|
In this case, it is the \*(Silos\*(So. To show just a small part of
|
||
|
the implementation of the \*(Silos\*(So:
|
||
|
.DS
|
||
|
\f6
|
||
|
C_los $1 == 4 ==>
|
||
|
if (type_of_tos() == T_cst) {
|
||
|
arith size;
|
||
|
const_str_t n;
|
||
|
|
||
|
size= pop_const();
|
||
|
if (size <= 4) {
|
||
|
reg_t a;
|
||
|
reg_t a;
|
||
|
char *LD;
|
||
|
|
||
|
switch (size) {
|
||
|
case 1: LD = "ldub"; break;
|
||
|
case 2: LD = "lduh"; break;
|
||
|
case 4: LD = "ld"; break;
|
||
|
default: arg_error("C_los", size);
|
||
|
}
|
||
|
a = pop_reg_c13(n);
|
||
|
b = alloc_reg();
|
||
|
"$LD [$a+$n], $b";
|
||
|
push_reg(b);
|
||
|
free_reg(a);
|
||
|
} else ...
|
||
|
\f1
|
||
|
.DE
|
||
|
For the full implementation, the reader is again referred to the actual
|
||
|
implementation. Just to show how other instructions are affected
|
||
|
by the optimization we will show that implementation of the \*(Sitge\*(So
|
||
|
instruction:
|
||
|
.DS
|
||
|
\f6
|
||
|
C_tge ==> {
|
||
|
reg_t a;
|
||
|
reg_t b;
|
||
|
|
||
|
a = pop_reg();
|
||
|
b = alloc_reg();
|
||
|
" tst $a";
|
||
|
" bge,a 1f";
|
||
|
" mov 1, $b"; /* delay slot */
|
||
|
" set 0, $b";
|
||
|
"1:";
|
||
|
free_reg(a);
|
||
|
push_reg(b);
|
||
|
}.
|
||
|
|
||
|
\f1
|
||
|
.DE
|
||
|
.SH
|
||
|
.bp
|
||
|
CREDITS
|
||
|
.PP
|
||
|
In order of appearance:
|
||
|
.TS
|
||
|
center;
|
||
|
r c l.
|
||
|
Original idea - Dick Grune
|
||
|
Design & implementation - Philip Homburg
|
||
|
- Raymond Michiels
|
||
|
Tutor - Dick Grune
|
||
|
Assistant Tutor - Ceriel Jacobs
|
||
|
Proofreading - Dick Grune
|
||
|
- Hans van Eck
|
||
|
.TE
|
||
|
.SH
|
||
|
REFERENCES
|
||
|
.PP
|
||
|
.[
|
||
|
$LIST$
|
||
|
.]
|