Как загрузить в FPU число без знака?

Тема в разделе "WASM.ASSEMBLER", создана пользователем AsmGuru62, 1 июн 2010.

  1. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    Есть инструкция FILD, но она "видит" знак числа.
    Может кто знает инструкцию для беззнаковых чисел?
    Просмотрел все инструкции из руководства Intel - вроде нет такого.

    Делаю пока таким образом:

    Если бит 31 == 1, то снимаю этот бит и затем (после FILD) добавляю 2 в степени 31.
    Но морока это конечно.
     
  2. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    AsmGuru62
    sub [int16],8000h
    fild [int16]
    fisub [C8000];=8000h
     
  3. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.787
    AsmGuru62
    я бы сделал так
    Код (Text):
    1. a dw 0FFFFh
    2.     shr a,1; убираю значение из знакового разряда
    3.     fild a;гружу в FPU
    4.     fadd st,st; удваиваю
    5.     jnc @f; операции в FPU не влияют на регистр флагов
    6.     fld1; если был перенос добавляю 1
    7.     fadd st,st(1)
    8. @@: ...
     
  4. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.787
    AsmGuru62
    а можно и не заморачиваться
    Код (Text):
    1. a dw 0FFFFh
    2. b dd 0FFFFFFFFh
    3.     movzx ebx,a; расширяем word до dword'a
    4.     push ebx
    5.     fild dword ptr [esp];грузим результат в FPU
    6.     push 0; расширяем dword до qword'a
    7.     push b
    8.     fild qword ptr [esp];грузим результат в FPU
    9.     add esp,12; приводим стек в нормальное состояние
     
  5. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    Mikl___
    То что надо!
    FILD 64-битный бывает!
    Это я просмотрел - старею, однако...
     
  6. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    То что надо!
    А что надо ? Нехилые тормоза на чтение 8 байт после записи двух по 4 (store-to-load forwarding stall) ?! ;)

    Еще вариантик:
    Код (Text):
    1. f32 dd 0, 4F800000h ;2^32 в формате single
    2.  
    3. fild [i32]
    4. mov eax,[i32]
    5. shr eax,31
    6. fadd dword ptr [f32+eax*4]
     
  7. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    leo
    ну я бы проще сделал...
    Код (Text):
    1. bs  dd  4F800000h
    2.  
    3. sub     [i32], 80000000h
    4. fild    [i32]
    5. fadd    [bs]
    gcc вообще не заморачивается:
    Код (Text):
    1.     xorl    %edx, %edx
    2.     movl    16(%esp), %eax
    3.     movl    %edx, 4(%esp)
    4.     movl    %eax, (%esp)
    5.     fildq   (%esp)
    ms тоже :)
    Код (Text):
    1.     fild    DWORD PTR _x$[esp-4]
    2.     test    eax, eax
    3.     jge SHORT $LN3@ff
    4.     fadd    QWORD PTR __real@41f0000000000000
    5. $LN3@ff:
     
  8. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    leo
    З.Ы. давненько вас чего-то видно не было :)
     
  9. PSR1257

    PSR1257 New Member

    Публикаций:
    0
    Регистрация:
    30 ноя 2008
    Сообщения:
    933
    А что, в самом FPU нету FABS? Или это некошерно по соображениям производительности?
     
  10. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    PSR1257
    Я так понял, что тк надо, чтобы при наличии числа скажем 3753753753h в копроцессор загружалось 3753753753, а не -541213543.
    Ну и при чем здесь FABS? Получить не -541213543, а 541213543? Ржунимагу. :)
     
  11. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    AsmGuru62
    А можно на x64 и с SSE3? ;)
     
  12. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    Замечательный поток предложений - буду учиться!
    Про stall (large load after two short stores) - это верно. В принципе скорости мне не надо, но всё таки интересно покопать!
    Дисассемблировать как хороший компилер это делает - тоже неплохая идея.
     
  13. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    leo
    Твой код работает великолепно!
     
  14. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.787
    AsmGuru62
    leo только бы поворчать, о быстродействии в ТЗ не было ни слова и мой вариант с пушами ничем не отличается от варианта gcc только push eax поменять на mov [esp],eax :)
     
  15. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Ustus
    Во-первых, аналогичный вариант уже Black_mirror предложил в #2 (правда с опечаткой fisub вместо fiadd). Во-вторых, он "проще" по размеру\числу_команд, а по кол-ву "блох" (микроопераций и их зависимости) - "хуже" ;) Ну и самое главное - он изменяет исходный операнд, что во многих случаях недопустимо

    ms "заморачивается", т.к. partial write тормозит всегда, а jcc только в случае непредсказанного перехода

    Mikl___
    В данном случае я не ворчу, а просто принимаю посильное участие, вставляя свои 5 копеек ;)
    А вариант с пушами и мувами юзается и gcc, и борманом, т.к. он прост и очевиден "как валенок". С загрузкой беззнакового целого еще можно как-то обойтись без partial write, а вот при передаче double в функцию (по значению) наверняка все компилеры юзают пуши и "ворчать" тут бесполезно - можно только самому "заморачиваться" и передавать их по ссылке\указателю
     
  16. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    leo
    Никакой опечатки там нет, там числа просто двухбайтовые.
     
  17. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Black_mirror
    Упс, пардон. Не учел, что вычитание - целочисленное и соотв-но 8000h воспринимается как отрицательное и "минус на минус дает плюс" :)
     
  18. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    leo
    Не заметил, торможу :dntknw:
    Это да.
    Переходите на x64 :) Кстати, многие компилеры умеют и на 32 передавать double через регистры, если их как следует попросить. Правда это нифига не стандартизовано, что плохо.
     
  19. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.787
    Покажите как, просто интересно...
     
  20. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    Mikl___
    Ну вообще-то я имел ввиду SSE. С FPU такое можно проделать только через извращения. Например Watcom'овский компилер в свое время был очень популярен в частности потому, что хорошо оптимизил вещественную арифметику сам по себе и кроме того позволял чуть ли не собственные соглашения вызовов сочинить используя pragma aux.