From ad37f72dee0b15c4c3072870c3f4a91c6e31ae4e Mon Sep 17 00:00:00 2001
From: luxia <linluxia@buaa.edu.cn>
Date: Tue, 26 Jul 2022 16:31:25 +0800
Subject: [PATCH] fix: invalid immediate number when stack change

---
 .DS_Store                                     | Bin 0 -> 8196 bytes
 .gitignore                                    |   4 +-
 lib/antlr-4.8-complete.jar                    | Bin
 .../machineCode/Instruction/LoadImm.java      |  16 +++--
 .../machineCode/Operand/ImmediateNumber.java  |  61 ++++++++++++++++--
 src/backend/pass/InstructionSelector.java     |  24 ++++---
 src/backend/pass/RegAllocator.java            |  13 +++-
 src/run.py                                    |  24 +++----
 8 files changed, 106 insertions(+), 36 deletions(-)
 create mode 100644 .DS_Store
 mode change 100644 => 100755 lib/antlr-4.8-complete.jar

diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..adcd479f6621d1bb6cce8a49a577ad2ef16f984c
GIT binary patch
literal 8196
zcmeHMO>fgc5S>i|aVSWU0MQGQC9Y9PX+^2Hgfs|o;DQkxC<<{LrBNMk6gxyHij*6I
z@;^9o<PUJ-2k>7wg|{E6Vy8J4P??c--+K1V+WXdPdlDiN^--`*v`It`io)^+sxwUW
ztFmG_>$wgTh$q?hL+RtFyuxJ%E5Hh{0;~WlzzX~u3gDfs%vtl^H@#f50<6G)sepPu
zxF`y17H0<aqXU&r0e}U#wV|y){(-J?0BaU!2H}AT6ACn;!loF)<_^MyqrYbPGlM3a
zgg!IIv1b-GLlHLh5U!?^s2Sv%6<`Hc6;Qc*o<i!8|1?bH?~l;4HP@!YEXyCq1DoZ4
z^9NxsPO8<PB9|{*x?FUM&W7{GJCb8BX(gk$-WtAEM=zud{YAUwzwC9!&GL-{86~Y=
z)EVl4UeE#M@KrAg<hU+JQ4s4`&vZB?r_?OpnoRZ{RNS5Yy=ldr?BA<a+})k~(`m`M
zdFSrK=gs4=AIXnqmcl+M=$bh`tv{h<C-cr5Mxl(l@F;eUp3y;C2Jr>{&r33B&czTx
zPbKVbdu`btV44fl{=RH9>^eL1{7L!n$#-=}*uG$G-{9!%@iJ0hh14DDQj0u#Pch0C
z?!i8VY5D0Z&Y8XoC5<Rav&8KcR!l=`XILj^vo6MB<{=`coRPV>ByX2?GlKle2;xwJ
zMTt?ju`n@p(tP>>{s*%c=5w@H_(9wbeQb8MnXY69!wSdg0ds2OEw8THhUNv%?|(?c
z#tNLH0(mp`rpo^xumAo39It?fW(8P*zpa2MG`vO~SF!kF&R&qpwOy3AD9RLXW>ANq
k(&;!*r{loWKMc`!K~*s|i!+1p!1#v%Edy7qz#moMH$E6X`2YX_

literal 0
HcmV?d00001

diff --git a/.gitignore b/.gitignore
index 4bd337a..94a9d2b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,5 +2,5 @@
 /out/
 /testcase/
 /.idea/
-src/backend/test/
-/MC/
\ No newline at end of file
+/src/backend/test/*
+/MC/
diff --git a/lib/antlr-4.8-complete.jar b/lib/antlr-4.8-complete.jar
old mode 100644
new mode 100755
diff --git a/src/backend/machineCode/Instruction/LoadImm.java b/src/backend/machineCode/Instruction/LoadImm.java
index 28f4454..7535ed4 100644
--- a/src/backend/machineCode/Instruction/LoadImm.java
+++ b/src/backend/machineCode/Instruction/LoadImm.java
@@ -51,13 +51,17 @@ public class LoadImm extends MachineInstruction {
                     .append(", #:lower16:").append(((Addressable) src).getLabel()).append("\n")
                     .append("\tmovt\t").append(dest)
                     .append(", #:upper16:").append(((Addressable) src).getLabel()).append("\n");
-        } else if (src instanceof ImmediateNumber){
+        } else if (src instanceof ImmediateNumber) {
             int value = ((ImmediateNumber) src).getValue();
-            if(ImmediateNumber.isLegalImm(value)){
-                sb.append("mov\t").append(dest).append(", ").append(value);
-            }else
-            sb.append("movw\t").append(dest).append(", ").append(value & 0xFFFF).append("\n")
-                    .append("\tmovt\t").append(dest).append(", ").append((value & 0xFFFF0000)>>>16).append("\n");
+            if (ImmediateNumber.isLegalImm(value)) {
+                if (dest.isFloat())
+                    sb.append("v");
+                sb.append("mov");
+                if (dest.isFloat()) sb.append(typeInfoString());
+                sb.append("\t").append(dest).append(", ").append(value);
+            } else
+                sb.append("movw\t").append(dest).append(", ").append(value & 0xFFFF).append("\n")
+                        .append("\tmovt\t").append(dest).append(", ").append((value & 0xFFFF0000) >>> 16).append("\n");
         } else {
             throw new RuntimeException("Unknown type");
         }
diff --git a/src/backend/machineCode/Operand/ImmediateNumber.java b/src/backend/machineCode/Operand/ImmediateNumber.java
index ab6f964..1f0e4e6 100644
--- a/src/backend/machineCode/Operand/ImmediateNumber.java
+++ b/src/backend/machineCode/Operand/ImmediateNumber.java
@@ -1,18 +1,24 @@
 package backend.machineCode.Operand;
 
+import backend.machineCode.Instruction.LoadImm;
 import backend.machineCode.Instruction.LoadOrStore;
 import backend.machineCode.Instruction.Move;
 import backend.machineCode.MachineBasicBlock;
 import backend.machineCode.MachineInstruction;
+import util.IListNode;
+
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.Arrays;
 
 public class ImmediateNumber extends MCOperand {
     public int getValue() {
         return value;
     }
 
-    public enum Type{
-       Int,
-       Float;
+    public enum Type {
+        Int,
+        Float;
     }
 
     final int value;
@@ -44,14 +50,57 @@ public class ImmediateNumber extends MCOperand {
     }
 
 
-    static public MachineInstruction loadNum(MachineBasicBlock parent, Register reg, int num) {
+    static public Register loadNum(MachineBasicBlock parent, Register reg, int num) {
         if (isLegalImm(num)) {
-            return new Move(parent, reg, new ImmediateNumber(num));
+            new Move(parent, reg, new ImmediateNumber(num)).setForFloat(reg.isFloat(), new ArrayList<>(Arrays.asList("32"))).pushBacktoInstList();
+            return reg;
         } else {
-            return new LoadOrStore(parent, LoadOrStore.Type.LOAD, reg, new ImmediateNumber(num));
+
+
+                 if(! reg.isFloat()){
+                     new LoadImm(parent, reg, num).pushBacktoInstList();
+                     return reg;
+                 } else{
+                     var temp = new VirtualRegister();
+                     new LoadImm(parent, temp, num).pushBacktoInstList();
+                     new Move(parent, reg, temp);
+                     return reg;
+                 }
+
         }
     }
 
+    static public MCOperand getLegalOperand(MachineBasicBlock parent, int value) {
+        if (isLegalImm(value)) {
+            return new ImmediateNumber(value);
+        } else {
+            Register reg = new VirtualRegister();
+            new LoadImm(parent, reg, value).pushBacktoInstList();
+            return reg;
+        }
+    }
+
+    static public MCOperand getLegalOperandInsertBefore(IListNode<MachineInstruction, MachineBasicBlock> node, int value) {
+        if (isLegalImm(value)) {
+            return new ImmediateNumber(value);
+        } else {
+            Register reg = new VirtualRegister();
+            new LoadImm(node.getParent().getVal(), reg, value).getInstNode().insertBefore(node);
+            return reg;
+        }
+    }
+
+    static public MCOperand getLegalOperand(MachineBasicBlock parent, int value, Register.Content type) {
+        if (isLegalImm(value)) {
+            return new ImmediateNumber(value);
+        } else {
+            Register reg = new VirtualRegister(type);
+            new LoadImm(parent, reg, value).pushBacktoInstList();
+            return reg;
+        }
+    }
+
+
     @Override
     public String toString() {
         return (isLegalImm ? "#" : "") + value;
diff --git a/src/backend/pass/InstructionSelector.java b/src/backend/pass/InstructionSelector.java
index d7ec92e..88f838b 100644
--- a/src/backend/pass/InstructionSelector.java
+++ b/src/backend/pass/InstructionSelector.java
@@ -110,6 +110,12 @@ public class InstructionSelector {
             mbb.pushBacktoBBList();
             bbMap.put(bb, mbb);
         }
+        for(var bb: bbList){
+            for(var inst : bb.getInstList()){
+                if(inst.getOp() == Instruction.Ops.Call)
+                    mf.setLeaf(false);
+            }
+        }
 
         // 稍微处理了一下参数。。。这个不太行。目前是用Virtual Regitser又转存了一次。TODO: 在完成Phi指令的时候应该顺便修改这里
         var firstbb = mf.getBbList().getFirst().getVal();
@@ -137,6 +143,11 @@ public class InstructionSelector {
 
             translateBB(bb);
         }
+
+        //
+        MachineInstruction newInst = new PushOrPop(mf.getBbList().getFirst().getVal(), PushOrPop.Type.Push, new MCRegister(MCRegister.RegName.LR));
+        newInst.setPrologue(true);
+        newInst.pushtofront();
     }
 
     private void translateBB(BasicBlock bb) {
@@ -159,20 +170,17 @@ public class InstructionSelector {
         var mbb = mf.getBBMap().get(bb);
         var valueMap = mf.getValueMap();
         new Comment(mbb, ir.toString()).pushBacktoInstList();
+
         switch (ir.getOp()) {
             case Ret -> {
                 if (ir.getNumOperands() == 1) {
                     var op1 = ir.getOperand(0);
                     new Move(mbb, new MCRegister(MCRegister.RegName.r0), valueToMCOperand(mbb, op1)).pushBacktoInstList();
                 }
-
+                MachineInstruction newInst;
                 // 不管是不是叶子节点都push了,为了解决栈上参数的问题 TODO:未来修改
-                MachineInstruction newInst = new PushOrPop(mf.getBbList().getFirst().getVal(), PushOrPop.Type.Push, new MCRegister(MCRegister.RegName.LR));
-                newInst.setPrologue(true);
-                newInst.pushtofront();
-
                 if (mf.isLeaf()) {
-                    newInst = new Branch(mbb, new MCRegister(MCRegister.RegName.LR), false, Branch.Type.Ret);
+                     newInst = new Branch(mbb, new MCRegister(MCRegister.RegName.LR), false, Branch.Type.Ret);
 
                 } else {
                     newInst = new PushOrPop(mbb, PushOrPop.Type.Pop, new MCRegister(MCRegister.RegName.PC));
@@ -217,7 +225,7 @@ public class InstructionSelector {
                 }
             }
             case Call -> {
-                mf.setLeaf(false);
+
                 // TODO : change after phi
 
                 // TODO : Float num
@@ -537,7 +545,7 @@ public class InstructionSelector {
             return (Register) res;
         if (res instanceof ImmediateNumber) {
             var dest = new VirtualRegister();
-            ImmediateNumber.loadNum(parent, dest, ((ImmediateNumber) res).getValue()).pushBacktoInstList();
+            ImmediateNumber.loadNum(parent, dest, ((ImmediateNumber) res).getValue());
             return dest;
         }
         if (res instanceof Address) {
diff --git a/src/backend/pass/RegAllocator.java b/src/backend/pass/RegAllocator.java
index 67b010c..83c0b1e 100644
--- a/src/backend/pass/RegAllocator.java
+++ b/src/backend/pass/RegAllocator.java
@@ -1,6 +1,7 @@
 package backend.pass;
 
 import backend.machineCode.Instruction.Arithmetic;
+import backend.machineCode.Instruction.LoadImm;
 import backend.machineCode.Instruction.LoadOrStore;
 import backend.machineCode.Instruction.PushOrPop;
 import backend.machineCode.MachineBasicBlock;
@@ -66,8 +67,15 @@ public class RegAllocator {
                         newInst.setPrologue(true);
                         newInst.getInstNode().insertBefore(inst.getInstNode());
 
-                        new Arithmetic(firstBb, SUB, new MCRegister(MCRegister.RegName.SP),
-                                new ImmediateNumber(4 * numOnStack)).getInstNode().insertBefore(inst.getInstNode());
+                        MCOperand c;
+                        if(ImmediateNumber.isLegalImm(4 * numOnStack))
+                            c = new ImmediateNumber(4 * numOnStack);
+                        else{
+                            c = new MCRegister(Register.Content.Int, 9);
+                            new LoadImm(firstBb, (Register) c, 4 * numOnStack).getInstNode().insertBefore(inst.getInstNode());;
+
+                        }
+                        new Arithmetic(firstBb, SUB, new MCRegister(MCRegister.RegName.SP), c).getInstNode().insertBefore(inst.getInstNode());
                         break;
                     }
                 }
@@ -76,6 +84,7 @@ public class RegAllocator {
                 for (var bb : func.getBbList()) {
                     for (var inst : bb.getInstList()) {
                         if (inst.isEpilogue()) {
+
                             new Arithmetic(firstBb, SUB, new MCRegister(MCRegister.RegName.SP), new MCRegister(MCRegister.RegName.r11),
                                     new ImmediateNumber(4)).getInstNode().insertBefore(inst.getInstNode());
                             newInst = new PushOrPop(bb, PushOrPop.Type.Pop, new MCRegister(MCRegister.RegName.r11));
diff --git a/src/run.py b/src/run.py
index 9d3062c..2c6eedb 100644
--- a/src/run.py
+++ b/src/run.py
@@ -1,13 +1,13 @@
 import os
 
-# testcase="D:\JavaProject\MegaSysy\oldtestcases"
-abspath=os.path.abspath(os.path.join(os.getcwd(), "..")) # D:\JavaProject\MegaSysy
-testcase=abspath+"\\testcase"
-out_directory=abspath+"\MC"
-classpath=abspath+"\out\production\MegaSysy;"+abspath+"\lib\\antlr-4.8-complete.jar"
-
-functional_testcase=testcase+"\\functional\\"
-functional_out_pass=out_directory+"\\functional\\"
+# testcase="D:/JavaProject/MegaSysy/oldtestcases"
+abspath=os.path.abspath(os.path.join(os.getcwd(), "..")) # D:/JavaProject/MegaSysy
+testcase=abspath+"/testcase"
+out_directory=abspath+"/MC"
+classpath=abspath+"/out/production/MegaSysy::"+abspath+"/lib/antlr-4.8-complete.jar"
+
+functional_testcase=testcase+"/functional/"
+functional_out_pass=out_directory+"/functional/"
 functional_file_list=[]
 
 for file in os.listdir(functional_testcase):
@@ -18,8 +18,8 @@ for file in functional_file_list:
     print(functional_testcase+file+".sy:")
     a=os.system("java -classpath "+classpath+" Compiler -S -o "+functional_out_pass+file+".s "+functional_testcase+file+".sy")
 
-performance_testcase=testcase+"\\performance\\"
-performance_out_pass=out_directory+"\\performance\\"
+performance_testcase=testcase+"/performance/"
+performance_out_pass=out_directory+"/performance/"
 performance_file_list=[]
 
 for file in os.listdir(performance_testcase):
@@ -30,8 +30,8 @@ for file in performance_file_list:
     print(performance_testcase+file+".sy:")
     a=os.system("java -classpath "+classpath+" Compiler -S -o "+performance_out_pass+file+".s "+performance_testcase+file+".sy")
 
-# thu_testcase=testcase+"\\thu_test\\"
-# thu_out=out_directory+"\\thu_test\\"
+# thu_testcase=testcase+"/thu_test/"
+# thu_out=out_directory+"/thu_test/"
 # thu_file_list=[]
 #
 # for file in os.listdir(thu_testcase):
-- 
GitLab