mirror of https://git.wuffs.org/MWCC
195 lines
4.3 KiB
C
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
|