Я хочу использовать встроенный asm для ARMv7 с clang 3.4, чтобы написать код низкого уровня, который обращается к регистрам управления ЦП. В качестве теста я написал программу, которая читает из регистра, условно спрятается с некоторыми битами и записывает новое значение.Inline asm с побочными эффектами
Однако, когда я смотрю на произведенный машинный код, вся бит-вождение оптимизирована. По-видимому, я не использовал правильные ограничения asm, чтобы сказать clang, что результат записи в регистр зависит от того, что написано. (Я использовал простой «изменчивый» модификатор).
Как написать встроенный код asm, чтобы clang генерировал правильный asm? Вот код test.c
typedef unsigned int uint32_t;
// code that reads and writes the ID_PFR1 register
uint32_t read_ID_PFR1() {
uint32_t a;
asm volatile ("mrc p15, 0, %0, c0, c1, 1" : : "r"(a) :);
return a;
}
void write_ID_PFR1(uint32_t a) {
asm volatile ("mcr p15, 0, %0, c0, c1, 1" :"=r"(a) : : );
}
// regular c code that modifies the register
uint32_t foo(uint32_t b) {
uint32_t a;
a = read_ID_PFR1();
write_ID_PFR1(b);
return a+b;
}
void bit_fiddle() {
uint32_t a;
a = read_ID_PFR1();
if ((a & 0x3) == 1) {
a |= 1<<2;
}
a |= 1<<3;
write_ID_PFR1(a);
}
Я составил его с
clang-3.4 -target armv7a-none-eabi test.c -o test -O3
Это результирующий машинный код
$ arm-linux-gnueabi-objdump -S test
test: file format elf32-littlearm
Disassembly of section .text:
00000000 <read_ID_PFR1>:
0: ee100f31 mrc 15, 0, r0, cr0, cr1, {1}
4: e12fff1e bx lr
00000008 <write_ID_PFR1>:
8: ee000f31 mcr 15, 0, r0, cr0, cr1, {1}
c: e12fff1e bx lr
00000010 <foo>:
10: ee100f31 mrc 15, 0, r0, cr0, cr1, {1}
14: ee000f31 mcr 15, 0, r0, cr0, cr1, {1}
18: e12fff1e bx lr
0000001c <bit_fiddle>:
1c: ee100f31 mrc 15, 0, r0, cr0, cr1, {1}
20: ee000f31 mcr 15, 0, r0, cr0, cr1, {1}
24: e12fff1e bx lr
Как вы можете видеть в <bit_fiddle>
, ничего не осталось между mrc
и mcr
инструкция. А также посмотрите, как foo
не может добавить вместе a+b
в полученный машинный код.
попробовать скомпилировать с 'лязгом-3,4 -target armv7a-ни-EABI test.c -o тест -O0' – 0x90
ли я просто перепутать "г" и "= г" ограничения? Разве это будет наоборот? – larsr