0

我正在用 c++ 开发一个提升器,将 armv7m 指令提升到 LLVM IR 中。

现在我处于翻译阶段,我只需输入一条手臂指令并将其翻译成等效的 SSA LLVM IR 指令。

我的架构只是为我的汇编代码中的每个函数创建一个 llvm 函数,并为函数内的每个基本块创建一个 llvm 基本块,对于基本块内的每个汇编指令,我使用构建器为该指令构建等效的 llvm IR 指令(同时将该指令的基本块的 llvm 基本块传递给 IRBuilder)..我的 ADD 汇编指令代码示例。

//Translates an ADD assembly instruction object into the equivalent SSA llvm IR instructions.  
llvm::Instruction* ADD(Instr* instruction, bool update_condition_flags = false) {

    IRBuilder<> builder(instruction->basic_block->get_llvm_basic_block());

    std::vector<Reg*> registers = instruction->get_registers();

    std::vector<Immediate*> immediates = instruction->get_immediates();

    if (instruction->get_immediates().empty()) {

            std::string register1 = registers[1]->get_register_name();

            Value* register1_val = registers[1]->get_register_value();

            llvm::Value* immediate = immediates[0]->get_immediate_value_long();

            std::string output_register = registers[0]->get_register_name();

            llvm::Instruction* x = builder.CreateAlloca(Type::getInt32Ty(TheContext), nullptr);

            instruction->insert_llvm_instructions(x);

            llvm::Instruction* s = builder.CreateStore(register1_val, x, /*isVolatile=*/false);

            instruction->insert_llvm_instructions(s);

            llvm::Instruction* LHS = builder.CreateLoad(x, register1);

            instruction->insert_llvm_instructions(LHS);

            llvm::Instruction* add_ll = BinaryOperator::Create(Instruction::Add,
                LHS, immediate, output_register);

            instruction->insert_llvm_instructions(add_ll);

            return add_ll;

基本上,我正在尝试为示例add r1, r3, #2汇编指令生成 llvm IR 指令。

我想在生成的等效 llvm ir 指令(即 %r1、%r3)中使用汇编指令(r1、r3)中使用的寄存器的名称。但是,在生成的 IR 中的许多情况下,在此示例中,我将附加索引添加到寄存器名称中作为 %r346(在“%r3”之后添加了“46”)。为什么要添加这些索引,请问有没有办法删除它们。

例如add r1, r3, #2汇编指令。我想要的输出是:

%12 = alloca i32,对齐 4

存储 i32 0,i32* %12,对齐 4

%r3 = 加载 i32,i32* %12,对齐 4

%r1 = 添加 i32 %r3, 2

虽然我得到的输出是:

%12 = alloca i32,对齐 4

存储 i32 0,i32* %12,对齐 4

%r346 = 加载 i32,i32* %12,对齐 4

%r1 = 添加 i32 %r346, 2

我可以在这里像 %1 这样的 llvm 函数中更新变量吗?

%1 = 多重 i32 %x, %y

%1 = 添加 i32 %1, %z

当我测试我的升降机 id 时,我喜欢跟随一个特定的寄存器(r3),因为它在一个函数中通过不同的汇编指令进行。这些额外的索引会增加混乱。对于以下汇编代码 id,例如为每个汇编指令生成的 llvm IR,使其具有 %r3 而没有任何附加索引。

 ldr r3, [fp, #-8] 

 add r3, r3, #1 

 str r3, [fp, #-8] 
4

1 回答 1

2

LLVM IR 使用 SSA,即。每个符号仅指一个值。add r3, r3, #1不可能,因为 r3 指的是两个值(结果和输入)。

我认为最常见的解决方案是添加一个后缀,该后缀由函数内的偏移量确定。如果那个 add 是第 16 条指令并且它使用的 r3 来自第 12 条,也许%r3.16 = add i32 %r3.12, 1.

于 2021-05-16T16:32:03.910 回答