如何在LLVM x86机器函数pass中使用buildmi插入JNE指令(跳转不等于)

问题描述 投票:0回答:1

我正在编写一个 LLVM 机器函数传递,需要在每个基本块的开头插入一些指令。这些指令的作用是从一个地方加载一个值并将其与一个数字进行比较,然后如果之前的比较不相等则跳转到基本块,因此我尝试插入一条指令

JNE
跳转不等于,但我无法让它工作。

这是我的代码

void SomeFunction(llvm::MachineFunction &MF) {
        const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
//        MachineRegisterInfo &MRI = MF.getRegInfo();

        MachineBasicBlock *TrueBB = MF.CreateMachineBasicBlock();
        MF.insert(MF.end(),TrueBB);

        //      get the false basic block ready
//      this is stored at the end of the function that if in the previous block, if any of the jne actually jump into this block, it should terminate
        //                Location testing
        llvm::BuildMI(*TrueBB, TrueBB->begin(), TrueBB->begin()->getDebugLoc(), TII->get(X86::MOV64mr))
                .addReg(X86::RAX) // Base register for the destination address
                .addImm(1)        // Scale factor
                .addReg(0)        // Index register, none in this case
                .addImm(0)        // Displacement
                .addReg(0)        // Segment register, not used here
                .addImm(0);       // Immediate value to store
        llvm::BuildMI(*TrueBB, TrueBB->begin(), TrueBB->begin()->getDebugLoc(), TII->get(X86::MOV64ri), X86::RAX).addImm(0);
        llvm::BuildMI(*TrueBB, TrueBB->begin(), TrueBB->begin()->getDebugLoc(), TII->get(X86::NOOP));


//        then for other basic blocks that are not the first and last
        for (llvm::MachineFunction::iterator MBBItr = MF.begin(), MBBEnd = MF.end(); MBBItr != MBBEnd; MBBItr++){
            llvm::MachineBasicBlock &MBB = *MBBItr;
            if (&MBB != &MF.front() && &MBB != &MF.front()) {
                MachineBasicBlock::iterator FirstMI = MBB.begin();
                DebugLoc DL = FirstMI->getDebugLoc();

//                Location indicator for debug purpose
                BuildMI(MBB, FirstMI, DL, TII->get(X86::NOOP));
//              Both way works
//              Firstly load value from address stored in R14
//              addRegOffset(llvm::BuildMI(MBB, FirstMI, DL, TII->get(llvm::X86::MOV64rm),llvm::X86::RAX),
//                             llvm::X86::R14, false, 0);

                llvm::BuildMI(MBB, FirstMI, DL, TII->get(llvm::X86::MOV64rm),llvm::X86::RAX)
                    .addReg(llvm::X86::R14)
                    .addImm(1)
                    .addReg(llvm::X86::NoRegister)
                    .addImm(0)
                    .addReg(llvm::X86::NoRegister);

//              Then Compare it with our value
                llvm::BuildMI(MBB,FirstMI,DL,TII->get(llvm::X86::CMP64ri32))
                    .addReg(llvm::X86::RAX)
                    .addImm(0x11111111);

//              if the value isn't the same, means interrupt happened, jump to terminate block
//              This is the code that I couldn't get it to work
                llvm::BuildMI(MBB, FirstMI, DL, TII->get(llvm::X86::JCC_1))
                        .addImm(llvm::X86::COND_NE)
                        .addMBB(TrueBB);

            }
        }

        return;
    }

LLVM 已成功构建,然后当我尝试编译一些代码时,会出现类似这样的内容

# %bb.3:                                #   in Loop: Header=BB25_1 Depth=1
    nop
    movq    (%r14), %rax
    cmpq    $286331153, %rax                # imm = 0x11111111
    jo  5

它没有编译成

JNE
而是
JO
,不知道为什么会出错。 我知道在一个基本块内,不应该有任何分支,这是出于学术目的,所以我只想让它发挥作用。预先感谢

assembly x86 clang llvm
1个回答
0
投票

首先感谢Micheal 帮忙订购。 BuildMi 确实需要按顺序添加内容。另一件重要的事情是我需要添加

MBB.addSuccessor(TrueBB);
因为您需要声明哪个块是插入块的后继。

© www.soinside.com 2019 - 2024. All rights reserved.