MWCC/includes/compiler/PCode.h

195 lines
4.3 KiB
C

#ifndef COMPILER_PCODE_H
#define COMPILER_PCODE_H
#include "compiler/common.h"
#ifdef __MWERKS__
#pragma options align=mac68k
#endif
#define PCODE_FLAG_SET_T(pcode) (((pcode)->flags & (fPCodeFlag1 | fPCodeFlag8)) ? (pcode)->flags : 0)
#define PCODE_FLAG_SET_F(pcode) (((pcode)->flags & (fPCodeFlag1 | fPCodeFlag8)) ? 0 : (pcode)->flags)
enum {
EffectRead = 1,
EffectWrite = 2
};
typedef enum {
PCOp_REGISTER,
PCOp_SYSREG,
PCOp_IMMEDIATE,
PCOp_MEMORY,
PCOp_LABEL,
PCOp_LABELDIFF,
PCOp_PLACEHOLDEROPERAND
} PCOpKind;
typedef enum {
RefType_0,
RefType_1,
RefType_2,
RefType_3,
RefType_4,
RefType_5,
RefType_6,
RefType_7,
RefType_8,
RefType_9,
RefType_A,
RefType_B,
RefType_C,
RefType_D
} PCRefType;
struct PCodeArg {
PCOpKind kind;
char arg;
union {
struct {
unsigned short effect;
short reg;
} reg;
struct {
SInt32 value;
Object *obj;
} imm;
struct {
SInt32 offset;
Object *obj;
} mem;
struct {
PCodeLabel *label;
} label;
struct {
SInt16 offset;
PCodeLabel *labelA;
PCodeLabel *labelB;
} labeldiff;
unsigned char placeholder[10]; // keep the size
} data;
};
struct PCode {
PCode *nextPCode;
PCode *prevPCode;
PCodeBlock *block;
unsigned int xx_C;
unsigned int _10;
int flags;
void *_18;
SInt32 sourceoffset;
short op;
short argCount;
PCodeArg args[0];
};
struct PCodeLabel {
PCodeLabel *nextLabel;
PCodeBlock *block;
short resolved;
short index;
};
typedef struct _PCLink {
struct _PCLink *nextLink;
struct PCodeBlock *block;
} PCLink;
struct PCodeBlock {
struct PCodeBlock *nextBlock;
struct PCodeBlock *prevBlock;
PCodeLabel *labels;
PCLink *predecessors;
PCLink *successors;
PCode *firstPCode;
PCode *lastPCode;
int blockIndex;
int codeOffset; // in bytes
int loopWeight;
short pcodeCount;
unsigned short flags;
};
/* PCode Flags */
enum {
fPCodeFlag1 = 1,
fPCodeFlag2 = 2,
fPCodeFlag4 = 4,
fPCodeFlag8 = 8,
fPCodeFlag10 = 0x10,
fPCodeFlag20 = 0x20,
// Always valid
fIsConst = 0x40,
fIsVolatile = 0x80,
fSideEffects = 0x100,
fPCodeFlag200 = 0x200, // ?
fPCodeFlag400 = 0x400, // ?
fPCodeFlag800 = 0x800, // ?
fPCodeFlag1000 = 0x1000, // ?
fCommutative = 0x2000,
fIsCSE = 0x4000,
fPCodeFlag8000 = 0x8000,
fPCodeFlag20000 = 0x20000, // ?
fPCodeFlag40000 = 0x40000, // ?
// Set 1 only
fLink = 0x1000000,
fBranchNotTaken = 0x4000000,
fBranchTaken = 0x8000000,
fAbsolute = 0x10000000,
// Set 2 only
fIsPtrOp = 0x20,
fOverflow = 0x800000,
fSetsCarry = 0x10000000,
// ??
fPCodeFlag8000000 = 0x8000000,
fPCodeFlag10000000 = 0x10000000,
fPCodeFlag20000000 = 0x20000000,
fPCodeFlag40000000 = 0x40000000,
fPCodeFlag80000000 = 0x80000000
};
enum {
fPCBlockFlag1 = 1, // prologue
fPCBlockFlag2 = 2, // epilogue
fPCBlockFlag4 = 4,
fPCBlockFlag8 = 8,
fPCBlockFlag10 = 0x10,
fPCBlockFlag20 = 0x20,
fPCBlockFlag4000 = 0x4000
};
extern PCodeBlock *pcbasicblocks;
extern PCodeBlock *pclastblock;
extern PCodeBlock *prologue;
extern PCodeBlock *epilogue;
extern PCodeBlock **depthfirstordering;
extern int pcblockcount;
extern int pcloopweight;
extern void initpcode();
extern PCode *makepcode(short op, ...);
extern void emitpcode(short op, ...);
extern PCode *copypcode(PCode *pcode);
extern PCodeLabel *makepclabel();
extern PCodeBlock *makepcblock();
extern void pclabel(PCodeBlock *block, PCodeLabel *label);
extern void pcbranch(PCodeBlock *block, PCodeLabel *label);
extern void pccomputepredecessors();
extern void deleteblock(PCodeBlock *block);
extern void deleteunreachableblocks();
extern void appendpcode(PCodeBlock *block, PCode *pcode);
extern void deletepcode(PCode *pcode);
extern void insertpcodebefore(PCode *anchor, PCode *newpcode);
extern void insertpcodeafter(PCode *anchor, PCode *newpcode);
extern void setpcodeflags(int flags);
extern void clearpcodeflags(int flags);
extern int pccomputeoffsets();
extern void computedepthfirstordering();
#ifdef __MWERKS__
#pragma options align=reset
#endif
#endif