Jack Carter
2011-Oct-10 17:11 UTC
[LLVMdev] Adding fixups and relocations late in code generation
Gang, I'm tasked with direct object generation for Mips and am trying to not hack the code. I how exactly does one set an expression to be PC relative and if the compiler can resolve it, not produce a relocation? In our case, the backend produces an expression for the branch which is the target label. I make a call from the .td for the branch instruction which calls a routine in MipsMCCodeEmmitter.cpp. That routine ############################################################## unsigned MipsMCCodeEmitter:: getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups) const { const MCOperand &MO = MI.getOperand(OpNo); if (MO.isReg()) { unsigned Reg = MO.getReg(); unsigned RegNo = getMipsRegisterNumbering(Reg); return RegNo; } else if (MO.isImm()) { return static_cast<unsigned>(MO.getImm()); } else if (MO.isFPImm()) { return static_cast<unsigned>(APFloat(MO.getFPImm()) .bitcastToAPInt().getHiBits(32).getLimitedValue()); } else if (MO.isExpr()) { const MCExpr *p_expr = MO.getExpr(); Fixups.push_back(MCFixup::Create(0, p_expr, MCFixupKind(Mips::fixup_Mips_Branch_PCRel))); } return 0; } ############################################ Later in MipsAsmBackend.cpp:ApplyFixup() I find the value is the offset of the target value from the beginning of the section and not the delta from the branch address. I also get a relocation request even though the label should be resolved. So, I must not be telling the compiler what to do when setting up the relocation. What am I doing wrong here? As a hack, I calculate the delta in ApplyFixup() but it should have been done before ApplyFixup(). In ApplyFixup() I believe I just need to adjust the final value for Mips idiosyncrasies like shifting the delta 2 bits to the right. I would really like to become fluent in clean llvm expression building. Thanks, Jack
Jim Grosbach
2011-Oct-10 18:27 UTC
[LLVMdev] Adding fixups and relocations late in code generation
On Oct 10, 2011, at 10:11 AM, Jack Carter wrote:> Gang, > > I'm tasked with direct object generation for Mips and am trying to not > hack the code. > > I how exactly does one set an expression to be PC relative and if the > compiler can resolve it, not produce a relocation? >Fixups are created for all expressions that may need a relocation. The MC layer evaluates them as best it can (MCAssembler::EvaluateFixup()) and calls the target hook RecordRelocation() if it cannot evaluate it directly and needs a relocation in the object file.> In our case, the backend produces an expression for the branch which is > the target label. I make a call from the .td for the branch instruction > which calls a routine in MipsMCCodeEmmitter.cpp. That routine > > ############################################################## > unsigned MipsMCCodeEmitter:: > getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, > SmallVectorImpl<MCFixup> &Fixups) const { > > const MCOperand &MO = MI.getOperand(OpNo); > > if (MO.isReg()) { > unsigned Reg = MO.getReg(); > > unsigned RegNo = getMipsRegisterNumbering(Reg); > return RegNo; > > } else if (MO.isImm()) { > return static_cast<unsigned>(MO.getImm()); > } else if (MO.isFPImm()) { > return static_cast<unsigned>(APFloat(MO.getFPImm()) > .bitcastToAPInt().getHiBits(32).getLimitedValue()); > } else if (MO.isExpr()) { > const MCExpr *p_expr = MO.getExpr(); > Fixups.push_back(MCFixup::Create(0, p_expr, > MCFixupKind(Mips::fixup_Mips_Branch_PCRel))); > } > return 0; > } > > ############################################ > > Later in MipsAsmBackend.cpp:ApplyFixup() I find the value is the offset > of the target value from the beginning of the section and not the delta > from the branch address. >I'm not sure I follow. Wouldn't that still require a relocation from the start of the section?> I also get a relocation request even though the label should be > resolved. >The logic for which cases are considered resolved and which require relocations is in MCAssembler::EvaluateFixup(). It's currently not factored all that well, with some target-specific knowledge embedded in the generic code. It's entirely possible we need to create a target hook there to handle any special cases.> So, I must not be telling the compiler what to do when setting up the > relocation. What am I doing wrong here? > > As a hack, I calculate the delta in ApplyFixup() but it should have been > done before ApplyFixup(). In ApplyFixup() I believe I just need to > adjust the final value for Mips idiosyncrasies like shifting the delta 2 > bits to the right. > > I would really like to become fluent in clean llvm expression building. > > Thanks, > > Jack > > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Carter, Jack
2011-Oct-10 18:41 UTC
[LLVMdev] Adding fixups and relocations late in code generation
Jim, Both the branch and the branch target are in the same function. This is known delta and should not matter where it is relocated because the delta will remain the same once it is a .o or later. I just want to know how to tell the compiler that this expression is target offset - branch offset. More generally, I want to know the rules for setting up expressions in general. I have no idea if one uses post fix, in fix or pre fix. How does one layer different relocations? This will really come in to play for embedded assembler where the gentle user can be as perverse as they want with expressions, resulting with possibly multiple relocations and an immediate for a given instruction operand. Is expression layering described in the documentation anywhere? Cheers, Jack ________________________________________> > Later in MipsAsmBackend.cpp:ApplyFixup() I find the value is the offset > of the target value from the beginning of the section and not the delta > from the branch address. >I'm not sure I follow. Wouldn't that still require a relocation from the start of the section?> I also get a relocation request even though the label should be > resolved. >The logic for which cases are considered resolved and which require relocations is in MCAssembler::EvaluateFixup(). It's currently not factored all that well, with some target-specific knowledge embedded in the generic code. It's entirely possible we need to create a target hook there to handle any special cases.