Convert Hex Integer to 32 bit Float (ASM) Vega bl the_admin Posts: 3,402 Threads: 857 Joined: Feb 2018 Reputation: 82 08-22-2019, 09:35 PM (This post was last modified: 08-22-2019, 09:41 PM by Vega.) Here's a little snippet of PPC ASM I made that will convert your Hex integer to a IEEE-754 32 bit standard Float The integer can only be a byte or halfword, and it must NOT be negative. Implementing negatives (neg. halfs and bytes) shouldn't be that difficult. However, adding the ability to do words too, may be a bit of a pain. This is written to be as a subroutine (via a function call), you will need to add LR storage plus stack pushing and popping. Args: r3 = Integer to convert Return Value: r3 = the Float, or -1 for error Raw ASM: 5464001F 40A20030 38A0001F 38C0007F 7C640034 7CE42850 7D263A14 5529B810 20870017 7C632030 5463027E 7D231B78 48000008 3860FFFF 4E800020 Source: #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# # Check For Negative Value, and Check if Halfword/Byte wasn't Used # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# clrrwi. r4, r3, 16 bne+ skip_conversion #Not doing words or negative values #~~~~~~~~~~~~~~~~~~~~~~~~~~~~# # Set Static Register Values # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~# li r5, 31 #Used for formula to calculate amount to add to the Bias li r6, 127 #This is the IEEE 754 Bias Standard #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# # Start Conversion, Count Leading Zeros, Give Variable of Bias Equation # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# cntlzw r4, r3 #Count the leading zeros til first 1 subf r7, r4, r5 #This will give us the amount to add to the Bias #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# # Calculate Final Bias, Store Bias to Bits 1 thru 8 # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# add r9, r6, r7 #Add to bias slwi r9, r9, 23 #Shift the Bias over to bits 1 thru 8, bit 0 is reserved #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# # Calculate where to Store Fraction Bits at Beginning of Mantissa # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# subfic r4, r7, 23 #This will give amount of left-hand shift to place fraction bits at beginning of mantissa slw r3, r3, r4 #Execute the shift clrlwi r3, r3, 9 #Get rid of possible '1' bit that is left in bit 8's spot #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# # Final Step, Insert the Mantissa Bits # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# or r3, r9, r3 #Place Mantissa bits with all other bits now. Use logical OR to not erase all of our progress b the_end skip_conversion: li r3, -1 the_end: blr JoshuaMK Super Moderator Posts: 1,006 Threads: 95 Joined: Jun 2019 Reputation: 36 08-22-2019, 09:39 PM This is cool Super Mario Eclipse, what Super Mario Sunshine could've been. Vega bl the_admin Posts: 3,402 Threads: 857 Joined: Feb 2018 Reputation: 82 08-22-2019, 09:47 PM (This post was last modified: 08-22-2019, 09:48 PM by Vega.) If you want a crack at this to put in negative values, you need to subtract FROM the bias (instead of adding to it). Then you need implement adding in the sign bit (bit 0 being the value 1) to the final result. This may cause some shifting issues that will need to be adjusted. salmon01 Coder / Dev Posts: 14 Threads: 1 Joined: Aug 2019 Reputation: 2 08-22-2019, 11:26 PM (This post was last modified: 08-23-2019, 12:53 AM by salmon01. Edit Reason: Shortened code. ) The PowerPC Compiler Writer's Guide contains a number of helpful algorithms, including a conversion for 32-bit signed integer to float, so any integer between 0x80000000 and 0x7FFFFFFF is supported. I modified that code to work by itself and then turned it into a proper function: Code:```s32_to_float: lis r4, 0x4330 stw r4, -0x8 (r1) lis r4, 0x8000 stw r4, -0x4 (r1) lfd f2, -0x8 (r1) # load magic double into f2 xoris r3, r3, 0x8000 # flip sign bit stw r3, -0x4 (r1) # store lower half (upper half already stored) lfd f1, -0x8 (r1) fsub f1, f1, f2 # complete conversion blr``` The parameter for this function (passed via r3) would be the integer you wish to convert, and the return value (placed in f1) would be the converted float. Also note that I used the red zone (area beneath the stack) to store/load values temporarily, this is safe to do in this case as no function calls exist between the store and load operations. To be fair, your code is definitely more clever than mine, as you actually bothered to learn how floats work instead of just copying code from the web. However, since this one works for negative values and words, I thought it would be useful too. Vega bl the_admin Posts: 3,402 Threads: 857 Joined: Feb 2018 Reputation: 82 08-23-2019, 01:38 AM Nice! That compilers guide is amazing. Thank you for the link. I'll add it to the ASM Links/References thread in the Resources sub forum. salmon01 Coder / Dev Posts: 14 Threads: 1 Joined: Aug 2019 Reputation: 2 08-23-2019, 03:10 AM (This post was last modified: 08-23-2019, 03:14 AM by salmon01.) (08-23-2019, 01:38 AM)Vega Wrote: Nice! That compilers guide is amazing. Thank you for the link. I'll add it to the ASM Links/References thread in the Resources sub forum.I agree. Also, it is likely that Mario Kart Wii uses functions similar to the ones from that guide, so perhaps using Ghidra you could find the actual addresses of those functions in memory. « Next Oldest | Next Newest »

Forum Jump:

Users browsing this thread: 1 Guest(s)