#ifndef RENESASBOARD #include #include #endif /*RENESASBOARD*/ #include #include #include "engine.h" #include "heap.h" #include "show.h" #include "debug.h" #include "within.h" #define STACKSIZE 18 #define HEAPSIZE 42 #define WIRESIZE 152 #define nWires 5 #define nBoxes 3 #define nCons 0 uint16 wireCnt() { return nWires; } uint16 boxCnt() { return nBoxes; } wire_t wire[nWires]; box_t box[nBoxes]; STACK stack[STACKSIZE]; HEAP heap[HEAPSIZE + WIRESIZE]; /* box uses the bottom, while wires steal memory from the top */ #ifdef SUPPORT_DEBUG const char *boxName[nBoxes] = { "itermult", "mult2", "output" }; const char *wireName[nWires] = { "itermult0->itermult1", "mult21->itermult0", "mult22->output0", "itermult1->mult21", "mult20->mult20" }; const char *getBoxName(box_t *b) { return boxName[b - box]; } const char *getWireName(wire_t *w) { return wireName[w - wire]; } const char *getConName(uint16 c) { return "?"; } #else const char *getBoxName(box_t *b) { return NULL; } const char *getWireName(wire_t *w) { return NULL; } const char *getConName(uint16 c) { return NULL; } #endif /*SUPPORT_DEBUG*/ /* Constant Strings */ const char *str_0 = "\n"; int exitCode; char **arguments; /* NULL terminated */ extern char **environ; /* NULL terminated */ #include /* for STDOUT_FILENO */ int16 fd0 = STDOUT_FILENO; void ioGrpInit0() {/*nothing*/ } #include /* for STDERR_FILENO */ void ioInit2() { ioGrpInit0(); /* @TODO check the fd0 and panic if -1 */ } void ioOutput2() { HEAP *ptr = wire[2].available; if(ptr->tag == TSTR) { char *str = (char*)(ptr+1); int len = strlen(str); if(write(fd0, str, len) != len) { write(STDERR_FILENO, "\n", 16); exit(1); } } else { char buff[1000001]; int len = textValue(buff, 1000000, ptr); if(len != -1) { buff[len] = '\0'; if(write(fd0, buff, len) != len) { write(STDERR_FILENO, "\n", 16); exit(1); } } else { write(fd0, "\n", 21); write(STDERR_FILENO, "\n", 21); exit(1); } } wireConsume(wire+2); } /* * prepare the engine * */ void engineInit() { uint16 i; hpLimit = heap + HEAPSIZE + WIRESIZE; spLimit = STACKSIZE; initWithin(); updateCurrentTime(); for(i=0;i */ wireOutput(wire+0); } if(wire[3].pendingFlag) { /* wire to mult2 */ wireOutput(wire+3); if(box[1].state == BlockedIn) box[1].state = RunnableIn; } box[0].blockPattern = 0x8000; box[0].state = RunnableIn; } } /* box mult2 */ if(box[1].state == RunnableOut) { uint16 blocking = box[1].blockPattern; if(blocking) { blocking = 0x0000; if(wire[4].availableFlag && wire[4].pendingFlag) blocking |= 0x0001; if(wire[1].availableFlag && wire[1].pendingFlag) blocking |= 0x0002; if(wire[2].availableFlag && wire[2].pendingFlag) blocking |= 0x0004; box[1].blockPattern = blocking; box[1].state = BlockedOut; } if(!blocking) { if(wire[4].pendingFlag) { /* wire to */ wireOutput(wire+4); } if(wire[1].pendingFlag) { /* wire to itermult */ wireOutput(wire+1); if(box[0].state == BlockedIn) box[0].state = RunnableIn; } if(wire[2].pendingFlag) { /* wire to output */ wireOutput(wire+2); updateCurrentTime(); boxBegin(box+2); ioOutput2(); updateCurrentTime(); boxEnd(box+2); } box[1].blockPattern = 0x8000; box[1].state = RunnableIn; } } } /* * main function of the engine * */ void engineRun() { if(setjmp(excJmp) == 0) goto itermult_init; /* next init */ __humeHandle: #ifdef SUPPORT_DEBUG { exception_e exc = stack[sp-4].hp->tag - TCON; dumpException(stderr, exc); debugException(exc); } #endif /* No handlers */ currentBox->state = Dead; #ifdef SUPPORT_DEBUG dumpBox(stderr, currentBox); #endif /*SUPPORT_DEBUG*/ return; /* terminate on unhandled exception */ __humeNext: switch(currentBox - box) { case 0: goto mult2; /* next box */ case 1: goto __humeSuperstep; /* exit run */ case 2: goto __humeSuperstep; /* exit run */ } return; /* unreachable code? */ /* * Main scheduling loop * */ __humeSuperstep: currentBox = NULL; /* so the debugger knows we are superstep-ing */ output(); schedules++; if((nSchedules != 0) && (schedules > nSchedules)) return; goto itermult; /* next box */ /* * Function call return (i.e. goto ) * */ __humeReturn: switch(pc) { default: throwException(InternalError); } /* * box mult2 * - rules=1 * - nInputs=2 nOutputs=3 * */ mult2: /* -------------- 2: Label "mult2" */ if(box[1].state != RunnableIn) goto __humeSuperstep; /* exit run */ currentBox = box + 1; hp = heap; sp = 0; fp = 0; slp = 0; hpSoftLimit = heap + 30; spSoftLimit = 12; /* -------------- 3: Extension.CopyAllInputs */ stack[inc_sp()].hp = wireRead(wire+3); /* wire from itermult */ stack[inc_sp()].hp = wireRead(wire+4); /* wire from */ /* -------------- 5: Push 3 */ inc_spn(3); /* -------------- 6: CreateFrame 2 */ if(slp == 0) slp = sp + 1; stack[inc_sp()].sp = fp; fp = sp; inc_spn(2); rp = sp; mult2_0: /* -------------- 10: Extension.AvailSet 0 1 */ if(!wire[4].availableFlag || !wire[3].availableFlag) { box[1].state = BlockedIn; goto __humeSuperstep; /* exit run */ } /* -------------- 9: MatchRule */ mp = ARG(0)+1; sp = rp; /* -------------- 11: MatchVar 0 */ stack[VAR(0)] = stack[--mp]; /* -------------- 13: MatchVar 1 */ stack[VAR(1)] = stack[--mp]; /* -------------- 16: MatchedRule */ sp = rp; /* -------------- 14: Extension.ConsumeSet 0 1 */ #ifdef SUPPORT_DEBUG updateCurrentTime(); #endif /*SUPPORT_DEBUG*/ wireConsume(wire+4); wireConsume(wire+3); box[0].blockPattern &= 0xfffd; if(!box[0].blockPattern) box[0].state = RunnableOut; #ifdef SUPPORT_DEBUG boxBegin(box+1); #endif /*SUPPORT_DEBUG*/ /* -------------- 17: MkString "\n" */ stack[inc_sp()].hp = mkString((char*)str_0); /* -------------- 18: PushVar 1 */ stack[inc_sp()] = stack[VAR(1)]; /* -------------- 19: CallPrim "show" */ { HEAP *arg = stack[--sp].hp; stack[sp++].hp = show(arg); } /* -------------- 20: CallPrim "++" */ { HEAP *arg1 = stack[--sp].hp; HEAP *arg2 = stack[--sp].hp; if(arg1->tag == TSTR && arg2->tag == TSTR) { char *s1 = (char *) (arg1+1); char *s2 = (char *) (arg2+1); stack[sp++].hp = mkCatString(s1, s2); } else if(arg1->tag >= TCON && arg2->tag >= TCON) { /* assume they are lists */ HEAP *p = arg1; HEAP *r; HEAP **u = &r; while(p[1].lv == 2) { /* assume size=2 is a cons, copy the cons ':' cells of the 1st list */ *u = mkCon(1, 2); setHeap(p[2].hp); u = (HEAP**)(hp++); p = p[3].hp; } *u = stack[sp].hp; /* set the tail of last to the 2nd list */ stack[sp++].hp = r; } else if(arg1->tag == TVECTOR && arg2->tag == TVECTOR) { HEAP *vec = mkVector((arg1+1)->lv + (arg2+1)->lv); hp += (arg1+1)->lv + (arg2+1)->lv; memcpy(vec+2, arg1+2, sizeof(HEAP)*((arg1+1)->lv)); /* copy the first vector body */ memcpy(vec+2+(arg1+1)->lv, arg2+2, sizeof(HEAP)*((arg2+1)->lv)); /* copy the second vector body */ stack[sp++].hp = vec; } #ifndef NDEBUG else throwException(InternalError); #endif /*NDEBUG*/ } /* -------------- 21: PushVar 0 */ stack[inc_sp()] = stack[VAR(0)]; /* -------------- 22: PushVar 0 */ stack[inc_sp()] = stack[VAR(0)]; /* -------------- 23: MkInt 0 */ stack[inc_sp()].hp = mkInt(0); /* -------------- 24: MkTuple 3 */ { HEAP *tup = mkTup(3); setHeap(stack[--sp].hp); setHeap(stack[--sp].hp); setHeap(stack[--sp].hp); stack[inc_sp()].hp = tup; } /* -------------- 25: MkInt 1 */ stack[inc_sp()].hp = mkInt(1); /* -------------- 26: PushVar 0 */ stack[inc_sp()] = stack[VAR(0)]; /* -------------- 27: CallPrim "+" */ { HEAP *arg1 = stack[--sp].hp; HEAP *arg2 = stack[--sp].hp; if(arg1->tag == TINT && arg2->tag == TINT) { stack[sp++].hp = mkInt((arg1+1)->lv + (arg2+1)->lv); #ifdef SUPPORT_FLOAT } else if (arg1->tag == TFLOAT && arg2->tag == TFLOAT) { stack[sp++].hp = mkFloat((arg1+1)->fv + (arg2+1)->fv); #endif /*SUPPORT_FLOAT*/ } #ifndef NDEBUG else throwException(InternalError); #endif /*NDEBUG*/ } mult2_exit: /* -------------- 30: CheckOutputs */ updateCurrentTime(); boxEnd(box+1); wireSetPending(wire+4, 2, stack[sp-1].hp); /* wire to */ wireSetPending(wire+1, 11, stack[sp-2].hp); /* wire to itermult */ wireSetPending(wire+2, 50, stack[sp-3].hp); /* wire to output */ box[1].state = RunnableOut; goto __humeSuperstep; /* exit run */ /* * box itermult * - rules=2 * - nInputs=2 nOutputs=2 * */ itermult: /* -------------- 36: Label "itermult" */ if(box[0].state != RunnableIn) goto mult2; /* next box */ currentBox = box + 0; hp = heap; sp = 0; fp = 0; slp = 0; hpSoftLimit = heap + 42; spSoftLimit = 18; /* -------------- 37: Extension.CopyAllInputs */ stack[inc_sp()].hp = wireRead(wire+0); /* wire from */ stack[inc_sp()].hp = wireRead(wire+1); /* wire from mult2 */ /* -------------- 39: Push 3 */ inc_spn(3); /* -------------- 40: CreateFrame 3 */ if(slp == 0) slp = sp + 1; stack[inc_sp()].sp = fp; fp = sp; inc_spn(3); rp = sp; itermult_0: /* -------------- 44: Extension.AvailSet 0 */ if(!wire[1].availableFlag) { goto itermult_1; /* next rule */ } /* -------------- 43: MatchRule */ mp = ARG(0)+1; sp = rp; /* -------------- 45: MatchTuple 3 */ --mp; /* -------------- 46: MatchNone */ --mp; /* -------------- 47: CopyArg 0 */ stack[inc_sp()] = stack[ARG(0)]; /* -------------- 48: Unpack */ { HEAP *nodep = stack[--sp].hp; uint32 i; uint32 size = nodep[1].lv; for (i = 0; i < size; i++) stack[inc_sp()].hp = nodep[1+size-i].hp; mp = sp; } /* -------------- 49: MatchVar 0 */ stack[VAR(0)] = stack[--mp]; /* -------------- 50: MatchVar 1 */ stack[VAR(1)] = stack[--mp]; /* -------------- 51: MatchVar 2 */ stack[VAR(2)] = stack[--mp]; /* -------------- 54: MatchedRule */ sp = rp; /* -------------- 53: Extension.ConsumeSet 0 */ #ifdef SUPPORT_DEBUG updateCurrentTime(); #endif /*SUPPORT_DEBUG*/ wireConsume(wire+1); box[1].blockPattern &= 0xfffd; if(!box[1].blockPattern) box[1].state = RunnableOut; #ifdef SUPPORT_DEBUG boxBegin(box+0); #endif /*SUPPORT_DEBUG*/ /* -------------- 55: MkNone */ stack[inc_sp()].hp = NULL; /* -------------- 56: PushVar 2 */ stack[inc_sp()] = stack[VAR(2)]; /* -------------- 57: PushVar 1 */ stack[inc_sp()] = stack[VAR(1)]; /* -------------- 58: PushVar 0 */ stack[inc_sp()] = stack[VAR(0)]; /* -------------- 59: MkTuple 3 */ { HEAP *tup = mkTup(3); setHeap(stack[--sp].hp); setHeap(stack[--sp].hp); setHeap(stack[--sp].hp); stack[inc_sp()].hp = tup; } itermult_exit: /* -------------- 62: CheckOutputs */ updateCurrentTime(); boxEnd(box+0); wireSetPending(wire+0, 11, stack[sp-1].hp); /* wire to */ wireSetPending(wire+3, 2, stack[sp-2].hp); /* wire to mult2 */ box[0].state = RunnableOut; goto mult2; /* next box */ itermult_1: /* -------------- 70: Extension.AvailSet 1 */ if(!wire[0].availableFlag) { box[0].state = BlockedIn; goto mult2; /* next box */ } /* -------------- 68: MatchRule */ mp = ARG(0)+1; sp = rp; /* -------------- 69: MatchNone */ --mp; /* -------------- 71: MatchTuple 3 */ --mp; /* -------------- 72: CopyArg 1 */ stack[inc_sp()] = stack[ARG(1)]; /* -------------- 73: Unpack */ { HEAP *nodep = stack[--sp].hp; uint32 i; uint32 size = nodep[1].lv; for (i = 0; i < size; i++) stack[inc_sp()].hp = nodep[1+size-i].hp; mp = sp; } /* -------------- 74: MatchVar 0 */ stack[VAR(0)] = stack[--mp]; /* -------------- 75: MatchVar 1 */ stack[VAR(1)] = stack[--mp]; /* -------------- 76: MatchVar 2 */ stack[VAR(2)] = stack[--mp]; /* -------------- 79: MatchedRule */ sp = rp; /* -------------- 78: Extension.ConsumeSet 1 */ #ifdef SUPPORT_DEBUG updateCurrentTime(); #endif /*SUPPORT_DEBUG*/ wireConsume(wire+0); #ifdef SUPPORT_DEBUG boxBegin(box+0); #endif /*SUPPORT_DEBUG*/ /* -------------- 80: MkInt 0 */ stack[inc_sp()].hp = mkInt(0); /* -------------- 81: PushVar 2 */ stack[inc_sp()] = stack[VAR(2)]; /* -------------- 82: CallPrim "==" */ { HEAP *arg1 = stack[--sp].hp; HEAP *arg2 = stack[--sp].hp; stack[sp++].hp = mkBool(cmpPrim(arg1, arg2, TRUE, FALSE)); } /* -------------- 83: If "t_itermult_1_0" */ if(stack[--sp].hp[1].lv == TRUE) goto t_itermult_1_0; /* -------------- 84: MkNone */ stack[inc_sp()].hp = NULL; /* -------------- 85: MkInt 1 */ stack[inc_sp()].hp = mkInt(1); /* -------------- 86: PushVar 2 */ stack[inc_sp()] = stack[VAR(2)]; /* -------------- 87: CallPrim "-" */ { HEAP *arg1 = stack[--sp].hp; HEAP *arg2 = stack[--sp].hp; if(arg1->tag == TINT && arg2->tag == TINT) { stack[sp++].hp = mkInt((arg1+1)->lv - (arg2+1)->lv); #ifdef SUPPORT_FLOAT } else if (arg1->tag == TFLOAT && arg2->tag == TFLOAT) { stack[sp++].hp = mkFloat((arg1+1)->fv - (arg2+1)->fv); #endif /*SUPPORT_FLOAT*/ } #ifndef NDEBUG else throwException(InternalError); #endif /*NDEBUG*/ } /* -------------- 88: PushVar 1 */ stack[inc_sp()] = stack[VAR(1)]; /* -------------- 89: PushVar 1 */ stack[inc_sp()] = stack[VAR(1)]; /* -------------- 90: PushVar 0 */ stack[inc_sp()] = stack[VAR(0)]; /* -------------- 91: CallPrim "+" */ { HEAP *arg1 = stack[--sp].hp; HEAP *arg2 = stack[--sp].hp; if(arg1->tag == TINT && arg2->tag == TINT) { stack[sp++].hp = mkInt((arg1+1)->lv + (arg2+1)->lv); #ifdef SUPPORT_FLOAT } else if (arg1->tag == TFLOAT && arg2->tag == TFLOAT) { stack[sp++].hp = mkFloat((arg1+1)->fv + (arg2+1)->fv); #endif /*SUPPORT_FLOAT*/ } #ifndef NDEBUG else throwException(InternalError); #endif /*NDEBUG*/ } /* -------------- 92: MkTuple 3 */ { HEAP *tup = mkTup(3); setHeap(stack[--sp].hp); setHeap(stack[--sp].hp); setHeap(stack[--sp].hp); stack[inc_sp()].hp = tup; } /* -------------- 93: MkTuple 2 */ { HEAP *tup = mkTup(2); setHeap(stack[--sp].hp); setHeap(stack[--sp].hp); stack[inc_sp()].hp = tup; } /* -------------- 94: Goto "n_itermult_1_0" */ goto n_itermult_1_0; t_itermult_1_0: /* -------------- 97: PushVar 0 */ stack[inc_sp()] = stack[VAR(0)]; /* -------------- 98: MkNone */ stack[inc_sp()].hp = NULL; /* -------------- 99: MkTuple 2 */ { HEAP *tup = mkTup(2); setHeap(stack[--sp].hp); setHeap(stack[--sp].hp); stack[inc_sp()].hp = tup; } n_itermult_1_0: /* -------------- 102: Unpack */ { HEAP *nodep = stack[--sp].hp; uint32 i; uint32 size = nodep[1].lv; for (i = 0; i < size; i++) stack[inc_sp()].hp = nodep[1+size-i].hp; mp = sp; } /* -------------- 103: Goto "itermult_exit" */ goto itermult_exit; /* * init itermult_init * - nOutputs=2 * */ itermult_init: /* -------------- 117: Label "itermult_init" */ currentBox = box + 0; hp = heap; sp = 0; fp = 0; slp = 0; hpSoftLimit = heap + 42; spSoftLimit = 18; /* -------------- 118: MkInt 0 */ stack[inc_sp()].hp = mkInt(0); /* -------------- 119: Write 1 */ wireSetPending(wire+3, 2, stack[--sp].hp); /* wire to mult2 */ /* -------------- 120: Schedule */ box[0].state = RunnableOut; goto mult2_init; /* next init */ /* * init mult2_init * - nOutputs=3 * */ mult2_init: /* -------------- 122: Label "mult2_init" */ currentBox = box + 1; hp = heap; sp = 0; fp = 0; slp = 0; hpSoftLimit = heap + 30; spSoftLimit = 12; /* -------------- 123: MkInt 0 */ stack[inc_sp()].hp = mkInt(0); /* -------------- 124: Write 0 */ wireSetPending(wire+4, 2, stack[--sp].hp); /* wire to */ /* -------------- 125: Schedule */ box[1].state = RunnableOut; goto __humeSuperstep; /* exit init */ } int main2(int argc, char *argv[]) { arguments = argv; /* only useful for boxes that read main_args */ exitCode = 0; /* only useful for boxes that write to main_exit */ engineInit(); #ifdef SUPPORT_DEBUG debugInit("/tmp_mnt/3/staff/greg/EmBounded/EmBounded/local/hwu/Budapest/itermult.ham"); #endif /*SUPPORT_DEBUG*/ engineRun(); #ifdef SUPPORT_DEBUG { uint16 i; dumpState(stderr); for(i=0;i