@@ -3847,6 +3847,43 @@ class X86BaseCallingConvention: public CallingConvention
38473847};
38483848
38493849
3850+ class X86SystemVCallingConvention : public X86BaseCallingConvention
3851+ {
3852+ public:
3853+ X86SystemVCallingConvention (Architecture* arch): X86BaseCallingConvention(arch, " sysv" )
3854+ {
3855+ }
3856+
3857+ bool IsReturnTypeRegisterCompatible (Type* type) override
3858+ {
3859+ if (!type)
3860+ return false ;
3861+ if (type->IsFloat ())
3862+ return true ;
3863+ if (type->IsStructure () || type->IsArray ())
3864+ return false ;
3865+ if (type->GetWidth () == 0 || type->GetWidth () == 1 || type->GetWidth () == 2 || type->GetWidth () == 4
3866+ || type->GetWidth () == 8 )
3867+ return true ;
3868+ return false ;
3869+ }
3870+
3871+ int64_t GetStackAdjustmentForLocations (const std::optional<ValueLocation>& returnValue,
3872+ const vector<ValueLocation>&, const vector<Ref<Type>>&) override
3873+ {
3874+ if (!returnValue.has_value ())
3875+ return 0 ;
3876+ for (auto & component: returnValue->components )
3877+ {
3878+ // Indirect return values have the pointer popped off the stack by the called function
3879+ if (component.indirect )
3880+ return 4 ;
3881+ }
3882+ return 0 ;
3883+ }
3884+ };
3885+
3886+
38503887class X86CdeclCallingConvention : public X86BaseCallingConvention
38513888{
38523889public:
@@ -3870,17 +3907,68 @@ class X86StdcallCallingConvention: public X86BaseCallingConvention
38703907};
38713908
38723909
3910+ class X86SystemVStdcallCallingConvention : public X86BaseCallingConvention
3911+ {
3912+ public:
3913+ X86SystemVStdcallCallingConvention (Architecture* arch): X86BaseCallingConvention(arch, " sysv-stdcall" )
3914+ {
3915+ }
3916+
3917+ bool IsStackAdjustedOnReturn () override
3918+ {
3919+ return true ;
3920+ }
3921+
3922+ bool IsReturnTypeRegisterCompatible (Type* type) override
3923+ {
3924+ if (!type)
3925+ return false ;
3926+ if (type->IsFloat ())
3927+ return true ;
3928+ if (type->IsStructure () || type->IsArray ())
3929+ return false ;
3930+ if (type->GetWidth () == 0 || type->GetWidth () == 1 || type->GetWidth () == 2 || type->GetWidth () == 4
3931+ || type->GetWidth () == 8 )
3932+ return true ;
3933+ return false ;
3934+ }
3935+ };
3936+
3937+
38733938class X86RegParmCallingConvention : public X86BaseCallingConvention
38743939{
38753940public:
38763941 X86RegParmCallingConvention (Architecture* arch): X86BaseCallingConvention(arch, " regparm" )
38773942 {
38783943 }
38793944
3880- virtual vector<uint32_t > GetIntegerArgumentRegisters () override
3945+ vector<uint32_t > GetIntegerArgumentRegisters () override
38813946 {
38823947 return vector<uint32_t >{ XED_REG_EAX, XED_REG_EDX, XED_REG_ECX };
38833948 }
3949+
3950+ bool IsReturnTypeRegisterCompatible (Type* type) override
3951+ {
3952+ if (!type)
3953+ return false ;
3954+ if (type->IsFloat ())
3955+ return true ;
3956+ if (type->IsStructure () || type->IsArray ())
3957+ return false ;
3958+ if (type->GetWidth () == 0 || type->GetWidth () == 1 || type->GetWidth () == 2 || type->GetWidth () == 4
3959+ || type->GetWidth () == 8 )
3960+ return true ;
3961+ return false ;
3962+ }
3963+
3964+ bool IsArgumentTypeRegisterCompatible (Type* type) override
3965+ {
3966+ if (!type)
3967+ return false ;
3968+ if (type->IsFloat ())
3969+ return true ;
3970+ return type->GetWidth () <= 12 ;
3971+ }
38843972};
38853973
38863974
@@ -3903,6 +3991,82 @@ class X86FastcallCallingConvention: public X86BaseCallingConvention
39033991};
39043992
39053993
3994+ class X86GCCFastcallCallingConvention : public X86BaseCallingConvention
3995+ {
3996+ public:
3997+ X86GCCFastcallCallingConvention (Architecture* arch): X86BaseCallingConvention(arch, " gcc-fastcall" )
3998+ {
3999+ }
4000+
4001+ vector<uint32_t > GetIntegerArgumentRegisters () override
4002+ {
4003+ return vector<uint32_t >{ XED_REG_ECX, XED_REG_EDX };
4004+ }
4005+
4006+ bool IsStackAdjustedOnReturn () override
4007+ {
4008+ return true ;
4009+ }
4010+
4011+ bool IsReturnTypeRegisterCompatible (Type* type) override
4012+ {
4013+ if (!type)
4014+ return false ;
4015+ if (type->IsFloat ())
4016+ return true ;
4017+ if (type->IsStructure () || type->IsArray ())
4018+ return false ;
4019+ if (type->GetWidth () == 0 || type->GetWidth () == 1 || type->GetWidth () == 2 || type->GetWidth () == 4
4020+ || type->GetWidth () == 8 )
4021+ return true ;
4022+ return false ;
4023+ }
4024+
4025+ Variable GetIndirectReturnValueLocation () override
4026+ {
4027+ return Variable::Register (XED_REG_ECX);
4028+ }
4029+ };
4030+
4031+
4032+ class X86ClangFastcallCallingConvention : public X86BaseCallingConvention
4033+ {
4034+ public:
4035+ X86ClangFastcallCallingConvention (Architecture* arch): X86BaseCallingConvention(arch, " clang-fastcall" )
4036+ {
4037+ }
4038+
4039+ vector<uint32_t > GetIntegerArgumentRegisters () override
4040+ {
4041+ return vector<uint32_t >{ XED_REG_ECX, XED_REG_EDX };
4042+ }
4043+
4044+ bool IsStackAdjustedOnReturn () override
4045+ {
4046+ return true ;
4047+ }
4048+
4049+ bool IsReturnTypeRegisterCompatible (Type* type) override
4050+ {
4051+ if (!type)
4052+ return false ;
4053+ if (type->IsFloat ())
4054+ return true ;
4055+ if (type->IsStructure () || type->IsArray ())
4056+ return false ;
4057+ if (type->GetWidth () == 0 || type->GetWidth () == 1 || type->GetWidth () == 2 || type->GetWidth () == 4
4058+ || type->GetWidth () == 8 )
4059+ return true ;
4060+ return false ;
4061+ }
4062+
4063+ Variable GetIndirectReturnValueLocation () override
4064+ {
4065+ return Variable::StackOffset (4 );
4066+ }
4067+ };
4068+
4069+
39064070class X86ThiscallCallingConvention : public X86BaseCallingConvention
39074071{
39084072public:
@@ -3927,6 +4091,92 @@ class X86ThiscallCallingConvention: public X86BaseCallingConvention
39274091};
39284092
39294093
4094+ class X86GCCThiscallCallingConvention : public X86BaseCallingConvention
4095+ {
4096+ public:
4097+ X86GCCThiscallCallingConvention (Architecture* arch): X86BaseCallingConvention(arch, " gcc-thiscall" )
4098+ {
4099+ }
4100+
4101+ vector<uint32_t > GetIntegerArgumentRegisters () override
4102+ {
4103+ return vector<uint32_t >{ XED_REG_ECX };
4104+ }
4105+
4106+ vector<uint32_t > GetRequiredArgumentRegisters () override
4107+ {
4108+ return vector<uint32_t >{ XED_REG_ECX };
4109+ }
4110+
4111+ bool IsStackAdjustedOnReturn () override
4112+ {
4113+ return true ;
4114+ }
4115+
4116+ bool IsReturnTypeRegisterCompatible (Type* type) override
4117+ {
4118+ if (!type)
4119+ return false ;
4120+ if (type->IsFloat ())
4121+ return true ;
4122+ if (type->IsStructure () || type->IsArray ())
4123+ return false ;
4124+ if (type->GetWidth () == 0 || type->GetWidth () == 1 || type->GetWidth () == 2 || type->GetWidth () == 4
4125+ || type->GetWidth () == 8 )
4126+ return true ;
4127+ return false ;
4128+ }
4129+
4130+ Variable GetIndirectReturnValueLocation () override
4131+ {
4132+ return Variable::Register (XED_REG_ECX);
4133+ }
4134+ };
4135+
4136+
4137+ class X86ClangThiscallCallingConvention : public X86BaseCallingConvention
4138+ {
4139+ public:
4140+ X86ClangThiscallCallingConvention (Architecture* arch): X86BaseCallingConvention(arch, " clang-thiscall" )
4141+ {
4142+ }
4143+
4144+ vector<uint32_t > GetIntegerArgumentRegisters () override
4145+ {
4146+ return vector<uint32_t >{ XED_REG_ECX };
4147+ }
4148+
4149+ vector<uint32_t > GetRequiredArgumentRegisters () override
4150+ {
4151+ return vector<uint32_t >{ XED_REG_ECX };
4152+ }
4153+
4154+ bool IsStackAdjustedOnReturn () override
4155+ {
4156+ return true ;
4157+ }
4158+
4159+ bool IsReturnTypeRegisterCompatible (Type* type) override
4160+ {
4161+ if (!type)
4162+ return false ;
4163+ if (type->IsFloat ())
4164+ return true ;
4165+ if (type->IsStructure () || type->IsArray ())
4166+ return false ;
4167+ if (type->GetWidth () == 0 || type->GetWidth () == 1 || type->GetWidth () == 2 || type->GetWidth () == 4
4168+ || type->GetWidth () == 8 )
4169+ return true ;
4170+ return false ;
4171+ }
4172+
4173+ Variable GetIndirectReturnValueLocation () override
4174+ {
4175+ return Variable::StackOffset (4 );
4176+ }
4177+ };
4178+
4179+
39304180class X86LinuxSystemCallConvention : public CallingConvention
39314181{
39324182public:
@@ -5288,15 +5538,27 @@ extern "C"
52885538 x86->RegisterCallingConvention (conv);
52895539 x86->SetDefaultCallingConvention (conv);
52905540 x86->SetCdeclCallingConvention (conv);
5541+ conv = new X86SystemVCallingConvention (x86);
5542+ x86->RegisterCallingConvention (conv);
52915543 conv = new X86StdcallCallingConvention (x86);
52925544 x86->RegisterCallingConvention (conv);
52935545 x86->SetStdcallCallingConvention (conv);
5546+ conv = new X86SystemVStdcallCallingConvention (x86);
5547+ x86->RegisterCallingConvention (conv);
52945548 conv = new X86RegParmCallingConvention (x86);
52955549 x86->RegisterCallingConvention (conv);
52965550 conv = new X86FastcallCallingConvention (x86);
52975551 x86->RegisterCallingConvention (conv);
5552+ conv = new X86GCCFastcallCallingConvention (x86);
5553+ x86->RegisterCallingConvention (conv);
5554+ conv = new X86ClangFastcallCallingConvention (x86);
5555+ x86->RegisterCallingConvention (conv);
52985556 conv = new X86ThiscallCallingConvention (x86);
52995557 x86->RegisterCallingConvention (conv);
5558+ conv = new X86GCCThiscallCallingConvention (x86);
5559+ x86->RegisterCallingConvention (conv);
5560+ conv = new X86ClangThiscallCallingConvention (x86);
5561+ x86->RegisterCallingConvention (conv);
53005562 conv = new X86LinuxSystemCallConvention (x86);
53015563 x86->RegisterCallingConvention (conv);
53025564 conv = new X86PascalCallingConvention (x86);
0 commit comments