MWCC/includes/compiler/PCode.h

246 lines
6.7 KiB
C
Raw Normal View History

2022-11-07 03:06:21 +00:00
#ifndef COMPILER_PCODE_H
#define COMPILER_PCODE_H
#include "compiler/common.h"
#include "compiler/PCodeInfo.h"
2022-11-07 03:06:21 +00:00
#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))
2022-11-07 03:06:21 +00:00
#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,
Effect4 = 4,
Effect8 = 8,
Effect40 = 0x40 // spilled register?
2022-11-07 03:06:21 +00:00
};
/*typedef enum {
2022-11-07 03:06:21 +00:00
PCOp_REGISTER,
PCOp_SYSREG,
PCOp_IMMEDIATE,
PCOp_MEMORY,
PCOp_LABEL,
PCOp_LABELDIFF,
PCOp_PLACEHOLDEROPERAND
} PCOpKind;*/
2022-11-07 03:06:21 +00:00
typedef enum {
RefType_0,
2022-12-29 12:32:55 +00:00
RefType_1, // like D, but 32-bit?
RefType_2, // matches MW_RELOC_3?
RefType_3, // matches MW_RELOC_4?
2022-11-07 03:06:21 +00:00
RefType_4,
RefType_5,
2022-12-29 12:32:55 +00:00
RefType_6, // LO16?
RefType_7, // HI16?
RefType_8, // HA16?
2022-11-07 03:06:21 +00:00
RefType_9,
2022-12-29 12:32:55 +00:00
RefType_A, // another LO
RefType_B, // another HA
RefType_C, // another HA
RefType_D // another LO
2022-11-07 03:06:21 +00:00
} PCRefType;
struct PCodeArg {
PCOpKind kind;
RegClass arg;
2022-11-07 03:06:21 +00:00
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;
};
#define PC_OP_IS_REGISTER(_op, _rclass, _reg) \
((_op)->kind == PCOp_REGISTER && \
(_op)->arg == (_rclass) && \
(_op)->data.reg.reg == (_reg))
#define PC_OP_IS_READ_REGISTER(_op, _rclass, _reg) \
((_op)->kind == PCOp_REGISTER && \
(_op)->arg == (_rclass) && \
(_op)->data.reg.reg == (_reg) && \
((_op)->data.reg.effect & EffectRead))
#define PC_OP_IS_WRITE_REGISTER(_op, _rclass, _reg) \
((_op)->kind == PCOp_REGISTER && \
(_op)->arg == (_rclass) && \
(_op)->data.reg.reg == (_reg) && \
((_op)->data.reg.effect & EffectWrite))
2022-12-29 12:32:55 +00:00
#define PC_OP_IS_R_OR_W_REGISTER(_op, _rclass, _reg) \
((_op)->kind == PCOp_REGISTER && \
(_op)->arg == (_rclass) && \
(_op)->data.reg.reg == (_reg) && \
((_op)->data.reg.effect & (EffectRead | EffectWrite)))
#define PC_OP_IS_ANY_REGISTER(_op, _rclass) \
((_op)->kind == PCOp_REGISTER && \
(_op)->arg == (_rclass))
#define PC_OP_IS_READ_ANY_REGISTER(_op, _rclass) \
((_op)->kind == PCOp_REGISTER && \
(_op)->arg == (_rclass) && \
((_op)->data.reg.effect & EffectRead))
#define PC_OP_IS_WRITE_ANY_REGISTER(_op, _rclass) \
((_op)->kind == PCOp_REGISTER && \
(_op)->arg == (_rclass) && \
((_op)->data.reg.effect & EffectWrite))
2022-11-07 03:06:21 +00:00
struct PCode {
PCode *nextPCode;
PCode *prevPCode;
PCodeBlock *block;
int useID;
int defID;
UInt32 flags;
struct Alias *alias;
2022-11-07 03:06:21 +00:00
SInt32 sourceoffset;
short op;
short argCount;
PCodeArg args[0];
};
struct PCodeLabel {
PCodeLabel *nextLabel;
PCodeBlock *block;
short resolved;
unsigned short index;
2022-11-07 03:06:21 +00:00
};
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 {
2022-12-29 12:32:55 +00:00
fPCodeFlag1 = 1, // some kinds of branches
fPCodeFlag2 = 2, // read from memory
fPCodeFlag4 = 4, // write to memory
fPCodeFlag8 = 8, // other kinds of branches
fPCodeFlag10 = 0x10, // moves
fPCodeFlag20 = 0x20, // indexed operations
2022-11-07 03:06:21 +00:00
// Always valid
fIsConst = 0x40,
fIsVolatile = 0x80,
2022-12-29 12:32:55 +00:00
fSideEffects = 0x100, // instructions that do weird stuff with PPC state
2022-11-07 03:06:21 +00:00
fPCodeFlag200 = 0x200, // ?
fPCodeFlag400 = 0x400, // ?
fPCodeFlag800 = 0x800, // ?
fPCodeFlag1000 = 0x1000, // ?
fCommutative = 0x2000,
fIsCSE = 0x4000,
fPCodeFlag8000 = 0x8000,
fPCodeFlag20000 = 0x20000, // some kinda load?
fPCodeFlag40000 = 0x40000, // some kinda store?
2022-12-29 12:32:55 +00:00
// Set 1 (branches) only
2022-11-07 03:06:21 +00:00
fLink = 0x1000000,
fBranchNotTaken = 0x4000000,
fBranchTaken = 0x8000000,
fAbsolute = 0x10000000,
2022-12-29 12:32:55 +00:00
// Set 2 (non-branches) only
2022-11-07 03:06:21 +00:00
fIsPtrOp = 0x20,
fOverflow = 0x800000,
fSetsCarry = 0x10000000,
2022-12-29 12:32:55 +00:00
fPCodeFlag20000000 = 0x20000000, // record bit?
2022-11-07 03:06:21 +00:00
// ??
fPCodeFlag2000000 = 0x2000000,
fPCodeFlag4000000 = 0x4000000,
2022-11-07 03:06:21 +00:00
fPCodeFlag8000000 = 0x8000000,
fPCodeFlag10000000 = 0x10000000,
fPCodeFlag40000000 = 0x40000000,
2022-12-29 12:32:55 +00:00
fPCodeFlag80000000 = 0x80000000,
fPCodeFlagC0000000 = 0xC0000000
2022-11-07 03:06:21 +00:00
};
enum {
fPCBlockFlag1 = 1, // prologue
fPCBlockFlag2 = 2, // epilogue
fPCBlockFlag4 = 4,
fPCBlockFlag8 = 8, // scheduled?
2022-11-07 03:06:21 +00:00
fPCBlockFlag10 = 0x10,
fPCBlockFlag20 = 0x20,
fPCBlockFlag2000 = 0x2000,
2022-12-29 12:32:55 +00:00
fPCBlockFlag4000 = 0x4000,
fPCBlockFlag6000 = 0x6000,
fPCBlockFlag8000 = 0x8000
2022-11-07 03:06:21 +00:00
};
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, ...);
2022-11-07 03:06:21 +00:00
extern PCode *copypcode(PCode *pcode);
extern PCodeLabel *makepclabel(void);
extern PCodeBlock *makepcblock(void);
2022-11-07 03:06:21 +00:00
extern void pclabel(PCodeBlock *block, PCodeLabel *label);
extern void pcbranch(PCodeBlock *block, PCodeLabel *label);
extern void pccomputepredecessors(void);
2022-11-07 03:06:21 +00:00
extern void deleteblock(PCodeBlock *block);
extern void deleteunreachableblocks(void);
2022-11-07 03:06:21 +00:00
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);
2022-11-07 03:06:21 +00:00
#ifdef __MWERKS__
#pragma options align=reset
#endif
#endif