1 |
<html> |
<html><head><title>Gavare's eXperimental Emulator: Technical details</title> |
2 |
<head><title>GXemul documentation: Technical details</title> |
<meta name="robots" content="noarchive,nofollow,noindex"></head> |
|
</head> |
|
3 |
<body bgcolor="#f8f8f8" text="#000000" link="#4040f0" vlink="#404040" alink="#ff0000"> |
<body bgcolor="#f8f8f8" text="#000000" link="#4040f0" vlink="#404040" alink="#ff0000"> |
4 |
<table border=0 width=100% bgcolor="#d0d0d0"><tr> |
<table border=0 width=100% bgcolor="#d0d0d0"><tr> |
5 |
<td width=100% align=center valign=center><table border=0 width=100%><tr> |
<td width=100% align=center valign=center><table border=0 width=100%><tr> |
6 |
<td align="left" valign=center bgcolor="#d0efff"><font color="#6060e0" size="6"> |
<td align="left" valign=center bgcolor="#d0efff"><font color="#6060e0" size="6"> |
7 |
<b>GXemul documentation:</b></font> |
<b>Gavare's eXperimental Emulator: </b></font> |
8 |
<font color="#000000" size="6"><b>Technical details</b> |
<font color="#000000" size="6"><b>Technical details</b> |
9 |
</font></td></tr></table></td></tr></table><p> |
</font></td></tr></table></td></tr></table><p> |
|
<!-- The first 10 lines are cut away by the homepage updating script. --> |
|
|
|
|
10 |
|
|
11 |
<!-- |
<!-- |
12 |
|
|
13 |
$Id: technical.html,v 1.49 2005/04/16 00:29:45 debug Exp $ |
$Id: technical.html,v 1.63 2005/10/07 15:10:00 debug Exp $ |
14 |
|
|
15 |
Copyright (C) 2004-2005 Anders Gavare. All rights reserved. |
Copyright (C) 2004-2005 Anders Gavare. All rights reserved. |
16 |
|
|
40 |
--> |
--> |
41 |
|
|
42 |
|
|
43 |
|
|
44 |
<a href="./">Back to the index</a> |
<a href="./">Back to the index</a> |
45 |
|
|
46 |
<p><br> |
<p><br> |
47 |
<h2>Technical details</h2> |
<h2>Technical details</h2> |
48 |
|
|
49 |
<p> |
<p>This page describes some of the internals of GXemul. |
|
This page describes some of the internals of GXemul. |
|
50 |
|
|
51 |
<p> |
<p> |
52 |
<ul> |
<ul> |
53 |
<li><a href="#overview">Overview</a> |
<li><a href="#speed">Speed and emulation modes</a> |
|
<li><a href="#speed">Speed</a> |
|
54 |
<li><a href="#net">Networking</a> |
<li><a href="#net">Networking</a> |
55 |
<li><a href="#devices">Emulation of hardware devices</a> |
<li><a href="#devices">Emulation of hardware devices</a> |
|
<li><a href="#regtest">Regression tests</a> |
|
56 |
</ul> |
</ul> |
57 |
|
|
58 |
|
|
59 |
|
|
60 |
|
|
|
<p><br> |
|
|
<a name="overview"></a> |
|
|
<h3>Overview</h3> |
|
|
|
|
|
In simple terms, GXemul is just a simple fetch-and-execute |
|
|
loop; an instruction is fetched from memory, and executed. |
|
|
|
|
|
<p> |
|
|
In reality, a lot of things need to be handled. Before each instruction is |
|
|
executed, the emulator checks to see if any interrupts are asserted which |
|
|
are not masked away. If so, then an INT exception is generated. Exceptions |
|
|
cause the program counter to be set to a specific value, and some of the |
|
|
system coprocessor's registers to be set to values signifying what kind of |
|
|
exception it was (an interrupt exception in this case). |
|
|
|
|
|
<p> |
|
|
Reading instructions from memory is done through a TLB, a translation |
|
|
lookaside buffer. The TLB on MIPS is software controlled, which means that |
|
|
the program running inside the emulator (for example an operating system |
|
|
kernel) has to take care of manually updating the TLB. Some memory |
|
|
addresses are translated into physical addresses directly, some are |
|
|
translated into valid physical addresses via the TLB, and some memory |
|
|
references are not valid. Invalid memory references cause exceptions. |
|
|
|
|
|
<p> |
|
|
After an instruction has been read from memory, the emulator checks which |
|
|
opcode it contains and executes the instruction. Executing an instruction |
|
|
usually involves reading some register and writing some register, or perhaps a |
|
|
load from memory (or a store to memory). The program counter is increased |
|
|
for every instruction. |
|
|
|
|
|
<p> |
|
|
Some memory references point to physical addresses which are not in the |
|
|
normal RAM address space. They may point to hardware devices. If that is |
|
|
the case, then loads and stores are converted into calls to a device |
|
|
access function. The device access function is then responsible for |
|
|
handling these reads and writes. For example, a graphical framebuffer |
|
|
device may put a pixel on the screen when a value is written to it, or a |
|
|
serial controller device may output a character to stdout when written to. |
|
|
|
|
|
|
|
61 |
|
|
62 |
|
|
63 |
<p><br> |
<p><br> |
64 |
<a name="speed"></a> |
<a name="speed"></a> |
65 |
<h3>Speed</h3> |
<h3>Speed and emulation modes</h3> |
|
|
|
|
There are two modes in which the emulator can run, <b>a</b>) a straight forward |
|
|
loop which fetches one instruction from emulated RAM and executes it |
|
|
(described in the previous section), and <b>b</b>) |
|
|
using dynamic binary translation. |
|
|
|
|
|
<p> |
|
|
Mode <b>a</b> is very slow. On a 2.8 GHz Intel Xeon host the resulting |
|
|
emulated machine is rougly equal to a 7 MHz R3000 (or a 3.5 MHz R4000). |
|
|
The actual performance varies a lot, maybe between 5 and 10 million |
|
|
instructions per second, depending on workload. |
|
|
|
|
|
<p> |
|
|
Mode <b>b</b> ("bintrans") is still to be considered experimental, but |
|
|
gives higher performance than mode <b>a</b>. It translates MIPS machine |
|
|
code into machine code that can be executed on the host machine |
|
|
on-the-fly. The translation itself obviously takes some time, but this is |
|
|
usually made up for by the fact that the translated code chunks are |
|
|
executed multiple times. |
|
|
To run the emulator with binary translation enabled, just add <b>-b</b> |
|
|
to the command line. |
|
|
|
|
|
<p> |
|
|
Only small pieces of MIPS machine code are translated, usually the size of |
|
|
a function, or less. There is no "intermediate representation" code, so |
|
|
all translations are done directly from MIPS to host machine code. |
|
|
|
|
|
<p> |
|
|
The default bintrans cache size is 16 MB, but you can change this by adding |
|
|
-DDEFAULT_BINTRANS_SIZE_IN_MB=<i>xx</i> to your CFLAGS environment variable |
|
|
before running the configure script, or by using the bintrans_size() |
|
|
configuration file option when running the emulator. |
|
66 |
|
|
67 |
<p> |
So, how fast is GXemul? There is no short answer to this. There is |
68 |
By default, an emulated OS running under DECstation emulation which listens to |
especially no answer to the question <b>What is the slowdown factor?</b>, |
69 |
interrupts from the mc146818 clock will get interrupts that are close to the |
because the host architecture and emulated architecture can usually not be |
70 |
host's clock. That is, if the emulated OS says it wants 100 interrupts per |
compared just like that. |
71 |
second, it will get approximately 100 interrupts per real second. |
|
72 |
|
<p>Performance depends on several factors, including (but not limited to) |
73 |
|
host architecture, host clock speed, which compiler and compiler flags |
74 |
|
were used to build the emulator, what the workload is, and so on. For |
75 |
|
example, if an emulated operating system tries to read a block from disk, |
76 |
|
from its point of view the read was instantaneous (no waiting). So 1 MIPS |
77 |
|
in an emulated OS might have taken more than one million instructions on a |
78 |
|
real machine. |
79 |
|
|
80 |
|
<p>Also, if the emulator says it has executed 1 million instructions, and |
81 |
|
the CPU family in question was capable of scalar execution (i.e. one cycle |
82 |
|
per instruction), it might still have taken more than 1 million cycles on |
83 |
|
a real machine because of cache misses and similar micro-architectural |
84 |
|
penalties that are not simulated by GXemul. |
85 |
|
|
86 |
|
<p>Because of these issues, it is in my opinion best to measure |
87 |
|
performance as the actual (real-world) time it takes to perform a task |
88 |
|
with the emulator. Typical examples would be "How long does it take to |
89 |
|
install NetBSD?", or "How long does it take to compile XYZ inside NetBSD |
90 |
|
in the emulator?". |
91 |
|
|
92 |
|
<p>So, how fast is it? :-) Answer: it varies. |
93 |
|
|
94 |
|
<p>The emulation technique used varies depending on which processor type |
95 |
|
is being emulated. (One of my main goals with GXemul is to experiment with |
96 |
|
different kinds of emulation, so these might change in the future.) |
97 |
|
|
98 |
<p> |
<ul> |
99 |
There is however a -I option, which sets the number of emulated cycles per |
<li><b>MIPS:</b><br> |
100 |
seconds to a fixed value. Let's say you wish to make the emulated OS think it |
There are two emulation modes. The most important one is an |
101 |
is running on a 40 MHz DECstation, and not a 7 MHz one, then you can add |
implementation of a <i>dynamic binary translator</i>. |
102 |
-I 40000000 to the command line. This will not make the emulation faster, of |
(Compared to real binary translators, though, GXemul's bintrans |
103 |
course. It might even make it seem slower; for example, if NetBSD/pmax waits |
subsystem is very simple and does not perform very well.) |
104 |
2 seconds for SCSI devices to settle during bootup, those 2 seconds will take |
This mode can be used on Alpha and i386 host. The other emulation |
105 |
2*40000000 cycles (which will take more time than 2*7000000). |
mode is simple interpretation, where an instruction is read from |
106 |
|
emulated memory, and interpreted one-at-a-time. (Slow, but it |
107 |
|
works. It can be forcefully used by using the <tt>-B</tt> command |
108 |
|
line option.) |
109 |
|
<p> |
110 |
|
<li><b>All other modes:</b><br> |
111 |
|
These use a kind of dynamic translation system. (This system does |
112 |
|
not use host-specific backends, so it is not "recompilation" or |
113 |
|
anything like that.) Speed is slower than real binary translation, |
114 |
|
but faster than traditional interpretation, and with some tricks |
115 |
|
it will hopefully still give reasonable speed. ARM emulation uses |
116 |
|
this kind of translation, for example. |
117 |
|
</ul> |
118 |
|
|
|
<p> |
|
|
The -I option is also necessary if you want to run deterministic experiments, |
|
|
if a mc146818 device is present. |
|
119 |
|
|
|
<p> |
|
|
Some emulators make claims such as "x times slowdown," but in the case of |
|
|
GXemul, the host is often not a MIPS-based machine, and hence comparing |
|
|
one MIPS instruction to a host instruction doesn't work. Performance depends on |
|
|
a lot of factors, including (but not limited to) host architecture, host speed, |
|
|
which compiler and compiler flags were used to build GXemul, what the |
|
|
workload is, and so on. For example, if an emulated operating system tries |
|
|
to read a block from disk, from its point of view the read was instantaneous |
|
|
(no waiting). So 1 MIPS in an emulated OS might have taken more than one |
|
|
million instructions on a real machine. Because of this, imho it is best |
|
|
to measure performance as the actual (real-world) time it takes to perform |
|
|
a task with the emulator. |
|
120 |
|
|
121 |
|
|
122 |
|
|
125 |
<a name="net"></a> |
<a name="net"></a> |
126 |
<h3>Networking</h3> |
<h3>Networking</h3> |
127 |
|
|
128 |
Running an entire operating system under emulation is very interesting in |
<font color="#ff0000">NOTE/TODO: This section is very old and a bit |
129 |
itself, but for several reasons, running a modern OS without access to |
out of date.</font> |
130 |
TCP/IP networking is a bit akward. Hence, I feel the need to implement TCP/IP |
|
131 |
(networking) support in the emulator. |
<p>Running an entire operating system under emulation is very interesting |
132 |
|
in itself, but for several reasons, running a modern OS without access to |
133 |
|
TCP/IP networking is a bit akward. Hence, I feel the need to implement |
134 |
|
TCP/IP (networking) support in the emulator. |
135 |
|
|
136 |
<p> |
<p> |
137 |
As far as I have understood it, there seems to be two different ways to go: |
As far as I have understood it, there seems to be two different ways to go: |
152 |
connect from the emulated OS to the OS running on the |
connect from the emulated OS to the OS running on the |
153 |
host, as packets sent out on the host's NIC are not |
host, as packets sent out on the host's NIC are not |
154 |
received by itself. (?) |
received by itself. (?) |
155 |
|
<li>All specific networking protocols will be handled by the |
156 |
|
physical network. |
157 |
</ul> |
</ul> |
158 |
<p> |
<p> |
159 |
or |
or |
182 |
</ul> |
</ul> |
183 |
</ol> |
</ol> |
184 |
|
|
185 |
Other emulators that I have heard of seem to use the first one, if they |
<p> |
186 |
support networking. |
Some emulators/simulators use the first approach, while others use the |
187 |
|
second. I think that SIMH and QEMU are examples of emulators using the |
188 |
|
first and second approach, respectively. |
189 |
|
|
190 |
<p> |
<p> |
191 |
Since I have choosen the second kind of implementation, I have to write |
Since I have choosen the second kind of implementation, I have to write |
200 |
and converted to ARP responses. (This is used by the emulated OS |
and converted to ARP responses. (This is used by the emulated OS |
201 |
to find out the MAC address of the gateway.) |
to find out the MAC address of the gateway.) |
202 |
<li>ICMP echo requests (that is the kind of packet produced by the |
<li>ICMP echo requests (that is the kind of packet produced by the |
203 |
<b>ping</b> program) are interpreted and converted to ICMP echo |
<b><tt>ping</tt></b> program) are interpreted and converted to ICMP echo |
204 |
replies, <i>regardless of the IP address</i>. This means that |
replies, <i>regardless of the IP address</i>. This means that |
205 |
running ping from within the emulated OS will <i>always</i> |
running ping from within the emulated OS will <i>always</i> |
206 |
receive a response. The ping packets never leave the emulated |
receive a response. The ping packets never leave the emulated |
214 |
packets are handled (but more state is kept for each connection). |
packets are handled (but more state is kept for each connection). |
215 |
<font color="#ff0000">NOTE: Much of the TCP handling code is very |
<font color="#ff0000">NOTE: Much of the TCP handling code is very |
216 |
ugly and hardcoded.</font> |
ugly and hardcoded.</font> |
217 |
|
<!-- |
218 |
<li>RARP is not implemented yet. (I haven't needed it so far.) |
<li>RARP is not implemented yet. (I haven't needed it so far.) |
219 |
|
--> |
220 |
</ul> |
</ul> |
221 |
|
|
222 |
|
<p> |
223 |
The gateway machine, which is the only "other" machine that the emulated |
The gateway machine, which is the only "other" machine that the emulated |
224 |
OS sees on its emulated network, works as a NAT-style firewall/gateway. It |
OS sees on its emulated network, works as a NAT-style firewall/gateway. It |
225 |
has a fixed IPv4 address of 10.0.0.254. An OS running in the emulator |
usually has a fixed IPv4 address of <tt>10.0.0.254</tt>. An OS running in |
226 |
can thus have any 10.x.x.x address; a typical choice would be 10.0.0.1. |
the emulator would usually have an address of the form <tt>10.x.x.x</tt>; |
227 |
|
a typical choice would be <tt>10.0.0.1</tt>. |
228 |
|
|
229 |
<p> |
<p> |
230 |
Inside emulated NetBSD or OpenBSD, running the following commands should |
Inside emulated NetBSD/pmax or OpenBSD/pmax, running the following |
231 |
configure the emulated NIC: |
commands should configure the emulated NIC: |
232 |
<pre> |
<pre> |
233 |
# <b>ifconfig le0 10.0.0.1</b> |
# <b>ifconfig le0 10.0.0.1</b> |
234 |
# <b>route add default 10.0.0.254</b> |
# <b>route add default 10.0.0.254</b> |
235 |
add net default: gateway 10.0.0.254 |
add net default: gateway 10.0.0.254 |
236 |
</pre> |
</pre> |
237 |
|
|
238 |
|
<p> |
239 |
If you want nameserver lookups to work, you need a valid /etc/resolv.conf |
If you want nameserver lookups to work, you need a valid /etc/resolv.conf |
240 |
as well: |
as well: |
241 |
<pre> |
<pre> |
242 |
# <b>echo nameserver 129.16.1.3 > /etc/resolv.conf</b> |
# <b>echo nameserver 129.16.1.3 > /etc/resolv.conf</b> |
243 |
</pre> |
</pre> |
244 |
(But replace 129.16.1.3 with the actual real-world IP address of your |
(But replace <tt>129.16.1.3</tt> with the actual real-world IP address of |
245 |
nearest nameserver.) |
your nearest nameserver.) |
246 |
|
|
247 |
<p> |
<p> |
248 |
Now, host lookups should work: |
Now, host lookups should work: |
249 |
<pre> |
<pre> |
266 |
uucp-gw-2.pa.dec.com 172799 IN A 204.123.2.19 |
uucp-gw-2.pa.dec.com 172799 IN A 204.123.2.19 |
267 |
</pre> |
</pre> |
268 |
|
|
269 |
To transfer files via UDP, you can use the tftp program. |
<p> |
270 |
|
At this point, UDP and TCP should (mostly) work. |
|
<pre> |
|
|
# <b>tftp 12.34.56.78</b> |
|
|
tftp> <b>get filename</b> |
|
|
Received XXXXXX bytes in X.X seconds |
|
|
tftp> <b>quit</b> |
|
|
# |
|
|
</pre> |
|
|
|
|
|
or, to do it non-interactively (with ugly output): |
|
|
|
|
|
<pre> |
|
|
# <b>echo get filename | tftp 12.34.56.78</b> |
|
|
tftp> Received XXXXXX bytes in X.X seconds |
|
|
tftp> # |
|
|
</pre> |
|
271 |
|
|
272 |
This, of course, requires that you have put the file <i>filename</i> in |
<p> |
273 |
the root directory of the tftp server (12.34.56.78). |
Here is an example of how to configure a server machine and an emulated |
274 |
|
client machine for sharing files via NFS: |
275 |
|
|
276 |
<p> |
<p> |
277 |
It is also possible to run NFS via UDP. This is very useful if you want to |
(This is very useful if you want to share entire directory trees |
278 |
share entire directory trees between the emulated environment and another |
between the emulated environment and another machine. These instruction |
279 |
machine. These instruction will work for FreeBSD, if you are running |
will work for FreeBSD, if you are running something else, use your |
280 |
something else, use your imagination to modify them: |
imagination to modify them.) |
281 |
|
|
282 |
|
<p> |
283 |
<ul> |
<ul> |
284 |
<li>On the server, add a line to your /etc/exports file, exporting |
<li>On the server, add a line to your /etc/exports file, exporting |
285 |
the files you wish to use in the emulator:<pre> |
the files you wish to use in the emulator:<pre> |
318 |
files in both directions, but then you should be aware of the |
files in both directions, but then you should be aware of the |
319 |
fragmentation issue mentioned above. |
fragmentation issue mentioned above. |
320 |
|
|
321 |
<p> |
<p>TODO: Write a section on how to connect multiple emulator instances. |
322 |
TCP is implemented to some extent, but should not be considered to be |
(Using the <tt>local_port</tt> and <tt>add_remote</tt> configuration file |
323 |
stable yet. It is enough to let NetBSD/pmax and OpenBSD/pmax install via |
commands.) |
324 |
ftp, though. |
|
325 |
|
|
326 |
|
|
327 |
|
|
328 |
|
|
331 |
<a name="devices"></a> |
<a name="devices"></a> |
332 |
<h3>Emulation of hardware devices</h3> |
<h3>Emulation of hardware devices</h3> |
333 |
|
|
334 |
Each file in the device/ directory is responsible for one hardware device. |
Each file in the <tt>src/device/</tt> directory is responsible for one |
335 |
These are used from src/machine.c, when initializing which hardware a |
hardware device. These are used from <tt>src/machine.c</tt>, when |
336 |
particular machine model will be using, or when adding devices to a |
initializing which hardware a particular machine model will be using, or |
337 |
machine using the <b>device()</b> command in configuration files. |
when adding devices to a machine using the <tt>device()</tt> command in |
338 |
|
configuration files. |
339 |
|
|
340 |
<p> |
<p><font color="#ff0000">NOTE: The device registry subsystem is currently |
341 |
<font color="#ff0000">NOTE: 2005-02-26: I'm currently rewriting the |
in a state of flux, as it is being redesigned.</font> |
|
device registry subsystem.</font> |
|
342 |
|
|
343 |
<p> |
<p>(I'll be using the name "<tt>foo</tt>" as the name of the device in all |
344 |
(I'll be using the name 'foo' as the name of the device in all these |
these examples. This is pseudo code, it might need some modification to |
|
examples. This is pseudo code, it might need some modification to |
|
345 |
actually compile and run.) |
actually compile and run.) |
346 |
|
|
347 |
<p> |
<p>Each device should have the following: |
|
Each device should have the following: |
|
348 |
|
|
349 |
<p> |
<p> |
350 |
<ul> |
<ul> |
351 |
<li>A devinit function in dev_foo.c. It would typically look |
<li>A <tt>devinit</tt> function in <tt>src/devices/dev_foo.c</tt>. It |
352 |
something like this: |
would typically look something like this: |
353 |
<pre> |
<pre> |
354 |
/* |
/* |
355 |
* devinit_foo(): |
* devinit_foo(): |
386 |
} |
} |
387 |
</pre><br> |
</pre><br> |
388 |
|
|
389 |
<li>At the top of dev_foo.c, the foo_data struct should be defined. |
<li>At the top of <tt>dev_foo.c</tt>, the <tt>foo_data</tt> struct |
390 |
|
should be defined. |
391 |
<pre> |
<pre> |
392 |
struct foo_data { |
struct foo_data { |
393 |
int irq_nr; |
int irq_nr; |
395 |
} |
} |
396 |
</pre><br> |
</pre><br> |
397 |
|
|
398 |
<li>If foo has a tick function (that is, something that needs to be |
<li>If <tt>foo</tt> has a tick function (that is, something that needs to be |
399 |
run at regular intervals) then FOO_TICKSHIFT and a tick function |
run at regular intervals) then <tt>FOO_TICKSHIFT</tt> and a tick |
400 |
need to be defined as well: |
function need to be defined as well: |
401 |
<pre> |
<pre> |
402 |
#define FOO_TICKSHIFT 10 |
#define FOO_TICKSHIFT 10 |
403 |
|
|
442 |
</ul> |
</ul> |
443 |
|
|
444 |
<p> |
<p> |
445 |
The return value of the access function has until 20040702 been a |
The return value of the access function has until 2004-07-02 been a |
446 |
true/false value; 1 for success, or 0 for device access failure. A device |
true/false value; 1 for success, or 0 for device access failure. A device |
447 |
access failure (on MIPS) will result in a DBE exception. |
access failure (on MIPS) will result in a DBE exception. |
448 |
|
|
456 |
|
|
457 |
<p> |
<p> |
458 |
To be compatible with pre-20040702 devices, a return value of 0 is treated |
To be compatible with pre-20040702 devices, a return value of 0 is treated |
459 |
by the caller (in src/memory.c) as a value of -1. |
by the caller (in <tt>src/memory_rw.c</tt>) as a value of -1. |
|
|
|
|
|
|
|
|
|
460 |
|
|
461 |
|
|
|
<p><br> |
|
|
<a name="regtest"></a> |
|
|
<h3>Regression tests</h3> |
|
|
|
|
|
In order to make sure that the emulator actually works like it is supposed |
|
|
to, it must be tested. For this purpose, there is a simple regression |
|
|
testing framework in the <b>tests/</b> directory. |
|
|
|
|
|
<p> |
|
|
<i>NOTE: The regression testing framework is basically just a skeleton so far. |
|
|
Regression tests are very good to have. However, the fact that complete |
|
|
operating systems can run in the emulator indicate that the emulation is |
|
|
probably not too incorrect. This makes it less of a priority to write |
|
|
regression tests.</i> |
|
|
|
|
|
<p> |
|
|
To run all the regression tests, type <b>make regtest</b>. Each assembly |
|
|
language file matching the pattern <b>test_*.S</b> will be compiled and |
|
|
linked into a 64-bit MIPS ELF (using a gcc cross compiler), and run in the |
|
|
emulator. If everything goes well, you should see something like this: |
|
|
|
|
|
<pre> |
|
|
$ make regtest |
|
|
cd tests; make run_tests; cd .. |
|
|
gcc33 -Wall -fomit-frame-pointer -fmove-all-movables -fpeephole -O2 |
|
|
-mcpu=ev5 -I/usr/X11R6/include -lm -L/usr/X11R6/lib -lX11 do_tests.c |
|
|
-o do_tests |
|
|
do_tests.c: In function `main': |
|
|
do_tests.c:173: warning: unused variable `s' |
|
|
/var/tmp//ccFOupvD.o: In function `do_tests': |
|
|
/var/tmp//ccFOupvD.o(.text+0x3a8): warning: tmpnam() possibly used |
|
|
unsafely; consider using mkstemp() |
|
|
mips64-unknown-elf-gcc -g -O3 -fno-builtin -fschedule-insns -mips64 |
|
|
-mabi=64 test_common.c -c -o test_common.o |
|
|
./do_tests "mips64-unknown-elf-gcc -g -O3 -fno-builtin -fschedule-insns |
|
|
-mips64 -mabi=64" "mips64-unknown-elf-as -mabi=64 -mips64" |
|
|
"mips64-unknown-elf-ld -Ttext 0xa800000000030000 -e main |
|
|
--oformat=elf64-bigmips" "../gxemul" |
|
|
|
|
|
Starting tests: |
|
|
test_addu.S (-a) |
|
|
test_addu.S (-a -b) |
|
|
test_clo_clz.S (-a) |
|
|
test_clo_clz.S (-a -b) |
|
|
.. |
|
|
test_unaligned.S (-a) |
|
|
test_unaligned.S (-a -b) |
|
|
|
|
|
Done. (12 tests done) |
|
|
PASS: 12 |
|
|
FAIL: 0 |
|
|
|
|
|
---------------- |
|
|
|
|
|
All tests OK |
|
|
|
|
|
---------------- |
|
|
</pre> |
|
|
|
|
|
<p> |
|
|
Each test writes output to stdout, and there is a <b>test_*.good</b> for |
|
|
each <b>.S</b> file which contains the wanted output. If the actual output |
|
|
matches the <b>.good</b> file, then the test passes, otherwise it fails. |
|
|
|
|
|
<p> |
|
|
Read <b>tests/README</b> for more information. |
|
462 |
|
|
463 |
|
|
464 |
|
|