summaryrefslogtreecommitdiff
path: root/includes/compiler/PCode.h
diff options
context:
space:
mode:
Diffstat (limited to 'includes/compiler/PCode.h')
-rw-r--r--includes/compiler/PCode.h194
1 files changed, 194 insertions, 0 deletions
diff --git a/includes/compiler/PCode.h b/includes/compiler/PCode.h
new file mode 100644
index 0000000..55aac38
--- /dev/null
+++ b/includes/compiler/PCode.h
@@ -0,0 +1,194 @@
+#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