Added some eye-candy for Subtarget type checking

Added X86 StdCall & FastCall calling conventions. Codegen will follow.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30446 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Anton Korobeynikov
2006-09-17 20:25:45 +00:00
parent 2f463865c2
commit bcb9770efe
18 changed files with 1782 additions and 1631 deletions

View File

@@ -1636,11 +1636,31 @@ that people test.</p>
<li><b>i386-unknown-freebsd5.3</b> - FreeBSD 5.3</li> <li><b>i386-unknown-freebsd5.3</b> - FreeBSD 5.3</li>
<li><b>i686-pc-cygwin</b> - Cygwin on Win32</li> <li><b>i686-pc-cygwin</b> - Cygwin on Win32</li>
<li><b>i686-pc-mingw32</b> - MingW on Win32</li> <li><b>i686-pc-mingw32</b> - MingW on Win32</li>
<li><b>i386-pc-mingw32msvc</b> - MingW crosscompiler on Linux</li>
<li><b>i686-apple-darwin*</b> - Apple Darwin on X86</li> <li><b>i686-apple-darwin*</b> - Apple Darwin on X86</li>
</ul> </ul>
</div> </div>
<!-- _______________________________________________________________________ -->
<div class="doc_subsubsection">
<a name="x86_cc">X86 Calling Conventions supported</a>
</div>
<div class="doc_text">
<p>The folowing target-specific calling conventions are known to backend:</p>
<ul>
<li><b>x86_StdCall</b> - stdcall calling convention seen on Microsoft Windows
platform (CC ID = 64).</li>
<li><b>x86_FastCall</b> - fastcall calling convention seen on Microsoft Windows
platform (CC ID = 65).</li>
</ul>
</div>
<!-- _______________________________________________________________________ --> <!-- _______________________________________________________________________ -->
<div class="doc_subsubsection"> <div class="doc_subsubsection">
<a name="x86_memory">Representing X86 addressing modes in MachineInstrs</a> <a name="x86_memory">Representing X86 addressing modes in MachineInstrs</a>

View File

@@ -24,10 +24,10 @@ namespace CallingConv {
/// calling conventions. /// calling conventions.
/// @brief LLVM Calling Convention Representation /// @brief LLVM Calling Convention Representation
enum ID { enum ID {
// C - The default llvm calling convention, compatible with C. This /// C - The default llvm calling convention, compatible with C. This
// convention is the only calling convention that supports varargs calls. /// convention is the only calling convention that supports varargs calls.
// As with typical C calling conventions, the callee/caller have to tolerate /// As with typical C calling conventions, the callee/caller have to tolerate
// certain amounts of prototype mismatch. /// certain amounts of prototype mismatch.
C = 0, C = 0,
/// CSRet - C Struct Return calling convention. This convention requires /// CSRet - C Struct Return calling convention. This convention requires
@@ -42,8 +42,8 @@ namespace CallingConv {
// support varargs calls, and all assume that the caller and callee // support varargs calls, and all assume that the caller and callee
// prototype exactly match. // prototype exactly match.
// Fast - This calling convention attempts to make calls as fast as possible /// Fast - This calling convention attempts to make calls as fast as possible
// (e.g. by passing things in registers). /// (e.g. by passing things in registers).
Fast = 8, Fast = 8,
// Cold - This calling convention attempts to make code in the caller as // Cold - This calling convention attempts to make code in the caller as
@@ -54,7 +54,18 @@ namespace CallingConv {
// Target - This is the start of the target-specific calling conventions, // Target - This is the start of the target-specific calling conventions,
// e.g. fastcall and thiscall on X86. // e.g. fastcall and thiscall on X86.
FirstTargetCC = 64 FirstTargetCC = 64,
/// X86_StdCall - stdcall is the calling conventions mostly used by the
/// Win32 API. It is basically the same as the C convention with the
/// difference in that the callee is responsible for popping the arguments
/// from the stack.
X86_StdCall = 64,
/// X86_FastCall - 'fast' analog of X86_StdCall. Passes first two arguments
/// in ECX:EDX registers, others - via stack. Callee is responsible for
/// stack cleaning.
X86_FastCall = 65
}; };
} // End CallingConv namespace } // End CallingConv namespace

File diff suppressed because it is too large Load Diff

View File

@@ -224,6 +224,8 @@ ccc { return CCC_TOK; }
csretcc { return CSRETCC_TOK; } csretcc { return CSRETCC_TOK; }
fastcc { return FASTCC_TOK; } fastcc { return FASTCC_TOK; }
coldcc { return COLDCC_TOK; } coldcc { return COLDCC_TOK; }
x86_stdcallcc { return X86_STDCALLCC_TOK; }
x86_fastcallcc { return X86_FASTCALLCC_TOK; }
void { llvmAsmlval.PrimType = Type::VoidTy ; return VOID; } void { llvmAsmlval.PrimType = Type::VoidTy ; return VOID; }
bool { llvmAsmlval.PrimType = Type::BoolTy ; return BOOL; } bool { llvmAsmlval.PrimType = Type::BoolTy ; return BOOL; }

View File

@@ -224,6 +224,8 @@ ccc { return CCC_TOK; }
csretcc { return CSRETCC_TOK; } csretcc { return CSRETCC_TOK; }
fastcc { return FASTCC_TOK; } fastcc { return FASTCC_TOK; }
coldcc { return COLDCC_TOK; } coldcc { return COLDCC_TOK; }
x86_stdcallcc { return X86_STDCALLCC_TOK; }
x86_fastcallcc { return X86_FASTCALLCC_TOK; }
void { llvmAsmlval.PrimType = Type::VoidTy ; return VOID; } void { llvmAsmlval.PrimType = Type::VoidTy ; return VOID; }
bool { llvmAsmlval.PrimType = Type::BoolTy ; return BOOL; } bool { llvmAsmlval.PrimType = Type::BoolTy ; return BOOL; }

File diff suppressed because it is too large Load Diff

View File

@@ -105,43 +105,45 @@
CSRETCC_TOK = 321, CSRETCC_TOK = 321,
FASTCC_TOK = 322, FASTCC_TOK = 322,
COLDCC_TOK = 323, COLDCC_TOK = 323,
RET = 324, X86_STDCALLCC_TOK = 324,
BR = 325, X86_FASTCALLCC_TOK = 325,
SWITCH = 326, RET = 326,
INVOKE = 327, BR = 327,
UNWIND = 328, SWITCH = 328,
UNREACHABLE = 329, INVOKE = 329,
ADD = 330, UNWIND = 330,
SUB = 331, UNREACHABLE = 331,
MUL = 332, ADD = 332,
DIV = 333, SUB = 333,
REM = 334, MUL = 334,
AND = 335, DIV = 335,
OR = 336, REM = 336,
XOR = 337, AND = 337,
SETLE = 338, OR = 338,
SETGE = 339, XOR = 339,
SETLT = 340, SETLE = 340,
SETGT = 341, SETGE = 341,
SETEQ = 342, SETLT = 342,
SETNE = 343, SETGT = 343,
MALLOC = 344, SETEQ = 344,
ALLOCA = 345, SETNE = 345,
FREE = 346, MALLOC = 346,
LOAD = 347, ALLOCA = 347,
STORE = 348, FREE = 348,
GETELEMENTPTR = 349, LOAD = 349,
PHI_TOK = 350, STORE = 350,
CAST = 351, GETELEMENTPTR = 351,
SELECT = 352, PHI_TOK = 352,
SHL = 353, CAST = 353,
SHR = 354, SELECT = 354,
VAARG = 355, SHL = 355,
EXTRACTELEMENT = 356, SHR = 356,
INSERTELEMENT = 357, VAARG = 357,
SHUFFLEVECTOR = 358, EXTRACTELEMENT = 358,
VAARG_old = 359, INSERTELEMENT = 359,
VANEXT_old = 360 SHUFFLEVECTOR = 360,
VAARG_old = 361,
VANEXT_old = 362
}; };
#endif #endif
/* Tokens. */ /* Tokens. */
@@ -211,43 +213,45 @@
#define CSRETCC_TOK 321 #define CSRETCC_TOK 321
#define FASTCC_TOK 322 #define FASTCC_TOK 322
#define COLDCC_TOK 323 #define COLDCC_TOK 323
#define RET 324 #define X86_STDCALLCC_TOK 324
#define BR 325 #define X86_FASTCALLCC_TOK 325
#define SWITCH 326 #define RET 326
#define INVOKE 327 #define BR 327
#define UNWIND 328 #define SWITCH 328
#define UNREACHABLE 329 #define INVOKE 329
#define ADD 330 #define UNWIND 330
#define SUB 331 #define UNREACHABLE 331
#define MUL 332 #define ADD 332
#define DIV 333 #define SUB 333
#define REM 334 #define MUL 334
#define AND 335 #define DIV 335
#define OR 336 #define REM 336
#define XOR 337 #define AND 337
#define SETLE 338 #define OR 338
#define SETGE 339 #define XOR 339
#define SETLT 340 #define SETLE 340
#define SETGT 341 #define SETGE 341
#define SETEQ 342 #define SETLT 342
#define SETNE 343 #define SETGT 343
#define MALLOC 344 #define SETEQ 344
#define ALLOCA 345 #define SETNE 345
#define FREE 346 #define MALLOC 346
#define LOAD 347 #define ALLOCA 347
#define STORE 348 #define FREE 348
#define GETELEMENTPTR 349 #define LOAD 349
#define PHI_TOK 350 #define STORE 350
#define CAST 351 #define GETELEMENTPTR 351
#define SELECT 352 #define PHI_TOK 352
#define SHL 353 #define CAST 353
#define SHR 354 #define SELECT 354
#define VAARG 355 #define SHL 355
#define EXTRACTELEMENT 356 #define SHR 356
#define INSERTELEMENT 357 #define VAARG 357
#define SHUFFLEVECTOR 358 #define EXTRACTELEMENT 358
#define VAARG_old 359 #define INSERTELEMENT 359
#define VANEXT_old 360 #define SHUFFLEVECTOR 360
#define VAARG_old 361
#define VANEXT_old 362
@@ -295,7 +299,7 @@ typedef union YYSTYPE
llvm::Module::Endianness Endianness; llvm::Module::Endianness Endianness;
} }
/* Line 1528 of yacc.c. */ /* Line 1528 of yacc.c. */
#line 299 "llvmAsmParser.tab.h" #line 303 "llvmAsmParser.tab.h"
YYSTYPE; YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_DECLARED 1

View File

@@ -1006,6 +1006,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
%token OPAQUE NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG ALIGN %token OPAQUE NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG ALIGN
%token DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT %token DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
%token CC_TOK CCC_TOK CSRETCC_TOK FASTCC_TOK COLDCC_TOK %token CC_TOK CCC_TOK CSRETCC_TOK FASTCC_TOK COLDCC_TOK
%token X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
%type <UIntVal> OptCallingConv %type <UIntVal> OptCallingConv
// Basic Block Terminating Operators // Basic Block Terminating Operators
@@ -1083,12 +1084,14 @@ OptLinkage : INTERNAL { $$ = GlobalValue::InternalLinkage; } |
EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; } | EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; } |
/*empty*/ { $$ = GlobalValue::ExternalLinkage; }; /*empty*/ { $$ = GlobalValue::ExternalLinkage; };
OptCallingConv : /*empty*/ { $$ = CallingConv::C; } | OptCallingConv : /*empty*/ { $$ = CallingConv::C; } |
CCC_TOK { $$ = CallingConv::C; } | CCC_TOK { $$ = CallingConv::C; } |
CSRETCC_TOK { $$ = CallingConv::CSRet; } | CSRETCC_TOK { $$ = CallingConv::CSRet; } |
FASTCC_TOK { $$ = CallingConv::Fast; } | FASTCC_TOK { $$ = CallingConv::Fast; } |
COLDCC_TOK { $$ = CallingConv::Cold; } | COLDCC_TOK { $$ = CallingConv::Cold; } |
CC_TOK EUINT64VAL { X86_STDCALLCC_TOK { $$ = CallingConv::X86_StdCall; } |
X86_FASTCALLCC_TOK { $$ = CallingConv::X86_FastCall; } |
CC_TOK EUINT64VAL {
if ((unsigned)$2 != $2) if ((unsigned)$2 != $2)
GEN_ERROR("Calling conv too large!"); GEN_ERROR("Calling conv too large!");
$$ = $2; $$ = $2;

View File

@@ -1006,6 +1006,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
%token OPAQUE NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG ALIGN %token OPAQUE NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG ALIGN
%token DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT %token DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
%token CC_TOK CCC_TOK CSRETCC_TOK FASTCC_TOK COLDCC_TOK %token CC_TOK CCC_TOK CSRETCC_TOK FASTCC_TOK COLDCC_TOK
%token X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
%type <UIntVal> OptCallingConv %type <UIntVal> OptCallingConv
// Basic Block Terminating Operators // Basic Block Terminating Operators
@@ -1083,12 +1084,14 @@ OptLinkage : INTERNAL { $$ = GlobalValue::InternalLinkage; } |
EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; } | EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; } |
/*empty*/ { $$ = GlobalValue::ExternalLinkage; }; /*empty*/ { $$ = GlobalValue::ExternalLinkage; };
OptCallingConv : /*empty*/ { $$ = CallingConv::C; } | OptCallingConv : /*empty*/ { $$ = CallingConv::C; } |
CCC_TOK { $$ = CallingConv::C; } | CCC_TOK { $$ = CallingConv::C; } |
CSRETCC_TOK { $$ = CallingConv::CSRet; } | CSRETCC_TOK { $$ = CallingConv::CSRet; } |
FASTCC_TOK { $$ = CallingConv::Fast; } | FASTCC_TOK { $$ = CallingConv::Fast; } |
COLDCC_TOK { $$ = CallingConv::Cold; } | COLDCC_TOK { $$ = CallingConv::Cold; } |
CC_TOK EUINT64VAL { X86_STDCALLCC_TOK { $$ = CallingConv::X86_StdCall; } |
X86_FASTCALLCC_TOK { $$ = CallingConv::X86_FastCall; } |
CC_TOK EUINT64VAL {
if ((unsigned)$2 != $2) if ((unsigned)$2 != $2)
GEN_ERROR("Calling conv too large!"); GEN_ERROR("Calling conv too large!");
$$ = $2; $$ = $2;

View File

@@ -1278,7 +1278,15 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
if (F->hasInternalLinkage()) Out << "static "; if (F->hasInternalLinkage()) Out << "static ";
if (F->hasDLLImportLinkage()) Out << "__declspec(dllimport) "; if (F->hasDLLImportLinkage()) Out << "__declspec(dllimport) ";
if (F->hasDLLExportLinkage()) Out << "__declspec(dllexport) "; if (F->hasDLLExportLinkage()) Out << "__declspec(dllexport) ";
switch (F->getCallingConv()) {
case CallingConv::X86_StdCall:
Out << "__stdcall ";
break;
case CallingConv::X86_FastCall:
Out << "__fastcall ";
break;
}
// Loop over the arguments, printing them... // Loop over the arguments, printing them...
const FunctionType *FT = cast<FunctionType>(F->getFunctionType()); const FunctionType *FT = cast<FunctionType>(F->getFunctionType());

View File

@@ -1278,7 +1278,15 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
if (F->hasInternalLinkage()) Out << "static "; if (F->hasInternalLinkage()) Out << "static ";
if (F->hasDLLImportLinkage()) Out << "__declspec(dllimport) "; if (F->hasDLLImportLinkage()) Out << "__declspec(dllimport) ";
if (F->hasDLLExportLinkage()) Out << "__declspec(dllexport) "; if (F->hasDLLExportLinkage()) Out << "__declspec(dllexport) ";
switch (F->getCallingConv()) {
case CallingConv::X86_StdCall:
Out << "__stdcall ";
break;
case CallingConv::X86_FastCall:
Out << "__fastcall ";
break;
}
// Loop over the arguments, printing them... // Loop over the arguments, printing them...
const FunctionType *FT = cast<FunctionType>(F->getFunctionType()); const FunctionType *FT = cast<FunctionType>(F->getFunctionType());

View File

@@ -707,3 +707,29 @@ etc.
//===---------------------------------------------------------------------===// //===---------------------------------------------------------------------===//
Currently we don't have elimination of redundant stack manipulations. Consider
the code:
int %main() {
entry:
call fastcc void %test1( )
call fastcc void %test2( sbyte* cast (void ()* %test1 to sbyte*) )
ret int 0
}
declare fastcc void %test1()
declare fastcc void %test2(sbyte*)
This currently compiles to:
subl $16, %esp
call _test5
addl $12, %esp
subl $16, %esp
movl $_test5, (%esp)
call _test6
addl $12, %esp
The add\sub pair is really unneeded here.

View File

@@ -63,7 +63,7 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
".section __TEXT,__textcoal_nt,coalesced,pure_instructions", F); ".section __TEXT,__textcoal_nt,coalesced,pure_instructions", F);
O << "\t.globl\t" << CurrentFnName << "\n"; O << "\t.globl\t" << CurrentFnName << "\n";
O << "\t.weak_definition\t" << CurrentFnName << "\n"; O << "\t.weak_definition\t" << CurrentFnName << "\n";
} else if (Subtarget->TargetType == X86Subtarget::isCygwin) { } else if (Subtarget->isTargetCygwin()) {
EmitAlignment(4, F); // FIXME: This should be parameterized somewhere. EmitAlignment(4, F); // FIXME: This should be parameterized somewhere.
O << "\t.section\t.llvm.linkonce.t." << CurrentFnName O << "\t.section\t.llvm.linkonce.t." << CurrentFnName
<< ",\"ax\"\n"; << ",\"ax\"\n";

View File

@@ -83,7 +83,7 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
} else } else
O << TAI->getCOMMDirective() << name << "," << Size; O << TAI->getCOMMDirective() << name << "," << Size;
} else { } else {
if (Subtarget->TargetType != X86Subtarget::isCygwin) { if (!Subtarget->isTargetCygwin()) {
if (I->hasInternalLinkage()) if (I->hasInternalLinkage())
O << "\t.local\t" << name << "\n"; O << "\t.local\t" << name << "\n";
} }
@@ -101,7 +101,7 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
O << "\t.globl " << name << "\n" O << "\t.globl " << name << "\n"
<< "\t.weak_definition " << name << "\n"; << "\t.weak_definition " << name << "\n";
SwitchToDataSection(".section __DATA,__const_coal,coalesced", I); SwitchToDataSection(".section __DATA,__const_coal,coalesced", I);
} else if (Subtarget->TargetType == X86Subtarget::isCygwin) { } else if (Subtarget->isTargetCygwin()) {
O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\"\n" O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\"\n"
<< "\t.weak " << name << "\n"; << "\t.weak " << name << "\n";
} else { } else {

View File

@@ -468,7 +468,7 @@ void X86DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
/// the main function. /// the main function.
void X86DAGToDAGISel::EmitSpecialCodeForMain(MachineBasicBlock *BB, void X86DAGToDAGISel::EmitSpecialCodeForMain(MachineBasicBlock *BB,
MachineFrameInfo *MFI) { MachineFrameInfo *MFI) {
if (Subtarget->TargetType == X86Subtarget::isCygwin) if (Subtarget->isTargetCygwin())
BuildMI(BB, X86::CALLpcrel32, 1).addExternalSymbol("__main"); BuildMI(BB, X86::CALLpcrel32, 1).addExternalSymbol("__main");
// Switch the FPU to 64-bit precision mode for better compatibility and speed. // Switch the FPU to 64-bit precision mode for better compatibility and speed.

View File

@@ -3907,7 +3907,7 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) {
MachineFunction &MF = DAG.getMachineFunction(); MachineFunction &MF = DAG.getMachineFunction();
const Function* Fn = MF.getFunction(); const Function* Fn = MF.getFunction();
if (Fn->hasExternalLinkage() && if (Fn->hasExternalLinkage() &&
Subtarget->TargetType == X86Subtarget::isCygwin && Subtarget->isTargetCygwin() &&
Fn->getName() == "main") Fn->getName() == "main")
MF.getInfo<X86FunctionInfo>()->setForceFramePointer(true); MF.getInfo<X86FunctionInfo>()->setForceFramePointer(true);

View File

@@ -993,7 +993,7 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
MFI->setStackSize(NumBytes); MFI->setStackSize(NumBytes);
if (NumBytes) { // adjust stack pointer: ESP -= numbytes if (NumBytes) { // adjust stack pointer: ESP -= numbytes
if (NumBytes >= 4096 && Subtarget->TargetType == X86Subtarget::isCygwin) { if (NumBytes >= 4096 && Subtarget->isTargetCygwin()) {
// Function prologue calls _alloca to probe the stack when allocating // Function prologue calls _alloca to probe the stack when allocating
// more than 4k bytes in one go. Touching the stack at 4K increments is // more than 4k bytes in one go. Touching the stack at 4K increments is
// necessary to ensure that the guard pages used by the OS virtual memory // necessary to ensure that the guard pages used by the OS virtual memory
@@ -1035,7 +1035,7 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
// If it's main() on Cygwin\Mingw32 we should align stack as well // If it's main() on Cygwin\Mingw32 we should align stack as well
if (Fn->hasExternalLinkage() && Fn->getName() == "main" && if (Fn->hasExternalLinkage() && Fn->getName() == "main" &&
Subtarget->TargetType == X86Subtarget::isCygwin) { Subtarget->isTargetCygwin()) {
MI = BuildMI(X86::AND32ri, 2, X86::ESP).addReg(X86::ESP).addImm(-Align); MI = BuildMI(X86::AND32ri, 2, X86::ESP).addReg(X86::ESP).addImm(-Align);
MBB.insert(MBBI, MI); MBB.insert(MBBI, MI);

View File

@@ -332,6 +332,7 @@ void Verifier::visitFunction(Function &F) {
break; break;
case CallingConv::Fast: case CallingConv::Fast:
case CallingConv::Cold: case CallingConv::Cold:
case CallingConv::X86_FastCall:
Assert1(!F.isVarArg(), Assert1(!F.isVarArg(),
"Varargs functions must have C calling conventions!", &F); "Varargs functions must have C calling conventions!", &F);
break; break;