Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8437017
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 10, 20262026-06-10T07:19:24+00:00 2026-06-10T07:19:24+00:00

I’m curious if someone can shed some light on this for me. I’m working

  • 0

I’m curious if someone can shed some light on this for me. I’m working on some numeric data conversion stuff, and I’ve got several functions that do data conversions, which I define using two macros:

#define CONV_VIA_CAST(name, dtype, vtype)                               \
    static inline void name(void *data, void *view, size_t len) {       \
        vtype *vptr = (vtype*)view;                                     \
        dtype *dptr = (dtype*)data;                                     \
        for (size_t ii=0; ii < len/sizeof(vtype); ii++) {               \
            *vptr++ = (vtype)*dptr++;                                   \
        }                                                               \
    } 


#define CONV_VIA_FUNC(name, dtype, vtype, via)                          \
    static inline void name(void *data, void *view, size_t len) {       \
        vtype *vptr = (vtype*)view;                                     \
        dtype *dptr = (dtype*)data;                                     \
        for (size_t ii=0; ii < len/sizeof(vtype); ii++) {               \
            *vptr++ = (vtype)via(*dptr++);                              \
        }                                                               \
    } 

When I define a float to int conversion:

 CONV_VIA_FUNC(f_to_i, float, int16_t, lrintf); 

I get a nice terse little piece of assemble with -O3 on:

   0x0000000000401fb0 <+0>:     shr    %rdx
   0x0000000000401fb3 <+3>:     je     0x401fd3 <f_to_i+35>
   0x0000000000401fb5 <+5>:     xor    %eax,%eax
   0x0000000000401fb7 <+7>:     nopw   0x0(%rax,%rax,1)
   0x0000000000401fc0 <+16>:    cvtss2si (%rdi,%rax,4),%rcx
   0x0000000000401fc6 <+22>:    mov    %cx,(%rsi,%rax,2)
   0x0000000000401fca <+26>:    add    $0x1,%rax
   0x0000000000401fce <+30>:    cmp    %rdx,%rax
   0x0000000000401fd1 <+33>:    jne    0x401fc0 <f_to_i+16>
   0x0000000000401fd3 <+35>:    repz retq 

However, when I define a float->double (or double->float) function:

CONV_VIA_CAST(f_to_d, float,   double); 

I get this monstrosity:

   0x0000000000402040 <+0>:     mov    %rdx,%r8
   0x0000000000402043 <+3>:     shr    $0x3,%r8
   0x0000000000402047 <+7>:     test   %r8,%r8
   0x000000000040204a <+10>:    je     0x402106 <f_to_d+198>
   0x0000000000402050 <+16>:    shr    $0x5,%rdx
   0x0000000000402054 <+20>:    lea    0x0(,%rdx,4),%r9
   0x000000000040205c <+28>:    test   %r9,%r9
   0x000000000040205f <+31>:    je     0x402108 <f_to_d+200>
   0x0000000000402065 <+37>:    lea    (%rdi,%r8,4),%rax
   0x0000000000402069 <+41>:    cmp    $0xb,%r8
   0x000000000040206d <+45>:    lea    (%rsi,%r8,8),%r10
   0x0000000000402071 <+49>:    seta   %cl
   0x0000000000402074 <+52>:    cmp    %rax,%rsi
   0x0000000000402077 <+55>:    seta   %al
   0x000000000040207a <+58>:    cmp    %r10,%rdi
   0x000000000040207d <+61>:    seta   %r10b
   0x0000000000402081 <+65>:    or     %r10d,%eax
   0x0000000000402084 <+68>:    test   %al,%cl
   0x0000000000402086 <+70>:    je     0x402108 <f_to_d+200>
   0x000000000040208c <+76>:    xorps  %xmm3,%xmm3
   0x000000000040208f <+79>:    xor    %eax,%eax
   0x0000000000402091 <+81>:    xor    %ecx,%ecx
   0x0000000000402093 <+83>:    nopl   0x0(%rax,%rax,1)
   0x0000000000402098 <+88>:    movaps %xmm3,%xmm0
   0x000000000040209b <+91>:    add    $0x1,%rcx
   0x000000000040209f <+95>:    movlps (%rdi,%rax,1),%xmm0
   0x00000000004020a3 <+99>:    movhps 0x8(%rdi,%rax,1),%xmm0
   0x00000000004020a8 <+104>:   movhlps %xmm0,%xmm1
   0x00000000004020ab <+107>:   cvtps2pd %xmm0,%xmm2
   0x00000000004020ae <+110>:   cvtps2pd %xmm1,%xmm0
   0x00000000004020b1 <+113>:   movlpd %xmm2,(%rsi,%rax,2)
   0x00000000004020b6 <+118>:   movhpd %xmm2,0x8(%rsi,%rax,2)
   0x00000000004020bc <+124>:   movlpd %xmm0,0x10(%rsi,%rax,2)
   0x00000000004020c2 <+130>:   movhpd %xmm0,0x18(%rsi,%rax,2)
   0x00000000004020c8 <+136>:   add    $0x10,%rax
   0x00000000004020cc <+140>:   cmp    %rcx,%rdx
   0x00000000004020cf <+143>:   ja     0x402098 <f_to_d+88>
   0x00000000004020d1 <+145>:   cmp    %r9,%r8
   0x00000000004020d4 <+148>:   lea    (%rsi,%r9,8),%rsi
   0x00000000004020d8 <+152>:   lea    (%rdi,%r9,4),%rdi
   0x00000000004020dc <+156>:   je     0x40210d <f_to_d+205>
   0x00000000004020de <+158>:   mov    %r9,%rdx
   0x00000000004020e1 <+161>:   mov    %r9,%rax
   0x00000000004020e4 <+164>:   neg    %rdx
   0x00000000004020e7 <+167>:   lea    (%rsi,%rdx,8),%rcx
   0x00000000004020eb <+171>:   lea    (%rdi,%rdx,4),%rdx
   0x00000000004020ef <+175>:   nop
   0x00000000004020f0 <+176>:   movss  (%rdx,%rax,4),%xmm0
   0x00000000004020f5 <+181>:   cvtps2pd %xmm0,%xmm0
   0x00000000004020f8 <+184>:   movsd  %xmm0,(%rcx,%rax,8)
   0x00000000004020fd <+189>:   add    $0x1,%rax
   0x0000000000402101 <+193>:   cmp    %rax,%r8
   0x0000000000402104 <+196>:   ja     0x4020f0 <f_to_d+176>
   0x0000000000402106 <+198>:   repz retq 
   0x0000000000402108 <+200>:   xor    %r9d,%r9d
   0x000000000040210b <+203>:   jmp    0x4020de <f_to_d+158>
   0x000000000040210d <+205>:   nopl   (%rax)
   0x0000000000402110 <+208>:   retq   

Can anyone shed some light on what’s going on under the hood here for the float->double conversion? And perhaps how it might be written to get more efficient assembly out? I’m using gcc 4.6.3 if that matters.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-10T07:19:25+00:00Added an answer on June 10, 2026 at 7:19 am

    There’s several things going on here that I can see quickly (the code is a bit long, the time is a bit late, and I’m not a fan of AT&T syntax).

    Firstly, the second loop was vectorized (but badly, see below). That inherently causes some code bloat – it now has to deal with a “tail end” that is shorter than a vector and such.

    Second, float to double is a widening conversion. That doesn’t matter for scalars, but with vectors that means that you can’t just read some data, convert it and write it back – somewhere along the lines you’ll end up with double as many bytes and they have to be dealt with. (hence the movhlps %xmm0,%xmm1)

    The actual loop only spans from 402098h to 4020cfh, below that is the “tail handling”, and above that is a monstrosity that tests whether it has the skip the main loop completely and some things I haven’t quite figured out – it would make sense if it was for alignment, but I don’t see any test rdi, 15‘s in there, nor anything obvious that would get rid of an unaligned beginning.

    And thirdly, GCC is being lame. This is not unusual. It seems to think that xmm3 is somehow involved, which it isn’t, and it seems to have forgotten that vectors can be loaded to an from memory in one piece – then again this could be because the monstrosity at the beginning really didn’t test for alignment and this is its defense against unaligned pointers. In any case though, GCC did a bad job here.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

For some reason, after submitting a string like this Jack’s Spindle from a text
I have this code to decode numeric html entities to the UTF8 equivalent character.
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
Does anyone know how can I replace this 2 symbol below from the string
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I have just tried to save a simple *.rtf file with some websites and
I have a jquery bug and I've been looking for hours now, I can't
this is what i have right now Drawing an RSS feed into the php,
I've got a string that has curly quotes in it. I'd like to replace

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.