Recent

Author Topic: Addition of 2 consts to var: how it's encoded?  (Read 421 times)

AlexTP

  • Hero Member
  • *****
  • Posts: 2725
    • UVviewsoft
Addition of 2 consts to var: how it's encoded?
« on: May 26, 2026, 09:03:25 am »
Code: Pascal  [Select][+][-]
  1.   function ParseHexDigit(c: char): Byte;
  2.   begin
  3.     case c of
  4.       '0'..'9': Result := Byte(c) - Byte('0');
  5.       'a'..'f': Result := Byte(c) - Byte('a') + 10;
  6.       'A'..'F': Result := Byte(c) - Byte('A') + 10;
  7.       else TryStringToGUID := False;
  8.     end;
  9.   end;
  10.  

In this line
Result := Byte(c) - Byte('A') + 10
is this encoded as subtraction and then addition? Or as only one addition?

ALLIGATOR

  • Sr. Member
  • ****
  • Posts: 456
  • I use FPC [main] 💪🐯💪
Re: Addition of 2 consts to var: how it's encoded?
« Reply #1 on: May 26, 2026, 09:17:50 am »
O0: sub + add
O1,2,3: sub OR lea
I may seem rude - please don't take it personally

jamie

  • Hero Member
  • *****
  • Posts: 7832
Re: Addition of 2 consts to var: how it's encoded?
« Reply #2 on: May 26, 2026, 11:38:23 am »
StrToInt('$'+C)
The only true wisdom is knowing you know nothing

creaothceann

  • Sr. Member
  • ****
  • Posts: 389
Re: Addition of 2 consts to var: how it's encoded?
« Reply #3 on: May 26, 2026, 01:11:08 pm »
Compiler Explorer to the rescue:

https://godbolt.org/z/Ynsb8ovjv

(ParseHexDigit_2 is a table look-up and should be much faster, since it has fewer instructions and is branch-free.)

Code: ASM  [Select][+][-]
  1. parsehexdigit(char):
  2.         movb    %dil,%al
  3.         cmpb    $48,%al
  4.         jb      .Lj6
  5.         subb    $57,%al
  6.         jbe     .Lj7
  7.         subb    $8,%al
  8.         jb      .Lj6
  9.         subb    $5,%al
  10.         jbe     .Lj9
  11.         subb    $27,%al
  12.         jb      .Lj6
  13.         subb    $5,%al
  14.         jbe     .Lj8
  15.         jmp     .Lj6
  16. .Lj7:
  17.         movzbl  %dil,%eax
  18.         subl    $48,%eax
  19.         ret
  20. .Lj8:
  21.         movzbl  %dil,%edx
  22.         subl    $97,%edx
  23.         addl    $10,%edx
  24.         movl    %edx,%eax
  25.         ret
  26. .Lj9:
  27.         andl    $255,%edi
  28.         subl    $65,%edi
  29.         leal    10(%edi),%eax
  30.         ret
  31. .Lj6:
  32.         xorl    %eax,%eax
  33.         movq    trystringtoguid@GOTPCREL(%rip),%rdx
  34.         movb    $0,(%rdx)
  35.         ret

Code: ASM  [Select][+][-]
  1. parsehexdigit_2(char):
  2.         andl    $255,%edi
  3.         leaq    tc_$output$_$.lut()(%rip),%rax
  4.         movzbl  (%rax,%rdi,1),%eax
  5.         cmpl    $128,%eax
  6.         movq    trystringtoguid@GOTPCREL(%rip),%rdx
  7.         setgeb  (%rdx)
  8.         andl    $15,%eax
  9.         ret

Code: ASM  [Select][+][-]
  1. trystringtoguid:
  2.         .zero 1
  3.  
  4. tc_$output$_$.lut():
  5.         .byte   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,129,130,131,132,133,134,135
  6.         .byte   136,137,0,0,0,0,0,0,0,138,139,140,141,142,143,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  7.         .byte   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  8.         .byte   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  9.         .byte   0,0,0

jamie

  • Hero Member
  • *****
  • Posts: 7832
Re: Addition of 2 consts to var: how it's encoded?
« Reply #4 on: May 26, 2026, 02:12:43 pm »
The compiler would be broken if it went out and first added 10 to Byte('A') and used the sum to subtract from BYTE(C)

Only / or * will do that and related multiplier operators.

Now if we are talking C language, there are some screwy things about that, but Pascal is supposed to follow what you learned in school.
Now, there is always the possibility the compiler could be optimizing those two on the right into a single value since they are constants, that would be a problem.
Jamie
The only true wisdom is knowing you know nothing

jamie

  • Hero Member
  • *****
  • Posts: 7832
Re: Addition of 2 consts to var: how it's encoded?
« Reply #5 on: May 26, 2026, 03:06:13 pm »
Code: Pascal  [Select][+][-]
  1. Function GetHex(C:Char):Integer; inline; //Returns -1 if not valid.
  2. Const H:Array[0..15] of Char = '0123456789abcdef';
  3. Begin
  4.  Exit(IndexChar(H,SizeOF(H),Char(Byte(C) Or $20)));
  5. end;                                                        
  6.  

That will return -1 if not a vailed digit and also it in lines making only one call to the indexChar which is an RTL level call which should make things faster.
The only true wisdom is knowing you know nothing

creaothceann

  • Sr. Member
  • ****
  • Posts: 389
Re: Addition of 2 consts to var: how it's encoded?
« Reply #6 on: May 26, 2026, 03:20:04 pm »
there is always the possibility the compiler could be optimizing those two on the right into a single value since they are constants, that would be a problem

That is exactly what the compiler is doing.
« Last Edit: May 26, 2026, 05:03:50 pm by creaothceann »

jamie

  • Hero Member
  • *****
  • Posts: 7832
Re: Addition of 2 consts to var: how it's encoded?
« Reply #7 on: May 26, 2026, 03:53:49 pm »
Looking at you ASM dump, I don't see that, it looks like it's adding 10 at the last step after it has already subtracted prior to.

P.S.

 I just ran his code here on 3.2.2 32 bits, it works ok and I did it inline, also.

jamie
« Last Edit: May 26, 2026, 04:02:47 pm by jamie »
The only true wisdom is knowing you know nothing

creaothceann

  • Sr. Member
  • ****
  • Posts: 389
Re: Addition of 2 consts to var: how it's encoded?
« Reply #8 on: May 26, 2026, 11:44:36 pm »
It combines the operations after changing the code to this:

Code: Pascal  [Select][+][-]
  1.                 '0'..'9': Result := ord(c) + (   - ord('0'));
  2.                 'a'..'f': Result := ord(c) + (10 - ord('a'));
  3.                 'A'..'F': Result := ord(c) + (10 - ord('A'));

 

TinyPortal © 2005-2018