#ifndef COMPILER_PCODE_H #define COMPILER_PCODE_H #include "compiler/common.h" #include "compiler/PCodeInfo.h" #ifdef __MWERKS__ #pragma options align=mac68k #endif #define FLAG_SET_T(flags) (((flags) & (fPCodeFlag1 | fPCodeFlag8)) ? (flags) : 0) #define FLAG_SET_F(flags) (((flags) & (fPCodeFlag1 | fPCodeFlag8)) ? 0 : (flags)) #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, // ?? fPCodeFlag2000000 = 0x2000000, fPCodeFlag4000000 = 0x4000000, 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(void); extern PCode *makepcode(Opcode op, ...); extern void emitpcode(Opcode op, ...); extern PCode *copypcode(PCode *pcode); extern PCodeLabel *makepclabel(void); extern PCodeBlock *makepcblock(void); extern void pclabel(PCodeBlock *block, PCodeLabel *label); extern void pcbranch(PCodeBlock *block, PCodeLabel *label); extern void pccomputepredecessors(void); extern void deleteblock(PCodeBlock *block); extern void deleteunreachableblocks(void); 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(void); extern void computedepthfirstordering(void); #ifdef __MWERKS__ #pragma options align=reset #endif #endif