MSVC compiler - cmov in 32-bit code

Тема в разделе "LANGS.C", создана пользователем green, 27 мар 2010.

  1. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    При каких условиях компилятор VC генерирует инструкцию cmov в 32-битном коде?
    Что-то не удаётся его заставить... /arch:SSE2 не помогает.
    VC 2008 SP1, 2010.
     
  2. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    А такую конструкцию пробовал?
    Код (Text):
    1. dest = (condition) ? (source1) : (source2);
     
  3. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    AsmGuru62
    Да. По разному провоцировал.
    Для 64 бит cmov генерит без проблем.
     
  4. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    green
    cmov была на 386 проце?
     
  5. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    KeSqueer
    Нет. Как и SSE2.
     
  6. PowerASM

    PowerASM New Member

    Публикаций:
    0
    Регистрация:
    27 мар 2010
    Сообщения:
    59
    KeSqueer
    нет не было. наличие этих инструкций надо дополнительно проверять (CPUID(1).eax:15)
    Intel® 64 and IA-32 Architectures Software Developer's Manual (Volume 2A)
     
  7. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    KeSqueer
    PowerASM

    Инструкция cmov присутствует во всех процах, поддерживающих SSE2 (насчёт SSE не уверен). Поэтому есть основания ожидать, что компилятор будет использовать эту инструкцию при /arch:SSE2.
    Вот цитата из MSDN (статья об опции /arch):
     
  8. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    VS 2005

    Код (Text):
    1. cl /c /Ox /Os /arch:SSE /FAsc test.c
    Код (Text):
    1. #include<stdio.h>
    2. #include<stdlib.h>
    3.  
    4. int main(int argc,char *argv[])
    5. {
    6.     int x,y;
    7.     if(argc!=3)
    8.     {
    9.         printf("Usage: test <num1> <num2>\n");
    10.         return -1;
    11.     }
    12.     x=atoi(argv[1]);
    13.     y=atoi(argv[2]);
    14.     return x!=32 ? x:y;
    15. }
    Код (Text):
    1. ; Listing generated by Microsoft (R) Optimizing Compiler Version 14.00.50727.42
    2.  
    3.     TITLE   C:\Prog\CHDK\test.c
    4.     .686P
    5.     .XMM
    6.     include listing.inc
    7.     .model  flat
    8.  
    9. INCLUDELIB LIBCMT
    10. INCLUDELIB OLDNAMES
    11.  
    12. _DATA   SEGMENT
    13. $SG3546 DB  'Usage: test <num1> <num2>', 0aH, 00H
    14. _DATA   ENDS
    15. PUBLIC  _main
    16. EXTRN   _atoi:PROC
    17. EXTRN   _printf:PROC
    18. ; Function compile flags: /Ogspy
    19. ; File c:\prog\chdk\test.c
    20. _TEXT   SEGMENT
    21. _argc$ = 8                      ; size = 4
    22. _argv$ = 12                     ; size = 4
    23. _main   PROC
    24.  
    25. ; 6    :     int x,y;
    26. ; 7    :     if(argc!=3)
    27.  
    28.   00000 83 7c 24 04 03   cmp     DWORD PTR _argc$[esp-4], 3
    29.   00005 74 0f        je  SHORT $LN1@main
    30.  
    31. ; 8    :     {
    32. ; 9    :         printf("Usage: test <num1> <num2>\n");
    33.  
    34.   00007 68 00 00 00 00   push    OFFSET $SG3546
    35.   0000c e8 00 00 00 00   call    _printf
    36.   00011 59       pop     ecx
    37.  
    38. ; 10   :         return -1;
    39.  
    40.   00012 83 c8 ff     or  eax, -1
    41.  
    42. ; 15   : }
    43.  
    44.   00015 c3       ret     0
    45. $LN1@main:
    46.   00016 56       push    esi
    47.  
    48. ; 11   :     }
    49. ; 12   :     x=atoi(argv[1]);
    50.  
    51.   00017 8b 74 24 0c  mov     esi, DWORD PTR _argv$[esp]
    52.   0001b 57       push    edi
    53.   0001c ff 76 04     push    DWORD PTR [esi+4]
    54.   0001f e8 00 00 00 00   call    _atoi
    55.  
    56. ; 13   :     y=atoi(argv[2]);
    57.  
    58.   00024 ff 76 08     push    DWORD PTR [esi+8]
    59.   00027 8b f8        mov     edi, eax
    60.   00029 e8 00 00 00 00   call    _atoi
    61.   0002e 59       pop     ecx
    62.  
    63. ; 14   :     return x!=32 ? x:y;
    64.  
    65.   0002f 83 ff 20     cmp     edi, 32            ; 00000020H
    66.   00032 59       pop     ecx
    67.   00033 0f 45 c7     cmovne  eax, edi
    68.   00036 5f       pop     edi
    69.   00037 5e       pop     esi
    70.  
    71. ; 15   : }
    72.  
    73.   00038 c3       ret     0
    74. _main   ENDP
    75. _TEXT   ENDS
    76. END
     
  9. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Кстати в своём блоге разработчики студии пишут что в 2010 студии генерацию CMOV улучшат.
    http://blogs.msdn.com/vcblog/archive/2009/11/02/visual-c-code-generation-in-visual-studio-2010.aspx
     
  10. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    cppasm
    Точно, при оптимизации по размеру генерится cmov. Спасибо.

    Но странно всё-таки... получается, что компилер считает jxx/mov быстрее cmov в 32битном коде.
     
  11. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Оно так и есть при условии что переход предсказан верно.