diff --git a/sources/zweic/Generator.scala b/sources/zweic/Generator.scala index 3787729..76cb878 100644 --- a/sources/zweic/Generator.scala +++ b/sources/zweic/Generator.scala @@ -24,11 +24,16 @@ val lowBits = value & 0xFFFF; if (highBits != 0) { - code.emit(ORIU, r, ZERO, highBits, value.toString()+"<<"); - code.emit(LSHI, r, r, 16, "<< 16"); + code.emit(ORIU, r, ZERO, highBits, value.toString()+" high Bits"); + code.emit(LSHI, r, r, 16, "<<"); + } + + if (lowBits != 0) { code.emit(ORIU, r, ZERO, lowBits, value.toString()); - } else { - code.emit(ORIU, r, ZERO, lowBits, value.toString()); + } + + if (highBits == 0 && lowBits == 0) { + code.emit(ORIU, r, ZERO, ZERO, "0"); } } @@ -48,13 +53,15 @@ } } - // generate class and function definitions + // generate class and function definitions classes.foreach(gen); - genTmp { tmpReg => - emitLoadConstant(tmpReg, offset); - code.emit(SYSCALL, tmpReg, tmpReg, SYS_GC_ALLOC); - } + //TODO: what was that??? its writing some stuff in fromt of the program... + //TODO: allocation what???? + //genTmp { tmpReg => + // emitLoadConstant(tmpReg, offset); + // code.emit(SYSCALL, tmpReg, tmpReg, SYS_GC_ALLOC); + // } // generate main expression val start = code.getLabel(); @@ -83,22 +90,26 @@ emitLoadConstant(r3,SP << 27); code.emit(ADD, r2, r2, r3); code.emit(SYSCALL, r1, r2, SYS_GC_INIT); - code.freeRegister(r3); - code.freeRegister(r2); code.freeRegister(r1); + code.freeRegister(r2); + code.freeRegister(r3); - // populate VMTs - genTmp { classHeader => - genTmp { methodAddr => - for ( val ClassDef(cname, _, members) <- classes ) { + + // populate VMTs + genTmp { classHeader => + + for ( val ClassDef(cname, _, members) <- classes ) { emitLoadConstant(classHeader, cname.sym.offset); for ( val m <- cname.sym.asInstanceOf[ClassSymbol].allMethods ) { - emitLoadConstant(methodAddr, m.address); - code.emit(STW, methodAddr, classHeader, m.offset); + //TODO: why use LNK here? don't we use a normal register??? + emitLoadConstant(LNK, m.address); + code.emit(STW, LNK, classHeader, m.offset, + cname.name + "::" + m.name); } + } } - } - } + + // jump to main expression code.emit(BEQ, ZERO, start); @@ -110,32 +121,31 @@ case FieldDecl(_) => ; case method @ MethodDef(name, params, _, body) => - val oldFrameSize = code.getFrameSize(); - code.decFrameSize(oldFrameSize); // fs = 0 - code.incFrameSize(params.length*4+4); // fs = params + this + val oldFrameSize = code.getFrameSize(); + code.decFrameSize(oldFrameSize); // fs = 0 + code.incFrameSize(params.length*4+4); // fs = params + this - code.emit(PSH, LNK, SP, 4, "def "+ method.self+"::"+name); - code.incFrameSize(4); // fs = params + this + lnk + code.emit(PSH, LNK, SP, 4, "def "+ method.self+"::"+name); + code.incFrameSize(4); // fs = params + this + lnk - name.sym.asInstanceOf[MethodSymbol].address = code.pc(); + name.sym.asInstanceOf[MethodSymbol].address = code.pc(); - code.getRegister(RES); - genLoad(body, RES); // fs = params + this + lnk + ... - code.freeRegister(RES); + code.getRegister(RES); + genLoad(body, RES); // fs = params + this + lnk + ... + code.freeRegister(RES); + code.emit(SUBI, SP, SP, code.getFrameSize() - (4+4+4*params.length) ); + code.decFrameSize(code.getFrameSize()); // fs = 0 + code.incFrameSize(4+4+4*params.length); // fs = params + this + lnk - code.emit(SUBI, SP, SP, code.getFrameSize() - (4+4+4*params.length) ); - code.decFrameSize(code.getFrameSize()); // fs = 0 - code.incFrameSize(4+4+4*params.length); // fs = params + this + lnk + code.emit(POP, LNK, SP, 4); + code.decFrameSize(4); // fs = params + this - code.emit(POP, LNK, SP, 4); - code.decFrameSize(4); // fs = params + this + code.emit(SUBI, SP, SP, params.length*4+4); + code.decFrameSize(code.getFrameSize()); // fs = 0 + code.incFrameSize(oldFrameSize); // fs = oldframesize - code.emit(SUBI, SP, SP, params.length*4+4); - code.decFrameSize(code.getFrameSize()); // fs = 0 - code.incFrameSize(oldFrameSize); // fs = oldframesize - - code.emit(RET, LNK); + code.emit(RET, LNK, "end -- " + method.self + "::" + name); @@ -158,7 +168,7 @@ genTmp { tmpReg => genLoad(init, tmpReg); varname.sym.offset = code.getFrameSize() + 4; - code.emit(PSH, tmpReg, SP, 4); + code.emit(PSH, tmpReg, SP, 4, "var " + varname.name); code.incFrameSize(4); } @@ -189,16 +199,15 @@ } case _ => - - //Console.println("gen __________________________________" + tree); error("gen: " + tree); } // def gen(Tree): Unit def genLoad(tree: Expr, targetReg: Int): Unit = { - def caseDefault(tree: Expr): Unit = genLoad( - new If(tree, new IntLit(1), new IntLit(0)), - targetReg); + //TODO: what the hell is that supposed to be??? + //def caseDefault(tree: Expr): Unit = genLoad( + // new If(tree, new IntLit(1), new IntLit(0)), + // targetReg); assert(code.usedRegisters()(targetReg), "invariant violated: target register R" @@ -220,15 +229,15 @@ case Unop(op, expr) => op match { case Operators.NOT => - val store1 = code.getLabel(); - val end = code.getLabel(); + val storeTrue = code.getLabel(); + val stored = code.getLabel(); - genCond(expr, store1, false); + genCond(expr, storeTrue, false); emitLoadConstant(targetReg, 0); - code.emit(BEQ, ZERO, end); - code.anchorLabel(store1); + code.emit(BEQ, ZERO, stored); + code.anchorLabel(storeTrue); emitLoadConstant(targetReg, 1); - code.anchorLabel(end); + code.anchorLabel(stored); case Operators.NEG => genLoad(expr, targetReg); @@ -271,8 +280,11 @@ stats.foreach(gen); code.getRegister(targetReg); genLoad(main, targetReg); - - code.emit(SUBI, SP, SP, fs-code.getFrameSize()); + + //OPTIMISATION: only reset SP if it has changed + if (code.getFrameSize() - fs != 0) { + code.emit(ADDI, SP, SP, code.getFrameSize()-fs, "end of block SP reset"); + } code.decFrameSize(code.getFrameSize()); code.incFrameSize(fs); @@ -284,38 +296,38 @@ } case New(name, args) => - val af = name.sym.asInstanceOf[ClassSymbol].allFields; - genTmp { tmpReg => - emitLoadConstant(tmpReg, 4+af.length*4); - code.emit(SYSCALL, targetReg, tmpReg, SYS_GC_ALLOC, " allocate memory for instance of '"+name+"'"); + val af = name.sym.asInstanceOf[ClassSymbol].allFields; + emitLoadConstant(targetReg, 4+af.length*4); + code.emit(SYSCALL, targetReg, targetReg, SYS_GC_ALLOC, "new "+name); - /* pointer to class header */ - emitLoadConstant(tmpReg, name.sym.offset); - code.emit(STW, tmpReg, targetReg, 0); + genTmp { tmpReg => + /* pointer to class header */ + emitLoadConstant(tmpReg, name.sym.offset); + code.emit(STW, tmpReg, targetReg, 0); - /* class variables */ - for ( val x <- args.zip(af) ) { + /* class variables */ + for ( val x <- args.zip(af) ) { genLoad(x._1, tmpReg); code.emit(STW, tmpReg, targetReg, x._2.offset+4); - } - } + } + } case Select(prefix, selector) => - genLoad(prefix, targetReg); + genLoad(prefix, targetReg); - val okLabel = code.getLabel(); + val okLabel = code.getLabel(); - // check prefix != null - code.emit(BNE, targetReg, okLabel); - emitLoadConstant(targetReg, 1); - code.emit(SYSCALL, targetReg, ZERO, SYS_EXIT); + // check prefix != null + code.emit(BNE, targetReg, okLabel); + emitLoadConstant(targetReg, 1); + code.emit(SYSCALL, targetReg, ZERO, SYS_EXIT); - code.anchorLabel(okLabel); + code.anchorLabel(okLabel); - code.emit(LDW, targetReg, targetReg, selector.sym.offset+4); + code.emit(LDW, targetReg, targetReg, selector.sym.offset+4); - case Call(receiver, method, args) => - + + case Call(receiver, method, args) => // put all registers on stack val used = code.usedRegisters(); var freed:List[Int] = Nil; @@ -350,25 +362,24 @@ code.incFrameSize(4); } } - //load method address code.emit(LDW, targetReg, targetReg, method.sym.offset); - // check receiver.method() != null - val okLabel2 = code.getLabel(); - code.emit(BNE, targetReg, okLabel2); - emitLoadConstant(targetReg, 1); - code.emit(SYSCALL, targetReg, ZERO, SYS_EXIT); - code.anchorLabel(okLabel2); - - //set return address - code.emit(SUBI, LNK, SP, 4, "store return address"); +// //TODO +// // check receiver.method() != null +// val okLabel2 = code.getLabel(); +// code.emit(BNE, targetReg, okLabel2); +// emitLoadConstant(targetReg, 1); +// code.emit(SYSCALL, targetReg, ZERO, SYS_EXIT); +// code.anchorLabel(okLabel2); //call function + code.emit(ADD, 1, ZERO, ZERO, "call " + + method.sym.name.toString() + " offset:" + method.sym.offset.toString()); code.emit(RET, targetReg); //store return value - code.emit(ADD, targetReg, ZERO, RES); + code.emit(ADD, targetReg, ZERO, RES, "store return value to target reg"); code.decFrameSize(args.length*4+4); // fs = oldframesize - params - this @@ -406,61 +417,22 @@ tree match { case Binop(op, left, right) => { genTmp { tmpLeft => - genTmp { tmpRight => genLoad(left, tmpLeft); + genTmp { tmpRight => genLoad(right, tmpRight); + op match { // TODO do all this with CMP !!! case Operators.EQ => - code.emit(CMP, tmpLeft, tmpLeft, tmpRight, ""); + code.emit(CMP, tmpLeft, tmpLeft, tmpRight, "=="); if ( when ) { - code.emit(BNE, tmpLeft, targetLabel); - } else { code.emit(BEQ, tmpLeft, targetLabel); + } else { + code.emit(BNE, tmpLeft, targetLabel); } case Operators.NE => - code.emit(CMP, tmpLeft, tmpLeft, tmpRight, ""); - if ( when ) { - code.emit(BEQ, tmpLeft, targetLabel); - } else { - code.emit(BNE, tmpLeft, targetLabel); - } - - case Operators.ADD => - code.emit(ADD, tmpLeft, tmpLeft, tmpRight); - if ( when ) { - code.emit(BNE, tmpLeft, targetLabel); - } else { - code.emit(BEQ, tmpLeft, targetLabel); - } - - case Operators.SUB => - code.emit(CMP, tmpLeft, tmpLeft, tmpRight); - if ( when ) { - code.emit(BNE, tmpLeft, targetLabel); - } else { - code.emit(BEQ, tmpLeft, targetLabel); - } - - case Operators.MUL => - code.emit(MUL, tmpLeft, tmpLeft, tmpRight); - if ( when ) { - code.emit(BNE, tmpLeft, targetLabel); - } else { - code.emit(BEQ, tmpLeft, targetLabel); - } - - case Operators.DIV => - code.emit(DIV, tmpLeft, tmpLeft, tmpRight); - if ( when ) { - code.emit(BNE, tmpLeft, targetLabel); - } else { - code.emit(BEQ, tmpLeft, targetLabel); - } - - case Operators.MOD => - code.emit(MOD, tmpLeft, tmpLeft, tmpRight); + code.emit(CMP, tmpLeft, tmpLeft, tmpRight, "!="); if ( when ) { code.emit(BNE, tmpLeft, targetLabel); } else { @@ -506,6 +478,47 @@ } else { code.emit(BEQ, tmpLeft, targetLabel); } + +// case Operators.ADD => +// code.emit(ADD, tmpLeft, tmpLeft, tmpRight); +// if ( when ) { +// code.emit(BNE, tmpLeft, targetLabel); +// } else { +// code.emit(BEQ, tmpLeft, targetLabel); +// } + +// case Operators.SUB => +// code.emit(CMP, tmpLeft, tmpLeft, tmpRight); +// if ( when ) { +// code.emit(BNE, tmpLeft, targetLabel); +// } else { +// code.emit(BEQ, tmpLeft, targetLabel); +// } + +// case Operators.MUL => +// code.emit(MUL, tmpLeft, tmpLeft, tmpRight); +// if ( when ) { +// code.emit(BNE, tmpLeft, targetLabel); +// } else { +// code.emit(BEQ, tmpLeft, targetLabel); +// } + +// case Operators.DIV => +// code.emit(DIV, tmpLeft, tmpLeft, tmpRight); +// if ( when ) { +// code.emit(BNE, tmpLeft, targetLabel); +// } else { +// code.emit(BEQ, tmpLeft, targetLabel); +// } + +// case Operators.MOD => +// code.emit(MOD, tmpLeft, tmpLeft, tmpRight); +// if ( when ) { +// code.emit(BNE, tmpLeft, targetLabel); +// } else { +// code.emit(BEQ, tmpLeft, targetLabel); +// } + case _ => genLoad(tree, tmpLeft); if ( when ) { @@ -516,29 +529,26 @@ } } } - () } - case Unop(op, expr) => { - op match { - case Operators.NOT => - genCond(expr, targetLabel, !when); - case Operators.NEG => - genCond(expr, targetLabel, when); - } - () + case Unop(op, expr) => { + op match { + case Operators.NOT => + genCond(expr, targetLabel, !when); + case Operators.NEG => + genCond(expr, targetLabel, when); } + } - case _ => + case _ => genTmp { tmpReg => - genLoad(tree, tmpReg); - if ( when ) { - code.emit(BNE, tmpReg, targetLabel); - } else { - code.emit(BEQ, tmpReg, targetLabel); - } - } - () + genLoad(tree, tmpReg); + if ( when ) { + code.emit(BNE, tmpReg, targetLabel); + } else { + code.emit(BEQ, tmpReg, targetLabel); + } + } } } // genCond diff --git a/tests/5/cond_not.zwei b/tests/5/cond_not.zwei index 234ae64..622f1f2 100644 --- a/tests/5/cond_not.zwei +++ b/tests/5/cond_not.zwei @@ -1,11 +1,11 @@ //#isut { -//#1 +//#0 +printInt(!17); +//#1\n printInt(1); -//#0\n -printInt(!1); printChar(10); //#01 diff --git a/tests/5/if.zwei b/tests/5/if.zwei index caca64d..fdee25e 100644 --- a/tests/5/if.zwei +++ b/tests/5/if.zwei @@ -7,4 +7,5 @@ else (4 -7) * 5 ); + } \ No newline at end of file diff --git a/tests/5/new.zwei b/tests/5/new.zwei index acbf81a..850993a 100644 --- a/tests/5/new.zwei +++ b/tests/5/new.zwei @@ -1,4 +1,4 @@ -//this is a yet untested file... +//#startut class A { Int a; Int b;