2002.06.09 ~14 Q3LCC-PH v1 http://www.icculus.org/~phaethon/q3a/q3lcc-ph/q3lcc-ph.html My next major hack is showing progress. Since the sources to q3lcc (modifed lcc for Q3 mods), I started my endeavor to modify the stock lcc to see if I could make it Q3VM-compatible. A few weeks ago I had modified lcc sufficiently to accomodate the widths of data types. However, that wasn't enough -- Q3 consistently crashed on the resulting qvm files. Some groveling through the assembly files (*.asm) showed an opcode/directive not found in stock lcc: "pop". Comments in q3asm indicate this is an opcode to discard the return value of function calls. One pattern was that all CALLV (call to function of void type) were followed by a "pop". I took this to mean that even void functions returned a value (despite the meaning of "void"). What I also noticed where the some CALLI (call to function of unsigned integer type) were followed by "pop", but most weren't. Some pattern checking showed that the return values of CALLI were discarded if the return value wasn't used for another operation immediately (such as for assignement, comparison, or arithmetic). This pattern also held for the other CALL* variants. Groveling through lcc-4.1/src/bytecode.c led to a pretty evil hack tha brute-forcefully checks if the return value of a CALL* is used. CALLV did not need to be special-cased, as the return value of CALLV is never used. I don't think qvm worked yet at this point. When I got this far, I sort of back-burnered further modding. A few hours ago, zinx on irc.openprojects.net piped up regarding sources to q3lcc. Apparently my patches to q3asm have been making the rounds, as I've been called upon by name regarding lcc. Apparently zinx was determined to patch stock lcc to be qvm-compatible, and so I started sharing what changes I had so far. To figure out what I had to change, I had to read through the lcc sources again. Freshened up on the lcc source again, I decided I might as well continue with my own quest. The big stickler was CNSTF4, opcode for loading a floating-point constant. The canonical q3lcc outputs an actual CNSTF4 opcode, but my patched lcc turns this into "ADDRGP4 floataddress; INDIRF4", i.e. loading the float value from the data segment via indirection rather than placing the float value inline. In my search, I found where float is parsed, in lex.c. What I thought was happening was that when lcc reads in a literal floating- point constant, it would type it as a double, then attempt to spit out code for loading a 64b double indirectly, but that the data-width mods changed the INDIRF8 to INDIRF4. Though I eliminated setting type as double (to float-only) in lex.c, CNSTF4 was still coming out as "ADDRGP4; INDIRF4". I decided to try compiling qvm with the changes anyway, and surprisingly, Q3 didn't crash. I even went to the extent of eliminate any traces of the original linuxq3a-sdk I had. Still no crash. "It compiles, ship it". I'll bang on it some more later. In the meantime, zinx is busy tracking down the CNSTF4 thingy.