-3
int function (float X, float Y, float Z, int result) 
{
    result = (X*Y)+ Z;
    
    
}

I tried using https://godbolt.org/ but it doesnt support rv64i

fuz
  • 88,405
  • 25
  • 200
  • 352
  • This isn't valid C, so compiling it isn't very useful. When you have some correct code, the best way to compile it is with a compiler. Get an appropriate version of gcc and run it with the -S option. – Gene Nov 19 '22 at 17:58
  • You can split this into sub-problems like "how can I multiply two float numbers in RISC-V?", "how can I add two numbers in RISC-V?", and research those instead. – Sedat Kapanoglu Nov 19 '22 at 18:08
  • 1
    @Gene It isn't valid C? It's undefined behavior but it seems valid C to me. – Margaret Bloom Nov 19 '22 at 18:16
  • 3
    Looks like legal C, though rather meaningless: not returning a value for a non-void function, and assigning a value to a parameter that is never used and not usable after the function exits. – Erik Eidt Nov 19 '22 at 18:47
  • This is angels dancing on pinheads. It's syntactically correct. I call UB invalid. @MargaretBloom – Gene Nov 20 '22 at 00:31
  • 1
    @Gene: It's not UB in C, only C++. In C, UB only happens if the caller tries to use the return value. (Historically, C didn't have `void`, but C++ had it from the start without historical codebases that did this.) – Peter Cordes Nov 20 '22 at 00:45
  • GCC/clang for RISC-V let you specify what RV extensions you want to target. https://godbolt.org/z/5YWT7jK5W shows `-O3 -Wall -march=rv64i -mabi=lp64`. The FP operations compile to calls to libgcc helper functions, to multiply, add, and convert the result to integer. (See also [RISCV branchless coding](https://stackoverflow.com/q/72340698) for an example of enabling extension B 0.93) – Peter Cordes Nov 20 '22 at 01:05
  • Okay. I bow to language law. But you're letting the trees obscure the forest. The OP is asking how to see compiled code. When the compiled code they are looking for is meaningless - i.e. could be absolutely anything the compiler chooses to produce - then I call the program invalid for the OP's purposes. As I said, angels dancing on pinheads. @PeterCordes – Gene Nov 22 '22 at 00:43
  • @Gene: Yeah, nobody is saying this code is useful to compile except maybe in debug mode. Just that it's not UB in what they've shown. It's occasionally an important distinction, e.g. a C++ compiler can and would emit zero instructions for this, not even a `ret`, since it's impossible for this function to ever be called in a UB-free program. But the symbol has to exist. A C compiler, on the other hand, would have to emit at least a `ret` instruction (and nothing else with optimization enabled, since there are no observable side-effects), since a UB-free program could call this function. – Peter Cordes Nov 22 '22 at 05:06
  • @Gene: https://godbolt.org/z/rTd7j4rdn shows `gcc -O3` (in C mode) vs. `gcc -xc++ -O3` for this broken function, showing the difference in code-gen as I described. In C++, the compiler could have produced absolutely anything, including an illegal instruction, rather than zero instruction with fall-through tailcall into whatever machine code happened to be next, emitted from the same compilation unit or not. But not in C, there it has to return cleanly, in case it's called by a caller that doesn't use the return value. – Peter Cordes Nov 22 '22 at 05:11
  • godbolt.org does have MIPS, you could use that to get an idea of what the assembly code might look like (it's not exactly the same but it's very close.) – puppydrum64 Nov 23 '22 at 18:10

1 Answers1

1

Your code is broken, but just assume that it was written as:

float function (float X, float Y, float Z) 
{
   return (X*Y) + Z;    
}

Also, assume that you have a floating point unit, i.e. that you are using a rv64if or rv64id device. Then the following assembly code would do the job:

function:
    fmul.s ft0, fa0, fa1
    fadd.s fa0, ft0, fa2
    ret

Unfortunately, the device you are using rv64i doesn't have a floating-point unit. A normal C compiler would provide a number of subroutines to perform various floating-point operations, the best way to check what they are named is to compile the program.

If you plan to write the subroutines yourself you are in for a mammoth task, as it probably take an experienced assembly programmer weeks if not months to do that.

Lindydancer
  • 25,428
  • 4
  • 49
  • 68
  • https://godbolt.org/z/5YWT7jK5W shows gcc and clang `-O3 -Wall -march=rv64i -mabi=lp64`. The FP operations compile to calls to libgcc helper functions, to multiply `(__mulsf3`), add (`__addsf3`), and convert the result to 32-bit integer with truncation toward zero (`__fixsfsi`). Agreed that `float` is probably a bad idea on rv64i (without F or D extensions). There are probably some non-GPLed soft-FP functions you could copy, though, if you need your own and can't call libgcc. – Peter Cordes Nov 20 '22 at 01:11
  • Writing your own soft-FP functions and thoroughly testing them for NaN, negative-zero, infinities, subnormals, and normals with huge/tiny exponents would take some time even if you already understand IEEE 754 floating point and RV64 assembly. Yeah, probably at least a week including test suites. It seems RV64i doesn't have a multiply instruction, so that's a pain for an efficient implementation of multiply, would have to shift / and / conditional-add. And it doesn't have bit-scan (leading zero count) to help renormalize after subtracting, or adding numbers of different signs. – Peter Cordes Nov 20 '22 at 01:14