4 ms·
This is the second emulator I'm seen in rust, the other being an ARM emulator done as a personal project by somebody who was an intern here. I do emulators, but
by souprock 8y ago
This is the second emulator I'm seen in rust, the other being an ARM emulator done as a personal project by somebody who was an intern here. I do emulators, but in C. (BTW, hiring)
For an expert performance-sensitive C programmer who pulls out all the platform-specific tricks to make stuff go fast, how do you think rust would be? The default safety is appealing, but I have lots of concerns.
Bitfield access looks painful. In C, I can set things up to make read/write named access to bitfields easy. Granted, the header to set this up is complicated: make an union of anonymous structs, each with a bitfield and the needed padding. With that though, I can use bitfields just like ordinary struct members. I can pluck fields out of opcodes for emulation, or I can fill them in for a JIT.
Sometimes in C, one might use gcc's computed goto extension. (getting a void pointer from a unary && operator applied to a label, then derefing it at the goto) It doesn't seem like rust has this, even in unsafe code. Actually, there isn't even a "goto" keyword... which I find to be a worrisome sign that might indicate stubbornly academic language design.
The bounds checking on arrays is kind of the whole point of rust, but if that can't get out of the way for speed then I'd have to make everything unsafe. If I do that, then rust is pointless. Has anybody checked the assembly to see if the compiler is good at eliminating the checks? For example, if I use a 5-bit bitfield to index into a 32-entry table, do the checks get optimized out?
What if I want aliasing? With gcc I can mark things __may_alias__, and with Visual Studio I don't even need that. I had a case where I needed to lay structs over each other like shingles, in groups of 4 with internal padding, so that the same struct member of each of the 4 structs would be adjacent in memory. This was needed so that vector intrinsics could be used.
Speaking of that, are there vector intrinsics? What if I specifically want MMX opcodes in one place (for MMX emulation) and SSE opcodes in another place?
Can I get a switch without a default, such that the compiler doesn't try to generate code for a case that isn't listed? I know this will seem like a horrible idea to many programmers, but sometimes performance matters. When the language can't keep up, I have to drop down into assembly, and that sucks more.
- steveklabnik 8y agoRust does not have goto, but it’s not about being academic: a lot of Rust’s compile time checks are flow-based, and unstructured control flow would make them a lot more slow and complex. Bitfields have a package that makes them easy. If you want aliasing, there’s UnsafeCell. Yes, there are vector intrinsics, and they’re part of the language, not a non-standard extension. And there are tools to choose between things too. Switch requires a default, but you can declare the default unreachable. You should always be able to get the same asm.
- sanxiyn 8y agoRust has no strict aliasing, so all Rust types are may_alias.
- souprock 8y agoI thought it was the other way, all being effectively restrict, with the hazard removed by the borrow checker. In any case, I want to be able to have both behaviors.