structure A = Assem structure T = Tree fun codegen (frame) (stm: Tree.stm) : Assem.instr list = let val ilist = ref (nil: A.instr list) fun emit x = ilist := x :: !ilist fun result (gen ) = let val t = Temp.newtemp() in gen t; t end fun munchStm (T.SEQ(a,b)) = (munchStm a; munchStm b) | munchStm (T.MOVE(T.MEM(T.BINOP(T.PLUS, e1, T.CONST i)), e2)) = (* sw Rsrc, address = sw e2, i(e1) *) emit (A.OPER{assem="sw 's0," ^ (Int.toString i) ^ "('s1)\n", src=[munchExp e1, munchExp e2], dst=[], jump=NONE}) | munchStm (T.MOVE(T.MEM(T.BINOP(T.PLUS, T.CONST i, e1)), e2)) = (* sw Rsrc, address = sw e2, i(e1) *) emit (A.OPER{assem="sw 's0," ^ (Int.toString i) ^ "('s1)\n", src=[munchExp e1, munchExp e2], dst=[], jump=NONE}) | munchStm (T.MOVE(T.MEM(e1),T.MEM(e2))) = emit (A.OPER {assem="sw 's0, 'd0\n", src=[munchExp (T.MEM(e1))], dst=[munchExp (T.MEM(e2))], jump=NONE}) | munchStm (T.MOVE(T.MEM(T.CONST i), e2)) = emit (A.OPER {assem="sw 's0, " ^ (Int.toString i) ^ "\n", src=[munchExp(e2)], dst=[],jump=NONE}) | munchStm (T.MOVE(T.MEM(e1), e2)) = (* M[e1] <- e2 *) emit (A.OPER {assem="sw 's0, 'd0\n", src=[munchExp(e1)], dst=[munchExp(e2)], jump=NONE}) | munchStm (T.MOVE(T.TEMP i, e2)) = (* i <- e2 *) emit (A.OPER {assem="move 'd0, ('s0)\n", src=[munchExp(e2)], dst=[i], jump=NONE}) | munchStm (T.LABEL lab) = (* LAB: I didn't double check the syntax of this one? *) emit (A.LABEL{assem=Temp.labelname(lab) ^ ":\n", lab=lab}) and munchExp (T.MEM(T.BINOP(T.PLUS, e1,T.CONST i))) = (* lw 'd0 M[i + e1] *) result (fn r => emit (A.OPER {assem="ld 'd0, " ^ (Int.toString i) ^ "('s0)\n", src=[munchExp(e1)], dst=[r], jump=NONE})) | munchExp (T.MEM(T.BINOP(T.PLUS,T.CONST i, e1))) = (* lw 'd0 M[i + e1] *) result (fn r => emit (A.OPER {assem="ld 'd0, " ^ (Int.toString i) ^ "('s0)\n", src=[munchExp(e1)], dst=[r], jump=NONE})) | munchExp (T.MEM(T.CONST i)) = result (fn r => emit (A.OPER {assem="ld 'd0, " ^ (Int.toString i) ^ "\n", src=[], dst=[r], jump=NONE})) | munchExp (T.MEM (e1)) = result (fn r => emit (A.OPER {assem="ld 'd0, ('s0)", src=[munchExp(e1)], dst=[r], jump=NONE})) (* adding : *) | munchExp (T.BINOP(T.PLUS, e1, T.CONST i)) = result (fn r => emit (A.OPER {assem="addi 'd0, ('s0), " ^ (Int.toString i) ^ "\n", src=[munchExp(e1)], dst=[r], jump=NONE})) | munchExp (T.BINOP (T.PLUS, T.CONST i, e1)) = result (fn r => emit (A.OPER {assem="addi 'd0, ('s0), " ^ (Int.toString i) ^ "\n", src=[munchExp(e1)], dst=[r], jump=NONE})) | munchExp (T.BINOP (T.PLUS, e1, e2)) = result (fn r => emit (A.OPER {assem="add 'd0, ('s0), ('s1)\n", src=[munchExp(e1), munchExp(e2)], dst=[r], jump=NONE})) (* subtracting: *) (* not sure if this one will work, can we have negitive immediate? *) | munchExp (T.BINOP(T.MINUS, e1, T.CONST i)) = result (fn r => emit (A.OPER {assem="addi 'd0, ('s0), -" ^ (Int.toString i) ^ "\n", src=[munchExp(e1)], dst=[r], jump=NONE})) | munchExp (T.BINOP (T.MINUS, T.CONST i, e1)) = result (fn r => (emit (A.OPER {assem="neg 's0, 's0", src=[munchExp(e1)], dst=[], jump=NONE}), emit (A.OPER {assem="addi 'd0, ('s0), " ^ (Int.toString i) ^ "\n", src=[munchExp(e1)], dst=[r], jump=NONE}))) | munchExp (T.BINOP (T.MINUS, e1, e2)) = result (fn r => emit (A.OPER {assem="sub 'd0, ('s0), ('s1)\n", src=[munchExp(e1), munchExp(e2)], dst=[r], jump=NONE})) (* MUL DIV: *) (* maybe we can fix powers-of-two mult to be shift *) | munchExp (T.BINOP(T.MUL, e1, T.CONST i)) = result (fn r => let val t = Temp.newtemp() in emit (A.OPER {assem="ld 's0, " ^ (Int.toString i) ^ "\n", src=[t], dst=[r], jump=NONE}); emit (A.OPER {assem="mul 'd0, ('s0), ('s1)", src=[munchExp(e1), t], dst=[r], jump=NONE}) end) | munchExp (T.BINOP (T.MUL, T.CONST i, e1)) = result (fn r => let val t = Temp.newtemp() in emit (A.OPER {assem="ld 's0, " ^ (Int.toString i) ^ "\n", src=[t], dst=[r], jump=NONE}); emit (A.OPER {assem="mul 'd0, ('s0), ('s1)", src=[munchExp(e1), t], dst=[r], jump=NONE}) end) | munchExp (T.BINOP (T.MUL, e1, e2)) = result (fn r => emit (A.OPER {assem="mul 'd0, ('s0), ('s1)\n", src=[munchExp(e1), munchExp(e2)], dst=[r], jump=NONE})) | munchExp (T.CONST i) = result (fn r => emit (A.OPER {assem="lw 'd0, " ^ (Int.toString i) ^ "\n", src=[], dst=[r], jump=NONE})) | munchExp (T.TEMP t) = t (*idono, this is how it was in the book? *) in munchStm stm; rev (!ilist) end