flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
Roman 23 Dec 2014, 10:26
I have 16 bit data.
For example: 0xC100,0x3C00 How convert 0xC100 to 32 bit float and 0x3C00 convert to 32 bit float ? |
|||
![]() |
|
revolution 23 Dec 2014, 10:36
Use FILD:
Code: my_data dw 0xC100,0x3C00 fild [my_data+0] fild [my_data+2] ;st0=15360.0, st1=-16128.0 |
|||
![]() |
|
Roman 23 Dec 2014, 11:37
how about SSE ?
|
|||
![]() |
|
Roman 23 Dec 2014, 15:05
Thanks tthsqe !
In 3d max i get 7.086182 float value from 16 bit int 0x2C89 * 0x64. But fild word 0x2C89 get me another float value ?! |
|||
![]() |
|
r22 23 Dec 2014, 16:15
@Roman you have to give more details when you ask for help.
I think you are talking about the 16bit half precision floating point values not integers. Just because you are representing the value in binary format 0xABCD doesn't make it an integer. http://en.wikipedia.org/wiki/Half-precision_floating-point_format If this is the case then you would need the CVTPH2PS opcode. PH = packed half precision and PS = packed signle precision |
|||
![]() |
|
Roman 23 Dec 2014, 17:00
You right r22.
Sorry. |
|||
![]() |
|
Roman 23 Dec 2014, 18:39
Code: ; input: 4x F16 in XMM0 (low words of each DWord) ; original idea+implementation by Dean Macri ; WARNING: copy & pasted together from other code, this ver is untested!! ; though the original version was definitely correct. bits 32 section .data FP32_no_sign times 4 dd 0x7FFFFFFF FP32_sign_bit times 4 dd 0x80000000 FP16_FP32_sgn_adj times 4 dd 0x70000000 FP16_FP32_sgn_adj2 times 4 dd 0x8FFFFFFF FP16_FP32_denorm times 4 dd 0x38000000 FP16_FP32_denorm_adj times 4 dd 0x00800000 FP16_FP32_exp_adj times 4 dd 0x38000000 FP16_exp_shifted times 4 dd 0x0F800000 FP16_exp_adjust_for_NaN times 4 dd 0x7F800000 FP16_exp_adjust_for_Zero times 4 dd 0x7F800000 FP16_FP32_exp_adj_for_Zero dd 0x38000000, 0x38000000, 0x38000000, 0x38000000 dd 0xB8000000, 0x38000000, 0x38000000, 0x38000000 dd 0x38000000, 0xB8000000, 0x38000000, 0x38000000 dd 0xB8000000, 0xB8000000, 0x38000000, 0x38000000 dd 0x38000000, 0x38000000, 0xB8000000, 0x38000000 dd 0xB8000000, 0x38000000, 0xB8000000, 0x38000000 dd 0x38000000, 0xB8000000, 0xB8000000, 0x38000000 dd 0xB8000000, 0xB8000000, 0xB8000000, 0x38000000 dd 0x38000000, 0x38000000, 0x38000000, 0xB8000000 dd 0xB8000000, 0x38000000, 0x38000000, 0xB8000000 dd 0x38000000, 0xB8000000, 0x38000000, 0xB8000000 dd 0xB8000000, 0xB8000000, 0x38000000, 0xB8000000 dd 0x38000000, 0x38000000, 0xB8000000, 0xB8000000 dd 0xB8000000, 0x38000000, 0xB8000000, 0xB8000000 dd 0x38000000, 0xB8000000, 0xB8000000, 0xB8000000 dd 0xB8000000, 0xB8000000, 0xB8000000, 0xB8000000 section .text f16tof32: ; Shift the mantissa to the correct place (bit 23 in F32 from bit 10 in F16) pslld xmm0, 13 ; Get the sign bit set appropriately paddd xmm0, [FP16_FP32_sgn_adj] pand xmm0, [FP16_FP32_sgn_adj2] ; Save copy, adjust exponent movdqa xmm1, xmm0 paddd xmm0, [FP16_FP32_exp_adj] ; Check for NaNs, inf pand xmm1, [FP16_exp_shifted] pcmpeqd xmm1, [FP16_exp_shifted] pand xmm1, [FP16_exp_adjust_for_NaN] por xmm0, xmm1 lea edx, [FP16_FP32_exp_adj_for_Zero] ; Check for zeros/denorms. This is a pain. We need to ; figure out which FP16 values had a zero value for the biased ; exponent. THEN, we have to subtract away the new exponent, ; so that if we had a denorm orginally, we'll get rid of the ; implicit one we created in the FP32 format. ; movmskps eax, xmm0 movdqa xmm1, xmm0 shl eax, 4 pand xmm1, [FP16_exp_adjust_for_Zero] pcmpeqd xmm1, [FP16_FP32_exp_adj] pand xmm1, [edx + eax] ; Subtract off the implicit 1 if we had a denorm, make the value ; zero if it should be zero. Unfortunately, negative zero become positive ; so we have to put the sign back. ; subps xmm0, xmm1 ; Find the values < 2^(-15) (Denorms) movaps xmm2, [FP32_no_sign] andps xmm2, xmm0 cmpleps xmm2, [FP16_FP32_denorm] andps xmm2, [FP16_FP32_denorm_adj] paddd xmm0, xmm2 ; Get the zeros back movdqa xmm2, xmm0 pcmpeqd xmm0, [FP16_FP32_denorm_adj] andnps xmm0, xmm2 ; Put the sign bits back pand xmm1, [FP32_sign_bit] por xmm0, xmm1 ; All done! ret |
|||
![]() |
|
Roman 23 Dec 2014, 19:31
Work good but sometimes wrong sign
![]() Sometimes right sign. |
|||
![]() |
|
Roman 23 Dec 2014, 20:21
How work VCVTPH2PS ?
And how version fasm support VCVTPH2PS ? |
|||
![]() |
|
Roman 23 Dec 2014, 21:02
c++ how convert half to float
https://github.com/codingdude/vetools/blob/master/half.h |
|||
![]() |
|
r22 24 Dec 2014, 00:34
All the CVT opcodes should work the same, I don't know which processor version introduced it though I think only the most recent CPUs would have it.
Code: value dd 0x2c89 movd xmm0, [value] ;; xmm0 = ?, ?, ?, 0x00002c89 cvtph2ps xmm0, xmm0 ;; xmm0 = ?, ?, ?, answer |
|||
![]() |
|
Mikl___ 08 Jan 2015, 09:16
|
|||
![]() |
|
revolution 08 Jan 2015, 10:19
So I guess if your FPU is faulty you can use the all integer code to prepare a float value. fasm does this also for float values.
|
|||
![]() |
|
Mikl___ 08 Jan 2015, 13:11
Hi, revolution!
I thought it would be interesting for all translations integer to real, you offered fild/fstp, tthsqe suggested used SSE2, I suggested using integer instructions. Possible that this will be faster than the first two methods |
|||
![]() |
|
revolution 08 Jan 2015, 13:38
Mikl___: Yes, it is interesting to see such code. Some might find it instructive to see how floats are constructed.
As for the execution speed, well that is probably system dependant, but I feel that in almost all cases using the native FPU would give more performance. But performance would not be the only reason someone might use such code. I already gave the example of fasm using the integer core to construct floats. The FPU can only operate on certain fixed sized values and precision loss might be a factor for some cases. |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.