diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/MC/MCAsmStreamer.cpp | 13 | ||||
| -rw-r--r-- | llvm/lib/MC/MCDwarf.cpp | 12 | ||||
| -rw-r--r-- | llvm/lib/MC/MCRegisterInfo.cpp | 28 | 
3 files changed, 43 insertions, 10 deletions
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index 44bac8eabdc..d1b475f2ca0 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -1296,12 +1296,17 @@ void MCAsmStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {  void MCAsmStreamer::EmitRegisterName(int64_t Register) {    if (!MAI->useDwarfRegNumForCFI()) { +    // User .cfi_* directives can use arbitrary DWARF register numbers, not +    // just ones that map to LLVM register numbers and have known names. +    // Fall back to using the original number directly if no name is known.      const MCRegisterInfo *MRI = getContext().getRegisterInfo(); -    unsigned LLVMRegister = MRI->getLLVMRegNum(Register, true); -    InstPrinter->printRegName(OS, LLVMRegister); -  } else { -    OS << Register; +    int LLVMRegister = MRI->getLLVMRegNumFromEH(Register); +    if (LLVMRegister != -1) { +      InstPrinter->printRegName(OS, LLVMRegister); +      return; +    }    } +  OS << Register;  }  void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) { diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp index a36ff4cb907..3dc0786e445 100644 --- a/llvm/lib/MC/MCDwarf.cpp +++ b/llvm/lib/MC/MCDwarf.cpp @@ -1057,8 +1057,8 @@ void FrameEmitterImpl::EmitCFIInstruction(const MCCFIInstruction &Instr) {      unsigned Reg1 = Instr.getRegister();      unsigned Reg2 = Instr.getRegister2();      if (!IsEH) { -      Reg1 = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg1, true), false); -      Reg2 = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg2, true), false); +      Reg1 = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg1); +      Reg2 = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg2);      }      Streamer.EmitIntValue(dwarf::DW_CFA_register, 1);      Streamer.EmitULEB128IntValue(Reg1); @@ -1094,7 +1094,7 @@ void FrameEmitterImpl::EmitCFIInstruction(const MCCFIInstruction &Instr) {    case MCCFIInstruction::OpDefCfa: {      unsigned Reg = Instr.getRegister();      if (!IsEH) -      Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false); +      Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);      Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa, 1);      Streamer.EmitULEB128IntValue(Reg);      CFAOffset = -Instr.getOffset(); @@ -1105,7 +1105,7 @@ void FrameEmitterImpl::EmitCFIInstruction(const MCCFIInstruction &Instr) {    case MCCFIInstruction::OpDefCfaRegister: {      unsigned Reg = Instr.getRegister();      if (!IsEH) -      Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false); +      Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);      Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_register, 1);      Streamer.EmitULEB128IntValue(Reg); @@ -1118,7 +1118,7 @@ void FrameEmitterImpl::EmitCFIInstruction(const MCCFIInstruction &Instr) {      unsigned Reg = Instr.getRegister();      if (!IsEH) -      Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false); +      Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);      int Offset = Instr.getOffset();      if (IsRelative) @@ -1154,7 +1154,7 @@ void FrameEmitterImpl::EmitCFIInstruction(const MCCFIInstruction &Instr) {    case MCCFIInstruction::OpRestore: {      unsigned Reg = Instr.getRegister();      if (!IsEH) -      Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false); +      Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);      Streamer.EmitIntValue(dwarf::DW_CFA_restore | Reg, 1);      return;    } diff --git a/llvm/lib/MC/MCRegisterInfo.cpp b/llvm/lib/MC/MCRegisterInfo.cpp index 0f76c1838b5..8e47963b441 100644 --- a/llvm/lib/MC/MCRegisterInfo.cpp +++ b/llvm/lib/MC/MCRegisterInfo.cpp @@ -88,6 +88,34 @@ int MCRegisterInfo::getLLVMRegNum(unsigned RegNum, bool isEH) const {    return I->ToReg;  } +int MCRegisterInfo::getLLVMRegNumFromEH(unsigned RegNum) const { +  const DwarfLLVMRegPair *M = EHDwarf2LRegs; +  unsigned Size = EHDwarf2LRegsSize; + +  if (!M) +    return -1; +  DwarfLLVMRegPair Key = { RegNum, 0 }; +  const DwarfLLVMRegPair *I = std::lower_bound(M, M+Size, Key); +  if (I == M+Size || I->FromReg != RegNum) +    return -1; +  return I->ToReg; +} + +int MCRegisterInfo::getDwarfRegNumFromDwarfEHRegNum(unsigned RegNum) const { +  // On ELF platforms, DWARF EH register numbers are the same as DWARF +  // other register numbers.  On Darwin x86, they differ and so need to be +  // mapped.  The .cfi_* directives accept integer literals as well as +  // register names and should generate exactly what the assembly code +  // asked for, so there might be DWARF/EH register numbers that don't have +  // a corresponding LLVM register number at all.  So if we can't map the +  // EH register number to an LLVM register number, assume it's just a +  // valid DWARF register number as is. +  int LRegNum = getLLVMRegNumFromEH(RegNum); +  if (LRegNum != -1) +    return getDwarfRegNum(LRegNum, false); +  return RegNum; +} +  int MCRegisterInfo::getSEHRegNum(unsigned RegNum) const {    const DenseMap<unsigned, int>::const_iterator I = L2SEHRegs.find(RegNum);    if (I == L2SEHRegs.end()) return (int)RegNum;  | 

