Я заметил, что llvm.read_register()
может читать значение указателя стека, а также llvm.write_register()
может установить значение указателя стека. Добавить основную функцию в stackpointer.ll
, которые могут быть найдены в LLVM ЦСИ:Как использовать llvm intrinsics @ llvm.read_register?
;stackpointer.ll
define i32 @get_stack() nounwind {
%sp = call i32 @llvm.read_register.i32(metadata !0)
ret i32 %sp
}
declare i32 @llvm.read_register.i32(metadata) nounwind
!0 = metadata !{metadata !"sp\00"}
define i32 @main() {
%1 = call i32 @get_stack()
ret i32 %1
}
я тестировал на ARMv7 плате под управлением Ubuntu 11.04:
lli stackpointer.ll
тогда, я получаю дамп стека:
ARMCodeEmitter::emitPseudoInstruction
UNREACHABLE executed at ARMCodeEmitter.cpp:847!
Stack dump:
0. Program arguments: lli stackpointer.ll
1. Running pass 'ARM Machine Code Emitter' on function '@main'
Aborted
Я также попытался LLC:
messege ошибка:
Can't get register for value!
UNREACHABLE executed at ARMCodeEmitter.cpp:1183!
Stack dump:
0. Program arguments: llc stackpointer.ll -o stackpointer.s
1. Running pass 'Function Pass Manager' on moulude 'stackpointer.ll'
2. Running pass 'ARM Instruction Selection' on function '@get_stack'
Aborted
Я также попытался на платформе x86-64, она не работает. Каков правильный способ использования этих свойств?
Кажется, что версия llvm имеет значение. В настоящее время я использую llvm 3.4.2, и мой lli не смог принять приведенный выше синтаксис. какую версию вы используете? Что касается белого пространства, я оставил его намеренно. – winter333
@ winter333 Я использую довольно новую версию LLVM, построенную из источника: 3.7.0svn –
Спасибо за ваш ответ. Я загружаю исходные бинарные файлы llvm 3.6, и он работает! – winter333