mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-17 20:23:59 +00:00
Include a source location when complaining about bad inline assembly.
Add a MI->emitError() method that the backend can use to report errors related to inline assembly. Call it from X86FloatingPoint.cpp when the constraints are wrong. This enables proper clang diagnostics from the backend: $ clang -c pr30848.c pr30848.c:5:12: error: Inline asm output regs must be last on the x87 stack __asm__ ("" : "=u" (d)); /* { dg-error "output regs" } */ ^ 1 error generated. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@134307 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -22,6 +22,7 @@
|
|||||||
#include "llvm/ADT/ilist.h"
|
#include "llvm/ADT/ilist.h"
|
||||||
#include "llvm/ADT/ilist_node.h"
|
#include "llvm/ADT/ilist_node.h"
|
||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
|
#include "llvm/ADT/StringRef.h"
|
||||||
#include "llvm/ADT/DenseMapInfo.h"
|
#include "llvm/ADT/DenseMapInfo.h"
|
||||||
#include "llvm/Support/DebugLoc.h"
|
#include "llvm/Support/DebugLoc.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -180,6 +181,15 @@ public:
|
|||||||
///
|
///
|
||||||
DebugLoc getDebugLoc() const { return debugLoc; }
|
DebugLoc getDebugLoc() const { return debugLoc; }
|
||||||
|
|
||||||
|
/// emitError - Emit an error referring to the source location of this
|
||||||
|
/// instruction. This should only be used for inline assembly that is somehow
|
||||||
|
/// impossible to compile. Other errors should have been handled much
|
||||||
|
/// earlier.
|
||||||
|
///
|
||||||
|
/// If this method returns, the caller should try to recover from the error.
|
||||||
|
///
|
||||||
|
void emitError(StringRef Msg) const;
|
||||||
|
|
||||||
/// getDesc - Returns the target instruction descriptor of this
|
/// getDesc - Returns the target instruction descriptor of this
|
||||||
/// MachineInstr.
|
/// MachineInstr.
|
||||||
const MCInstrDesc &getDesc() const { return *MCID; }
|
const MCInstrDesc &getDesc() const { return *MCID; }
|
||||||
|
@ -15,13 +15,16 @@
|
|||||||
#include "llvm/Constants.h"
|
#include "llvm/Constants.h"
|
||||||
#include "llvm/Function.h"
|
#include "llvm/Function.h"
|
||||||
#include "llvm/InlineAsm.h"
|
#include "llvm/InlineAsm.h"
|
||||||
|
#include "llvm/LLVMContext.h"
|
||||||
#include "llvm/Metadata.h"
|
#include "llvm/Metadata.h"
|
||||||
|
#include "llvm/Module.h"
|
||||||
#include "llvm/Type.h"
|
#include "llvm/Type.h"
|
||||||
#include "llvm/Value.h"
|
#include "llvm/Value.h"
|
||||||
#include "llvm/Assembly/Writer.h"
|
#include "llvm/Assembly/Writer.h"
|
||||||
#include "llvm/CodeGen/MachineConstantPool.h"
|
#include "llvm/CodeGen/MachineConstantPool.h"
|
||||||
#include "llvm/CodeGen/MachineFunction.h"
|
#include "llvm/CodeGen/MachineFunction.h"
|
||||||
#include "llvm/CodeGen/MachineMemOperand.h"
|
#include "llvm/CodeGen/MachineMemOperand.h"
|
||||||
|
#include "llvm/CodeGen/MachineModuleInfo.h"
|
||||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||||
#include "llvm/CodeGen/PseudoSourceValue.h"
|
#include "llvm/CodeGen/PseudoSourceValue.h"
|
||||||
#include "llvm/MC/MCInstrDesc.h"
|
#include "llvm/MC/MCInstrDesc.h"
|
||||||
@ -1712,3 +1715,24 @@ MachineInstrExpressionTrait::getHashValue(const MachineInstr* const &MI) {
|
|||||||
}
|
}
|
||||||
return Hash;
|
return Hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MachineInstr::emitError(StringRef Msg) const {
|
||||||
|
// Find the source location cookie.
|
||||||
|
unsigned LocCookie = 0;
|
||||||
|
const MDNode *LocMD = 0;
|
||||||
|
for (unsigned i = getNumOperands(); i != 0; --i) {
|
||||||
|
if (getOperand(i-1).isMetadata() &&
|
||||||
|
(LocMD = getOperand(i-1).getMetadata()) &&
|
||||||
|
LocMD->getNumOperands() != 0) {
|
||||||
|
if (const ConstantInt *CI = dyn_cast<ConstantInt>(LocMD->getOperand(0))) {
|
||||||
|
LocCookie = CI->getZExtValue();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const MachineBasicBlock *MBB = getParent())
|
||||||
|
if (const MachineFunction *MF = MBB->getParent())
|
||||||
|
return MF->getMMI().getModule()->getContext().emitError(LocCookie, Msg);
|
||||||
|
report_fatal_error(Msg);
|
||||||
|
}
|
||||||
|
@ -884,7 +884,7 @@ void FPS::adjustLiveRegs(unsigned Mask, MachineBasicBlock::iterator I) {
|
|||||||
// Kill registers by popping.
|
// Kill registers by popping.
|
||||||
if (Kills && I != MBB->begin()) {
|
if (Kills && I != MBB->begin()) {
|
||||||
MachineBasicBlock::iterator I2 = llvm::prior(I);
|
MachineBasicBlock::iterator I2 = llvm::prior(I);
|
||||||
for (;;) {
|
while (StackTop) {
|
||||||
unsigned KReg = getStackEntry(0);
|
unsigned KReg = getStackEntry(0);
|
||||||
if (!(Kills & (1 << KReg)))
|
if (!(Kills & (1 << KReg)))
|
||||||
break;
|
break;
|
||||||
@ -1467,25 +1467,27 @@ void FPS::handleSpecialFP(MachineBasicBlock::iterator &I) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (STUses && !isMask_32(STUses))
|
if (STUses && !isMask_32(STUses))
|
||||||
report_fatal_error("Inline asm fixed input regs"
|
MI->emitError("Inline asm fixed input regs"
|
||||||
" must be last on the x87 stack");
|
" must be last on the x87 stack");
|
||||||
unsigned NumSTUses = CountTrailingOnes_32(STUses);
|
unsigned NumSTUses = CountTrailingOnes_32(STUses);
|
||||||
|
|
||||||
// Defs must be contiguous from the stack top. ST0-STn.
|
// Defs must be contiguous from the stack top. ST0-STn.
|
||||||
if (STDefs && !isMask_32(STDefs))
|
if (STDefs && !isMask_32(STDefs)) {
|
||||||
report_fatal_error("Inline asm output regs"
|
MI->emitError("Inline asm output regs"
|
||||||
" must be last on the x87 stack");
|
" must be last on the x87 stack");
|
||||||
|
STDefs = NextPowerOf2(STDefs) - 1;
|
||||||
|
}
|
||||||
unsigned NumSTDefs = CountTrailingOnes_32(STDefs);
|
unsigned NumSTDefs = CountTrailingOnes_32(STDefs);
|
||||||
|
|
||||||
// So must the clobbered stack slots. ST0-STm, m >= n.
|
// So must the clobbered stack slots. ST0-STm, m >= n.
|
||||||
if (STClobbers && !isMask_32(STDefs | STClobbers))
|
if (STClobbers && !isMask_32(STDefs | STClobbers))
|
||||||
report_fatal_error("Inline asm clobbers must be last on the x87 stack");
|
MI->emitError("Inline asm clobbers must be last on the x87 stack");
|
||||||
|
|
||||||
// Popped inputs are the ones that are also clobbered or defined.
|
// Popped inputs are the ones that are also clobbered or defined.
|
||||||
unsigned STPopped = STUses & (STDefs | STClobbers);
|
unsigned STPopped = STUses & (STDefs | STClobbers);
|
||||||
if (STPopped && !isMask_32(STPopped))
|
if (STPopped && !isMask_32(STPopped))
|
||||||
report_fatal_error("Inline asm implicitly popped regs"
|
MI->emitError("Inline asm implicitly popped regs"
|
||||||
" must be last on the x87 stack");
|
" must be last on the x87 stack");
|
||||||
unsigned NumSTPopped = CountTrailingOnes_32(STPopped);
|
unsigned NumSTPopped = CountTrailingOnes_32(STPopped);
|
||||||
|
|
||||||
DEBUG(dbgs() << "Asm uses " << NumSTUses << " fixed regs, pops "
|
DEBUG(dbgs() << "Asm uses " << NumSTUses << " fixed regs, pops "
|
||||||
@ -1501,7 +1503,7 @@ void FPS::handleSpecialFP(MachineBasicBlock::iterator &I) {
|
|||||||
if (!Op.isReg() || Op.getReg() < X86::FP0 || Op.getReg() > X86::FP6)
|
if (!Op.isReg() || Op.getReg() < X86::FP0 || Op.getReg() > X86::FP6)
|
||||||
continue;
|
continue;
|
||||||
if (!Op.isUse())
|
if (!Op.isUse())
|
||||||
report_fatal_error("Illegal \"f\" output constraint in inline asm");
|
MI->emitError("Illegal \"f\" output constraint in inline asm");
|
||||||
unsigned FPReg = getFPReg(Op);
|
unsigned FPReg = getFPReg(Op);
|
||||||
FPUsed |= 1U << FPReg;
|
FPUsed |= 1U << FPReg;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user