On Tue, May 25, 2010 at 02:47:06PM +0300, Oleksandr Gavenko wrote:
> Intel C compiler, MSVC, Sun Studio compiler, C for AIX,
> cc из zOS к сожалению на уровне синтаксиса не поддерживают
> встроеный 128-бытный тип. Нужно каверкать исходные тексты на Си
> различными ухищрениями, такая красота не получится
> 
> prod(uint64_t *a, uint64_t *b, uint64_t *r, int len)
> {
> ...
>     uint128_t prod =
>         (uint128_t) a[i] * (uint128_t) b[i]  /* это только в GCC */
>                        + r[i+j] + carry;
>     r[i+j] = (uint64_t) prod;
>     carry = (uint64_t) (prod >> 64);
> ...
> } 

Интересно, что без -O gcc генерирует страшненький код для 128-битного
умножения (cross-compiling on i386):

---------- multiplication.c ----------
#include <inttypes.h>

typedef __int128_t int128_t;

int128_t prod(int64_t a, int64_t b)
{
   return (int128_t)a * (int128_t)b;
}
--------------------------------------

$ gcc -m64 -c multiplication.c && objdump -d multiplication.o

multiplication.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <prod>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   53                      push   %rbx
   5:   48 89 7d f0             mov    %rdi,-0x10(%rbp)
   9:   48 89 75 e8             mov    %rsi,-0x18(%rbp)
   d:   48 8b 4d f0             mov    -0x10(%rbp),%rcx
  11:   48 8b 75 f0             mov    -0x10(%rbp),%rsi
  15:   48 c1 fe 3f             sar    $0x3f,%rsi
  19:   48 89 f3                mov    %rsi,%rbx
  1c:   48 8b 45 e8             mov    -0x18(%rbp),%rax
  20:   48 8b 75 e8             mov    -0x18(%rbp),%rsi
  24:   48 c1 fe 3f             sar    $0x3f,%rsi
  28:   48 89 f2                mov    %rsi,%rdx
  2b:   48 89 de                mov    %rbx,%rsi
  2e:   48 0f af f0             imul   %rax,%rsi
  32:   48 89 d7                mov    %rdx,%rdi
  35:   48 0f af f9             imul   %rcx,%rdi
  39:   48 01 fe                add    %rdi,%rsi
  3c:   48 f7 e1                mul    %rcx
  3f:   48 01 d6                add    %rdx,%rsi
  42:   48 89 f2                mov    %rsi,%rdx
  45:   5b                      pop    %rbx
  46:   c9                      leaveq 
  47:   c3                      retq   

А с оптимизацией - вполне нормальный:

$ gcc -O2 -m64 -c multiplication.c && objdump -d multiplication.o

multiplication.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <prod>:
   0:   48 89 f0                mov    %rsi,%rax
   3:   48 f7 ef                imul   %rdi
   6:   c3                      retq   

Причем, налицо передача параметров через регистры (вход: %rdi, %rsi,
выход: %rax, %rdx). А вот аналогичная функция 64-х битного
умножения на i386 передает параметры через стек.

-- 
Stanislav


-- 
To UNSUBSCRIBE, email to debian-russian-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org
Archive: http://lists.debian.org/20100526083424.gb10...@kaiba.homelan

Ответить