summaryrefslogtreecommitdiff
path: root/PCode.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--PCode.c286
1 files changed, 286 insertions, 0 deletions
diff --git a/PCode.c b/PCode.c
new file mode 100644
index 0000000..d677e22
--- /dev/null
+++ b/PCode.c
@@ -0,0 +1,286 @@
+#include "CompilerTools.h"
+#include "PCode.h"
+
+// TODO RESOLVE ME
+extern void initialize_aliases();
+extern void *current_statement;
+extern PCode *vformatpcode(short op, va_list args);
+
+PCBlock *pcbasicblocks;
+PCBlock *pclastblock;
+void *prologue;
+void *epilogue;
+PCBlock **depthfirstordering;
+int pcblockcount;
+int pcloopweight;
+static unsigned short pclabelcount;
+
+void initpcode() {
+ pclastblock = 0;
+ pcbasicblocks = 0;
+ pcblockcount = 0;
+ pclabelcount = 0;
+ pcloopweight = 1;
+ initialize_aliases();
+}
+
+PCode *makepcode(short op, ...) {
+ PCode *pcode;
+ va_list list;
+
+ va_start(list, op);
+ pcode = vformatpcode(op, list);
+ // TODO
+ return pcode;
+}
+
+void emitpcode(short op, ...) {
+ PCode *pcode;
+ va_list list;
+
+ va_start(list, op);
+ pcode = vformatpcode(op, list);
+ // TODO
+ appendpcode(pclastblock, pcode);
+}
+
+PCode *copypcode(PCode *pcode) {
+ PCode *newpc;
+ int flag;
+
+ flag = 0;
+ // TODO
+
+ return newpc;
+}
+
+PCLabel *makepclabel() {
+ PCLabel *label;
+
+ label = (PCLabel *) lalloc(sizeof(PCLabel));
+ memclrw(label, sizeof(PCLabel));
+ label->index = pclabelcount++;
+ return label;
+}
+
+PCBlock *makepcblock() {
+ PCBlock *block;
+
+ block = (PCBlock *) lalloc(sizeof(PCBlock));
+ memclrw(block, sizeof(PCBlock));
+ block->loopWeight = pcloopweight;
+ block->blockIndex = pcblockcount++;
+ if (pclastblock) {
+ pclastblock->nextBlock = block;
+ block->prevBlock = pclastblock;
+ } else {
+ pcbasicblocks = block;
+ }
+ pclastblock = block;
+ return block;
+}
+
+void pclabel(PCBlock *block, PCLabel *label) {
+ PCLink *iter;
+ PCLink *next;
+
+ iter = (PCLink *) label->block;
+ while (iter) {
+ next = (PCLink *) iter->block;
+ iter->block = block;
+ iter = next;
+ }
+
+ label->block = block;
+ label->resolved = 1;
+ label->nextLabel = block->labels;
+ block->labels = label;
+}
+
+void pcbranch(PCBlock *block, PCLabel *label) {
+ PCLink *link;
+
+ link = (PCLink *) lalloc(sizeof(PCLink));
+ memclrw(link, sizeof(PCLink));
+
+ link->block = label->block;
+ if (!label->resolved)
+ label->block = (PCBlock *) link;
+ link->nextLink = block->successors;
+ block->successors = link;
+}
+
+void pccomputepredecessors() {
+ PCBlock *block;
+ PCLink *succ;
+ PCLink *pred;
+
+ for (block = pcbasicblocks; block; block = block->nextBlock) {
+ for (succ = block->successors; succ; succ = succ->nextLink) {
+ pred = (PCLink *) lalloc(sizeof(PCLink));
+ memclrw(pred, sizeof(PCLink));
+
+ pred->block = block;
+ pred->nextLink = succ->block->predecessors;
+ succ->block->predecessors = pred;
+ }
+ }
+}
+
+void deleteblock(PCBlock *block) {
+ block->prevBlock->nextBlock = block->nextBlock;
+ if (block->nextBlock)
+ block->nextBlock->prevBlock = block->prevBlock;
+ block->flags |= fPCBlockFlag20;
+}
+
+void deleteunreachableblocks() {
+ PCBlock *block;
+
+ computedepthfirstordering();
+
+ for (block = pcbasicblocks->nextBlock; block; block = block->nextBlock) {
+ if (!(block->flags & fPCBlockFlag4))
+ deleteblock(block);
+ }
+}
+
+void appendpcode(PCBlock *block, PCode *pcode) {
+ if (block->firstPCode) {
+ pcode->nextPCode = 0;
+ pcode->prevPCode = block->lastPCode;
+ block->lastPCode->nextPCode = pcode;
+ block->lastPCode = pcode;
+ } else {
+ block->lastPCode = pcode;
+ block->firstPCode = pcode;
+ pcode->prevPCode = 0;
+ pcode->nextPCode = 0;
+ }
+ pcode->block = block;
+ block->pcodeCount++;
+}
+
+void deletepcode(PCode *pcode) {
+ PCBlock *block;
+
+ block = pcode->block;
+ if (pcode->prevPCode)
+ pcode->prevPCode->nextPCode = pcode->nextPCode;
+ else
+ block->firstPCode = pcode->nextPCode;
+ if (pcode->nextPCode)
+ pcode->nextPCode->prevPCode = pcode->prevPCode;
+ else
+ block->lastPCode = pcode->prevPCode;
+
+ pcode->block = 0;
+ block->pcodeCount--;
+ block->flags &= ~fPCBlockFlag8;
+}
+
+void insertpcodebefore(PCode *anchor, PCode *newpcode) {
+ PCBlock *block;
+
+ block = anchor->block;
+ if (anchor->prevPCode)
+ anchor->prevPCode->nextPCode = newpcode;
+ else
+ block->firstPCode = newpcode;
+ newpcode->nextPCode = anchor;
+ newpcode->prevPCode = anchor->prevPCode;
+ anchor->prevPCode = newpcode;
+ newpcode->_1C = anchor->_1C;
+
+ newpcode->block = block;
+ block->pcodeCount++;
+ block->flags &= ~fPCBlockFlag8;
+}
+
+void insertpcodeafter(PCode *anchor, PCode *newpcode) {
+ PCBlock *block;
+
+ block = anchor->block;
+ if (anchor->nextPCode)
+ anchor->nextPCode->prevPCode = newpcode;
+ else
+ block->lastPCode = newpcode;
+ newpcode->prevPCode = anchor;
+ newpcode->nextPCode = anchor->nextPCode;
+ anchor->nextPCode = newpcode;
+ newpcode->_1C = anchor->_1C;
+
+ newpcode->block = block;
+ block->pcodeCount++;
+ block->flags &= ~fPCBlockFlag8;
+}
+
+void setpcodeflags(int flags) {
+ pclastblock->lastPCode->flags |= flags;
+ if (flags & fSideEffects)
+ pclastblock->lastPCode->flags &= ~(fIsCSE | fCommutative | fPCodeFlag10);
+}
+
+void clearpcodeflags(int flags) {
+ pclastblock->lastPCode->flags &= ~flags;
+}
+
+int pccomputeoffsets() {
+ int offset;
+ PCBlock *block;
+
+ offset = 0;
+ for (block = pcbasicblocks; block; block = block->nextBlock) {
+ block->codeOffset = offset;
+ offset += block->pcodeCount * 4;
+ }
+
+ return offset;
+}
+
+typedef struct _DFO {
+ PCBlock *block;
+ PCLink *link;
+} DFO;
+
+static int depthfirstorder;
+
+void computedepthfirstordering() {
+ PCBlock *block;
+ PCLink *link;
+ DFO *dfo;
+ int index;
+
+ depthfirstordering = (PCBlock **) lalloc(sizeof(PCBlock *) * pcblockcount);
+ memclrw(depthfirstordering, sizeof(PCBlock *) * pcblockcount);
+ depthfirstorder = pcblockcount;
+
+ for (block = pcbasicblocks; block; block = block->nextBlock) {
+ block->flags &= ~fPCBlockFlag4;
+ }
+
+ dfo = (DFO *) oalloc(sizeof(DFO) * pcblockcount);
+ pcbasicblocks->flags |= fPCBlockFlag4;
+
+ dfo->block = pcbasicblocks;
+ dfo->link = pcbasicblocks->successors;
+ index = 1;
+ while (index) {
+ if ((link = dfo[index - 1].link)) {
+ dfo[index - 1].link = link->nextLink;
+ block = link->block;
+ if (!(block->flags & fPCBlockFlag4)) {
+ block->flags |= fPCBlockFlag4;
+ dfo[index].block = block;
+ dfo[index].link = block->successors;
+ index++;
+ }
+ } else {
+ depthfirstordering[--depthfirstorder] = dfo[--index].block;
+ }
+ }
+
+ while (depthfirstorder) {
+ depthfirstordering[--depthfirstorder] = 0;
+ }
+}