При попытке адресации отдельных байтов внутри uint64
AVR gcc⁽¹⁾ выдает мне странный пролог/эпилог, в то время как та же функция, написанная с использованием uint32_t
, дает мне один ret
(пример функции — это NOP).
Почему gcc это делает? Как это удалить?
Вы можете увидеть код здесь, в Compiler Explorer.
⁽¹⁾ gcc 5.4.0 из дистрибутива Arduino 1.8.9, параметры=-O3 -std=c++11
.
Исходный код:
#include <stdint.h>
uint32_t f_u32(uint32_t x) {
union y {
uint8_t p[4];
uint32_t w;
};
return y{ .p = {
y{ .w = x }.p[0],
y{ .w = x }.p[1],
y{ .w = x }.p[2],
y{ .w = x }.p[3]
} }.w;
}
uint64_t f_u64(uint64_t x) {
union y {
uint8_t p[8];
uint64_t w;
};
return y{ .p = {
y{ .w = x }.p[0],
y{ .w = x }.p[1],
y{ .w = x }.p[2],
y{ .w = x }.p[3],
y{ .w = x }.p[4],
y{ .w = x }.p[5],
y{ .w = x }.p[6],
y{ .w = x }.p[7]
} }.w;
}
Сгенерированная сборка для uint32_t
версии:
f_u32(unsigned long):
ret
Сгенерированная сборка для версии uint64_t
:
f_u64(unsigned long long):
push r28
push r29
in r28,__SP_L__
in r29,__SP_H__
subi r28,72
sbc r29,__zero_reg__
in __tmp_reg__,__SREG__
cli
out __SP_H__,r29
out __SREG__,__tmp_reg__
out __SP_L__,r28
subi r28,-72
sbci r29,-1
in __tmp_reg__,__SREG__
cli
out __SP_H__,r29
out __SREG__,__tmp_reg__
out __SP_L__,r28
pop r29
pop r28
ret
f_u64()
до NOP, и (2) вы можете удалить это, удалив функцию или попытавшись реализовать ее какreturn x;
. Если это не те ответы, которые вы ищете, возможно, вы могли бы перефразировать вопрос или уточнить в комментарии? - person nielsen   schedule 07.09.2019f_u64()
по какой-то причине выделяет 72 байта в стеке, а затем снова их освобождает. Я попытался добавить функцию, которая принимаетuint64_t
, вызываетf_u64()
и возвращает результат плюс 10 и скомпилирована с оптимизацией для size-Os
. Эта функция не получает никакой акробатики стека, поэтому это не общий аспект передачиuint64_t
. В настоящее время я думаю, что это какая-то проблема с компилятором/оптимизатором, но я не могу указать на это пальцем. Лично я бы смирился с этим или попытался найти обходной путь. - person nielsen   schedule 07.09.2019