Mips2cs is a tool that converts MIPS machine code into an equivalent C# program.
Some people suggested that I should port Knights to the Xbox 360. In theory, this would be a simple matter of converting the game to use XNA, and then publishing the result on Xbox Live Indie Games. In practice, there is a problem: XNA games must be written in C#, but Knights is written in C++. This naturally leads us to the question: is there an easy (preferably automatic) way to convert a C++ program into a C# program?
Mips2cs was my answer to that question.
The main idea is that we use GCC (built as a cross-compiler) to compile our C++ program into MIPS machine code. We then use Mips2cs to convert the MIPS code into an equivalent C# program. Finally, we use Visual Studio (or another C# compiler) to convert the C# program into an executable.
The end result is a C# program that behaves identically to the original C++ program, but runs on the .NET platform instead of as native code.
One certainly could write a tool to parse C++ code and convert it to C#. However, the complexity of the C++ language, and the differences in semantics between it and C#, make this somewhat difficult. Therefore, while there are some existing tools that can do it (e.g. this one), none of them are fully automatic; the user is required to edit the generated C# files by hand afterwards. Clearly this is unsatisfactory, especially if one wishes to maintain parallel C++ and C# versions of the same project.
Machine code, by contrast, is much lower level than C++, and therefore much more suited to automatic processing. Indeed, translating machine code into C# is straightforward (if one is happy with a "literal" translation) and can be done completely automatically.
One way to look at this is to say that we are re-using an existing compiler to do the hard work of parsing the C++ and converting it to a lower level representation; and then writing a relatively simple tool to convert that low level representation to C#.
Unfortunately, yes. Although the generated C# files have the same behaviour as the original program, they are virtually unreadable to humans. They read like disassembly listings.
Whether this is a problem or not depends on one's intentions. If one wishes to do a "one time" translation of a C++ project to C#, with all future development being done in C#, Mips2cs would not be suitable. However, if one simply wishes to make a .NET executable from a C++ codebase, while retaining C++ as the primary development language, then there is no problem; in this case, the C# files are just intermediate products in a build process, and one does not really need to read or edit them at all.
Since we are using GCC to compile our C++ code, we can pick any CPU architecture that GCC supports. We don't have to stick with x86. Choosing the MIPS architecture has several advantages:
In fact not. There are two other projects that came up with the idea before me. However, they are targetting Java rather than C#. Here are the links:
There is also Mips2Java which is an earlier version of NestedVM.
See also: "Related Work" at the bottom of this page.
It certainly is. Visual Studio offers two settings, /CLR:SAFE and /CLR:PURE, that do exactly that. However, there are some issues:
There is also a CLI backend for GCC. However, it appears this supports only C (and not C++) at this time. Also, it is not clear whether the generated binaries will run on Xbox 360.
Due to the above issues, I haven't looked any further into the "compiling C++ to bytecode" approach. I decided to use the Mips2cs approach instead.
It probably would be better. However, that would increase complexity: we would need to know details of CIL assembly language, CLR bytecode formats, etc. For now I have taken the simpler route and generated C# code as output. However, working directly with bytecode might be an interesting option in future.
Mips2cs cannot translate code that makes calls to the operating system. This means that things like file I/O, or calls to DirectX or OpenGL for example, will not work without modification.
Instead, Mips2cs provides a mechanism for the C++ program to call arbitrary C# code at runtime. Therefore, if you need to draw graphics (for example), you would write the required functionality in C#, and then arrange for your C# code to be called from the C++ program as required.
Mips2cs comes with two ready-made libraries which illustrate this process. These are:
Mips2cs performs a few optimization passes (such as constant folding and dead variable elimination) in order to improve the quality of the generated C# code. Also, of course, the .NET runtime is performing JIT optimizations of its own. So, the performance isn't as bad as one might think.
I haven't done much performance testing yet, but initial testing showed that the generated C# code is (very roughly) 50% slower than the native code, when doing integer operations.
Floating point operations will be a lot slower, because Mips2cs doesn't support the MIPS floating point instructions yet (so all floating point calculations are using software emulation).
As a demo I have written a very simple Arkanoid-like game.
The starting point was to write the game code in C++. This came to about 500 lines of code (not counting the code for the "graphical library" – see above – which provides the interface between the C++ code and XNA). A source code listing can be found here: bouncy_ball_game.cpp.
This was then compiled to MIPS machine code with GCC, and converted to C# source code using Mips2cs. If you are interested in seeing what the generated C# looks like, see: bouncy_ball_game.cs.
Finally the C# was compiled with Visual Studio / XNA to a Windows executable. It can be downloaded here: BouncyBallGame.exe. (Note you need the XNA Framework installed to be able to run this.)
The process worked perfectly well and the game plays without any problems on Windows. In theory a 360 version could be made as well (but the code would have to be modified to use an Xbox controller instead of a mouse).
Mips2cs is written in Haskell. The source code can be downloaded here: mips2cs.tar.gz.
The download includes instructions on how to build the required GCC cross compiler, as well as how to build and use Mips2cs.
If you are interested in the technical details of how Mips2cs works, then the following documents are available:
Originally Mips2cs was intended as a way to port Knights to Xbox 360. The project is now at a "proof of concept" stage, i.e., the basic concept of converting C++ code to C#, via MIPS machine code, has been proven to work. However there are still several tasks that would need to be completed before a 360 version of Knights could be produced:
There are also possibilities for further work on Mips2cs itself, as follows:
It has been pointed out to me that there are two existing projects that do similar things to Mips2cs: