NationalSecurityAgency / ghidra

Ghidra is a software reverse engineering (SRE) framework
https://www.nsa.gov/ghidra
Apache License 2.0
50.12k stars 5.74k forks source link

SH4: Missing two special instructions - 'fsrra' and 'fsca' #1730

Open ghost opened 4 years ago

ghost commented 4 years ago

Describe the bug A not well-known fact about the Super-H4 processor series is that they actually do have "fsca" and "fsrra" instructions that are normally listed as SH4A exclusive. Ghidra does not know this, and when working through SH4 programs that use these instructions, Ghidra is unable to make sense of the machine code for these. (Full disclosure: I only tested explicitly with fsrra, but neither of the instructions appear in the SuperH4.sinc file, so I assume it's true for both of them.)

To Reproduce Steps to reproduce the behavior:

  1. Decompile any program that uses one instruction or the other.

Expected behavior It works.

Screenshots N/A

Attachments Compile this function I've made for fsrra with GCC (I use GCC 9):

// 1/sqrt(x)
static inline __attribute__((always_inline)) float MATH_fsrra(float x)
{
  asm volatile ("fsrra %[one_div_sqrt]\n"

  : [one_div_sqrt] "+f" (x) // outputs, "+" means r/w
  : // no inputs
  : // no clobbers
  );

  return x;
}

And this one for fsca:

// For int input, input_int is in native fsca units (fastest)
static inline __attribute__((always_inline)) _Complex float MATH_fsca_Int(unsigned int input_int)
{
  _Complex float output;

  asm volatile ("lds %[input_number], FPUL\n\t" // load int from register (1 cycle)
    "fsca FPUL, %[out]\n" // 3 cycle simultaneous sine/cosine
    : [out] "=d" (output) // outputs
    : [input_number] "r" (input_int)  // inputs
    : "fpul" // clobbers
  );

  return output;
}

Environment

Additional context Details here: https://gcc.gnu.org/legacy-ml/gcc-patches/2005-03/msg01176.html Fun fact: the specific customer being referred to here is Sega, for the SH7091 variant of SH7750 used in the Dreamcast game console in the late '90s. However, all SH4 processors in the SH7750/SH7760 series have them despite their officially "untested" status.

The two instructions are described in the single-precision floating point section here: http://www.shared-ptr.com/sh_insns.html

jketting commented 4 years ago

It misses the movua.l instruction as well (SH4A specific). For example: Byte code 4E E9 should be recognized as: movua.l @r14+, r0

pjsoberoi commented 2 years ago

Add this to the end of your SuperH4.sinc:

# Calculate the sine and cosine approximations of FPUL
# pattern   1111nnn011111101
# text      fsca    FPUL, <F_REG_N>
:fsca FPUL,FRN_0            is OP_0=0xf & FRN_0 & OP_5=0xfd & FPUL 
unimpl

# Calculate approximate inverse of the arithmetic square root
# pattern   1111nnnn01111101
# text      fsrra   <F_REG_N>
:fsrra FRN_0                is OP_0=0xf & FRN_0 & OP_4=0x7d
unimpl

I have no clue how to implement it in p-code but this should at least get you to disassemble.