@@ -526,6 +526,14 @@ static llvm::Type* X86AdjustInlineAsmType(CodeGen::CodeGenFunction &CGF,
526
526
// X86-32 ABI Implementation
527
527
// ===----------------------------------------------------------------------===//
528
528
529
+ // / \brief Similar to llvm::CCState, but for Clang.
530
+ struct CCState {
531
+ CCState (unsigned CC) : CC(CC), FreeRegs(0 ) {}
532
+
533
+ unsigned CC;
534
+ unsigned FreeRegs;
535
+ };
536
+
529
537
// / X86_32ABIInfo - The X86-32 ABI information.
530
538
class X86_32ABIInfo : public ABIInfo {
531
539
enum Class {
@@ -549,19 +557,17 @@ class X86_32ABIInfo : public ABIInfo {
549
557
550
558
// / getIndirectResult - Give a source type \arg Ty, return a suitable result
551
559
// / such that the argument will be passed in memory.
552
- ABIArgInfo getIndirectResult (QualType Ty, bool ByVal,
553
- unsigned &FreeRegs) const ;
560
+ ABIArgInfo getIndirectResult (QualType Ty, bool ByVal, CCState &State) const ;
561
+
562
+ ABIArgInfo getIndirectReturnResult (CCState &State) const ;
554
563
555
564
// / \brief Return the alignment to use for the given type on the stack.
556
565
unsigned getTypeStackAlignInBytes (QualType Ty, unsigned Align) const ;
557
566
558
567
Class classify (QualType Ty) const ;
559
- ABIArgInfo classifyReturnType (QualType RetTy,
560
- unsigned callingConvention) const ;
561
- ABIArgInfo classifyArgumentType (QualType RetTy, unsigned &FreeRegs,
562
- bool IsFastCall) const ;
563
- bool shouldUseInReg (QualType Ty, unsigned &FreeRegs,
564
- bool IsFastCall, bool &NeedsPadding) const ;
568
+ ABIArgInfo classifyReturnType (QualType RetTy, CCState &State) const ;
569
+ ABIArgInfo classifyArgumentType (QualType RetTy, CCState &State) const ;
570
+ bool shouldUseInReg (QualType Ty, CCState &State, bool &NeedsPadding) const ;
565
571
566
572
public:
567
573
@@ -677,8 +683,18 @@ bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty,
677
683
return true ;
678
684
}
679
685
680
- ABIArgInfo X86_32ABIInfo::classifyReturnType (QualType RetTy,
681
- unsigned callingConvention) const {
686
+ ABIArgInfo X86_32ABIInfo::getIndirectReturnResult (CCState &State) const {
687
+ // If the return value is indirect, then the hidden argument is consuming one
688
+ // integer register.
689
+ if (State.FreeRegs ) {
690
+ --State.FreeRegs ;
691
+ return ABIArgInfo::getIndirectInReg (/* Align=*/ 0 , /* ByVal=*/ false );
692
+ }
693
+ return ABIArgInfo::getIndirect (/* Align=*/ 0 , /* ByVal=*/ false );
694
+ }
695
+
696
+ ABIArgInfo X86_32ABIInfo::classifyReturnType (QualType RetTy,
697
+ CCState &State) const {
682
698
if (RetTy->isVoidType ())
683
699
return ABIArgInfo::getIgnore ();
684
700
@@ -701,7 +717,7 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
701
717
return ABIArgInfo::getDirect (llvm::IntegerType::get (getVMContext (),
702
718
Size));
703
719
704
- return ABIArgInfo::getIndirect ( 0 );
720
+ return getIndirectReturnResult (State );
705
721
}
706
722
707
723
return ABIArgInfo::getDirect ();
@@ -710,21 +726,21 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
710
726
if (isAggregateTypeForABI (RetTy)) {
711
727
if (const RecordType *RT = RetTy->getAs <RecordType>()) {
712
728
if (isRecordReturnIndirect (RT, getCXXABI ()))
713
- return ABIArgInfo::getIndirect ( 0 , /* ByVal= */ false );
729
+ return getIndirectReturnResult (State );
714
730
715
731
// Structures with flexible arrays are always indirect.
716
732
if (RT->getDecl ()->hasFlexibleArrayMember ())
717
- return ABIArgInfo::getIndirect ( 0 );
733
+ return getIndirectReturnResult (State );
718
734
}
719
735
720
736
// If specified, structs and unions are always indirect.
721
737
if (!IsSmallStructInRegABI && !RetTy->isAnyComplexType ())
722
- return ABIArgInfo::getIndirect ( 0 );
738
+ return getIndirectReturnResult (State );
723
739
724
740
// Small structures which are register sized are generally returned
725
741
// in a register.
726
- if (X86_32ABIInfo::shouldReturnTypeInRegister (RetTy, getContext (),
727
- callingConvention )) {
742
+ if (X86_32ABIInfo::shouldReturnTypeInRegister (RetTy, getContext (),
743
+ State. CC )) {
728
744
uint64_t Size = getContext ().getTypeSize (RetTy);
729
745
730
746
// As a special-case, if the struct is a "single-element" struct, and
@@ -742,7 +758,7 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
742
758
return ABIArgInfo::getDirect (llvm::IntegerType::get (getVMContext (),Size));
743
759
}
744
760
745
- return ABIArgInfo::getIndirect ( 0 );
761
+ return getIndirectReturnResult (State );
746
762
}
747
763
748
764
// Treat an enum type as its underlying type.
@@ -806,10 +822,10 @@ unsigned X86_32ABIInfo::getTypeStackAlignInBytes(QualType Ty,
806
822
}
807
823
808
824
ABIArgInfo X86_32ABIInfo::getIndirectResult (QualType Ty, bool ByVal,
809
- unsigned &FreeRegs ) const {
825
+ CCState &State ) const {
810
826
if (!ByVal) {
811
- if (FreeRegs) {
812
- --FreeRegs; // Non-byval indirects just use one pointer.
827
+ if (State. FreeRegs ) {
828
+ --State. FreeRegs ; // Non-byval indirects just use one pointer.
813
829
return ABIArgInfo::getIndirectInReg (0 , false );
814
830
}
815
831
return ABIArgInfo::getIndirect (0 , false );
@@ -843,8 +859,8 @@ X86_32ABIInfo::Class X86_32ABIInfo::classify(QualType Ty) const {
843
859
return Integer;
844
860
}
845
861
846
- bool X86_32ABIInfo::shouldUseInReg (QualType Ty, unsigned &FreeRegs ,
847
- bool IsFastCall, bool &NeedsPadding) const {
862
+ bool X86_32ABIInfo::shouldUseInReg (QualType Ty, CCState &State ,
863
+ bool &NeedsPadding) const {
848
864
NeedsPadding = false ;
849
865
Class C = classify (Ty);
850
866
if (C == Float)
@@ -856,14 +872,14 @@ bool X86_32ABIInfo::shouldUseInReg(QualType Ty, unsigned &FreeRegs,
856
872
if (SizeInRegs == 0 )
857
873
return false ;
858
874
859
- if (SizeInRegs > FreeRegs) {
860
- FreeRegs = 0 ;
875
+ if (SizeInRegs > State. FreeRegs ) {
876
+ State. FreeRegs = 0 ;
861
877
return false ;
862
878
}
863
879
864
- FreeRegs -= SizeInRegs;
880
+ State. FreeRegs -= SizeInRegs;
865
881
866
- if (IsFastCall ) {
882
+ if (State. CC == llvm::CallingConv::X86_FastCall ) {
867
883
if (Size > 32 )
868
884
return false ;
869
885
@@ -876,7 +892,7 @@ bool X86_32ABIInfo::shouldUseInReg(QualType Ty, unsigned &FreeRegs,
876
892
if (Ty->isReferenceType ())
877
893
return true ;
878
894
879
- if (FreeRegs)
895
+ if (State. FreeRegs )
880
896
NeedsPadding = true ;
881
897
882
898
return false ;
@@ -885,21 +901,20 @@ bool X86_32ABIInfo::shouldUseInReg(QualType Ty, unsigned &FreeRegs,
885
901
return true ;
886
902
}
887
903
888
- ABIArgInfo X86_32ABIInfo::classifyArgumentType (QualType Ty,
889
- unsigned &FreeRegs,
890
- bool IsFastCall) const {
904
+ ABIArgInfo X86_32ABIInfo::classifyArgumentType (QualType Ty, CCState &State) const {
891
905
// FIXME: Set alignment on indirect arguments.
892
906
if (isAggregateTypeForABI (Ty)) {
893
907
if (const RecordType *RT = Ty->getAs <RecordType>()) {
894
908
if (IsWin32StructABI)
895
- return getIndirectResult (Ty, true , FreeRegs );
909
+ return getIndirectResult (Ty, true , State );
896
910
897
911
if (CGCXXABI::RecordArgABI RAA = getRecordArgABI (RT, getCXXABI ()))
898
- return getIndirectResult (Ty, RAA == CGCXXABI::RAA_DirectInMemory, FreeRegs);
912
+ return getIndirectResult (Ty, RAA == CGCXXABI::RAA_DirectInMemory,
913
+ State);
899
914
900
915
// Structures with flexible arrays are always indirect.
901
916
if (RT->getDecl ()->hasFlexibleArrayMember ())
902
- return getIndirectResult (Ty, true , FreeRegs );
917
+ return getIndirectResult (Ty, true , State );
903
918
}
904
919
905
920
// Ignore empty structs/unions.
@@ -909,7 +924,7 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
909
924
llvm::LLVMContext &LLVMContext = getVMContext ();
910
925
llvm::IntegerType *Int32 = llvm::Type::getInt32Ty (LLVMContext);
911
926
bool NeedsPadding;
912
- if (shouldUseInReg (Ty, FreeRegs, IsFastCall , NeedsPadding)) {
927
+ if (shouldUseInReg (Ty, State , NeedsPadding)) {
913
928
unsigned SizeInRegs = (getContext ().getTypeSize (Ty) + 31 ) / 32 ;
914
929
SmallVector<llvm::Type*, 3 > Elements (SizeInRegs, Int32);
915
930
llvm::Type *Result = llvm::StructType::get (LLVMContext, Elements);
@@ -923,9 +938,10 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
923
938
// optimizations.
924
939
if (getContext ().getTypeSize (Ty) <= 4 *32 &&
925
940
canExpandIndirectArgument (Ty, getContext ()))
926
- return ABIArgInfo::getExpandWithPadding (IsFastCall, PaddingType);
941
+ return ABIArgInfo::getExpandWithPadding (
942
+ State.CC == llvm::CallingConv::X86_FastCall, PaddingType);
927
943
928
- return getIndirectResult (Ty, true , FreeRegs );
944
+ return getIndirectResult (Ty, true , State );
929
945
}
930
946
931
947
if (const VectorType *VT = Ty->getAs <VectorType>()) {
@@ -950,7 +966,7 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
950
966
Ty = EnumTy->getDecl ()->getIntegerType ();
951
967
952
968
bool NeedsPadding;
953
- bool InReg = shouldUseInReg (Ty, FreeRegs, IsFastCall , NeedsPadding);
969
+ bool InReg = shouldUseInReg (Ty, State , NeedsPadding);
954
970
955
971
if (Ty->isPromotableIntegerType ()) {
956
972
if (InReg)
@@ -963,32 +979,19 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
963
979
}
964
980
965
981
void X86_32ABIInfo::computeInfo (CGFunctionInfo &FI) const {
966
- FI.getReturnInfo () = classifyReturnType (FI.getReturnType (),
967
- FI.getCallingConvention ());
968
-
969
- unsigned CC = FI.getCallingConvention ();
970
- bool IsFastCall = CC == llvm::CallingConv::X86_FastCall;
971
- unsigned FreeRegs;
972
- if (IsFastCall)
973
- FreeRegs = 2 ;
982
+ CCState State (FI.getCallingConvention ());
983
+ if (State.CC == llvm::CallingConv::X86_FastCall)
984
+ State.FreeRegs = 2 ;
974
985
else if (FI.getHasRegParm ())
975
- FreeRegs = FI.getRegParm ();
986
+ State. FreeRegs = FI.getRegParm ();
976
987
else
977
- FreeRegs = DefaultNumRegisterParameters;
988
+ State. FreeRegs = DefaultNumRegisterParameters;
978
989
979
- // If the return value is indirect, then the hidden argument is consuming one
980
- // integer register.
981
- if (FI.getReturnInfo ().isIndirect () && FreeRegs) {
982
- --FreeRegs;
983
- ABIArgInfo &Old = FI.getReturnInfo ();
984
- Old = ABIArgInfo::getIndirectInReg (Old.getIndirectAlign (),
985
- Old.getIndirectByVal (),
986
- Old.getIndirectRealign ());
987
- }
990
+ FI.getReturnInfo () = classifyReturnType (FI.getReturnType (), State);
988
991
989
992
for (CGFunctionInfo::arg_iterator it = FI.arg_begin (), ie = FI.arg_end ();
990
993
it != ie; ++it)
991
- it->info = classifyArgumentType (it->type , FreeRegs, IsFastCall );
994
+ it->info = classifyArgumentType (it->type , State );
992
995
}
993
996
994
997
llvm::Value *X86_32ABIInfo::EmitVAArg (llvm::Value *VAListAddr, QualType Ty,
0 commit comments