mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-13 01:15:32 +00:00
MS inline asm: Use memory constraints for functions instead of registers
This is consistent with how we parse them in a standalone .s file, and inline assembly shouldn't differ. This fixes errors about requiring more registers than available in cases like this: void f(); void __declspec(naked) g() { __asm pusha __asm call f __asm popa __asm ret } There are no registers available to pass the address of 'f' into the asm blob. The asm should now directly call 'f'. Tests will land in Clang shortly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@214550 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a2a42a6a4e
commit
ab418066a2
@ -731,6 +731,13 @@ private:
|
|||||||
(X86::Mode64Bit | X86::Mode32Bit | X86::Mode16Bit)));
|
(X86::Mode64Bit | X86::Mode32Bit | X86::Mode16Bit)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned getPointerWidth() {
|
||||||
|
if (is16BitMode()) return 16;
|
||||||
|
if (is32BitMode()) return 32;
|
||||||
|
if (is64BitMode()) return 64;
|
||||||
|
llvm_unreachable("invalid mode");
|
||||||
|
}
|
||||||
|
|
||||||
bool isParsingIntelSyntax() {
|
bool isParsingIntelSyntax() {
|
||||||
return getParser().getAssemblerDialect();
|
return getParser().getAssemblerDialect();
|
||||||
}
|
}
|
||||||
@ -982,15 +989,20 @@ std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm(
|
|||||||
unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg,
|
unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg,
|
||||||
unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier,
|
unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier,
|
||||||
InlineAsmIdentifierInfo &Info) {
|
InlineAsmIdentifierInfo &Info) {
|
||||||
// If this is not a VarDecl then assume it is a FuncDecl or some other label
|
// If we found a decl other than a VarDecl, then assume it is a FuncDecl or
|
||||||
// reference. We need an 'r' constraint here, so we need to create register
|
// some other label reference.
|
||||||
// operand to ensure proper matching. Just pick a GPR based on the size of
|
if (isa<MCSymbolRefExpr>(Disp) && Info.OpDecl && !Info.IsVarDecl) {
|
||||||
// a pointer.
|
// Insert an explicit size if the user didn't have one.
|
||||||
if (isa<MCSymbolRefExpr>(Disp) && !Info.IsVarDecl) {
|
if (!Size) {
|
||||||
unsigned RegNo =
|
Size = getPointerWidth();
|
||||||
is64BitMode() ? X86::RBX : (is32BitMode() ? X86::EBX : X86::BX);
|
InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_SizeDirective, Start,
|
||||||
return X86Operand::CreateReg(RegNo, Start, End, /*AddressOf=*/true,
|
/*Len=*/0, Size));
|
||||||
SMLoc(), Identifier, Info.OpDecl);
|
}
|
||||||
|
|
||||||
|
// Create an absolute memory reference in order to match against
|
||||||
|
// instructions taking a PC relative operand.
|
||||||
|
return X86Operand::CreateMem(Disp, Start, End, Size, Identifier,
|
||||||
|
Info.OpDecl);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We either have a direct symbol reference, or an offset from a symbol. The
|
// We either have a direct symbol reference, or an offset from a symbol. The
|
||||||
|
@ -110,7 +110,7 @@ define i32 @t31() {
|
|||||||
entry:
|
entry:
|
||||||
%val = alloca i32, align 64
|
%val = alloca i32, align 64
|
||||||
store i32 -1, i32* %val, align 64
|
store i32 -1, i32* %val, align 64
|
||||||
call void asm sideeffect inteldialect "mov dword ptr $0, esp", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %val) #1
|
call void asm sideeffect inteldialect "mov dword ptr $0, esp", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %val)
|
||||||
%sp = load i32* %val, align 64
|
%sp = load i32* %val, align 64
|
||||||
ret i32 %sp
|
ret i32 %sp
|
||||||
; CHECK-LABEL: t31:
|
; CHECK-LABEL: t31:
|
||||||
@ -125,3 +125,12 @@ entry:
|
|||||||
; CHECK: movl (%esp), %eax
|
; CHECK: movl (%esp), %eax
|
||||||
; CHECK: ret
|
; CHECK: ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare void @other_func()
|
||||||
|
|
||||||
|
define void @naked() #0 {
|
||||||
|
call void asm sideeffect inteldialect "call dword ptr $0", "*m,~{eax},~{ebx},~{ecx},~{edx},~{edi},~{esi},~{esp},~{ebp},~{dirflag},~{fpsr},~{flags}"(void()* @other_func)
|
||||||
|
unreachable
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes #0 = { naked }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user