{"id":375,"date":"2008-10-31T08:17:18","date_gmt":"2008-10-31T06:17:18","guid":{"rendered":"https:\/\/foton.no-ip.com\/BLOG\/?p=375"},"modified":"2010-04-17T00:18:45","modified_gmt":"2010-04-16T22:18:45","slug":"optimal-coding-2","status":"publish","type":"post","link":"https:\/\/foton.szikraistvan.hu\/blog\/?p=375","title":{"rendered":"Optimal Coding 2 &#8211; Borland vs. MS vs. GNU"},"content":{"rendered":"<p>Delphi (Borland Developer Studio 2006):<\/p>\n<p><code>function AddInt64_1(A, B : Int64) : Int64;<br \/>\nbegin<br \/>\n Result := A + B;<br \/>\nend;<\/code><\/p>\n<p>The BDS2006 compiler generated this:<br \/>\n<code>OptimizeMathFunctions.dpr.74: writeln(IntToHex(AddInt64_1($1111000022223333,$1234567890123456),16));<br \/>\n0040915F 6800001111       push $11110000<br \/>\n00409164 6833332222       push $22223333<br \/>\n00409169 6878563412       push $12345678<br \/>\n0040916E 6856341290       push $90123456<br \/>\n00409173 E844F8FFFF       call AddInt64_1<br \/>\n...<br \/>\nOptimizeMathFunctions.dpr.9: begin<br \/>\n004089BC 55               push ebp<br \/>\n004089BD 8BEC             mov ebp,esp<br \/>\n004089BF 83C4F8           add esp,-$08<br \/>\nOptimizeMathFunctions.dpr.10: Result := A + B;<br \/>\n004089C2 8B4510           mov eax,[ebp+$10]<br \/>\n004089C5 8B5514           mov edx,[ebp+$14]<br \/>\n004089C8 034508           add eax,[ebp+$08]<br \/>\n004089CB 13550C           adc edx,[ebp+$0c]<br \/>\n004089CE 8945F8           mov [ebp-$08],eax<br \/>\n004089D1 8955FC           mov [ebp-$04],edx<br \/>\nOptimizeMathFunctions.dpr.11: end;<br \/>\n004089D4 8B45F8           mov eax,[ebp-$08]<br \/>\n004089D7 8B55FC           mov edx,[ebp-$04]<br \/>\n004089DA 59               pop ecx<br \/>\n004089DB 59               pop ecx<br \/>\n004089DC 5D               pop ebp<br \/>\n004089DD C21000           ret $0010<\/code><\/p>\n<p>What We wanted is this:<\/p>\n<p><code>function AddInt64_A(A, B : Int64) : Int64;<br \/>\nasm<br \/>\n mov eax,[ebp+$10]<br \/>\n mov edx,[ebp+$14]<br \/>\n add eax,[ebp+$08]<br \/>\n adc edx,[ebp+$0c]<br \/>\nend;<\/code><\/p>\n<p>Which looks like this in action:<\/p>\n<p><code>OptimizeMathFunctions.dpr.82: writeln(IntToHex(AddInt64_A($1111000022223333,$1234567890123456),16));<br \/>\n004091A1 6800001111       push $11110000<br \/>\n004091A6 6833332222       push $22223333<br \/>\n004091AB 6878563412       push $12345678<br \/>\n004091B0 6856341290       push $90123456<br \/>\n004091B5 E826F8FFFF       call AddInt64_A<br \/>\n...<br \/>\nOptimizeMathFunctions.dpr.14: asm<br \/>\n004089E0 55               push ebp<br \/>\n004089E1 8BEC             mov ebp,esp<br \/>\n004089E3 8B4510           mov eax,[ebp+$10]<br \/>\n004089E6 8B5514           mov edx,[ebp+$14]<br \/>\n004089E9 034508           add eax,[ebp+$08]<br \/>\n004089EC 13550C           adc edx,[ebp+$0c]<br \/>\nOptimizeMathFunctions.dpr.19: end;<br \/>\n004089EF 5D               pop ebp<br \/>\n004089F0 C21000           ret $0010<\/code><\/p>\n<p>Much better, (the delphi optimizer looks lazy).<\/p>\n<p>Lets see the Visual Studio 2008 Pro C++:<\/p>\n<p><code>typedef long long int64;<br \/>\nint64 AddInt64_1(int64 A, int64 B)<br \/>\n{<br \/>\n  return (A+B);<br \/>\n}<\/code><\/p>\n<p><code>\tprintf(\"%I64xn\",AddInt64_1(0x1111000022223333UL,0x1234567890123456UL));<br \/>\n004135AC  push        12345678h<br \/>\n004135B1  push        90123456h<br \/>\n004135B6  push        11110000h<br \/>\n004135BB  push        22223333h<br \/>\n004135C0  call        AddInt64_1 (4111D1h)<br \/>\n...<br \/>\n004111D1  jmp         AddInt64_1 (4113A0h)<br \/>\n...<br \/>\n004113A0  push        ebp<br \/>\n004113A1  mov         ebp,esp<br \/>\n004113A3  sub         esp,0C0h<br \/>\n004113A9  push        ebx<br \/>\n004113AA  push        esi<br \/>\n004113AB  push        edi<br \/>\n004113AC  lea         edi,[ebp-0C0h]<br \/>\n004113B2  mov         ecx,30h<br \/>\n004113B7  mov         eax,0CCCCCCCCh<br \/>\n004113BC  rep stos    dword ptr es:[edi]<br \/>\n  return (A+B);<br \/>\n004113BE  mov         eax,dword ptr [A]<br \/>\n004113C1  add         eax,dword ptr [B]<br \/>\n004113C4  mov         edx,dword ptr [ebp+0Ch]<br \/>\n004113C7  adc         edx,dword ptr [ebp+14h]<br \/>\n}<br \/>\n004113CA  pop         edi<br \/>\n004113CB  pop         esi<br \/>\n004113CC  pop         ebx<br \/>\n004113CD  mov         esp,ebp<br \/>\n004113CF  pop         ebp<br \/>\n004113D0  ret              <\/code><\/p>\n<p>I would have expected something more efficient. I thought MS VS2008 would produce better code than BDS2006 for sure. I was wrong.<\/p>\n<p>What I wanted looks something like this:<\/p>\n<p><code>int64 __declspec(naked) AddInt64_AN2(int64 A, int64 B)<br \/>\n{<br \/>\n    __asm {<br \/>\n\t mov eax,dword ptr [esp+04h]\/\/[A]<br \/>\n\t add eax,dword ptr [esp+0ch]<br \/>\n\t mov edx,dword ptr [esp+08h]<br \/>\n\t adc edx,dword ptr [esp+10h]<br \/>\n        ret<br \/>\n    }<br \/>\n}<\/code><\/p>\n<p>Assembly is still king. And so is pascal\/delphi with assembler rutines.<\/p>\n<p>Next is gcc&#8230;<\/p>\n<p>MinGW32 &#8211; gcc 3.4.5 (mingw-vista special r3)<\/p>\n<p><code>int64 AddInt64_1(int64 A, int64 B)<br \/>\n{<br \/>\n  return (A+B);<br \/>\n}<br \/>\n...<br \/>\n  printf(\"%I64xn\",AddInt64_1(0x1111000022223333LL,0x1234567890123456LL));<\/code><\/p>\n<p>the result of  gcc -S :<\/p>\n<p><code>\tmovl\t$-1877855146, 8(%esp)<br \/>\n\tmovl\t$305419896, 12(%esp)<br \/>\n\tmovl\t$572666675, (%esp)<br \/>\n\tmovl\t$286326784, 4(%esp)<br \/>\n\tcall\t__Z10AddInt64_1xx<br \/>\n...<br \/>\n__Z10AddInt64_1xx:<br \/>\n\tpushl\t%ebp<br \/>\n\tmovl\t%esp, %ebp<br \/>\n\tmovl\t16(%ebp), %eax<br \/>\n\tmovl\t20(%ebp), %edx<br \/>\n\taddl\t8(%ebp), %eax<br \/>\n\tadcl\t12(%ebp), %edx<br \/>\n\tpopl\t%ebp<br \/>\n\tret<\/code><\/p>\n<p>Thats what I call nice code (apart from the GAS syntax)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Delphi (Borland Developer Studio 2006): function AddInt64_1(A, B : Int64) : Int64; begin Result := A + B; end; The BDS2006 compiler generated this: OptimizeMathFunctions.dpr.74: writeln(IntToHex(AddInt64_1($1111000022223333,$1234567890123456),16)); 0040915F 6800001111 push $11110000 00409164 6833332222 push $22223333 00409169 6878563412 push $12345678 0040916E 6856341290 &hellip; <a href=\"https:\/\/foton.szikraistvan.hu\/blog\/?p=375\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[32],"tags":[71,70],"class_list":["post-375","post","type-post","status-publish","format-standard","hentry","category-cooding","tag-develop","tag-programozas"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p3E7AZ-63","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/foton.szikraistvan.hu\/blog\/index.php?rest_route=\/wp\/v2\/posts\/375","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/foton.szikraistvan.hu\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/foton.szikraistvan.hu\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/foton.szikraistvan.hu\/blog\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/foton.szikraistvan.hu\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=375"}],"version-history":[{"count":12,"href":"https:\/\/foton.szikraistvan.hu\/blog\/index.php?rest_route=\/wp\/v2\/posts\/375\/revisions"}],"predecessor-version":[{"id":723,"href":"https:\/\/foton.szikraistvan.hu\/blog\/index.php?rest_route=\/wp\/v2\/posts\/375\/revisions\/723"}],"wp:attachment":[{"href":"https:\/\/foton.szikraistvan.hu\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=375"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/foton.szikraistvan.hu\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=375"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/foton.szikraistvan.hu\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=375"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}