ghidra icon indicating copy to clipboard operation
ghidra copied to clipboard

Simplifying bitwise operations on floats

Open yotann opened this issue 5 years ago • 0 comments

Some common floating-point operations can be optimized to bitwise operations. Ghidra should recognize these patterns and simplify them back into floating-point operations. For example:

#include <math.h>
float negate(float x) { return -x; }
float absolute(float x) { return fabs(x); }
float conditional(float x, float y, float z, float w) { return (x < y) ? z : w; }

Compiled with Clang, I get:

negate:
XORPS xmm0, 0x80000000

absolute:
ANDPS xmm0, 0x7fffffff

conditional:
CMPLTSS xmm0, xmm1
ANDPS xmm2, xmm0
ANDNPS xmm3, xmm0
ORPS xmm0, xmm2

Which Ghidra decompiles to:

float negate(float auParm1) { return (float)((uint)auParm1 ^ 0x80000000); }
float absolute(float auParm1) { return (float)((uint)auParm1 & 0x7fffffff); }
float conditional(float auParm1,float fParm2,float auParm3,float auParm4) {
  return (float)(~-(uint)(auParm1 < fParm2) & (uint)auParm4 |
                (uint)auParm3 & -(uint)(auParm1 < fParm2));
}

yotann avatar Apr 25 '19 23:04 yotann