blob: c166d454e68a2d4b41345e2914b1cd94082bd888 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Vyacheslav P. Shakin
*/
#ifndef HYX86CALLING_CONVENTION_H_
#define HYX86CALLING_CONVENTION_H_
#include "open/types.h"
#include "Type.h"
#include "Ia32IRConstants.h"
#include "Ia32Constraint.h"
/**
* When entering a function, obey the (sp)%%4 == 0 rule.
*/
#define STACK_ALIGN4 (0x00000004)
/**
* When entering a function, obey the (sp+8)%%16 == 0 rule
* (Required by Intel 64 calling convention).
*/
#define STACK_ALIGN_HALF16 (0x00000008)
/**
* When entering a function, obey the (sp)%%16 == 0 rule.
*/
#define STACK_ALIGN16 (0x00000010)
#ifdef HYX86_64
#define STACK_REG RegName_RSP
#define STACK_ALIGNMENT STACK_ALIGN_HALF16
#else
#define STACK_REG RegName_ESP
#define STACK_ALIGNMENT STACK_ALIGN16
#endif
namespace Jitrino
{
namespace Ia32{
//=========================================================================================================
//========================================================================================
// class CallingConvention
//========================================================================================
/**
* Interface CallingConvention describes a particular calling convention.
*
* As calling convention rules can be more or less formally defined,
* it is worth to define this entity as a separate class or interface
* Implementers of this interface are used as arguments to some IRManager methods
*/
class CallingConvention
{
public:
//--------------------------------------------------------------
struct OpndInfo
{
U_32 typeTag;
U_32 slotCount;
bool isReg;
U_32 slots[4];
};
//--------------------------------------------------------------
enum ArgKind
{
ArgKind_InArg,
ArgKind_RetArg
};
virtual ~CallingConvention() {}
/** Fills the infos array with information how incoming arguments or return values are passed
according to this calling convention
*/
virtual void getOpndInfo(ArgKind kind, U_32 argCount, OpndInfo * infos) const =0;
/** Returns a mask describing registers of regKind which are to be preserved by a callee
*/
virtual Constraint getCalleeSavedRegs(OpndKind regKind) const =0;
/** Returns true if restoring arg stack is callee's responsibility
*/
virtual bool calleeRestoresStack() const =0;
/** True arguments are pushed from the last to the first, false in the other case
*/
virtual bool pushLastToFirst()const =0;
/**
* Defines stack pointer alignment on method enter.
*/
virtual U_32 getStackAlignment()const { return 0; }
/**
* Maps a string representation of CallingConvention to the
* appropriate CallingConvention_* item.
* If cc_name is NULL, then default for this platform convention
* is returned.
*/
static const CallingConvention * str2cc(const char * cc_name);
};
typedef StlVector<const CallingConvention *> CallingConventionVector;
//========================================================================================
// STDCALLCallingConvention
//========================================================================================
/**
* Implementation of CallingConvention for the STDCALL calling convention
*/
class STDCALLCallingConventionIA32: public CallingConvention
{
public:
virtual ~STDCALLCallingConventionIA32() {}
virtual void getOpndInfo(ArgKind kind, U_32 argCount, OpndInfo * infos) const;
virtual Constraint getCalleeSavedRegs(OpndKind regKind) const;
virtual bool calleeRestoresStack() const{ return true; }
virtual bool pushLastToFirst() const { return true; }
};
class STDCALLCallingConventionEM64T: public CallingConvention
{
public:
virtual ~STDCALLCallingConventionEM64T() {}
virtual void getOpndInfo(ArgKind kind, U_32 argCount, OpndInfo * infos) const;
virtual Constraint getCalleeSavedRegs(OpndKind regKind) const;
virtual bool calleeRestoresStack() const { return false; }
virtual U_32 getStackAlignment() const { return STACK_ALIGNMENT; }
virtual bool pushLastToFirst() const { return true; }
};
//========================================================================================
// CDECL CallingConvention
//========================================================================================
/**
* Implementation of CallingConvention for the CDECL calling convention
*/
class CDECLCallingConventionIA32: public STDCALLCallingConventionIA32
{
public:
virtual ~CDECLCallingConventionIA32() {}
virtual bool calleeRestoresStack() const { return false; }
};
class CDECLCallingConventionEM64T: public STDCALLCallingConventionEM64T
{
public:
virtual ~CDECLCallingConventionEM64T() {}
};
//========================================================================================
// Managed CallingConvention
//========================================================================================
/**
* Implementation of CallingConvention for the Managed calling convention
*/
class ManagedCallingConventionIA32: public STDCALLCallingConventionIA32
{
public:
virtual ~ManagedCallingConventionIA32() {}
virtual void getOpndInfo(ArgKind kind, U_32 argCount, OpndInfo * infos) const;
virtual bool pushLastToFirst( ) const { return false; }
virtual U_32 getStackAlignment() const { return STACK_ALIGNMENT; }
};
class ManagedCallingConventionEM64T: public STDCALLCallingConventionEM64T
{
public:
virtual ~ManagedCallingConventionEM64T() {}
};
//========================================================================================
// MultiArray CallingConvention
//========================================================================================
/**
* Special calling convention for multi-array creation.
* It's CDECL like but always passes arguments through the stack.
*/
class MultiArrayCallingConventionIA32: public CDECLCallingConventionIA32
{
public:
virtual ~MultiArrayCallingConventionIA32() {}
};
class MultiArrayCallingConventionEM64T: public CDECLCallingConventionEM64T
{
public:
virtual ~MultiArrayCallingConventionEM64T() {}
virtual void getOpndInfo(ArgKind kind, U_32 argCount, OpndInfo * infos) const;
};
#ifdef HYX86_64
typedef STDCALLCallingConventionEM64T STDCALLCallingConvention;
typedef CDECLCallingConventionEM64T CDECLCallingConvention;
typedef ManagedCallingConventionEM64T ManagedCallingConvention;
typedef MultiArrayCallingConventionEM64T MultiArrayCallingConvention;
#else
typedef STDCALLCallingConventionIA32 STDCALLCallingConvention;
typedef CDECLCallingConventionIA32 CDECLCallingConvention;
typedef ManagedCallingConventionIA32 ManagedCallingConvention;
typedef MultiArrayCallingConventionIA32 MultiArrayCallingConvention;
#endif
extern STDCALLCallingConvention CallingConvention_STDCALL;
extern CDECLCallingConvention CallingConvention_CDECL;
extern ManagedCallingConvention CallingConvention_Managed;
extern MultiArrayCallingConvention CallingConvention_MultiArray;
}; // namespace Ia32
}
#endif