@@ -3843,6 +3843,43 @@ class X86BaseCallingConvention: public CallingConvention
38433843};
38443844
38453845
3846+ class X86SystemVCallingConvention : public X86BaseCallingConvention
3847+ {
3848+ public:
3849+ X86SystemVCallingConvention (Architecture* arch): X86BaseCallingConvention(arch, " sysv" )
3850+ {
3851+ }
3852+
3853+ bool IsReturnTypeRegisterCompatible (Type* type) override
3854+ {
3855+ if (!type)
3856+ return false ;
3857+ if (type->IsFloat ())
3858+ return true ;
3859+ if (type->IsStructure () || type->IsArray ())
3860+ return false ;
3861+ if (type->GetWidth () == 0 || type->GetWidth () == 1 || type->GetWidth () == 2 || type->GetWidth () == 4
3862+ || type->GetWidth () == 8 )
3863+ return true ;
3864+ return false ;
3865+ }
3866+
3867+ int64_t GetStackAdjustmentForLocations (const std::optional<ValueLocation>& returnValue,
3868+ const vector<ValueLocation>&, const vector<Ref<Type>>&) override
3869+ {
3870+ if (!returnValue.has_value ())
3871+ return 0 ;
3872+ for (auto & component: returnValue->components )
3873+ {
3874+ // Indirect return values have the pointer popped off the stack by the called function
3875+ if (component.indirect )
3876+ return 4 ;
3877+ }
3878+ return 0 ;
3879+ }
3880+ };
3881+
3882+
38463883class X86CdeclCallingConvention : public X86BaseCallingConvention
38473884{
38483885public:
@@ -3866,17 +3903,68 @@ class X86StdcallCallingConvention: public X86BaseCallingConvention
38663903};
38673904
38683905
3906+ class X86SystemVStdcallCallingConvention : public X86BaseCallingConvention
3907+ {
3908+ public:
3909+ X86SystemVStdcallCallingConvention (Architecture* arch): X86BaseCallingConvention(arch, " sysv-stdcall" )
3910+ {
3911+ }
3912+
3913+ bool IsStackAdjustedOnReturn () override
3914+ {
3915+ return true ;
3916+ }
3917+
3918+ bool IsReturnTypeRegisterCompatible (Type* type) override
3919+ {
3920+ if (!type)
3921+ return false ;
3922+ if (type->IsFloat ())
3923+ return true ;
3924+ if (type->IsStructure () || type->IsArray ())
3925+ return false ;
3926+ if (type->GetWidth () == 0 || type->GetWidth () == 1 || type->GetWidth () == 2 || type->GetWidth () == 4
3927+ || type->GetWidth () == 8 )
3928+ return true ;
3929+ return false ;
3930+ }
3931+ };
3932+
3933+
38693934class X86RegParmCallingConvention : public X86BaseCallingConvention
38703935{
38713936public:
38723937 X86RegParmCallingConvention (Architecture* arch): X86BaseCallingConvention(arch, " regparm" )
38733938 {
38743939 }
38753940
3876- virtual vector<uint32_t > GetIntegerArgumentRegisters () override
3941+ vector<uint32_t > GetIntegerArgumentRegisters () override
38773942 {
38783943 return vector<uint32_t >{ XED_REG_EAX, XED_REG_EDX, XED_REG_ECX };
38793944 }
3945+
3946+ bool IsReturnTypeRegisterCompatible (Type* type) override
3947+ {
3948+ if (!type)
3949+ return false ;
3950+ if (type->IsFloat ())
3951+ return true ;
3952+ if (type->IsStructure () || type->IsArray ())
3953+ return false ;
3954+ if (type->GetWidth () == 0 || type->GetWidth () == 1 || type->GetWidth () == 2 || type->GetWidth () == 4
3955+ || type->GetWidth () == 8 )
3956+ return true ;
3957+ return false ;
3958+ }
3959+
3960+ bool IsArgumentTypeRegisterCompatible (Type* type) override
3961+ {
3962+ if (!type)
3963+ return false ;
3964+ if (type->IsFloat ())
3965+ return true ;
3966+ return type->GetWidth () <= 12 ;
3967+ }
38803968};
38813969
38823970
@@ -3899,6 +3987,82 @@ class X86FastcallCallingConvention: public X86BaseCallingConvention
38993987};
39003988
39013989
3990+ class X86GCCFastcallCallingConvention : public X86BaseCallingConvention
3991+ {
3992+ public:
3993+ X86GCCFastcallCallingConvention (Architecture* arch): X86BaseCallingConvention(arch, " gcc-fastcall" )
3994+ {
3995+ }
3996+
3997+ vector<uint32_t > GetIntegerArgumentRegisters () override
3998+ {
3999+ return vector<uint32_t >{ XED_REG_ECX, XED_REG_EDX };
4000+ }
4001+
4002+ bool IsStackAdjustedOnReturn () override
4003+ {
4004+ return true ;
4005+ }
4006+
4007+ bool IsReturnTypeRegisterCompatible (Type* type) override
4008+ {
4009+ if (!type)
4010+ return false ;
4011+ if (type->IsFloat ())
4012+ return true ;
4013+ if (type->IsStructure () || type->IsArray ())
4014+ return false ;
4015+ if (type->GetWidth () == 0 || type->GetWidth () == 1 || type->GetWidth () == 2 || type->GetWidth () == 4
4016+ || type->GetWidth () == 8 )
4017+ return true ;
4018+ return false ;
4019+ }
4020+
4021+ Variable GetIndirectReturnValueLocation () override
4022+ {
4023+ return Variable::Register (XED_REG_ECX);
4024+ }
4025+ };
4026+
4027+
4028+ class X86ClangFastcallCallingConvention : public X86BaseCallingConvention
4029+ {
4030+ public:
4031+ X86ClangFastcallCallingConvention (Architecture* arch): X86BaseCallingConvention(arch, " clang-fastcall" )
4032+ {
4033+ }
4034+
4035+ vector<uint32_t > GetIntegerArgumentRegisters () override
4036+ {
4037+ return vector<uint32_t >{ XED_REG_ECX, XED_REG_EDX };
4038+ }
4039+
4040+ bool IsStackAdjustedOnReturn () override
4041+ {
4042+ return true ;
4043+ }
4044+
4045+ bool IsReturnTypeRegisterCompatible (Type* type) override
4046+ {
4047+ if (!type)
4048+ return false ;
4049+ if (type->IsFloat ())
4050+ return true ;
4051+ if (type->IsStructure () || type->IsArray ())
4052+ return false ;
4053+ if (type->GetWidth () == 0 || type->GetWidth () == 1 || type->GetWidth () == 2 || type->GetWidth () == 4
4054+ || type->GetWidth () == 8 )
4055+ return true ;
4056+ return false ;
4057+ }
4058+
4059+ Variable GetIndirectReturnValueLocation () override
4060+ {
4061+ return Variable::StackOffset (4 );
4062+ }
4063+ };
4064+
4065+
39024066class X86ThiscallCallingConvention : public X86BaseCallingConvention
39034067{
39044068public:
@@ -3923,6 +4087,92 @@ class X86ThiscallCallingConvention: public X86BaseCallingConvention
39234087};
39244088
39254089
4090+ class X86GCCThiscallCallingConvention : public X86BaseCallingConvention
4091+ {
4092+ public:
4093+ X86GCCThiscallCallingConvention (Architecture* arch): X86BaseCallingConvention(arch, " gcc-thiscall" )
4094+ {
4095+ }
4096+
4097+ vector<uint32_t > GetIntegerArgumentRegisters () override
4098+ {
4099+ return vector<uint32_t >{ XED_REG_ECX };
4100+ }
4101+
4102+ vector<uint32_t > GetRequiredArgumentRegisters () override
4103+ {
4104+ return vector<uint32_t >{ XED_REG_ECX };
4105+ }
4106+
4107+ bool IsStackAdjustedOnReturn () override
4108+ {
4109+ return true ;
4110+ }
4111+
4112+ bool IsReturnTypeRegisterCompatible (Type* type) override
4113+ {
4114+ if (!type)
4115+ return false ;
4116+ if (type->IsFloat ())
4117+ return true ;
4118+ if (type->IsStructure () || type->IsArray ())
4119+ return false ;
4120+ if (type->GetWidth () == 0 || type->GetWidth () == 1 || type->GetWidth () == 2 || type->GetWidth () == 4
4121+ || type->GetWidth () == 8 )
4122+ return true ;
4123+ return false ;
4124+ }
4125+
4126+ Variable GetIndirectReturnValueLocation () override
4127+ {
4128+ return Variable::Register (XED_REG_ECX);
4129+ }
4130+ };
4131+
4132+
4133+ class X86ClangThiscallCallingConvention : public X86BaseCallingConvention
4134+ {
4135+ public:
4136+ X86ClangThiscallCallingConvention (Architecture* arch): X86BaseCallingConvention(arch, " clang-thiscall" )
4137+ {
4138+ }
4139+
4140+ vector<uint32_t > GetIntegerArgumentRegisters () override
4141+ {
4142+ return vector<uint32_t >{ XED_REG_ECX };
4143+ }
4144+
4145+ vector<uint32_t > GetRequiredArgumentRegisters () override
4146+ {
4147+ return vector<uint32_t >{ XED_REG_ECX };
4148+ }
4149+
4150+ bool IsStackAdjustedOnReturn () override
4151+ {
4152+ return true ;
4153+ }
4154+
4155+ bool IsReturnTypeRegisterCompatible (Type* type) override
4156+ {
4157+ if (!type)
4158+ return false ;
4159+ if (type->IsFloat ())
4160+ return true ;
4161+ if (type->IsStructure () || type->IsArray ())
4162+ return false ;
4163+ if (type->GetWidth () == 0 || type->GetWidth () == 1 || type->GetWidth () == 2 || type->GetWidth () == 4
4164+ || type->GetWidth () == 8 )
4165+ return true ;
4166+ return false ;
4167+ }
4168+
4169+ Variable GetIndirectReturnValueLocation () override
4170+ {
4171+ return Variable::StackOffset (4 );
4172+ }
4173+ };
4174+
4175+
39264176class X86LinuxSystemCallConvention : public CallingConvention
39274177{
39284178public:
@@ -5284,15 +5534,27 @@ extern "C"
52845534 x86->RegisterCallingConvention (conv);
52855535 x86->SetDefaultCallingConvention (conv);
52865536 x86->SetCdeclCallingConvention (conv);
5537+ conv = new X86SystemVCallingConvention (x86);
5538+ x86->RegisterCallingConvention (conv);
52875539 conv = new X86StdcallCallingConvention (x86);
52885540 x86->RegisterCallingConvention (conv);
52895541 x86->SetStdcallCallingConvention (conv);
5542+ conv = new X86SystemVStdcallCallingConvention (x86);
5543+ x86->RegisterCallingConvention (conv);
52905544 conv = new X86RegParmCallingConvention (x86);
52915545 x86->RegisterCallingConvention (conv);
52925546 conv = new X86FastcallCallingConvention (x86);
52935547 x86->RegisterCallingConvention (conv);
5548+ conv = new X86GCCFastcallCallingConvention (x86);
5549+ x86->RegisterCallingConvention (conv);
5550+ conv = new X86ClangFastcallCallingConvention (x86);
5551+ x86->RegisterCallingConvention (conv);
52945552 conv = new X86ThiscallCallingConvention (x86);
52955553 x86->RegisterCallingConvention (conv);
5554+ conv = new X86GCCThiscallCallingConvention (x86);
5555+ x86->RegisterCallingConvention (conv);
5556+ conv = new X86ClangThiscallCallingConvention (x86);
5557+ x86->RegisterCallingConvention (conv);
52965558 conv = new X86LinuxSystemCallConvention (x86);
52975559 x86->RegisterCallingConvention (conv);
52985560 conv = new X86PascalCallingConvention (x86);
0 commit comments