flat assembler
Message board for the users of flat assembler.
Index
> Main > How implement signum for float value ?Goto page 1, 2 Next |
| Author |
|
|
macomics 12 Aug 2026, 15:07
Code: mov eax, 1f and eax, 80000000h jz .unsigned ; jump ; signed ; ... .unsigned: mov eax, -1f and eax, 80000000h jnz .signed ; jump ; unsigned ; ... .signed: |
|||
|
|
revolution 12 Aug 2026, 15:10
COMISS sets ZF, PF, and CF so a single comparison can use JA, JB, JZ and JP to detect all possible outcomes.
I don't recommend to use the raw binary value with integer compare, because NaN make it very complicated and worse than the internal hardware. |
|||
|
|
Roman 12 Aug 2026, 18:35
This ok.
Code: macro xmSign x1,r { local l2,ll xor r,r xorps xmm7,xmm7 comiss xmm#x1,xmm7 jz ll ja l2 mov r,-2 ;-2 l2: inc r ll: } |
|||
|
|
revolution 12 Aug 2026, 23:10
JP should be the first test in case of NaN, then test for JB/JA/JZ.
Code: comiss ... jp .unordered jz .equal ja .above jb .below ; can't reach here. |
|||
|
|
revolution 13 Aug 2026, 00:25
revolution wrote: I don't recommend to use the raw binary value with integer compare, because NaN make it very complicated and worse than the internal hardware. |
|||
|
|
revolution 13 Aug 2026, 04:05
To eliminate the branches:
Code: comiss xmm0, xmm1 jp .error setc dl setnz cl neg dl lea edx, [edx * 2 + ecx] ; dl = -1, 0, or +1 Code: format elf executable SYS32_exit_group = 252 xorpd xmm0, xmm0 irp v, -6.0f, 0.0f, +6.0f { x = dword v mov eax, x movd xmm1, eax comiss xmm0, xmm1 jp .error setc dl setnz cl neg dl lea edx, [edx * 2 + ecx] ; dl = -1, 0, or +1 if x and 0x7fffffff = 0 cmp dl, 0 jnz .error else if x shr 31 = 0 cmp dl, -1 jnz .error else cmp dl, 1 jnz .error end if } mov eax, SYS32_exit_group xor ebx, ebx int 0x80 .error: mov eax, SYS32_exit_group or ebx, -1 int 0x80 Code: $ fasm test.asm && ./test && echo passed flat assembler version 1.73.31 (16384 kilobytes memory) 2 passes, 200 bytes. passed |
|||
|
|
Roman 13 Aug 2026, 04:13
Code: xor edx,edx xor ecx,ecx comiss xmm0, xmm1 jp .error setc dl setnz cl neg dl lea edx, [edx * 2 + ecx] ; dl = -1, 0, or +1 |
|||
|
|
revolution 13 Aug 2026, 04:17
The leading xor's aren't sufficient unless the NEG DL is changed to NEG EDX.
It is probably easier to use a single MOVSX EDX, DL after DL is defined. |
|||
|
|
bitRAKE 13 Aug 2026, 06:35
signum function ...
Code: xor eax, eax comiss xmm0, xmm1 jp .unordered seta al sbb eax, 0 Code: movaps xmm2, xmm1 cmpltss xmm2, xmm0 ; -1 if b cmpltss xmm0, xmm1 ; -1 if a<b psubd xmm0, xmm2 movd eax, xmm0 ; -1 / 0 / +1, unordered -> 0 |
|||
|
|
revolution 13 Aug 2026, 06:52
bitRAKE wrote: signum function ... It can also be one instruction, and 3 bytes, shorter if a 32-bit value isn't needed. Code: comiss xmm0, xmm1 jp .unordered seta al sbb al, 0 Code: comiss xmm0, xmm1 jp .unordered seta al sbb al, 0 movsx eax,al |
|||
|
|
Roman 13 Aug 2026, 07:08
Thanks Revolution.
I took this for my intersection 3D point with 3D tetrahedron. Code: ;working good macro xmSign x1,r { xorps xmm7,xmm7 comiss xmm#x1,xmm7 seta r sbb r, 0 } |
|||
|
|
macgub 13 Aug 2026, 14:55
What about branchless negation float value?
I tried with this: Code: pcmpeqd xmm7,xmm7 pslld xmm7,31 xorps xmm6,xmm7 xm7 = temp register xm6 = register with float value But it sometimes produce NaN -0 value. |
|||
|
|
bitRAKE 14 Aug 2026, 08:18
macgub wrote: What about branchless negation float value? Code: pxor xmm0, xmm0 subss xmm0, xmm6 _________________ ¯\(°_o)/¯ AI may [not] have aided with the above reply. |
|||
|
|
macgub 14 Aug 2026, 09:28
It was so easy. I sometimes tend to complicate things. Thanks a lot bitRAKE!
|
|||
|
|
macgub 14 Aug 2026, 09:46
I have following statement:
Code: cmp eax,1b jne @f addps xmm7,xmm0 jmp .fix @@: subps xmm7,xmm0 .fix: Any ideas for turn it into branchless? Possibly equal or bit greater in size? I have idea: scatter eax value into xmm reg, shift left, and negate with xorps like above. But as I wrote it sometimes produce float -0 value |
|||
|
|
bitRAKE 14 Aug 2026, 10:22
If we assume the branch is random, 50%:
(Because a well predicted branch is better than branchless.) Code: xor eax, 1 neg eax ; CF = (eax != 1) sbb eax, eax ; 0 if ==1, -1 otherwise movd xmm1, eax pshufd xmm1, xmm1, 0 pslld xmm1, 31 ; 0 or 0x80000000 per lane xorps xmm0, xmm1 addps xmm7, xmm0 And the modern is eye candy for many...: Code: xor eax, 1 neg eax ; CF = (eax != 1) sbb eax, eax ; 0 if ==1, -1 otherwise vpbroadcastd xmm1, eax ; GPR->vec broadcast, AVX512VL vpternlogd xmm0, xmm1, [sign]{1to4}, 01111000b ; computes A ^ (B & C) vaddps xmm7, xmm7, xmm0 _________________ ¯\(°_o)/¯ AI may [not] have aided with the above reply. |
|||
|
|
macgub 15 Aug 2026, 07:41
bitRAKE, with this I cannot avoid -0 NaN problem
Code: ... pslld xmm1,31 ; if in xmm0 resides 0 in some place ; and in xmm1 broadcasted 0x80000000 xorps xmm0,xmm1 ; bring me 0x80000000 (-0) in xmm0 in some place Did I miss something? |
|||
|
|
bitRAKE 15 Aug 2026, 09:30
macgub wrote: I cannot avoid -0 NaN problem _________________ ¯\(°_o)/¯ AI may [not] have aided with the above reply. |
|||
|
|
macgub 15 Aug 2026, 13:59
Quote:
You are right. I have bug caused other reason. Thanks for responses. |
|||
|
| Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2026, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.