diff --git a/src/main/java/chocopy/pa3/CodeGenImpl.java b/src/main/java/chocopy/pa3/CodeGenImpl.java
index e7c8cee1d45128a4958b7e7512c53bec421c4585..f0443026ed9cb3f645ea737d1c46454d87e50eb0 100644
--- a/src/main/java/chocopy/pa3/CodeGenImpl.java
+++ b/src/main/java/chocopy/pa3/CodeGenImpl.java
@@ -1,9 +1,13 @@
 package chocopy.pa3;
 
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 
 import chocopy.common.analysis.SymbolTable;
 import chocopy.common.analysis.AbstractNodeAnalyzer;
+import chocopy.common.analysis.types.ValueType;
 import chocopy.common.astnodes.*;
 import chocopy.common.codegen.*;
 
@@ -51,8 +55,11 @@ public class CodeGenImpl extends CodeGenBase {
             backend.emitADDI(FP, SP, 2 * backend.getWordSize(), "Change FP to apply new frame.");
 
             // jal will set RA register properly.
+            // FIXME: Testing fucking silly $print
+            backend.emitADDI(SP, SP, 3 * backend.getWordSize(), "FUCKING SILLY BUILTIN CODE");
             backend.emitJAL(calledLabel, "Call it!");
 
+            backend.emitADDI(SP, FP, -2 * backend.getWordSize(), "Revert all local variables on this dying frame.");
             emitPop(FP, "restore parent FP.");
             emitPop(RA, "restore parent return address.");
         }
@@ -62,6 +69,59 @@ public class CodeGenImpl extends CodeGenBase {
             emitNoop(comment);
             backend.emitJR(RA, "Return to caller.");
         }
+        public void emitPushIntVal(RiscVBackend.Register tmpReg, Integer val, String comment) {
+            emitNoop(comment);
+            backend.emitLI(tmpReg, val, "INT VAL");
+            emitPush(tmpReg, null);
+            backend.emitLI(tmpReg, 0, "OBJECT HEAD - DISPATCH TBL = NULL");
+            emitPush(tmpReg, null);
+            backend.emitLI(tmpReg, 4, "OBJECT HEAD - SIZE = 3+1");
+            emitPush(tmpReg, null);
+            backend.emitLI(tmpReg, 1, "OBJECT HEAD - TYPE = INT");
+            emitPush(tmpReg, null);
+            backend.emitADDI(tmpReg, SP, backend.getWordSize(), "Return INT address.");
+        }
+    }
+
+    // Every function needs a register manager.
+    // Every variable should borrow a register, and maybe it's ok to never return it.
+    //     because our toy compiler will only be tested on naive program.
+    //     manager won't swap register to stack smartly (with graph coloring technic),
+    //     because it doesn't worth my effort(nobody pay for that).
+    private class registerManager {
+        private Map<RiscVBackend.Register, Boolean> usageMap; // true if the reg is in use.
+        registerManager() {
+            usageMap = new LinkedHashMap<>();
+            usageMap.put(T0, false);
+            usageMap.put(T1, false);
+            usageMap.put(T2, false);
+            usageMap.put(T3, false);
+            usageMap.put(T4, false);
+            usageMap.put(T5, false);
+            usageMap.put(T6, false);
+            usageMap.put(A0, false);
+            usageMap.put(A1, false);
+            usageMap.put(A2, false);
+            usageMap.put(A3, false);
+            usageMap.put(A4, false);
+            usageMap.put(A5, false);
+            usageMap.put(A6, false);
+            usageMap.put(A7, false);
+        }
+
+        public RiscVBackend.Register borrowOne() {
+            for(RiscVBackend.Register reg : usageMap.keySet()) {
+                if(usageMap.put(reg, true) == false) {
+                    return reg;
+                }
+            }
+            throw new RuntimeException("Too many variable, not enough register.");
+        }
+
+        public void returnOne(RiscVBackend.Register reg) {
+            boolean old = usageMap.put(reg, false);
+            assert old == true;
+        }
     }
 
     /** A code generator emitting instructions to BACKEND. */
@@ -174,6 +234,8 @@ public class CodeGenImpl extends CodeGenBase {
          *  level. */
         private FuncInfo funcInfo;
 
+        private registerManager regMgr = new registerManager();
+
         /** An analyzer for the function described by FUNCINFO0, which is null
          *  for the top level. */
         StmtAnalyzer(FuncInfo funcInfo0) {
@@ -210,19 +272,22 @@ public class CodeGenImpl extends CodeGenBase {
             if(called instanceof FuncInfo) {
                 FuncInfo func = (FuncInfo) called;
                 // TODO: Push the FUCKING arg0 (outter function frame ptr)
+                List<RiscVBackend.Register> args_reg = new ArrayList<>();
                 for(Expr expr : node.args) {
+                    // TODO: sub-expr may use stack.
                     RiscVBackend.Register result = expr.dispatch(this);
                     if(result == null) {
                         throw new RuntimeException("NotImplemented: Expression " + expr.getClass().getName() + " returns null register.");
                     }
-                    betterBackend.emitPush(result, "Push function arguments.");
+                    args_reg.add(result);
                 }
+                for(RiscVBackend.Register reg : args_reg)
+                    betterBackend.emitPush(reg, "Push function arguments.");
 
                 betterBackend.emitCall(func.getCodeLabel(), null);
 
-                for(Expr expr : node.args) {
+                for(Object reg : args_reg)
                     betterBackend.emitPop(null, "Pop function arguments.");
-                }
 
                 return A0; // Function return value is always in A0.
             }
@@ -234,8 +299,10 @@ public class CodeGenImpl extends CodeGenBase {
 
         @Override
         public RiscVBackend.Register analyze(IntegerLiteral node) {
-            backend.emitLI(T0, node.value, "Set constant int to reg.");
-            return T0;
+            // emitConstant(node, ValueType.INT_TYPE, "Set constant int literal.");
+            RiscVBackend.Register tmpReg = regMgr.borrowOne();
+            betterBackend.emitPushIntVal(tmpReg, node.value, "Push int literal");
+            return tmpReg;
         }
     }