LINUX.ORG.RU

[mingw32] Byte order. Чем заменить endian.h?


0

0

Здрасьте:) Скачал компилятор mingw32-gcc 4.4.0, mingw32-w32api 3.13; Пытаюсь скомпилить свою программу, но компилятор ругается на отсутствие файла endian.h. Программа использует функции htobe16, htobe32, htobe64. Чем их можно заменить? Самому писать чего-то не хочется...

Согласно man endian написано что эти функции добавлены начиная с glibc 2.9...

> Самому писать чего-то не хочется...

uint16_t htobe16(uint16_t x) {
    union { uint16_t u16; uint8_t v[2]; } ret;
    ret.v[0] = (uint8_t)(x >> 8);
    ret.v[1] = (uint8_t) x;
    return ret.u16;
}

uint32_t htobe32(uint32_t x) {
    union { uint32_t u32; uint8_t v[4]; } ret;
    ret.v[0] = (uint8_t)(x >> 24);
    ret.v[1] = (uint8_t)(x >> 16);
    ret.v[2] = (uint8_t)(x >> 8);
    ret.v[3] = (uint8_t) x;
    return ret.u32;
}

uint64_t htobe64(uint64_t x) {
    union { uint64_t u64; uint8_t v[8]; } ret;
    ret.v[0] = (uint8_t)(x >> 56);
    ret.v[1] = (uint8_t)(x >> 48);
    ret.v[2] = (uint8_t)(x >> 40);
    ret.v[3] = (uint8_t)(x >> 32);
    ret.v[4] = (uint8_t)(x >> 24);
    ret.v[5] = (uint8_t)(x >> 16);
    ret.v[6] = (uint8_t)(x >> 8);
    ret.v[7] = (uint8_t) x;
    return ret.u64;
}
arsi ★★★★★
()
Ответ на: комментарий от arsi

о__О Спасибо:) Это взято из оф. исходников, или это вы сами написали? Круто, но я не думал что так просто.

anterior
() автор топика
Ответ на: комментарий от klalafuda

> а лицензия? а то засудишь его потом как раскрутится..

BSD? ;) кстати, как там в мелкомягких опенсорц-лицензия зовётся? %)

arsi ★★★★★
()
Ответ на: комментарий от anterior

> Это взято из оф. исходников, или это вы сами написали?

с головы, написал прям вот в этом поле ответа, на работоспособность не проверял.

> Круто, но я не думал что так просто.

ничего сложного. просто работа такая, постоянно с подобными преобразованиями сталкиваюсь…

arsi ★★★★★
()

можно сделать проще

uint64_t htobe64(uint64_t source)
{
	uint64_t result;
	uint8_t* s = (uint8_t*)&source;
	uint8_t* r = (uint8_t*)&result;
	r[0] = s[7];
	r[1] = s[6];
	r[2] = s[5];
	r[3] = s[4];
	r[4] = s[3];
	r[5] = s[2];
	r[6] = s[1];
	r[7] = s[0];
	return result;
}

anonumus
()
Ответ на: комментарий от anonumus

> можно сделать проще

> htobe64

facepalm.jp2… что значит «h» знаешь, нет? что, по-твоему, сделает эта функция на BigEndian машине?

вот из-за таких «попроще» у нас до сих пор и нет телепортов… =(

arsi ★★★★★
()
Ответ на: комментарий от arsi

ну если это home to big endian, то всё равно можно проще. Зачем создавать объединения с массивами, если можно обращаться прямо по адресам?

uint64_t htobe64(uint64_t source)
{
   uint64_t result;
   uint8_t* r = (uint8_t*)&result;
   r[0] = (uint8_t)(source >> 56);
   r[1] = (uint8_t)(source >> 48);
   r[2] = (uint8_t)(source >> 40);
   r[3] = (uint8_t)(source >> 32);
   r[4] = (uint8_t)(source >> 24);
   r[5] = (uint8_t)(source >> 16);
   r[6] = (uint8_t)(source >> 8);
   r[7] = (uint8_t)(source);
   return result;
}

anonumus
()
Ответ на: комментарий от anonumus

> ну если это home to big endian

host to big-endian же…

> Зачем создавать объединения с массивами, если можно обращаться прямо по адресам?

ответный вопрос: зачем создавать ещё одну переменную, если можно использовать объединение? кнопка «.» залипает? ;)

> то всё равно можно проще

я не вижу здесь проще, я вижу здесь удобнее для конкретного программиста. другими словами, это очередной холивар, как и с расположением открывающей блочной скобки ;)

arsi ★★★★★
()
Ответ на: комментарий от arsi

мой вариант на gcc 4.3.4 с параметром -O2 даёт 16 mov и 7 shr и всего 23 инструкции процессора.

Ваше даёт 17 move, 6 shr, 1 xor, 8 and, 6 or, 1 push, 1 pop, 4 sal, давая 44 инструкции процессора.

Так что мой вариант компилятору gcc нравится больше в 2 раза.

anonumus
()
Ответ на: комментарий от anonumus

мой вариант на gcc 4.3.4 с параметром -O2 даёт 16 mov и 7 shr и всего 23 инструкции процессора.

Ваше даёт 17 move, 6 shr, 1 xor, 8 and, 6 or, 1 push, 1 pop, 4 sal, давая 44 инструкции процессора.

Так что мой вариант компилятору gcc нравится больше в 2 раза.

что доказывает только то, что гцц кривой как моя жизнь %)

раз:

$ gcc -O2 -c htobe64.c -o htobe64.o
$ objdump -d htobe64.o

htobe64.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <my_htobe64>:
   0:   48 89 fa                mov    %rdi,%rdx
   3:   31 c0                   xor    %eax,%eax
   5:   48 b9 ff ff ff 00 ff    mov    $0xffffffff00ffffff,%rcx
   c:   ff ff ff                                               
   f:   48 c1 ea 38             shr    $0x38,%rdx              
  13:   53                      push   %rbx                    
  14:   48 89 fb                mov    %rdi,%rbx               
  17:   88 d0                   mov    %dl,%al                 
  19:   48 89 fa                mov    %rdi,%rdx               
  1c:   48 c1 ea 30             shr    $0x30,%rdx              
  20:   88 d4                   mov    %dl,%ah                 
  22:   48 89 fa                mov    %rdi,%rdx               
  25:   48 c1 ea 18             shr    $0x18,%rdx              
  29:   48 25 ff ff 00 ff       and    $0xffffffffff00ffff,%rax
  2f:   81 e2 00 00 ff 00       and    $0xff0000,%edx          
  35:   48 09 d0                or     %rdx,%rax               
  38:   48 89 fa                mov    %rdi,%rdx               
  3b:   48 c1 ea 08             shr    $0x8,%rdx               
  3f:   48 21 c8                and    %rcx,%rax               
  42:   48 b9 ff ff ff ff 00    mov    $0xffffff00ffffffff,%rcx
  49:   ff ff ff                                               
[… ЛОР говорит «Слишком большое сообщение» …]
  a9:   ff ff 00                                               
  ac:   48 21 d0                and    %rdx,%rax               
  af:   48 09 d8                or     %rbx,%rax               
  b2:   5b                      pop    %rbx                    
  b3:   c3                      retq                           
  b4:   66 66 66 2e 0f 1f 84    nopw   %cs:0x0(%rax,%rax,1)    
  bb:   00 00 00 00 00

00000000000000c0 <anonymous_htobe64>:
  c0:   48 89 f8                mov    %rdi,%rax
  c3:   40 88 7c 24 ff          mov    %dil,-0x1(%rsp)
  c8:   48 c1 e8 38             shr    $0x38,%rax
  cc:   88 44 24 f8             mov    %al,-0x8(%rsp)
  d0:   48 89 f8                mov    %rdi,%rax
  d3:   48 c1 e8 30             shr    $0x30,%rax
  d7:   88 44 24 f9             mov    %al,-0x7(%rsp)
  db:   48 89 f8                mov    %rdi,%rax
  de:   48 c1 e8 28             shr    $0x28,%rax
  e2:   88 44 24 fa             mov    %al,-0x6(%rsp)
  e6:   48 89 f8                mov    %rdi,%rax
  e9:   48 c1 e8 20             shr    $0x20,%rax
  ed:   88 44 24 fb             mov    %al,-0x5(%rsp)
  f1:   48 89 f8                mov    %rdi,%rax
  f4:   48 c1 e8 18             shr    $0x18,%rax
  f8:   88 44 24 fc             mov    %al,-0x4(%rsp)
  fc:   48 89 f8                mov    %rdi,%rax
  ff:   48 c1 e8 10             shr    $0x10,%rax
 103:   88 44 24 fd             mov    %al,-0x3(%rsp)
 107:   48 89 f8                mov    %rdi,%rax
 10a:   48 c1 e8 08             shr    $0x8,%rax
 10e:   88 44 24 fe             mov    %al,-0x2(%rsp)
 112:   48 8b 44 24 f8          mov    -0x8(%rsp),%rax
 117:   c3                      retq
$

два:

$ /opt/sunstudio12.1/bin/cc -O2 -c htobe64.c -o htobe64.o
$ objdump -d htobe64.o

htobe64.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <my_htobe64>:
   0:   55                      push   %rbp
   1:   48 8b ec                mov    %rsp,%rbp
   4:   48 83 ec 10             sub    $0x10,%rsp
   8:   48 8b c7                mov    %rdi,%rax 
   b:   48 c1 e8 38             shr    $0x38,%rax
   f:   88 45 f8                mov    %al,-0x8(%rbp)
  12:   48 8b c7                mov    %rdi,%rax     
  15:   48 c1 e8 30             shr    $0x30,%rax    
  19:   88 45 f9                mov    %al,-0x7(%rbp)
  1c:   48 8b c7                mov    %rdi,%rax     
  1f:   48 c1 e8 28             shr    $0x28,%rax    
  23:   88 45 fa                mov    %al,-0x6(%rbp)
  26:   48 8b c7                mov    %rdi,%rax     
  29:   48 c1 e8 20             shr    $0x20,%rax    
  2d:   88 45 fb                mov    %al,-0x5(%rbp)
  30:   48 8b c7                mov    %rdi,%rax     
  33:   48 c1 e8 18             shr    $0x18,%rax    
  37:   88 45 fc                mov    %al,-0x4(%rbp)
  3a:   48 8b c7                mov    %rdi,%rax     
  3d:   48 c1 e8 10             shr    $0x10,%rax    
  41:   88 45 fd                mov    %al,-0x3(%rbp)
  44:   48 8b c7                mov    %rdi,%rax     
  47:   48 c1 e8 08             shr    $0x8,%rax     
  4b:   88 45 fe                mov    %al,-0x2(%rbp)
  4e:   40 88 7d ff             mov    %dil,-0x1(%rbp)
  52:   48 8b 45 f8             mov    -0x8(%rbp),%rax
  56:   c9                      leaveq                
  57:   c3                      retq                  

0000000000000058 <anonymous_htobe64>:
  58:   55                      push   %rbp
  59:   48 8b ec                mov    %rsp,%rbp
  5c:   48 83 ec 10             sub    $0x10,%rsp
  60:   48 8b c7                mov    %rdi,%rax
  63:   48 c1 e8 38             shr    $0x38,%rax
  67:   88 45 f8                mov    %al,-0x8(%rbp)
  6a:   48 8b c7                mov    %rdi,%rax
  6d:   48 c1 e8 30             shr    $0x30,%rax
  71:   88 45 f9                mov    %al,-0x7(%rbp)
  74:   48 8b c7                mov    %rdi,%rax
  77:   48 c1 e8 28             shr    $0x28,%rax
  7b:   88 45 fa                mov    %al,-0x6(%rbp)
  7e:   48 8b c7                mov    %rdi,%rax
  81:   48 c1 e8 20             shr    $0x20,%rax
  85:   88 45 fb                mov    %al,-0x5(%rbp)
  88:   48 8b c7                mov    %rdi,%rax
  8b:   48 c1 e8 18             shr    $0x18,%rax
  8f:   88 45 fc                mov    %al,-0x4(%rbp)
  92:   48 8b c7                mov    %rdi,%rax
  95:   48 c1 e8 10             shr    $0x10,%rax
  99:   88 45 fd                mov    %al,-0x3(%rbp)
  9c:   48 8b c7                mov    %rdi,%rax
  9f:   48 c1 e8 08             shr    $0x8,%rax
  a3:   88 45 fe                mov    %al,-0x2(%rbp)
  a6:   40 88 7d ff             mov    %dil,-0x1(%rbp)
  aa:   48 8b 45 f8             mov    -0x8(%rbp),%rax
  ae:   c9                      leaveq
  af:   c3                      retq
$
вы ещё вывариваете? ;)

зы: гцц с -О3 даёт тот же результат, что и с -О2.

arsi ★★★★★
()
Ответ на: комментарий от arsi

>>ответный вопрос: зачем создавать ещё одну переменную, если можно использовать объединение?

А объект объединения - это не переменная в стеке? :)

alex_custov ★★★★★
()
Ответ на: комментарий от anonumus

> uint8_t* s = (uint8_t*)&source; > uint8_t* r = (uint8_t*)&result;

Теоретически, тут можно нарваться на глюки при strict aliasing. Зависит от особенностей компилятора, оптимизации и наличия разницы между uint8_t и char. Вариант с объединением надёжнее.

legolegs ★★★★★
()

Лучше сдвигать с младшего байта.

Тогда достаточно всего 16 инструкций процессора: 9 move, 7 shr.

uint64_t htobe64(uint64_t source)
{
	uint64_t result;
	uint8_t* r = (uint8_t*)&result;
	r[7] = (uint8_t)(source);
	source >>= 8;
	r[6] = (uint8_t)(source);
	source >>= 8;
	r[5] = (uint8_t)(source);
	source >>= 8;
	r[4] = (uint8_t)(source);
	source >>= 8;
	r[3] = (uint8_t)(source);
	source >>= 8;
	r[2] = (uint8_t)(source);
	source >>= 8;
	r[1] = (uint8_t)(source);
	source >>= 8;
	r[0] = (uint8_t)(source);
	return result;
}
Этот код GCC превращает в следующее:

	movb	%dil, -1(%rsp)
	shrq	$8, %rdi
	movb	%dil, -2(%rsp)
	shrq	$8, %rdi
	movb	%dil, -3(%rsp)
	shrq	$8, %rdi
	movb	%dil, -4(%rsp)
	shrq	$8, %rdi
	movb	%dil, -5(%rsp)
	shrq	$8, %rdi
	movb	%dil, -6(%rsp)
	shrq	$8, %rdi
	movb	%dil, -7(%rsp)
	shrq	$8, %rdi
	movb	%dil, -8(%rsp)
	movq	-8(%rsp), %rax
	ret
anonumus
()
Ответ на: комментарий от anonumus

так сильно хотите помериться на гцц+х86_64? да ради бога…

uint64_t htobe64(uint64_t x)
{
#if defined (__GNUC__) && defined (__x86_64__)
   uint64_t ret;
   __asm ("bswapq %%rax" : "=A" (ret) : "A" (x));
   return ret;
#else
    union { uint64_t u64; uint8_t v[8]; } ret;
    /* … */
    return ret.u64;
#endif
}
 120:   48 89 f8                mov    %rdi,%rax
 123:   48 0f c8                bswap  %rax
 126:   c3                      retq
arsi ★★★★★
()
Ответ на: комментарий от arsi

Да, действительно, зачем создавать объект в стеке, когда можно создать объект в стеке? Ты сам уже запутался в своих рассуждениях.

alex_custov ★★★★★
()
Ответ на: комментарий от alex_custov

> Ты сам уже запутался в своих рассуждениях.

нет.

> Да, действительно, зачем создавать объект в стеке, когда можно создать объект в стеке?

я столько не выпью…

arsi ★★★★★
()
Ответ на: комментарий от alex_custov

> Автор не говорил ничего о x86_64

учите ассемблер, для общего развития. +автор говорил о гцц. и на основании гцц+x86_64 делал выводы. под другими процессорами и/или компиляторами картина может (и, скорее всего, будет) другой, но автор таки настаивает на гцц+x86_64. что ещё не понятно?

arsi ★★★★★
()
Ответ на: комментарий от arsi

зы: «автор» — в мысле автор альтернативного кода, т.е. анонимус.

arsi ★★★★★
()
Ответ на: комментарий от anonumus

> то есть виндовс 32 бита.

а почему тогда я наблюдаю дампинг 64-битового ассемблерного кода как аргумент от анонимуса?

arsi ★★★★★
()
Ответ на: комментарий от arsi

Для чего вводится дополнительная переменная ret?

uint64_t htobe64(uint64_t x)
{
...................
   uint64_t ret;
   __asm ("bswapq %%rax" : "=A" (ret) : "A" (x));
   return ret;
.........................
}
}

Можно же написать проще

uint64_t htobe64(uint64_t x)
{
    __asm__("bswap %0" : "+r" (x));
    return x;
}
anonumus
()
Ответ на: комментарий от anonumus

на результат не влияет. было ret, оставил ret… всё равно rax как аргумент не примем, а возвращать именно его придётся. была бы функция инлайн, можно было бы почесать затылок, а так…

arsi ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.