xv6 revisited…

I was hoping to do more with this, but things are going other ways in life.  Anyways a while back I had touched on xv6, a MIT teaching tool and semiport of Unix v6 to the i386!  The best part about it, is that it is SMALL…

I’ve been playing with it the last day on the latest version of Qemu and hit a snag with its SMP support (yes it does have that!) so I played with it, and couldn’t figure it out so I had to turn it off.. It is something ACPI related, and probably along the reason why Windows x64 doesn’t run on new Qemu either..

I’ve built the cross compiling environment needed (A bare elf compiler/linker/assembler) and managed to smash enough of it into a single directory that you won’t need MinGW installed, but can rather invoke ‘build.bat’ which will compile link, dd the disk image, and launch Qemu.

I’ve had trouble with mkfs so… you’ll have to live with a prebuilt root image.

If you want to build your own cross compiling toolchain, there is a good guide here on the OSWiki.  Naturally you’ll want my previous post on some snags I ran into on MinGW if you do choose that as your target environment.

What I’d love to do is port newlib, and see just how useful this xv6 could become..  I would imagine adding signals (well beyond kill) may allow things like bash 1.x to run, and maybe gcc itself.. Which would be cool.

You can download my work here.  Check it out, it’s cool!

building a cross compiler under MinGW snag in collect2

rm -f collect2.exe
gcc -DCROSS_COMPILE -DIN_GCC     -g -O2  -DHAVE_CONFIG_H  -o collect2.exe collect2.o tlink.o hash.o intl.o underscore.o version.o  obstack.o       -ladvapi32 ../libiberty/libiberty.a
collect2.o: In function `handler':
C:\MinGW\msys\1.0\src\gcc-2.95.3\gcc/collect2.c:527: undefined reference to `kill'
collect2.o: In function `scan_prog_file':
C:\MinGW\msys\1.0\src\gcc-2.95.3\gcc/collect2.c:2269: undefined reference to `pipe'
C:\MinGW\msys\1.0\src\gcc-2.95.3\gcc/collect2.c:2292: undefined reference to `fork'
collect2: ld returned 1 exit status
make[1]: *** [collect2.exe] Error 1
make[1]: Leaving directory `/usr/src/gcc-2.95.3/gcc'
make: *** [all-gcc] Error 2

Ugh, isn’t that annoying? Well it turns out from the mailing list

The mingw32-hosted GCCs does not need ‘collect2.exe’ hence
set USE_COLLECT2= nothing (empty) in the <gcc_obj_dir>/gcc/Makefile

This needs to be fixed in GCC mainlne.

Regards.
Nitin.

And the other half….

fixincl.c:316: error: `SIGQUIT' undeclared (first use in this function)
fixincl.c:316: error: (Each undeclared identifier is reported only once
fixincl.c:316: error: for each function it appears in.)
fixincl.c:323: error: `SIGALRM' undeclared (first use in this function)
fixincl.c: In function `internal_fix':
fixincl.c:808: warning: implicit declaration of function `pipe'
fixincl.c:816: warning: implicit declaration of function `fork'
fixincl.c:845: warning: implicit declaration of function `sleep'
fixincl.c:860: warning: implicit declaration of function `fcntl'
fixincl.c:860: error: `F_DUPFD' undeclared (first use in this function

Which is fixed by changing

STMP_FIXINC = stmp-fixinc

into

STMP_FIXINC =

Oops!



Failed Quakeworld port to OS/2 2.0

Yeah, I guess I just couldn’t salvage this thing… Sometimes when you stand on the shoulders of giants you fall off.

So what had started as a seemingly simple thing turned into a nightmare.. I took the source to my MS-DOS port of Quakeworld, and decided to build it under OS/2. And to be crazy about it, I thought it’d be awesome to get it to work under OS/2 2.0 .

Which means no sound, locked to 320×200 256 colours, full screen only, since the VGA driver won’t do anything but. Years ago on ebay I managed to score IBM TCP/IP for OS/2 2.0 & 2.1, with the LAN support!

IBM OS2 2.0 syslevel 1

IBM OS2 2.0 XR02000 (no fixpacks)

 

 

ibm os2 2.0 syslevel2

IBM TCP/IP for OS/2 with no fixpack

So as you can see from my syslevel’s I’m running a pretty bare machine, even the graphics subsystem is still 16bit!

Well the good news, is that with EMX and a HPFS disk, I was able to quickly get the null version running. With a minor amount of work, I had TCP/IP connectivity and things were going well. I had ripped apart a video demo, and got the display up, although it was ungodly slow.. Until I found out that when you are full screen you can request access to the physical video memory, under OS/2 so that sped things up a great deal!

Then all that really needed to be done was get the keyboard working.

And here is where I slipped up.

OS/2 is weird for interactive programs that want to know key states. It seems the best and most common way to do this was to setup a ‘monitor’ for the keyboard device, and try to read the stream as keys are pressed. Sadly idiots that slamm the keyboard, or gamers that hold down an arrow key for a minute lock the thing, and the key then is ‘jammed’ down until you hit it again for the release.

I’m pretty sure that I did it wrong, so I borrowed code from a more ‘advanced’ OS/2 port and it did the same thing. Maybe it’s OS/2 2.0? I don’t know, I did service pack it and update and still the same result.

I really didn’t want to spend that much time on it…..

QuakeWorld for OS/2

QuakeWorld for OS/2

I feel hesitant to release a binary as you will get killed, and I haven’t even tried the mouse yet, but I suspect it’ll still suck.

So for anyone that cares, here is the source… misspellings and all.

Quake1 & MS-DOS

And because I had a request for it, here is a 7zip containing a makefile, and source suitable for building quake under MS-DOS.

I sourced it from the Doom makefile, and cross built it under OS X… It builds in under 5 seconds using all 4 cpu’s on my OS X box with my OS X to MSDOS DJGPP cross compiler…. I had forgotten that the gpl’d source included MS-DOS support.. I had taken the video part from Chi Hoang’s DOS port of DOOM and gotten it to run until I remembered.. Oh well a few hours wasted.

So there it is, Quake1 built on a mac, and running on DOSBox on a PC.....

And speaking of Quake, it’s on sale too!

But just for today, on steam…..

Doom for MS-DOS

Today while checking out eets on steam ( yeah I know… ) I came across this sale… It’s Doom, Doom II, and Doom III all together, with all the expansion sets for $8.74 USD!

Well needless to say I couldn’t resist the offer, so I bought it. While playing around with Doom, I was wondering what was the first port of the Linux X11 doom back to MS-DOS. A bit of googling brought me to the doom wiki, and from there it seems that “DOSDoom” version is the first source port returning DOOM back to MS-DOS.

As mentioned in Chi Hoang’s notes, it took him 4-5 hours to do the initial port. So I figured it’d be worth re-creating the 0.1 version of his work, under DOSBOX with DJGPP.

I did find out the hard way that there is a single assembly clause that breaks under newer versions of DJGPP, and there is a small issue with the HOME environment variable that if it’s not set it’ll crash DOOM. So I ‘fixed’ that to use the current directory.

To install this legacy version of DJGPP, I found the needed files..

*bnu27b.zip
*csdpmi7b.zip
*djdev201.zip
*gcc2721b.zip
*gdb418b.zip
*mak3791b.zip
*pat253b.zip

Simply unzip all of this into a directory that your DOSBox mounts, and alter your dosbox.conf something like this:

[autoexec]
# Lines in this section will be run at startup.

mount c c:\dos
c:
set PATH=C:\DJGPP\BIN;z:\
set DJGPP=C:\DJGPP\DJGPP.ENV

Then you should be able to extract the doom source that I’ve patched up, and run make to re-build the exe. I’ve included a shareware wad file that won’t explode on missing demos…

So the end result is the following:

DOSDoom 0.1

DOSDoom 0.1

Which… has no networking support, no audio, but it does work! This port is overall minimally invasive to the code, and I’d suspect it’d make it a very easy starting point for yet even more ports of doom… I think there is over 40 out there.

That’s the one great thing about making the source available, is that the product lives on and on!

Building 32bit binaries on x86_64 Debian 7 / Wheezy

I’ve been going in circles with slirp trying to really get it to run on x86_64 mode so far to no avail…

So first thing, hello from the future of 2020 (I wrote this quick blurb in 2010), and Wheezy has been pulled from the main mirrors. So annoying! You need to update your apt sources to use the archive:

deb http://archive.debian.org/debian/ wheezy main
deb-src http://archive.debian.org/debian/ wheezy main
deb http://security.debian.org/ wheezy/updates main contrib
deb-src http://security.debian.org/ wheezy/updates main contrib

Do your apt-get update;apt-get upgrade and you’ll be ready to roll!

But it’d sure help to be able to compile code in 32bit/64bit on the same machine. Anyways after looking for far too long I managed to find that it’s really simple.

apt-get install lib32bz2-dev

And away we go!

Naturally, you’ll need a compiler already installed ( build-essential).

# cat x.c
#include
int main(){printf(“int is %d\n”,sizeof(int));return 0;}
#
# gcc -m64 x.c -o x64
# gcc -m32 x.c -o x32
# file x32 x64
x32: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.8, not stripped
x64: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.8, not stripped
# ./x32
int is 4
# ./x64
int is 4

Which alone is… interesting.

SIMH benchmark numbers…

I have to admit, I’m really surprised. In the past Visual C++ had been a clear winner every time I’d checked performance vs Gcc. And the tide seems to have really turned under Windows 7 x64. While not a massive lead, the winner after all these iterations of my simh benchmark was Gcc 4.5.2 for x86_64.

Just in the same fashion here, it seems that on some platforms -O1 is faster then -O2, and you really won’t find out until you run some comparisons.

gcc version 3.4.5 (mingw-vista special r3)

gcc O0
21.33333333333333
Dhrystone(1.1) time for 500000 passes = 23
This machine benchmarks at 21739 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 20
This machine benchmarks at 25000 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 21
This machine benchmarks at 23809 dhrystones/second

gcc O1
15.33333333333333
Dhrystone(1.1) time for 500000 passes = 16
This machine benchmarks at 31250 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 15
This machine benchmarks at 33333 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 15
This machine benchmarks at 33333 dhrystones/second

gcc 02
12.33333333333333
Dhrystone(1.1) time for 500000 passes = 12
This machine benchmarks at 41666 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 13
This machine benchmarks at 38461 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 12
This machine benchmarks at 41666 dhrystones/second

gcc version 4.5.2 20101002 (prerelease) [svn/rev.164902 – mingw-w64/oz] (GCC)

gcc O0
21.33333333333333
Dhrystone(1.1) time for 500000 passes = 21
This machine benchmarks at 23809 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 22
This machine benchmarks at 22727 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 21
This machine benchmarks at 23809 dhrystones/second

gcc O1
13.33333333333333
Dhrystone(1.1) time for 500000 passes = 13
This machine benchmarks at 38461 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 14
This machine benchmarks at 35714 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 13
This machine benchmarks at 38461 dhrystones/second

gcc O2
12
Dhrystone(1.1) time for 500000 passes = 11
This machine benchmarks at 45454 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 13
This machine benchmarks at 38461 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 12
This machine benchmarks at 41666 dhrystones/second

Microsoft (R) C/C++ Optimizing Compiler Version 16.00.30319.01 for x64

VC /Od /Bi0
21.33333333333333
Dhrystone(1.1) time for 500000 passes = 21
This machine benchmarks at 23809 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 21
This machine benchmarks at 23809 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 22
This machine benchmarks at 22727 dhrystones/second

VC /O2 /Ob2 /Oi
13
Dhrystone(1.1) time for 500000 passes = 13
This machine benchmarks at 38461 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 13
This machine benchmarks at 38461 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 13
This machine benchmarks at 38461 dhrystones/second

VC /O2
13.66666666666667
Dhrystone(1.1) time for 500000 passes = 14
This machine benchmarks at 35714 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 13
This machine benchmarks at 38461 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 14
This machine benchmarks at 35714 dhrystones/second

Vc /Og /Ox
13
Dhrystone(1.1) time for 500000 passes = 13
This machine benchmarks at 38461 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 13
This machine benchmarks at 38461 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 13
This machine benchmarks at 38461 dhrystones/second

Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80×86
VC /Og /Ox
13.33333333333333
Dhrystone(1.1) time for 500000 passes = 14
This machine benchmarks at 35714 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 13
This machine benchmarks at 38461 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 13
This machine benchmarks at 38461 dhrystones/second

And this is on my laptop, an Intel Core i7 Q 720 running at 1.6Ghz with 4GB of ram & Windows 7 Home Premium.

MinGW-w64

Well after yesterdays x86_64 excitement, I figured I’d take a look in the windows area to see about the 32bit vs 64bit performance on Windows…

I know this isn’t the ‘best’ test as I’m using VMWare Fusion on OS X and running Windows XP x64 sp2 (the 2007 edition, not the 2003 one).

If anyone wants to know how to get a 64bit gcc on windows, this is the best formula I’ve come up with so far.

First download a build of mingw-w64-bin_x86_64 from sourceforge… Right now I’m using a ‘Personal Build’ from sezero_20101003, because… it’s recent, and I would imagine a personal build has some hope of actually working.

I downloaded that, and extracted to the root of the C drive. Then I renamed the mingw64 to mingw.

Next up, I downloaded and installed MSYS 1.0.11, and installed that. I selected the default options, and of course specified my mingw is installed in

C:/mingw

After that, I install the MSYS DTK 1.0, again with default options.

The final part is some kind of editor, I like VIM but it’s… involved to download as the default package ‘vim-7.2-1-msys-1.0.11-bin.tar.lzma’ is in a 7zip compatible archive that needs a bit of tweaking to get a tar file out of. I can provide it here in gzip format, that you can simply extract within the msys command prompt in the /usr directory.

Now with all that done, you should be in business!

$ gcc -v
Using built-in specs.
Target: x86_64-w64-mingw32
Configured with: ../gcc44-svn/configure –host=x86_64-w64-mingw32 –target=x86_6
4-w64-mingw32 –disable-multilib –enable-checking=release –prefix=/mingw64 –w
ith-sysroot=/mingw64 –enable-languages=c,c++,fortran,objc,obj-c++ –enable-libg
omp –with-gmp=/mingw64 –with-mpfr=/mingw64 –disable-nls –disable-win32-regis
try
Thread model: win32
gcc version 4.4.5 20101001 (release) [svn/rev.164871 – mingw-w64/oz] (GCC)

 

But will it run Dungeon?

What is also cool, is that this build of mingw includes gfortran, which is a Fortran 95 compiler with various 2003 & 2008 enhancements. So for the heck of it, I’ve rebuilt the makefile from dungeon-2.5.6 and tweaked the machdep.f to at least call the ITIME function to get the current time. The resulting archive runs pretty well!

Windows XP x64 - dungeon

Yes, it runs! And without a *32 meaning this is a 64bit binary!

 

Onward with SIMH

So going back to SIMH as my benchmark, here is the vax780 with -O0/-O0

Dhrystone(1.1) time for 500000 passes = 18
This machine benchmarks at 27777 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 20
This machine benchmarks at 25000 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 19
This machine benchmarks at 26315 dhrystones/second

Which comparing it to the native x86_64 build is pretty good considering I’m running this in a VM (VMware Fusion!). Now the same test with -O1/-O1

Dhrystone(1.1) time for 500000 passes = 12
This machine benchmarks at 41666 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 12
This machine benchmarks at 41666 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 12
This machine benchmarks at 41666 dhrystones/second

Which is pretty good! Now for the finally with -O2/-O1

Dhrystone(1.1) time for 500000 passes = 12
This machine benchmarks at 41666 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 12
This machine benchmarks at 41666 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 12
This machine benchmarks at 41666 dhrystones/second

Which is interesting in that there is no appreciable difference in the -O2/-O1 vs the -O1/-O1 build. Although I kind of expect different results on a native machine. If anyone else cares to test, I’m going to make available the whole project here. This includes the source and the pre-built binaries.

Unzip it on a win64/win32 machine and it should be somewhat straightforward to build / run. You can alter the makefile and change the primary CC flags from O0 to O1 or O2 if you so wish… just run make and it’ll generate a vax780.exe . Then in the test directory you can bench your exe like this:

$ make
gcc -O0 -c -o VAX/vax_cpu.o VAX/vax_cpu.c -I. -DVM_VAX -DVAX_780 -DUSE_INT64 -DU
SE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o VAX/vax_cpu1.o VAX/vax_cpu1.c -I. -DVM_VAX -DVAX_780 -DUSE_INT64 –
DUSE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o VAX/vax_fpa.o VAX/vax_fpa.c -I. -DVM_VAX -DVAX_780 -DUSE_INT64 -DU
SE_ADDR64 -I VAX -I PDP11
VAX/vax_fpa.c: In function ‘op_cmpfd’:
VAX/vax_fpa.c:210: warning: integer constant is too large for ‘long’ type
VAX/vax_fpa.c:210: warning: integer constant is too large for ‘long’ type
VAX/vax_fpa.c:211: warning: integer constant is too large for ‘long’ type
VAX/vax_fpa.c:211: warning: integer constant is too large for ‘long’ type
VAX/vax_fpa.c: In function ‘op_cmpg’:
VAX/vax_fpa.c:233: warning: integer constant is too large for ‘long’ type
VAX/vax_fpa.c:233: warning: integer constant is too large for ‘long’ type
VAX/vax_fpa.c:234: warning: integer constant is too large for ‘long’ type
VAX/vax_fpa.c:234: warning: integer constant is too large for ‘long’ type
VAX/vax_fpa.c: In function ‘vax_fadd’:
VAX/vax_fpa.c:371: warning: integer constant is too large for ‘long’ type
VAX/vax_fpa.c:373: warning: integer constant is too large for ‘long’ type
VAX/vax_fpa.c:386: warning: integer constant is too large for ‘long’ type
VAX/vax_fpa.c: In function ‘unpackd’:
VAX/vax_fpa.c:525: warning: integer constant is too large for ‘long’ type
VAX/vax_fpa.c:525: warning: integer constant is too large for ‘long’ type
VAX/vax_fpa.c: In function ‘unpackg’:
VAX/vax_fpa.c:540: warning: integer constant is too large for ‘long’ type
VAX/vax_fpa.c:540: warning: integer constant is too large for ‘long’ type
VAX/vax_fpa.c: In function ‘norm’:
VAX/vax_fpa.c:548: warning: integer constant is too large for ‘long’ type
VAX/vax_fpa.c:548: warning: integer constant is too large for ‘long’ type
VAX/vax_fpa.c:548: warning: integer constant is too large for ‘long’ type
VAX/vax_fpa.c:549: warning: integer constant is too large for ‘long’ type
VAX/vax_fpa.c:549: warning: integer constant is too large for ‘long’ type
VAX/vax_fpa.c:557: warning: integer constant is too large for ‘long’ type
VAX/vax_fpa.c: In function ‘rpackfd’:
VAX/vax_fpa.c:574: warning: integer constant is too large for ‘long’ type
VAX/vax_fpa.c:575: warning: integer constant is too large for ‘long’ type
VAX/vax_fpa.c: In function ‘rpackg’:
VAX/vax_fpa.c:597: warning: integer constant is too large for ‘long’ type
gcc -O0 -c -o VAX/vax_cis.o VAX/vax_cis.c -I. -DVM_VAX -DVAX_780 -DUSE_INT64 -DU
SE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o VAX/vax_octa.o VAX/vax_octa.c -I. -DVM_VAX -DVAX_780 -DUSE_INT64 –
DUSE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o VAX/vax_cmode.o VAX/vax_cmode.c -I. -DVM_VAX -DVAX_780 -DUSE_INT64
-DUSE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o VAX/vax_mmu.o VAX/vax_mmu.c -I. -DVM_VAX -DVAX_780 -DUSE_INT64 -DU
SE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o VAX/vax_sys.o VAX/vax_sys.c -I. -DVM_VAX -DVAX_780 -DUSE_INT64 -DU
SE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o VAX/vax_syscm.o VAX/vax_syscm.c -I. -DVM_VAX -DVAX_780 -DUSE_INT64
-DUSE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o VAX/vax780_stddev.o VAX/vax780_stddev.c -I. -DVM_VAX -DVAX_780 -DU
SE_INT64 -DUSE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o VAX/vax780_sbi.o VAX/vax780_sbi.c -I. -DVM_VAX -DVAX_780 -DUSE_INT
64 -DUSE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o VAX/vax780_mem.o VAX/vax780_mem.c -I. -DVM_VAX -DVAX_780 -DUSE_INT
64 -DUSE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o VAX/vax780_uba.o VAX/vax780_uba.c -I. -DVM_VAX -DVAX_780 -DUSE_INT
64 -DUSE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o VAX/vax780_mba.o VAX/vax780_mba.c -I. -DVM_VAX -DVAX_780 -DUSE_INT
64 -DUSE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o VAX/vax780_fload.o VAX/vax780_fload.c -I. -DVM_VAX -DVAX_780 -DUSE
_INT64 -DUSE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o VAX/vax780_syslist.o VAX/vax780_syslist.c -I. -DVM_VAX -DVAX_780 –
DUSE_INT64 -DUSE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o PDP11/pdp11_rl.o PDP11/pdp11_rl.c -I. -DVM_VAX -DVAX_780 -DUSE_INT
64 -DUSE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o PDP11/pdp11_rq.o PDP11/pdp11_rq.c -I. -DVM_VAX -DVAX_780 -DUSE_INT
64 -DUSE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o PDP11/pdp11_ts.o PDP11/pdp11_ts.c -I. -DVM_VAX -DVAX_780 -DUSE_INT
64 -DUSE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o PDP11/pdp11_dz.o PDP11/pdp11_dz.c -I. -DVM_VAX -DVAX_780 -DUSE_INT
64 -DUSE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o PDP11/pdp11_lp.o PDP11/pdp11_lp.c -I. -DVM_VAX -DVAX_780 -DUSE_INT
64 -DUSE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o PDP11/pdp11_tq.o PDP11/pdp11_tq.c -I. -DVM_VAX -DVAX_780 -DUSE_INT
64 -DUSE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o PDP11/pdp11_xu.o PDP11/pdp11_xu.c -I. -DVM_VAX -DVAX_780 -DUSE_INT
64 -DUSE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o PDP11/pdp11_ry.o PDP11/pdp11_ry.c -I. -DVM_VAX -DVAX_780 -DUSE_INT
64 -DUSE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o PDP11/pdp11_cr.o PDP11/pdp11_cr.c -I. -DVM_VAX -DVAX_780 -DUSE_INT
64 -DUSE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o PDP11/pdp11_rp.o PDP11/pdp11_rp.c -I. -DVM_VAX -DVAX_780 -DUSE_INT
64 -DUSE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o PDP11/pdp11_tu.o PDP11/pdp11_tu.c -I. -DVM_VAX -DVAX_780 -DUSE_INT
64 -DUSE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o PDP11/pdp11_hk.o PDP11/pdp11_hk.c -I. -DVM_VAX -DVAX_780 -DUSE_INT
64 -DUSE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o PDP11/pdp11_io_lib.o PDP11/pdp11_io_lib.c -I. -DVM_VAX -DVAX_780 –
DUSE_INT64 -DUSE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o scp.o scp.c -I. -DVM_VAX -DVAX_780 -DUSE_INT64 -DUSE_ADDR64 -I VAX
-I PDP11
scp.c:470: warning: integer constant is too large for ‘long’ type
scp.c:470: warning: integer constant is too large for ‘long’ type
scp.c:470: warning: integer constant is too large for ‘long’ type
scp.c:470: warning: integer constant is too large for ‘long’ type
scp.c:471: warning: integer constant is too large for ‘long’ type
scp.c:471: warning: integer constant is too large for ‘long’ type
scp.c:471: warning: integer constant is too large for ‘long’ type
scp.c:471: warning: integer constant is too large for ‘long’ type
scp.c:472: warning: integer constant is too large for ‘long’ type
scp.c:472: warning: integer constant is too large for ‘long’ type
scp.c:472: warning: integer constant is too large for ‘long’ type
scp.c:472: warning: integer constant is too large for ‘long’ type
scp.c:473: warning: integer constant is too large for ‘long’ type
scp.c:473: warning: integer constant is too large for ‘long’ type
scp.c:473: warning: integer constant is too large for ‘long’ type
scp.c:473: warning: integer constant is too large for ‘long’ type
scp.c:474: warning: integer constant is too large for ‘long’ type
scp.c:474: warning: integer constant is too large for ‘long’ type
scp.c:474: warning: integer constant is too large for ‘long’ type
scp.c:474: warning: integer constant is too large for ‘long’ type
scp.c:475: warning: integer constant is too large for ‘long’ type
scp.c:475: warning: integer constant is too large for ‘long’ type
scp.c:475: warning: integer constant is too large for ‘long’ type
scp.c:475: warning: integer constant is too large for ‘long’ type
scp.c:476: warning: integer constant is too large for ‘long’ type
scp.c:476: warning: integer constant is too large for ‘long’ type
scp.c:477: warning: integer constant is too large for ‘long’ type
scp.c:477: warning: integer constant is too large for ‘long’ type
scp.c:478: warning: integer constant is too large for ‘long’ type
scp.c:478: warning: integer constant is too large for ‘long’ type
scp.c:479: warning: integer constant is too large for ‘long’ type
scp.c:479: warning: integer constant is too large for ‘long’ type
gcc -O0 -c -o sim_console.o sim_console.c -I. -DVM_VAX -DVAX_780 -DUSE_INT64 -DU
SE_ADDR64 -I VAX -I PDP11
gcc -O0 -c -o sim_fio.o sim_fio.c -I. -DVM_VAX -DVAX_780 -DUSE_INT64 -DUSE_ADDR6
4 -I VAX -I PDP11
gcc -O0 -c -o sim_timer.o sim_timer.c -I. -DVM_VAX -DVAX_780 -DUSE_INT64 -DUSE_A
DDR64 -I VAX -I PDP11
gcc -O0 -c -o sim_sock.o sim_sock.c -I. -DVM_VAX -DVAX_780 -DUSE_INT64 -DUSE_ADD
R64 -I VAX -I PDP11
gcc -O0 -c -o sim_tmxr.o sim_tmxr.c -I. -DVM_VAX -DVAX_780 -DUSE_INT64 -DUSE_ADD
R64 -I VAX -I PDP11
gcc -O0 -c -o sim_ether.o sim_ether.c -I. -DVM_VAX -DVAX_780 -DUSE_INT64 -DUSE_A
DDR64 -I VAX -I PDP11
gcc -O0 -c -o sim_tape.o sim_tape.c -I. -DVM_VAX -DVAX_780 -DUSE_INT64 -DUSE_ADD
R64 -I VAX -I PDP11
gcc -O0 -c -o VAX/vax_cpu2.o VAX/vax_cpu2.c -I. -DVM_VAX -DVAX_780 -DUSE_INT64 –
DUSE_ADDR64 -I VAX -I PDP11
gcc -O1 -c -o VAX/vax_cpu2.o VAX/vax_cpu2.c -I. -DVM_VAX -DVAX_780 -DUSE_INT64
-DUSE_ADDR64 -I VAX -I PDP11
gcc -o vax780 VAX/vax_cpu.o VAX/vax_cpu1.o VAX/vax_fpa.o VAX/vax_cis.o VAX/vax_
octa.o VAX/vax_cmode.o VAX/vax_mmu.o VAX/vax_sys.o VAX/vax_syscm.o VAX/vax780_st
ddev.o VAX/vax780_sbi.o VAX/vax780_mem.o VAX/vax780_uba.o VAX/vax780_mba.o VAX/v
ax780_fload.o VAX/vax780_syslist.o PDP11/pdp11_rl.o PDP11/pdp11_rq.o PDP11/pdp11
_ts.o PDP11/pdp11_dz.o PDP11/pdp11_lp.o PDP11/pdp11_tq.o PDP11/pdp11_xu.o PDP11/
pdp11_ry.o PDP11/pdp11_cr.o PDP11/pdp11_rp.o PDP11/pdp11_tu.o PDP11/pdp11_hk.o P
DP11/pdp11_io_lib.o scp.o sim_console.o sim_fio.o sim_timer.o sim_sock.o sim_tmx
r.o sim_ether.o sim_tape.o VAX/vax_cpu2.o -I. -DVM_VAX -DVAX_780 -DUSE_INT64 -DU
SE_ADDR64 -I VAX -I PDP11 -lwinmm -lwsock32

Administrator@JASON-4AC1B1EA0 /usr/src/simh
$ cd test/

Administrator@JASON-4AC1B1EA0 /usr/src/simh/test
$ ../vax780.exe bsd42.ini

VAX780 simulator V3.8-1
loading ra(0,0)boot
Boot
: ra(0,0)vmunix
199488+56036+51360 start 0x11a0
4.2 BSD UNIX #9: Wed Nov 2 16:00:29 PST 1983
real mem = 8384512
avail mem = 7073792
using 102 buffers containing 835584 bytes of memory
mcr0 at tr1
mcr1 at tr2
uba0 at tr3
hk0 at uba0 csr 177440 vec 210, ipl 15
rk0 at hk0 slave 0
rk1 at hk0 slave 1
uda0 at uba0 csr 172150 vec 774, ipl 15
ra0 at uda0 slave 0
ra1 at uda0 slave 1
zs0 at uba0 csr 172520 vec 224, ipl 15
ts0 at zs0 slave 0
dz0 at uba0 csr 160100 vec 300, ipl 15
dz1 at uba0 csr 160110 vec 310, ipl 15
dz2 at uba0 csr 160120 vec 320, ipl 15
dz3 at uba0 csr 160130 vec 330, ipl 15
root on ra0
WARNING: should run interleaved swap with >= 2Mb
Automatic reboot in progress…
Tue Nov 8 03:44:30 PST 1983
Can’t open checklist file: /etc/fstab
Automatic reboot failed… help!
erase ^?, kill ^U, intr ^C
# ./d2;./d2;./d2
Dhrystone(1.1) time for 500000 passes = 19
This machine benchmarks at 26315 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 19
This machine benchmarks at 26315 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 18
This machine benchmarks at 27777 dhrystones/second
# sync
# sync
# sync
#
Simulation stopped, PC: 80001629 (BNEQ 80001630)
sim> q
Goodbye

Administrator@JASON-4AC1B1EA0 /usr/src/simh/test
$

The d0,d1,d2 are the dhyrstone benchmark compiled with -O0, -O1, and -O2 respectively. This gives you a chance to observe various optimizations in the GCC 2.7.2.2 for the VAX.

gcc on the x86_64

Today I thought I’d isolate the portion of simh that crashes 4.X BSD, when SIMH is built with GCC. I managed to find that the “op_ldpctx” and “op_mtpr” procedures of vax_cpu1.c become unstable when built with -O2 flags.

So I extracted the two procedures so I could then built the remainder of SIMH with GCC’s O2 flags. Before going too far, I first went to verify that the results would be consistent with the i386/32bit binaries…

However the results were.. interesting. By default SIMH will build with -O0 flags for the VAX giving the following dhrystone benchmark in 4.3 UWisc BSD:

Dhrystone(1.1) time for 500000 passes = 24
This machine benchmarks at 20833 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 24
This machine benchmarks at 20833 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 24
This machine benchmarks at 20833 dhrystones/second

24 seconds, not so hot. Then the same thing with -O1 flags…

Dhrystone(1.1) time for 500000 passes = 18
This machine benchmarks at 27777 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 18
This machine benchmarks at 27777 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 18
This machine benchmarks at 27777 dhrystones/second

18 seconds! pretty good, thats a 33% increase! Now for my hybrid -O2/-O1

Dhrystone(1.1) time for 500000 passes = 17
This machine benchmarks at 29411 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 17
This machine benchmarks at 29411 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 17
This machine benchmarks at 29411 dhrystones/second

A 5% increase over the -O1 … Nothing too big, but still an INCREASE.

Now for the real fun, I re-ran these bulid factors with the x86_64 compiler.

The -O0/-O0 combination came in at 19 seconds!!

Dhrystone(1.1) time for 500000 passes = 19
This machine benchmarks at 26315 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 19
This machine benchmarks at 26315 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 19
This machine benchmarks at 26315 dhrystones/second

This is pretty amazing considering everything we do should make it faster… The next thing I tried was the -O1/-O1 combination and go the following:

Dhrystone(1.1) time for 500000 passes = 12
This machine benchmarks at 41666 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 13
This machine benchmarks at 38461 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 13
This machine benchmarks at 38461 dhrystones/second

A 12.5 second average! This blew the doors off of the -O2/-O1 on the i386! Naturally I was hoping for at least a 5% increase going to the -O2/-O1 flags on the x86_64, however I got this…

Dhrystone(1.1) time for 500000 passes = 14
This machine benchmarks at 35714 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 13
This machine benchmarks at 38461 dhrystones/second
Dhrystone(1.1) time for 500000 passes = 12
This machine benchmarks at 41666 dhrystones/second

And I ran it numerous times, but the bottom line is that the O2 flags actually produces a SLOWER SIMH on OS X 10.6.4 then -O1 flags… The whole exercise is a tad perplexing to me, to say the least, but unless you bench it, you’ll never know if the compiler is getting confused somewhere, and going to throw a loop. I should also point out that SIMH will not run with full -O2 flags as there is something in the code that breaks under optimization so this very well may not hold true 100% of the time, but at the same point things still have to be tested…