beardypig/ghidra-emotionengine

float to integer conversion

Closed this issue · 7 comments

This happens everywhere the cvt.w.S instruction is followed by the mfc1 instruction. I'm not sure, but shouldn't this be decompiled to just iVar25 = fVar38?

image

cvt.w.s fd, fs
Convert fs from float to integer and store result inside of fd
mfc1 rt, fs
Copy contents of floating point register fs to general purpose register gp

So its basically just casting the float as an int.
int ivar = (int)fvar;
You can't just make it equal to each other because you'll get a type error.

Thanks for the response. I made an error in my post, I should have typed iVar25 = (int)fVar38 instead of iVar25 = fVar38. I just wonder why it must complicate the decompilation view with what you see on the right of my screenshot when it could maybe just be iVar25 = (int)fVar38. I'm attempting to reverse some physics code and some of the larger functions are littered with these.

For anyone else: I fixed it by changing this code and rebuilding and reinstalling the extension:
https://github.com/beardypig/ghidra-emotionengine/blob/master/data/languages/cop1.sinc#L117-L131
to just this:

# 0100 0110 0000 0000 ssss sddd dd10 0100
:cvt.w.S fd, fs             		is ft=0 & fct=36 & fd & fs & format=0x10 {
    fd = trunc(fs);
}

It's probably technically incorrect in that it might not mirror exactly what the PS2 does, but it's good enough for my purposes now that I can read the decompilation more easily.

The ps2 cop1 does truncate floats when converting to integer.

I'm not gonna post it here but if you search "EE Core Instruction Set Manual" on google with the quotes, you'll find the docs as the first result. And checking the docs says that it rounds to 0 so trunc would be correct. I think we should add this as a PR since it makes the code look cleaner.

Thanks for the input and the reference manual! I've submitted a PR.

Just for reference, there are other manuals for the ps2. I can't post but its better to know they do exist.
image