1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 03:28:20 +02:00
Beef/IDEHelper/Compiler/CeMachine.h

360 lines
6.2 KiB
C
Raw Normal View History

#pragma once
#include "BfSystem.h"
#include "BfModule.h"
NS_BF_BEGIN
class BfMethodInstance;
class BeDbgLoc;
class BeType;
class BeValue;
class BeInst;
class BeDbgFile;
class BePhiInst;
class BeFunction;
class BeSwitchInst;
class CeMachine;
class CeFunction;
#define CEOP_SIZED(OPNAME) \
CeOp_##OPNAME##_8, \
CeOp_##OPNAME##_16, \
CeOp_##OPNAME##_32, \
CeOp_##OPNAME##_64, \
CeOp_##OPNAME##_X
#define CEOP_SIZED_NUMERIC(OPNAME) \
CeOp_##OPNAME##_I8, \
CeOp_##OPNAME##_I16, \
CeOp_##OPNAME##_I32, \
CeOp_##OPNAME##_I64
#define CEOP_SIZED_NUMERIC_PLUSF(OPNAME) \
CeOp_##OPNAME##_I8, \
CeOp_##OPNAME##_I16, \
CeOp_##OPNAME##_I32, \
CeOp_##OPNAME##_I64, \
CeOp_##OPNAME##_F32, \
CeOp_##OPNAME##_F64
enum CeOp : int16
{
CeOp_InvalidOp,
CeOp_Ret,
CeOp_Jmp,
CeOp_JmpIf,
CeOp_JmpIfNot,
CeOp_FrameAddr32,
CeOp_FrameAddr64,
2020-12-14 03:50:28 -08:00
CeOp_Zero,
CEOP_SIZED(Const),
CEOP_SIZED(Load),
2020-12-14 03:50:28 -08:00
CEOP_SIZED(Store),
CEOP_SIZED(Move),
CEOP_SIZED(Push),
2020-12-14 03:50:28 -08:00
CEOP_SIZED(Pop),
CeOp_AdjustSP,
CeOp_Call,
CeOp_Conv_I32_I64,
2020-12-14 03:50:28 -08:00
CEOP_SIZED_NUMERIC_PLUSF(AddConst),
CEOP_SIZED_NUMERIC_PLUSF(Add),
CEOP_SIZED_NUMERIC_PLUSF(Sub),
CEOP_SIZED_NUMERIC_PLUSF(Mul),
CEOP_SIZED_NUMERIC_PLUSF(SDiv),
CEOP_SIZED_NUMERIC(UDiv),
CEOP_SIZED_NUMERIC_PLUSF(SMod),
CEOP_SIZED_NUMERIC(UMod),
CEOP_SIZED_NUMERIC_PLUSF(Cmp_EQ),
CEOP_SIZED_NUMERIC_PLUSF(Cmp_SLT),
2020-12-14 03:50:28 -08:00
CEOP_SIZED_NUMERIC(Cmp_ULT),
CEOP_SIZED_NUMERIC_PLUSF(Cmp_SLE),
CEOP_SIZED_NUMERIC(Cmp_ULE),
CEOP_SIZED_NUMERIC_PLUSF(Neg),
CeOp_COUNT
};
struct CeEmitEntry
{
int mCodePos;
int mFile;
int mLine;
int mColumn;
};
class CeCallEntry
{
public:
String mFunctionName;
int mBindRevision;
CeFunction* mFunction;
public:
CeCallEntry()
{
mBindRevision = -1;
mFunction = NULL;
}
};
class CeFunction
{
public:
BfMethodInstance* mMethodInstance;
String mName;
bool mInitialized;
bool mFailed;
Array<uint8> mCode;
Array<String> mFiles;
Array<CeEmitEntry> mEmitTable;
Array<CeCallEntry> mCallTable;
String mGenError;
int mFrameSize;
public:
CeFunction()
{
mInitialized = false;
mMethodInstance = NULL;
mFailed = false;
mFrameSize = 0;
}
};
enum CeEvalFlags
{
CeEvalFlags_None = 0
};
enum CeOperandKind
{
CeOperandKind_None,
CeOperandKind_FrameOfs,
CeOperandKind_AllocaAddr,
CeOperandKind_Block,
2020-12-14 03:50:28 -08:00
CeOperandKind_Immediate
};
class CeOperand
{
public:
CeOperandKind mKind;
union
{
int mFrameOfs;
int mBlockIdx;
2020-12-14 03:50:28 -08:00
int mImmediate;
};
BeType* mType;
public:
CeOperand()
{
mKind = CeOperandKind_None;
mFrameOfs = 0;
mType = NULL;
}
operator bool() const
{
return mKind != CeOperandKind_None;
}
2020-12-14 03:50:28 -08:00
bool IsImmediate()
{
return mKind == CeOperandKind_Immediate;
}
};
#define BF_CE_STACK_SIZE 1024*1024
enum CeOperandInfoKind
{
CEOI_None,
CEOI_FrameRef,
CEOI_IMM8,
CEOI_IMM16,
CEOI_IMM32,
CEOI_IMM64,
2020-12-14 03:50:28 -08:00
CEOI_IMMF32,
CEOI_IMMF64,
CEOI_IMM_VAR,
CEOI_JMPREL
};
enum CeSizeClass
{
CeSizeClass_8,
CeSizeClass_16,
CeSizeClass_32,
CeSizeClass_64,
CeSizeClass_X,
};
class CeDumpContext
{
public:
CeFunction* mCeFunction;
String mStr;
uint8* mStart;
uint8* mPtr;
uint8* mEnd;
public:
void DumpOperandInfo(CeOperandInfoKind operandInfoKind);
void Dump();
};
struct CePhiOutgoing
{
BeValue* mPhiValue;
BePhiInst* mPhiInst;
int mPhiBlockIdx;
};
class CeBlock
{
public:
int mEmitOfs;
Array<CePhiOutgoing> mPhiOutgoing;
public:
CeBlock()
{
mEmitOfs = -1;
}
};
class CeJumpEntry
{
public:
int mEmitPos;
int mBlockIdx;
};
class CeBuilder
{
public:
CeMachine* mCeMachine;
CeFunction* mCeFunction;
BeFunction* mBeFunction;
CeOperand mReturnVal;
BeType* mIntPtrType;
int mPtrSize;
String mError;
BeDbgLoc* mCurDbgLoc;
Array<CeBlock> mBlocks;
Array<CeJumpEntry> mJumpTable;
Dictionary<BeValue*, CeOperand> mValueToOperand;
int mFrameSize;
Dictionary<BeDbgFile*, int> mDbgFileMap;
Dictionary<BeFunction*, int> mFunctionMap;
public:
CeBuilder()
{
mPtrSize = 0;
mCeFunction = NULL;
mBeFunction = NULL;
mCeMachine = NULL;
mCurDbgLoc = NULL;
mFrameSize = 0;
}
void Fail(const StringImpl& error);
CeOperand FrameAlloc(BeType* type);
2020-12-14 03:50:28 -08:00
CeOperand GetOperand(BeValue* value, bool allowAlloca = false, bool allowImmediate = false);
CeSizeClass GetSizeClass(int size);
int GetCodePos();
void HandleParams();
void Emit(uint8 val);
void Emit(CeOp val);
void Emit(int32 val);
void Emit(bool val);
void Emit(void* ptr, int size);
void EmitJump(CeOp op, const CeOperand& block);
void EmitBinarySwitchSection(BeSwitchInst* switchInst, int startIdx, int endIdx);
void EmitFrameOffset(const CeOperand& val);
void FlushPhi(CeBlock* ceBlock, int targetBlockIdx);
void EmitBinaryOp(CeOp iOp, CeOp fOp, const CeOperand& lhs, const CeOperand& rhs, CeOperand& result);
void EmitUnaryOp(CeOp iOp, CeOp fOp, const CeOperand& val, CeOperand& result);
void EmitSizedOp(CeOp op, const CeOperand& operand, CeOperand* result, bool allowNonStdSize);
void Build();
};
class CeFrame
{
public:
CeFunction* mFunction;
uint8* mStackPtr;
uint8* mFramePtr;
uint8* mInstPtr;
public:
CeFrame()
{
mFunction = NULL;
mStackPtr = NULL;
mFramePtr = NULL;
mInstPtr = NULL;
}
};
class CeMachine
{
public:
Dictionary<BfMethodInstance*, CeFunction*> mFunctions;
Dictionary<String, CeFunction*> mNamedFunctionMap;
BfCompiler* mCompiler;
BfModule* mCeModule;
int mRevision;
Array<CeFrame> mCallStack;
Array<uint8> mMemory;
uint8* mStackMin;
Array<CeFunction*> mWorkQueue;
2020-12-14 03:50:28 -08:00
BfAstNode* mCurTargetSrc;
BfModule* mCurModule;
public:
CeMachine(BfCompiler* compiler);
~CeMachine();
2020-12-14 03:50:28 -08:00
void Fail(const CeFrame& curFrame, const StringImpl& error);
void Init();
void RemoveMethod(BfMethodInstance* methodInstance);
int GetConstantSize(BfConstant* constant);
void WriteConstant(uint8* ptr, BfConstant* constant);
void CreateFunction(BfMethodInstance* methodInstance, CeFunction* ceFunction);
2020-12-14 03:50:28 -08:00
bool Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr);
void PrepareFunction(CeFunction* methodInstance);
2020-12-14 03:50:28 -08:00
void ProcessWorkQueue();
CeFunction* GetFunction(BfMethodInstance* methodInstance, bool& added);
public:
void CompileStarted();
void QueueMethod(BfMethodInstance* methodInstance);
2020-12-14 03:50:28 -08:00
BfTypedValue Call(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray<BfIRValue>& args, CeEvalFlags flags);
};
NS_BF_END