mips without optimize
This commit is contained in:
8
Compiler.java
Normal file → Executable file
8
Compiler.java
Normal file → Executable file
@@ -1,5 +1,7 @@
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import backend.BackEnd;
|
||||
import frontend.lexer.Lexer;
|
||||
import frontend.lexer.TokenStream;
|
||||
import frontend.parser.Parser;
|
||||
@@ -15,6 +17,7 @@ public class Compiler {
|
||||
try {
|
||||
String content = new String(Files.readAllBytes(Paths.get("testfile.txt")));
|
||||
String llvmFile = "llvm_ir.txt";
|
||||
String mipsFile = "mips.txt";
|
||||
String errorFile = "error.txt";
|
||||
Lexer lexer = new Lexer(content);
|
||||
lexer.lex(errors);
|
||||
@@ -33,7 +36,10 @@ public class Compiler {
|
||||
} else {
|
||||
Midend midend = new Midend(parser.getCompUnit());
|
||||
midend.generateLLvmIr();
|
||||
midend.writeToFile(llvmFile);
|
||||
// midend.writeToFile(llvmFile);
|
||||
BackEnd backEnd = new BackEnd(midend.getModule());
|
||||
backEnd.toMips();
|
||||
backEnd.writeToFile(mipsFile);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
32
backend/BackEnd.java
Normal file
32
backend/BackEnd.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package backend;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import backend.mips.MipsBuilder;
|
||||
import backend.mips.MipsModule;
|
||||
import midend.llvm.IrModule;
|
||||
|
||||
public class BackEnd {
|
||||
private MipsModule mipsModule;
|
||||
private IrModule irModule;
|
||||
|
||||
public BackEnd(IrModule irModule) {
|
||||
this.irModule = irModule;
|
||||
this.mipsModule = new MipsModule();
|
||||
}
|
||||
|
||||
public void toMips() {
|
||||
MipsBuilder.setModule(mipsModule);
|
||||
irModule.toMips();
|
||||
}
|
||||
|
||||
public void writeToFile(String fileName) {
|
||||
try {
|
||||
Files.write(Paths.get(fileName), mipsModule.toString().getBytes());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
93
backend/mips/MipsBuilder.java
Normal file
93
backend/mips/MipsBuilder.java
Normal file
@@ -0,0 +1,93 @@
|
||||
package backend.mips;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import backend.mips.instr.MipsInstr;
|
||||
import backend.mips.instr.data.MipsAsciiz;
|
||||
import backend.mips.instr.data.MipsSpace;
|
||||
import backend.mips.instr.data.MipsWord;
|
||||
import midend.llvm.value.IrFuncValue;
|
||||
import midend.llvm.value.IrValue;
|
||||
|
||||
public class MipsBuilder {
|
||||
private static MipsModule module = null;
|
||||
private static int offset = 0;
|
||||
private static HashMap<IrValue, Integer> valueOffsetMap = new HashMap<>();
|
||||
private static HashMap<IrValue, Register> valueRegisterMap = new HashMap<>();
|
||||
|
||||
public static void setModule(MipsModule module) {
|
||||
MipsBuilder.module = module;
|
||||
}
|
||||
|
||||
public static int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public static void setOffset(int offset) {
|
||||
MipsBuilder.offset = offset;
|
||||
}
|
||||
|
||||
public static void setValueOffsetMap(HashMap<IrValue, Integer> valueOffsetMap) {
|
||||
MipsBuilder.valueOffsetMap = valueOffsetMap;
|
||||
}
|
||||
|
||||
public static HashMap<IrValue, Integer> getValueOffsetMap() {
|
||||
return valueOffsetMap;
|
||||
}
|
||||
|
||||
public static void setValueRegisterMap(HashMap<IrValue, Register> valueRegisterMap) {
|
||||
MipsBuilder.valueRegisterMap = valueRegisterMap;
|
||||
}
|
||||
|
||||
public static HashMap<IrValue, Register> getValueRegisterMap() {
|
||||
return valueRegisterMap;
|
||||
}
|
||||
|
||||
public static MipsModule getModule() {
|
||||
return module;
|
||||
}
|
||||
|
||||
public static void addMipsInstr(MipsInstr instr) {
|
||||
if (instr instanceof MipsAsciiz || instr instanceof MipsWord || instr instanceof MipsSpace) { //data段
|
||||
module.addData(instr);
|
||||
} else {
|
||||
module.addText(instr);
|
||||
}
|
||||
}
|
||||
|
||||
public static void enterNewFunc(IrFuncValue func) {
|
||||
offset = 0;
|
||||
valueOffsetMap = func.getValueOffsetMap();
|
||||
valueOffsetMap.clear(); //TODO:是否需要清空?
|
||||
valueRegisterMap = func.getValueRegisterMap();
|
||||
}
|
||||
|
||||
public static Register getRegister(IrValue value) {
|
||||
return valueRegisterMap.get(value);
|
||||
}
|
||||
|
||||
public static Integer getOffset(IrValue value) {
|
||||
return valueOffsetMap.get(value);
|
||||
}
|
||||
|
||||
public static void allocaRegister(IrValue value, Register reg) {
|
||||
valueRegisterMap.put(value, reg);
|
||||
}
|
||||
|
||||
public static void allocaOffset(IrValue value) {
|
||||
if (!valueOffsetMap.containsKey(value)) {
|
||||
offset -= 4;
|
||||
int valueOffset = offset;
|
||||
valueOffsetMap.put(value, valueOffset);
|
||||
}
|
||||
}
|
||||
|
||||
public static void allocaOffset(int extra) {
|
||||
offset -= extra;
|
||||
}
|
||||
|
||||
public static ArrayList<Register> getUsedRegisters() {
|
||||
return new ArrayList<>(valueRegisterMap.values());
|
||||
}
|
||||
}
|
||||
51
backend/mips/MipsModule.java
Normal file
51
backend/mips/MipsModule.java
Normal file
@@ -0,0 +1,51 @@
|
||||
package backend.mips;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import backend.mips.instr.MipsAnnotation;
|
||||
import backend.mips.instr.MipsLabel;
|
||||
import backend.mips.instr.MipsInstr;
|
||||
|
||||
public class MipsModule {
|
||||
private ArrayList<MipsInstr> dataList;
|
||||
private ArrayList<MipsInstr> textList;
|
||||
|
||||
public MipsModule() {
|
||||
this.dataList = new ArrayList<MipsInstr>();
|
||||
this.textList = new ArrayList<MipsInstr>();
|
||||
}
|
||||
|
||||
public ArrayList<MipsInstr> getDataList() {
|
||||
return dataList;
|
||||
}
|
||||
|
||||
public ArrayList<MipsInstr> getTextList() {
|
||||
return textList;
|
||||
}
|
||||
|
||||
public void addData(MipsInstr instr) {
|
||||
dataList.add(instr);
|
||||
}
|
||||
|
||||
public void addText(MipsInstr instr) {
|
||||
textList.add(instr);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(".data\n");
|
||||
for (MipsInstr instr : dataList) {
|
||||
sb.append("\t" + instr.toString());
|
||||
}
|
||||
sb.append("\n.text\n");
|
||||
for (MipsInstr instr : textList) {
|
||||
if (instr instanceof MipsLabel || instr instanceof MipsAnnotation) {
|
||||
sb.append(instr.toString());
|
||||
continue;
|
||||
}
|
||||
sb.append("\t" + instr.toString());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
58
backend/mips/Register.java
Executable file
58
backend/mips/Register.java
Executable file
@@ -0,0 +1,58 @@
|
||||
package backend.mips;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public enum Register {
|
||||
ZERO("$zero"),
|
||||
AT("$at"),
|
||||
V0("$v0"),
|
||||
V1("$v1"),
|
||||
A0("$a0"),
|
||||
A1("$a1"),
|
||||
A2("$a2"),
|
||||
A3("$a3"),
|
||||
T0("$t0"),
|
||||
T1("$t1"),
|
||||
T2("$t2"),
|
||||
T3("$t3"),
|
||||
T4("$t4"),
|
||||
T5("$t5"),
|
||||
T6("$t6"),
|
||||
T7("$t7"),
|
||||
S0("$s0"),
|
||||
S1("$s1"),
|
||||
S2("$s2"),
|
||||
S3("$s3"),
|
||||
S4("$s4"),
|
||||
S5("$s5"),
|
||||
S6("$s6"),
|
||||
S7("$s7"),
|
||||
T8("$t8"),
|
||||
T9("$t9"),
|
||||
K0("$k0"),
|
||||
K1("$k1"),
|
||||
GP("$gp"),
|
||||
SP("$sp"),
|
||||
FP("$fp"),
|
||||
RA("$ra");
|
||||
|
||||
private String regName;
|
||||
|
||||
Register(String regName) {
|
||||
this.regName = regName;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return regName;
|
||||
}
|
||||
|
||||
public static ArrayList<Register> availableRegisters() {
|
||||
ArrayList<Register> regs = new ArrayList<>();
|
||||
for (Register reg : Register.values()) {
|
||||
if (reg.toString().charAt(1) == 't' || reg.toString().charAt(1) == 's') {
|
||||
regs.add(reg);
|
||||
}
|
||||
}
|
||||
return regs;
|
||||
}
|
||||
}
|
||||
39
backend/mips/instr/MipsAlu.java
Executable file
39
backend/mips/instr/MipsAlu.java
Executable file
@@ -0,0 +1,39 @@
|
||||
package backend.mips.instr;
|
||||
|
||||
import backend.mips.Register;
|
||||
import backend.mips.instr.type.MipsAluType;
|
||||
import backend.mips.instr.type.MipsType;
|
||||
|
||||
public class MipsAlu extends MipsInstr {
|
||||
private MipsAluType aluType;
|
||||
private Register rd;
|
||||
private Register rs;
|
||||
private Register rt;
|
||||
private int immediate;
|
||||
private boolean isImInstr;
|
||||
|
||||
public MipsAlu(MipsAluType aluType, Register rd, Register rs, Register rt) {
|
||||
super(MipsType.ALU);
|
||||
this.aluType = aluType;
|
||||
this.rd = rd;
|
||||
this.rs = rs;
|
||||
this.rt = rt;
|
||||
this.immediate = 0;
|
||||
this.isImInstr = false;
|
||||
}
|
||||
|
||||
public MipsAlu(MipsAluType aluType, Register rd, Register rs, int immediate) {
|
||||
super(MipsType.ALU);
|
||||
this.aluType = aluType;
|
||||
this.rd = rd;
|
||||
this.rs = rs;
|
||||
this.rt = null;
|
||||
this.immediate = immediate;
|
||||
this.isImInstr = true;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return isImInstr ? aluType.toString() + " " + rd + ", " + rs + ", " + immediate + "\n"
|
||||
: aluType.toString() + " " + rd + ", " + rs + ", " + rt + "\n";
|
||||
}
|
||||
}
|
||||
16
backend/mips/instr/MipsAnnotation.java
Executable file
16
backend/mips/instr/MipsAnnotation.java
Executable file
@@ -0,0 +1,16 @@
|
||||
package backend.mips.instr;
|
||||
|
||||
import backend.mips.instr.type.MipsType;
|
||||
|
||||
public class MipsAnnotation extends MipsInstr {
|
||||
private String annotation;
|
||||
|
||||
public MipsAnnotation(String anno) {
|
||||
super(MipsType.ANNOTATION);
|
||||
this.annotation = anno;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "# " + this.annotation + "\n";
|
||||
}
|
||||
}
|
||||
36
backend/mips/instr/MipsBranch.java
Normal file
36
backend/mips/instr/MipsBranch.java
Normal file
@@ -0,0 +1,36 @@
|
||||
package backend.mips.instr;
|
||||
|
||||
import backend.mips.instr.type.MipsBranchType;
|
||||
import backend.mips.instr.type.MipsType;
|
||||
import backend.mips.Register;
|
||||
|
||||
public class MipsBranch extends MipsInstr{
|
||||
private MipsBranchType branchType;
|
||||
private Register rs;
|
||||
private Register rt;
|
||||
private String label;
|
||||
|
||||
public MipsBranch(MipsBranchType branchType, Register rs, Register rt, String label) {
|
||||
super(MipsType.BRANCH);
|
||||
this.branchType = branchType;
|
||||
this.rs = rs;
|
||||
this.rt = rt;
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public MipsBranch(MipsBranchType branchType, Register rs, String label) {
|
||||
super(MipsType.BRANCH);
|
||||
this.branchType = branchType;
|
||||
this.rs = rs;
|
||||
this.rt = null;
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if (this.rt == null) {
|
||||
return this.branchType.toString() + " " + this.rs + ", " + this.label + "\n";
|
||||
} else {
|
||||
return this.branchType.toString() + " " + this.rs + ", " + this.rt + ", " + this.label + "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
42
backend/mips/instr/MipsComp.java
Normal file
42
backend/mips/instr/MipsComp.java
Normal file
@@ -0,0 +1,42 @@
|
||||
package backend.mips.instr;
|
||||
|
||||
import backend.mips.instr.type.MipsCompareType;
|
||||
import backend.mips.instr.type.MipsType;
|
||||
import backend.mips.Register;
|
||||
|
||||
public class MipsComp extends MipsInstr {
|
||||
private MipsCompareType compareType;
|
||||
private Register rd;
|
||||
private Register rs;
|
||||
private Register rt;
|
||||
private int immediate;
|
||||
private boolean isImmediate;
|
||||
|
||||
public MipsComp(MipsCompareType compareType, Register rd, Register rs, Register rt) {
|
||||
super(MipsType.COMPARE);
|
||||
this.compareType = compareType;
|
||||
this.rd = rd;
|
||||
this.rs = rs;
|
||||
this.rt = rt;
|
||||
this.immediate = 0;
|
||||
this.isImmediate = false;
|
||||
}
|
||||
|
||||
public MipsComp(MipsCompareType compareType, Register rd, Register rs, int immediate) {
|
||||
super(MipsType.COMPARE);
|
||||
this.compareType = compareType;
|
||||
this.rd = rd;
|
||||
this.rs = rs;
|
||||
this.rt = null;
|
||||
this.immediate = immediate;
|
||||
this.isImmediate = true;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if (this.isImmediate) {
|
||||
return this.compareType.toString() + " " + this.rd + ", " + this.rs + ", " + this.immediate + "\n";
|
||||
} else {
|
||||
return this.compareType.toString() + " " + this.rd + ", " + this.rs + ", " + this.rt + "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
21
backend/mips/instr/MipsInstr.java
Executable file
21
backend/mips/instr/MipsInstr.java
Executable file
@@ -0,0 +1,21 @@
|
||||
package backend.mips.instr;
|
||||
|
||||
import backend.mips.instr.type.MipsType;
|
||||
import backend.mips.MipsBuilder;
|
||||
|
||||
public class MipsInstr {
|
||||
private MipsType mt;
|
||||
|
||||
public MipsInstr(MipsType mt) {
|
||||
this.mt = mt;
|
||||
MipsBuilder.addMipsInstr(this);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public MipsType getType() {
|
||||
return mt;
|
||||
}
|
||||
}
|
||||
33
backend/mips/instr/MipsJump.java
Normal file
33
backend/mips/instr/MipsJump.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package backend.mips.instr;
|
||||
|
||||
import backend.mips.Register;
|
||||
import backend.mips.instr.type.MipsJumpType;
|
||||
import backend.mips.instr.type.MipsType;
|
||||
|
||||
public class MipsJump extends MipsInstr {
|
||||
private MipsJumpType jumpType;
|
||||
private String label;
|
||||
private Register rd;
|
||||
|
||||
public MipsJump(MipsJumpType jumpType, String label) {
|
||||
super(MipsType.JUMP);
|
||||
this.jumpType = jumpType;
|
||||
this.label = label;
|
||||
this.rd = null;
|
||||
}
|
||||
|
||||
public MipsJump(MipsJumpType jumpType, Register rd) {
|
||||
super(MipsType.JUMP);
|
||||
this.jumpType = jumpType;
|
||||
this.label = null;
|
||||
this.rd = rd;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if (this.rd == null) {
|
||||
return this.jumpType.toString() + " " + this.label + "\n";
|
||||
} else {
|
||||
return this.jumpType.toString() + " " + this.rd + "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
16
backend/mips/instr/MipsLabel.java
Normal file
16
backend/mips/instr/MipsLabel.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package backend.mips.instr;
|
||||
|
||||
import backend.mips.instr.type.MipsType;
|
||||
|
||||
public class MipsLabel extends MipsInstr {
|
||||
private String label;
|
||||
|
||||
public MipsLabel(String label) {
|
||||
super(MipsType.LABEL);
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.label + ":\n";
|
||||
}
|
||||
}
|
||||
39
backend/mips/instr/MipsLs.java
Normal file
39
backend/mips/instr/MipsLs.java
Normal file
@@ -0,0 +1,39 @@
|
||||
package backend.mips.instr;
|
||||
|
||||
import backend.mips.instr.type.MipsLsType;
|
||||
import backend.mips.instr.type.MipsType;
|
||||
import backend.mips.Register;
|
||||
|
||||
public class MipsLs extends MipsInstr {
|
||||
private MipsLsType lsType;
|
||||
private Register rd;
|
||||
private Register rt;
|
||||
private int offset;
|
||||
private String label;
|
||||
|
||||
public MipsLs(MipsLsType lsType, Register rd, Register rt, int offset) {
|
||||
super(MipsType.LS);
|
||||
this.lsType = lsType;
|
||||
this.rd = rd;
|
||||
this.rt = rt;
|
||||
this.offset = offset;
|
||||
this.label = null;
|
||||
}
|
||||
|
||||
public MipsLs(MipsLsType lsType, Register rd, int offset, String label) {
|
||||
super(MipsType.LS);
|
||||
this.lsType = lsType;
|
||||
this.rd = rd;
|
||||
this.rt = null;
|
||||
this.offset = offset;
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if (this.label == null) {
|
||||
return this.lsType.toString() + " " + this.rd + ", " + this.offset + "(" + this.rt + ")\n";
|
||||
} else {
|
||||
return this.lsType.toString() + " " + this.rd + ", " + this.label + " + " + this.offset + "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
33
backend/mips/instr/MipsMd.java
Normal file
33
backend/mips/instr/MipsMd.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package backend.mips.instr;
|
||||
|
||||
import backend.mips.instr.type.MipsMdType;
|
||||
import backend.mips.instr.type.MipsType;
|
||||
import backend.mips.Register;
|
||||
|
||||
public class MipsMd extends MipsInstr {
|
||||
private MipsMdType mdType;
|
||||
private Register rd;
|
||||
private Register rt;
|
||||
|
||||
public MipsMd(MipsMdType mdType, Register rd, Register rt) {
|
||||
super(MipsType.MD);
|
||||
this.mdType = mdType;
|
||||
this.rd = rd;
|
||||
this.rt = rt;
|
||||
}
|
||||
|
||||
public MipsMd(MipsMdType mdType, Register rd) {
|
||||
super(MipsType.MD);
|
||||
this.mdType = mdType;
|
||||
this.rd = rd;
|
||||
this.rt = null;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if (this.rt == null) {
|
||||
return this.mdType.toString() + " " + this.rd + "\n";
|
||||
} else {
|
||||
return this.mdType.toString() + " " + this.rd + ", " + this.rt + "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
13
backend/mips/instr/MipsSyscall.java
Normal file
13
backend/mips/instr/MipsSyscall.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package backend.mips.instr;
|
||||
|
||||
import backend.mips.instr.type.MipsType;
|
||||
|
||||
public class MipsSyscall extends MipsInstr {
|
||||
public MipsSyscall() {
|
||||
super(MipsType.SYSCALL);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "syscall\n";
|
||||
}
|
||||
}
|
||||
19
backend/mips/instr/data/MipsAsciiz.java
Normal file
19
backend/mips/instr/data/MipsAsciiz.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package backend.mips.instr.data;
|
||||
|
||||
import backend.mips.instr.MipsInstr;
|
||||
import backend.mips.instr.type.MipsType;
|
||||
|
||||
public class MipsAsciiz extends MipsInstr {
|
||||
private String name;
|
||||
private String str;
|
||||
|
||||
public MipsAsciiz(String name, String str) {
|
||||
super(MipsType.DATA);
|
||||
this.name = name;
|
||||
this.str = str;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return name + ": .asciiz \"" + str.replaceAll("\n", "\\n") + "\"\n";
|
||||
}
|
||||
}
|
||||
19
backend/mips/instr/data/MipsSpace.java
Normal file
19
backend/mips/instr/data/MipsSpace.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package backend.mips.instr.data;
|
||||
|
||||
import backend.mips.instr.MipsInstr;
|
||||
import backend.mips.instr.type.MipsType;
|
||||
|
||||
public class MipsSpace extends MipsInstr {
|
||||
private int size;
|
||||
private String name;
|
||||
|
||||
public MipsSpace(int size, String name) {
|
||||
super(MipsType.DATA);
|
||||
this.size = size;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return name + ": .space " + size + "\n";
|
||||
}
|
||||
}
|
||||
39
backend/mips/instr/data/MipsWord.java
Normal file
39
backend/mips/instr/data/MipsWord.java
Normal file
@@ -0,0 +1,39 @@
|
||||
package backend.mips.instr.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import backend.mips.instr.MipsInstr;
|
||||
import backend.mips.instr.type.MipsType;
|
||||
|
||||
public class MipsWord extends MipsInstr {
|
||||
private String name;
|
||||
private ArrayList<Integer> valueList;
|
||||
|
||||
public MipsWord(String name, ArrayList<Integer> valueList) {
|
||||
super(MipsType.DATA);
|
||||
this.name = name;
|
||||
this.valueList = valueList;
|
||||
}
|
||||
|
||||
public MipsWord(String name, int value) {
|
||||
super(MipsType.DATA);
|
||||
this.name = name;
|
||||
this.valueList = new ArrayList<Integer>();
|
||||
this.valueList.add(value);
|
||||
}
|
||||
|
||||
public int getValueNum() {
|
||||
return valueList.size();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(name).append(": .word ");
|
||||
for (int value : valueList) {
|
||||
sb.append(value).append(", ");
|
||||
}
|
||||
sb.delete(sb.length() - 2, sb.length());
|
||||
sb.append("\n");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
28
backend/mips/instr/fake/MipsLa.java
Normal file
28
backend/mips/instr/fake/MipsLa.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package backend.mips.instr.fake;
|
||||
|
||||
import backend.mips.instr.MipsInstr;
|
||||
import backend.mips.instr.type.MipsType;
|
||||
import backend.mips.Register;
|
||||
|
||||
public class MipsLa extends MipsInstr {
|
||||
private Register rd;
|
||||
private String label;
|
||||
|
||||
public MipsLa(Register rd, String label) {
|
||||
super(MipsType.FAKE);
|
||||
this.rd = rd;
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public Register getRd() {
|
||||
return rd;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "la " + rd + ", " + label + "\n";
|
||||
}
|
||||
}
|
||||
29
backend/mips/instr/fake/MipsLi.java
Normal file
29
backend/mips/instr/fake/MipsLi.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package backend.mips.instr.fake;
|
||||
|
||||
import backend.mips.instr.MipsInstr;
|
||||
import backend.mips.instr.type.MipsType;
|
||||
import backend.mips.Register;
|
||||
|
||||
|
||||
public class MipsLi extends MipsInstr {
|
||||
private Register rd;
|
||||
private int value;
|
||||
|
||||
public MipsLi(Register rd, int value) {
|
||||
super(MipsType.FAKE);
|
||||
this.rd = rd;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public Register getRd() {
|
||||
return rd;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "li " + rd + ", " + value + "\n";
|
||||
}
|
||||
}
|
||||
28
backend/mips/instr/fake/MipsMove.java
Normal file
28
backend/mips/instr/fake/MipsMove.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package backend.mips.instr.fake;
|
||||
|
||||
import backend.mips.instr.MipsInstr;
|
||||
import backend.mips.instr.type.MipsType;
|
||||
import backend.mips.Register;
|
||||
|
||||
public class MipsMove extends MipsInstr {
|
||||
private Register rd;
|
||||
private Register rt;
|
||||
|
||||
public MipsMove(Register rd, Register rt) {
|
||||
super(MipsType.FAKE);
|
||||
this.rd = rd;
|
||||
this.rt = rt;
|
||||
}
|
||||
|
||||
public Register getDest() {
|
||||
return rd;
|
||||
}
|
||||
|
||||
public Register getSrc() {
|
||||
return rt;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "move " + rd + ", " + rt + "\n";
|
||||
}
|
||||
}
|
||||
16
backend/mips/instr/type/MipsAluType.java
Executable file
16
backend/mips/instr/type/MipsAluType.java
Executable file
@@ -0,0 +1,16 @@
|
||||
package backend.mips.instr.type;
|
||||
|
||||
public enum MipsAluType {
|
||||
// calc_R
|
||||
ADD, SUB, ADDU, SUBU, AND, OR, NOR, XOR, SLT, SLTU,
|
||||
// shiftv
|
||||
SLLV, SRAV, SRLV,
|
||||
// calc_I
|
||||
ADDI, ADDIU, ANDI, ORI, XORI, SLTI, SLTIU,
|
||||
// shift
|
||||
SLL, SRA, SRL;
|
||||
|
||||
public String toString() {
|
||||
return this.name().toLowerCase();
|
||||
}
|
||||
}
|
||||
9
backend/mips/instr/type/MipsBranchType.java
Normal file
9
backend/mips/instr/type/MipsBranchType.java
Normal file
@@ -0,0 +1,9 @@
|
||||
package backend.mips.instr.type;
|
||||
|
||||
public enum MipsBranchType {
|
||||
BEQ, BNE, BLEZ, BGTZ, BLTZ, BGEZ;
|
||||
|
||||
public String toString() {
|
||||
return this.name().toLowerCase();
|
||||
}
|
||||
}
|
||||
9
backend/mips/instr/type/MipsCompareType.java
Normal file
9
backend/mips/instr/type/MipsCompareType.java
Normal file
@@ -0,0 +1,9 @@
|
||||
package backend.mips.instr.type;
|
||||
|
||||
public enum MipsCompareType {
|
||||
SLT, SLE, SGT, SGE, SEQ, SNE, SLTI;
|
||||
|
||||
public String toString() {
|
||||
return this.name().toLowerCase();
|
||||
}
|
||||
}
|
||||
9
backend/mips/instr/type/MipsJumpType.java
Normal file
9
backend/mips/instr/type/MipsJumpType.java
Normal file
@@ -0,0 +1,9 @@
|
||||
package backend.mips.instr.type;
|
||||
|
||||
public enum MipsJumpType {
|
||||
J, JAL, JR;
|
||||
|
||||
public String toString() {
|
||||
return this.name().toLowerCase();
|
||||
}
|
||||
}
|
||||
9
backend/mips/instr/type/MipsLsType.java
Normal file
9
backend/mips/instr/type/MipsLsType.java
Normal file
@@ -0,0 +1,9 @@
|
||||
package backend.mips.instr.type;
|
||||
|
||||
public enum MipsLsType {
|
||||
LW, SW, LH, SH, LHU, LB, SB, LBU;
|
||||
|
||||
public String toString() {
|
||||
return this.name().toLowerCase();
|
||||
}
|
||||
}
|
||||
9
backend/mips/instr/type/MipsMdType.java
Normal file
9
backend/mips/instr/type/MipsMdType.java
Normal file
@@ -0,0 +1,9 @@
|
||||
package backend.mips.instr.type;
|
||||
|
||||
public enum MipsMdType {
|
||||
MFHI, MFLO, MULT, DIV, MTHI, MTLO;
|
||||
|
||||
public String toString() {
|
||||
return this.name().toLowerCase();
|
||||
}
|
||||
}
|
||||
15
backend/mips/instr/type/MipsType.java
Executable file
15
backend/mips/instr/type/MipsType.java
Executable file
@@ -0,0 +1,15 @@
|
||||
package backend.mips.instr.type;
|
||||
|
||||
public enum MipsType {
|
||||
ALU,
|
||||
COMPARE,
|
||||
BRANCH,
|
||||
JUMP,
|
||||
SYSCALL,
|
||||
DATA,
|
||||
LABEL,
|
||||
ANNOTATION,
|
||||
LS,
|
||||
MD,
|
||||
FAKE
|
||||
}
|
||||
4
config.json
Executable file
4
config.json
Executable file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"programming language": "java",
|
||||
"object code": "mips"
|
||||
}
|
||||
0
error/Error.java
Normal file → Executable file
0
error/Error.java
Normal file → Executable file
0
error/ErrorType.java
Normal file → Executable file
0
error/ErrorType.java
Normal file → Executable file
0
error/Errors.java
Normal file → Executable file
0
error/Errors.java
Normal file → Executable file
0
frontend/.DS_Store
vendored
Normal file → Executable file
0
frontend/.DS_Store
vendored
Normal file → Executable file
0
frontend/ast/.DS_Store
vendored
Normal file → Executable file
0
frontend/ast/.DS_Store
vendored
Normal file → Executable file
0
frontend/ast/CompUnit.java
Normal file → Executable file
0
frontend/ast/CompUnit.java
Normal file → Executable file
0
frontend/ast/Node.java
Normal file → Executable file
0
frontend/ast/Node.java
Normal file → Executable file
0
frontend/ast/NodeStack.java
Normal file → Executable file
0
frontend/ast/NodeStack.java
Normal file → Executable file
0
frontend/ast/SyntaxType.java
Normal file → Executable file
0
frontend/ast/SyntaxType.java
Normal file → Executable file
0
frontend/ast/block/Block.java
Normal file → Executable file
0
frontend/ast/block/Block.java
Normal file → Executable file
0
frontend/ast/block/BlockItem.java
Normal file → Executable file
0
frontend/ast/block/BlockItem.java
Normal file → Executable file
0
frontend/ast/block/ForStmt.java
Normal file → Executable file
0
frontend/ast/block/ForStmt.java
Normal file → Executable file
0
frontend/ast/block/Stmt.java
Normal file → Executable file
0
frontend/ast/block/Stmt.java
Normal file → Executable file
0
frontend/ast/decl/ConstDecl.java
Normal file → Executable file
0
frontend/ast/decl/ConstDecl.java
Normal file → Executable file
0
frontend/ast/decl/ConstDef.java
Normal file → Executable file
0
frontend/ast/decl/ConstDef.java
Normal file → Executable file
0
frontend/ast/decl/Decl.java
Normal file → Executable file
0
frontend/ast/decl/Decl.java
Normal file → Executable file
0
frontend/ast/decl/VarDecl.java
Normal file → Executable file
0
frontend/ast/decl/VarDecl.java
Normal file → Executable file
0
frontend/ast/decl/VarDef.java
Normal file → Executable file
0
frontend/ast/decl/VarDef.java
Normal file → Executable file
0
frontend/ast/exp/AddExp.java
Normal file → Executable file
0
frontend/ast/exp/AddExp.java
Normal file → Executable file
0
frontend/ast/exp/Cond.java
Normal file → Executable file
0
frontend/ast/exp/Cond.java
Normal file → Executable file
0
frontend/ast/exp/ConstExp.java
Normal file → Executable file
0
frontend/ast/exp/ConstExp.java
Normal file → Executable file
0
frontend/ast/exp/EqExp.java
Normal file → Executable file
0
frontend/ast/exp/EqExp.java
Normal file → Executable file
0
frontend/ast/exp/Exp.java
Normal file → Executable file
0
frontend/ast/exp/Exp.java
Normal file → Executable file
0
frontend/ast/exp/LAndExp.java
Normal file → Executable file
0
frontend/ast/exp/LAndExp.java
Normal file → Executable file
0
frontend/ast/exp/LOrExp.java
Normal file → Executable file
0
frontend/ast/exp/LOrExp.java
Normal file → Executable file
0
frontend/ast/exp/LVal.java
Normal file → Executable file
0
frontend/ast/exp/LVal.java
Normal file → Executable file
0
frontend/ast/exp/MulExp.java
Normal file → Executable file
0
frontend/ast/exp/MulExp.java
Normal file → Executable file
0
frontend/ast/exp/NumberExp.java
Normal file → Executable file
0
frontend/ast/exp/NumberExp.java
Normal file → Executable file
0
frontend/ast/exp/PrimaryExp.java
Normal file → Executable file
0
frontend/ast/exp/PrimaryExp.java
Normal file → Executable file
0
frontend/ast/exp/RelExp.java
Normal file → Executable file
0
frontend/ast/exp/RelExp.java
Normal file → Executable file
0
frontend/ast/exp/UnaryExp.java
Normal file → Executable file
0
frontend/ast/exp/UnaryExp.java
Normal file → Executable file
0
frontend/ast/exp/UnaryOp.java
Normal file → Executable file
0
frontend/ast/exp/UnaryOp.java
Normal file → Executable file
0
frontend/ast/func/FuncDef.java
Normal file → Executable file
0
frontend/ast/func/FuncDef.java
Normal file → Executable file
0
frontend/ast/func/FuncFParam.java
Normal file → Executable file
0
frontend/ast/func/FuncFParam.java
Normal file → Executable file
0
frontend/ast/func/FuncFParams.java
Normal file → Executable file
0
frontend/ast/func/FuncFParams.java
Normal file → Executable file
0
frontend/ast/func/FuncRParams.java
Normal file → Executable file
0
frontend/ast/func/FuncRParams.java
Normal file → Executable file
0
frontend/ast/func/FuncType.java
Normal file → Executable file
0
frontend/ast/func/FuncType.java
Normal file → Executable file
0
frontend/ast/func/MainFuncDef.java
Normal file → Executable file
0
frontend/ast/func/MainFuncDef.java
Normal file → Executable file
0
frontend/ast/token/TokenNode.java
Normal file → Executable file
0
frontend/ast/token/TokenNode.java
Normal file → Executable file
0
frontend/ast/val/ConstInitVal.java
Normal file → Executable file
0
frontend/ast/val/ConstInitVal.java
Normal file → Executable file
0
frontend/ast/val/InitVal.java
Normal file → Executable file
0
frontend/ast/val/InitVal.java
Normal file → Executable file
0
frontend/lexer/Lexer.java
Normal file → Executable file
0
frontend/lexer/Lexer.java
Normal file → Executable file
0
frontend/lexer/Token.java
Normal file → Executable file
0
frontend/lexer/Token.java
Normal file → Executable file
0
frontend/lexer/TokenStream.java
Normal file → Executable file
0
frontend/lexer/TokenStream.java
Normal file → Executable file
0
frontend/lexer/TokenType.java
Normal file → Executable file
0
frontend/lexer/TokenType.java
Normal file → Executable file
0
frontend/parser/Parser.java
Normal file → Executable file
0
frontend/parser/Parser.java
Normal file → Executable file
5
midend/Midend.java
Normal file → Executable file
5
midend/Midend.java
Normal file → Executable file
@@ -21,6 +21,10 @@ public class Midend {
|
||||
visitor.visit();
|
||||
}
|
||||
|
||||
public IrModule getModule() {
|
||||
return module;
|
||||
}
|
||||
|
||||
public void writeToFile(String fileName) {
|
||||
try {
|
||||
Files.write(Paths.get(fileName), module.toString().getBytes());
|
||||
@@ -29,3 +33,4 @@ public class Midend {
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
|
||||
0
midend/errorhandle/ErrorHandler.java
Normal file → Executable file
0
midend/errorhandle/ErrorHandler.java
Normal file → Executable file
0
midend/llvm/IrBuilder.java
Normal file → Executable file
0
midend/llvm/IrBuilder.java
Normal file → Executable file
27
midend/llvm/IrModule.java
Normal file → Executable file
27
midend/llvm/IrModule.java
Normal file → Executable file
@@ -3,6 +3,13 @@ package midend.llvm;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import backend.mips.Register;
|
||||
import backend.mips.instr.MipsAnnotation;
|
||||
import backend.mips.instr.MipsJump;
|
||||
import backend.mips.instr.MipsLabel;
|
||||
import backend.mips.instr.fake.MipsLi;
|
||||
import backend.mips.instr.MipsSyscall;
|
||||
import backend.mips.instr.type.MipsJumpType;
|
||||
import midend.llvm.constant.IrConstantStr;
|
||||
import midend.llvm.value.IrFuncValue;
|
||||
import midend.llvm.value.IrGlobalValue;
|
||||
@@ -79,7 +86,6 @@ public class IrModule {
|
||||
return null;
|
||||
}
|
||||
|
||||
//TODO: toString()方法编写
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String decl : decls) {
|
||||
@@ -97,4 +103,23 @@ public class IrModule {
|
||||
// System.out.println(funcs.size());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void toMips() {
|
||||
for (IrGlobalValue globalVar : this.globalVars) {
|
||||
globalVar.toMips();
|
||||
}
|
||||
for (IrConstantStr str : this.strs.values()) {
|
||||
str.toMips(str.getMipsLabel());
|
||||
}
|
||||
new MipsAnnotation("jump to main");
|
||||
new MipsJump(MipsJumpType.JAL, "main");
|
||||
new MipsJump(MipsJumpType.J, "end");
|
||||
|
||||
for (IrFuncValue irFunction : this.funcs) {
|
||||
irFunction.toMips();
|
||||
}
|
||||
new MipsLabel("end");
|
||||
new MipsLi(Register.V0, 10);
|
||||
new MipsSyscall();
|
||||
}
|
||||
}
|
||||
|
||||
4
midend/llvm/constant/IrConstant.java
Normal file → Executable file
4
midend/llvm/constant/IrConstant.java
Normal file → Executable file
@@ -11,4 +11,8 @@ public class IrConstant extends IrValue {
|
||||
public String toString() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public void toMips(String label) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
17
midend/llvm/constant/IrConstantArray.java
Normal file → Executable file
17
midend/llvm/constant/IrConstantArray.java
Normal file → Executable file
@@ -2,6 +2,8 @@ package midend.llvm.constant;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import backend.mips.instr.data.MipsSpace;
|
||||
import backend.mips.instr.data.MipsWord;
|
||||
import midend.llvm.type.IrInterType;
|
||||
import midend.llvm.type.IrArrayType;
|
||||
|
||||
@@ -44,4 +46,19 @@ public class IrConstantArray extends IrConstant {
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void toMips(String label) {
|
||||
ArrayList<Integer> values = new ArrayList<>();
|
||||
if (elements.size() == 0) {
|
||||
new MipsSpace(size * 4, label);
|
||||
} else {
|
||||
for (IrConstant element : elements) {
|
||||
values.add(((IrConstantInt) element).getValue());
|
||||
}
|
||||
for (int i = 0; i < size - elements.size(); i++) {
|
||||
values.add(0);
|
||||
}
|
||||
new MipsWord(label, values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
5
midend/llvm/constant/IrConstantInt.java
Normal file → Executable file
5
midend/llvm/constant/IrConstantInt.java
Normal file → Executable file
@@ -1,5 +1,6 @@
|
||||
package midend.llvm.constant;
|
||||
|
||||
import backend.mips.instr.data.MipsWord;
|
||||
import midend.llvm.type.IrInterType;
|
||||
|
||||
public class IrConstantInt extends IrConstant {
|
||||
@@ -17,4 +18,8 @@ public class IrConstantInt extends IrConstant {
|
||||
public String toString() {
|
||||
return "i32 " + value;
|
||||
}
|
||||
|
||||
public void toMips(String label) {
|
||||
new MipsWord(label, value);
|
||||
}
|
||||
}
|
||||
|
||||
5
midend/llvm/constant/IrConstantStr.java
Normal file → Executable file
5
midend/llvm/constant/IrConstantStr.java
Normal file → Executable file
@@ -1,5 +1,6 @@
|
||||
package midend.llvm.constant;
|
||||
|
||||
import backend.mips.instr.data.MipsAsciiz;
|
||||
import midend.llvm.type.IrArrayType;
|
||||
import midend.llvm.type.IrPointerType;
|
||||
import midend.llvm.type.IrInterType;
|
||||
@@ -50,4 +51,8 @@ public class IrConstantStr extends IrConstant {
|
||||
sb.append("\\00\"");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void toMips(String label) {
|
||||
new MipsAsciiz(label, getRealStr(value));
|
||||
}
|
||||
}
|
||||
|
||||
28
midend/llvm/instr/AllocateInstr.java
Normal file → Executable file
28
midend/llvm/instr/AllocateInstr.java
Normal file → Executable file
@@ -1,7 +1,14 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
import backend.mips.MipsBuilder;
|
||||
import midend.llvm.type.IrArrayType;
|
||||
import midend.llvm.type.IrPointerType;
|
||||
import midend.llvm.type.IrType;
|
||||
import backend.mips.Register;
|
||||
import backend.mips.instr.MipsAlu;
|
||||
import backend.mips.instr.MipsLs;
|
||||
import backend.mips.instr.type.MipsAluType;
|
||||
import backend.mips.instr.type.MipsLsType;
|
||||
|
||||
public class AllocateInstr extends IrInstr {
|
||||
private IrType pointeeType;
|
||||
@@ -18,4 +25,25 @@ public class AllocateInstr extends IrInstr {
|
||||
public String toString() {
|
||||
return getName() + " = alloca " + this.pointeeType;
|
||||
}
|
||||
|
||||
public void toMips() {
|
||||
// 想法:在栈上分配数据所需要的空间,再分配四字节的指针,这就是个指针,将其当作指针就好理解了
|
||||
if (pointeeType instanceof IrArrayType) {
|
||||
MipsBuilder.allocaOffset(4 * ((IrArrayType) pointeeType).getSize());
|
||||
} else {
|
||||
MipsBuilder.allocaOffset(4);
|
||||
}
|
||||
|
||||
Register reg = MipsBuilder.getRegister(this);
|
||||
if (reg == null) { // 未分配寄存器情况
|
||||
int offset = MipsBuilder.getOffset();
|
||||
new MipsAlu(MipsAluType.ADDI, Register.K0, Register.SP, offset);
|
||||
MipsBuilder.allocaOffset(this); // 将该变量的偏移量设置为其指针的偏移量,后续取值先取指针,再根据指针取值
|
||||
offset = MipsBuilder.getOffset();
|
||||
new MipsLs(MipsLsType.SW, Register.K0, Register.SP, offset);
|
||||
} else {
|
||||
int offset = MipsBuilder.getOffset();
|
||||
new MipsAlu(MipsAluType.ADDI, reg, Register.SP, offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
37
midend/llvm/instr/AluInstr.java
Normal file → Executable file
37
midend/llvm/instr/AluInstr.java
Normal file → Executable file
@@ -1,5 +1,12 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
import backend.mips.MipsBuilder;
|
||||
import backend.mips.instr.MipsAlu;
|
||||
import backend.mips.instr.MipsMd;
|
||||
import backend.mips.instr.type.MipsAluType;
|
||||
import backend.mips.instr.type.MipsMdType;
|
||||
import backend.mips.Register;
|
||||
|
||||
import midend.llvm.type.IrInterType;
|
||||
import midend.llvm.value.IrValue;
|
||||
|
||||
@@ -21,4 +28,34 @@ public class AluInstr extends IrInstr {
|
||||
return getName() + " = " + alutype.toString() + " " + getType()
|
||||
+ " " + getUse(0).getName() + ", " + getUse(1).getName();
|
||||
}
|
||||
|
||||
public void toMips() {
|
||||
IrValue left = getUse(0);
|
||||
IrValue right = getUse(1);
|
||||
Register leftReg = MipsBuilder.getRegister(left) != null ? MipsBuilder.getRegister(left) : Register.K0;
|
||||
Register rightReg = MipsBuilder.getRegister(right) != null ? MipsBuilder.getRegister(right) : Register.K1;
|
||||
Register resultReg = MipsBuilder.getRegister(this) != null ? MipsBuilder.getRegister(this) : Register.K1;
|
||||
loadValueToReg(left, leftReg);
|
||||
loadValueToReg(right, rightReg);
|
||||
|
||||
if (getAluType() == AluType.ADD) {
|
||||
new MipsAlu(MipsAluType.ADDU, resultReg, leftReg, rightReg);
|
||||
} else if (getAluType() == AluType.SUB) {
|
||||
new MipsAlu(MipsAluType.SUBU, resultReg, leftReg, rightReg);
|
||||
} else if (getAluType() == AluType.AND) {
|
||||
new MipsAlu(MipsAluType.AND, resultReg, leftReg, rightReg);
|
||||
} else if (getAluType() == AluType.OR) {
|
||||
new MipsAlu(MipsAluType.OR, resultReg, leftReg, rightReg);
|
||||
} else if (getAluType() == AluType.MUL) {
|
||||
new MipsMd(MipsMdType.MULT, leftReg, rightReg);
|
||||
new MipsMd(MipsMdType.MFLO, resultReg);
|
||||
} else if (getAluType() == AluType.SDIV) {
|
||||
new MipsMd(MipsMdType.DIV, leftReg, rightReg);
|
||||
new MipsMd(MipsMdType.MFLO, resultReg);
|
||||
} else if (getAluType() == AluType.SREM) {
|
||||
new MipsMd(MipsMdType.DIV, leftReg, rightReg);
|
||||
new MipsMd(MipsMdType.MFHI, resultReg);
|
||||
}
|
||||
saveResult(this, resultReg);
|
||||
}
|
||||
}
|
||||
|
||||
0
midend/llvm/instr/AluType.java
Normal file → Executable file
0
midend/llvm/instr/AluType.java
Normal file → Executable file
15
midend/llvm/instr/BranchInstr.java
Normal file → Executable file
15
midend/llvm/instr/BranchInstr.java
Normal file → Executable file
@@ -2,6 +2,12 @@ package midend.llvm.instr;
|
||||
|
||||
import midend.llvm.value.IrBasicBlock;
|
||||
import midend.llvm.value.IrValue;
|
||||
import backend.mips.MipsBuilder;
|
||||
import backend.mips.Register;
|
||||
import backend.mips.instr.MipsBranch;
|
||||
import backend.mips.instr.type.MipsBranchType;
|
||||
import backend.mips.instr.type.MipsJumpType;
|
||||
import backend.mips.instr.MipsJump;
|
||||
import midend.llvm.type.IrInterType;
|
||||
|
||||
public class BranchInstr extends IrInstr {
|
||||
@@ -30,4 +36,13 @@ public class BranchInstr extends IrInstr {
|
||||
", label %" + getFalseBB().getName();
|
||||
}
|
||||
|
||||
public void toMips() {
|
||||
Register condReg = MipsBuilder.getRegister(getCond());
|
||||
if (condReg == null) {
|
||||
condReg = Register.K0;
|
||||
}
|
||||
loadValueToReg(getCond(), condReg);
|
||||
new MipsBranch(MipsBranchType.BNE, condReg, Register.ZERO, getTrueBB().getMipsLabel());
|
||||
new MipsJump(MipsJumpType.J, getFalseBB().getMipsLabel());
|
||||
}
|
||||
}
|
||||
|
||||
69
midend/llvm/instr/CallInstr.java
Normal file → Executable file
69
midend/llvm/instr/CallInstr.java
Normal file → Executable file
@@ -2,6 +2,14 @@ package midend.llvm.instr;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import backend.mips.Register;
|
||||
import backend.mips.instr.MipsAlu;
|
||||
import backend.mips.instr.MipsJump;
|
||||
import backend.mips.instr.MipsLs;
|
||||
import backend.mips.instr.type.MipsAluType;
|
||||
import backend.mips.instr.type.MipsJumpType;
|
||||
import backend.mips.instr.type.MipsLsType;
|
||||
import backend.mips.MipsBuilder;
|
||||
import midend.llvm.value.IrFuncValue;
|
||||
import midend.llvm.value.IrValue;
|
||||
|
||||
@@ -45,4 +53,65 @@ public class CallInstr extends IrInstr {
|
||||
sb.append(")");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void toMips() {
|
||||
ArrayList<Register> usedRegisters = MipsBuilder.getUsedRegisters();
|
||||
int offset = MipsBuilder.getOffset();
|
||||
save(usedRegisters, offset);
|
||||
ArrayList<IrValue> args = getArgs();
|
||||
saveArgs(args, offset, usedRegisters);
|
||||
offset -= (usedRegisters.size() + 2) * 4;
|
||||
new MipsAlu(MipsAluType.ADDI, Register.SP, Register.SP, offset);
|
||||
new MipsJump(MipsJumpType.JAL, getCalledFunc().getMipsLabel());
|
||||
offset += (usedRegisters.size() + 2) * 4;
|
||||
recover(usedRegisters, offset);
|
||||
saveResult(this, Register.V0);
|
||||
}
|
||||
|
||||
public void save(ArrayList<Register> usedRegisters, int offset) {
|
||||
int num = 0;
|
||||
for (Register reg : usedRegisters) {
|
||||
num++;
|
||||
new MipsLs(MipsLsType.SW, reg, Register.SP, offset - num * 4);
|
||||
}
|
||||
new MipsLs(MipsLsType.SW, Register.SP, Register.SP, offset - (num + 1) * 4);
|
||||
new MipsLs(MipsLsType.SW, Register.RA, Register.SP, offset - (num + 2) * 4);
|
||||
}
|
||||
|
||||
public void saveArgs(ArrayList<IrValue> args, int offset, ArrayList<Register> usedRegisters) {
|
||||
int num = 0;
|
||||
ArrayList<Register> argRegs = new ArrayList<>();
|
||||
argRegs.add(Register.A1);
|
||||
argRegs.add(Register.A2);
|
||||
argRegs.add(Register.A3);
|
||||
for (IrValue arg : args) {
|
||||
num++;
|
||||
if (num <= 3) { // 分配到A1、A2、A3
|
||||
if (argRegs.contains(MipsBuilder.getRegister(arg))) {
|
||||
int index = usedRegisters.indexOf(MipsBuilder.getRegister(arg));
|
||||
new MipsLs(MipsLsType.LW, argRegs.get(num - 1), Register.SP, offset - (index + 1) * 4);
|
||||
} else {
|
||||
loadValueToReg(arg, argRegs.get(num - 1));
|
||||
}
|
||||
} else {
|
||||
if (MipsBuilder.getRegister(arg) == Register.K0 || argRegs.contains(MipsBuilder.getRegister(arg))) {
|
||||
int index = usedRegisters.indexOf(MipsBuilder.getRegister(arg));
|
||||
new MipsLs(MipsLsType.LW, Register.K0, Register.SP, offset - (index + 1) * 4);
|
||||
} else {
|
||||
loadValueToReg(arg, Register.K0);
|
||||
}
|
||||
new MipsLs(MipsLsType.SW, Register.K0, Register.SP, offset - (usedRegisters.size() + num + 2) * 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void recover(ArrayList<Register> usedRegisters, int offset) {
|
||||
new MipsLs(MipsLsType.LW, Register.RA, Register.SP, 0);
|
||||
new MipsLs(MipsLsType.LW, Register.SP, Register.SP, 4);
|
||||
int num = 0;
|
||||
for (Register reg : usedRegisters) {
|
||||
num++;
|
||||
new MipsLs(MipsLsType.LW, reg, Register.SP, offset - num * 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
26
midend/llvm/instr/CmpInstr.java
Normal file → Executable file
26
midend/llvm/instr/CmpInstr.java
Normal file → Executable file
@@ -1,7 +1,11 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
import midend.llvm.value.IrValue;
|
||||
import backend.mips.Register;
|
||||
import backend.mips.instr.MipsComp;
|
||||
import backend.mips.instr.type.MipsCompareType;
|
||||
import midend.llvm.type.IrInterType;
|
||||
import backend.mips.MipsBuilder;
|
||||
|
||||
public class CmpInstr extends IrInstr {
|
||||
private CmpType cmpType;
|
||||
@@ -29,4 +33,26 @@ public class CmpInstr extends IrInstr {
|
||||
return getName() + " = " + "icmp " + cmpType.toString()
|
||||
+ " i32 " + getLhs().getName() + ", " + getRhs().getName();
|
||||
}
|
||||
|
||||
public void toMips() {
|
||||
Register leftReg = MipsBuilder.getRegister(getLhs()) != null ? MipsBuilder.getRegister(getLhs()) : Register.K0;
|
||||
Register rightReg = MipsBuilder.getRegister(getRhs()) != null ? MipsBuilder.getRegister(getRhs()) : Register.K1;
|
||||
Register resultReg = MipsBuilder.getRegister(this) != null ? MipsBuilder.getRegister(this) : Register.K1;
|
||||
loadValueToReg(getLhs(), leftReg);
|
||||
loadValueToReg(getRhs(), rightReg);
|
||||
if (getCmpType() == CmpType.EQ) {
|
||||
new MipsComp(MipsCompareType.SEQ, resultReg, leftReg, rightReg);
|
||||
} else if (getCmpType() == CmpType.NE) {
|
||||
new MipsComp(MipsCompareType.SNE, resultReg, leftReg, rightReg);
|
||||
} else if (getCmpType() == CmpType.SGE) {
|
||||
new MipsComp(MipsCompareType.SGE, resultReg, leftReg, rightReg);
|
||||
} else if (getCmpType() == CmpType.SLE) {
|
||||
new MipsComp(MipsCompareType.SLE, resultReg, leftReg, rightReg);
|
||||
} else if (getCmpType() == CmpType.SGT) {
|
||||
new MipsComp(MipsCompareType.SGT, resultReg, leftReg, rightReg);
|
||||
} else if (getCmpType() == CmpType.SLT) {
|
||||
new MipsComp(MipsCompareType.SLT, resultReg, leftReg, rightReg);
|
||||
}
|
||||
saveResult(this, resultReg);
|
||||
}
|
||||
}
|
||||
|
||||
0
midend/llvm/instr/CmpType.java
Normal file → Executable file
0
midend/llvm/instr/CmpType.java
Normal file → Executable file
11
midend/llvm/instr/ExtendInstr.java
Normal file → Executable file
11
midend/llvm/instr/ExtendInstr.java
Normal file → Executable file
@@ -1,5 +1,7 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
import backend.mips.MipsBuilder;
|
||||
import backend.mips.Register;
|
||||
import midend.llvm.type.IrType;
|
||||
import midend.llvm.value.IrValue;
|
||||
|
||||
@@ -28,4 +30,13 @@ public class ExtendInstr extends IrInstr {
|
||||
return getName() + " = zext " + getSrc().getType()
|
||||
+ " " + getSrc().getName() + " to " + getTargetType();
|
||||
}
|
||||
|
||||
public void toMips() {
|
||||
Register reg = MipsBuilder.getRegister(this);
|
||||
if (reg == null) {
|
||||
reg = Register.K0;
|
||||
}
|
||||
loadValueToReg(getSrc(), reg);
|
||||
saveResult(this, reg);
|
||||
}
|
||||
}
|
||||
|
||||
29
midend/llvm/instr/GepInstr.java
Normal file → Executable file
29
midend/llvm/instr/GepInstr.java
Normal file → Executable file
@@ -1,5 +1,10 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
import backend.mips.MipsBuilder;
|
||||
import backend.mips.Register;
|
||||
import backend.mips.instr.MipsAlu;
|
||||
import backend.mips.instr.type.MipsAluType;
|
||||
import midend.llvm.constant.IrConstantInt;
|
||||
import midend.llvm.type.IrArrayType;
|
||||
import midend.llvm.type.IrPointerType;
|
||||
import midend.llvm.type.IrType;
|
||||
@@ -54,4 +59,28 @@ public class GepInstr extends IrInstr {
|
||||
return targetType;
|
||||
}
|
||||
}
|
||||
|
||||
public void toMips() {
|
||||
Register pointerReg = MipsBuilder.getRegister(getPointer());
|
||||
if (pointerReg == null) {
|
||||
pointerReg = Register.K0;
|
||||
}
|
||||
loadValueToReg(getPointer(), pointerReg);
|
||||
Register offsetReg = MipsBuilder.getRegister(getOffset());
|
||||
if (offsetReg == null) {
|
||||
offsetReg = Register.K1;
|
||||
}
|
||||
Register resultReg = MipsBuilder.getRegister(this);
|
||||
if (resultReg == null) {
|
||||
resultReg = Register.K1;
|
||||
}
|
||||
if (getOffset() instanceof IrConstantInt intOffset) {
|
||||
new MipsAlu(MipsAluType.ADDI, resultReg, pointerReg, 4 * intOffset.getValue());
|
||||
} else {
|
||||
loadValueToReg(getOffset(), offsetReg);
|
||||
new MipsAlu(MipsAluType.SLL, resultReg, offsetReg, 2);
|
||||
new MipsAlu(MipsAluType.ADDU, resultReg, resultReg, pointerReg);
|
||||
}
|
||||
saveResult(this, resultReg);
|
||||
}
|
||||
}
|
||||
|
||||
9
midend/llvm/instr/GetIntInstr.java
Normal file → Executable file
9
midend/llvm/instr/GetIntInstr.java
Normal file → Executable file
@@ -1,5 +1,8 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
import backend.mips.Register;
|
||||
import backend.mips.instr.MipsSyscall;
|
||||
import backend.mips.instr.fake.MipsLi;
|
||||
import midend.llvm.type.IrInterType;
|
||||
|
||||
public class GetIntInstr extends IrInstr {
|
||||
@@ -14,4 +17,10 @@ public class GetIntInstr extends IrInstr {
|
||||
public static String getIntDecl() {
|
||||
return "declare i32 @getint()";
|
||||
}
|
||||
|
||||
public void toMips() {
|
||||
new MipsLi(Register.V0, 5);
|
||||
new MipsSyscall();
|
||||
saveResult(this, Register.V0);
|
||||
}
|
||||
}
|
||||
|
||||
47
midend/llvm/instr/IrInstr.java
Normal file → Executable file
47
midend/llvm/instr/IrInstr.java
Normal file → Executable file
@@ -2,6 +2,16 @@ package midend.llvm.instr;
|
||||
|
||||
import midend.llvm.use.IrUser;
|
||||
import midend.llvm.value.IrBasicBlock;
|
||||
import midend.llvm.value.IrGlobalValue;
|
||||
import midend.llvm.value.IrValue;
|
||||
import midend.llvm.constant.IrConstantInt;
|
||||
import backend.mips.MipsBuilder;
|
||||
import backend.mips.Register;
|
||||
import backend.mips.instr.MipsLs;
|
||||
import backend.mips.instr.fake.MipsLa;
|
||||
import backend.mips.instr.fake.MipsLi;
|
||||
import backend.mips.instr.fake.MipsMove;
|
||||
import backend.mips.instr.type.MipsLsType;
|
||||
import midend.llvm.type.IrType;
|
||||
|
||||
public class IrInstr extends IrUser {
|
||||
@@ -25,4 +35,41 @@ public class IrInstr extends IrUser {
|
||||
public void setBBlock(IrBasicBlock block) {
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
public void saveResult(IrValue value, Register reg) {
|
||||
Register valueReg = MipsBuilder.getRegister(value);
|
||||
if (valueReg == null) {
|
||||
Integer offset = MipsBuilder.getOffset(value);
|
||||
if (offset == null) {
|
||||
MipsBuilder.allocaOffset(value);
|
||||
offset = MipsBuilder.getOffset(value);
|
||||
}
|
||||
new MipsLs(MipsLsType.SW, reg, Register.SP, offset);
|
||||
} else {
|
||||
new MipsMove(valueReg, reg);
|
||||
}
|
||||
}
|
||||
|
||||
public void loadValueToReg(IrValue value, Register reg) {
|
||||
if (value instanceof IrGlobalValue) {
|
||||
new MipsLa(reg, value.getMipsLabel());
|
||||
return;
|
||||
}
|
||||
if (value instanceof IrConstantInt) {
|
||||
new MipsLi(reg, ((IrConstantInt) value).getValue());
|
||||
return;
|
||||
}
|
||||
|
||||
Register valueReg = MipsBuilder.getRegister(value);
|
||||
if (valueReg != null) {
|
||||
new MipsMove(reg, valueReg);
|
||||
return;
|
||||
}
|
||||
Integer offset = MipsBuilder.getOffset(value);
|
||||
if (offset == null) {
|
||||
MipsBuilder.allocaOffset(value);
|
||||
offset = MipsBuilder.getOffset(value);
|
||||
}
|
||||
new MipsLs(MipsLsType.LW, reg, Register.SP, offset);
|
||||
}
|
||||
}
|
||||
|
||||
0
midend/llvm/instr/IrInstrType.java
Normal file → Executable file
0
midend/llvm/instr/IrInstrType.java
Normal file → Executable file
7
midend/llvm/instr/JumpInstr.java
Normal file → Executable file
7
midend/llvm/instr/JumpInstr.java
Normal file → Executable file
@@ -1,6 +1,8 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
import midend.llvm.value.IrBasicBlock;
|
||||
import backend.mips.instr.MipsJump;
|
||||
import backend.mips.instr.type.MipsJumpType;
|
||||
import midend.llvm.type.IrInterType;
|
||||
|
||||
public class JumpInstr extends IrInstr {
|
||||
@@ -16,5 +18,8 @@ public class JumpInstr extends IrInstr {
|
||||
public String toString() {
|
||||
return "br label " + "%" + getTargetBlock().getName();
|
||||
}
|
||||
|
||||
public void toMips() {
|
||||
new MipsJump(MipsJumpType.J, getTargetBlock().getMipsLabel()); //TODO: 该用JAL吗?
|
||||
}
|
||||
}
|
||||
// TODO:所有的指令的基本块设置还需完善
|
||||
19
midend/llvm/instr/LoadInstr.java
Normal file → Executable file
19
midend/llvm/instr/LoadInstr.java
Normal file → Executable file
@@ -1,5 +1,9 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
import backend.mips.MipsBuilder;
|
||||
import backend.mips.Register;
|
||||
import backend.mips.instr.MipsLs;
|
||||
import backend.mips.instr.type.MipsLsType;
|
||||
import midend.llvm.type.IrPointerType;
|
||||
import midend.llvm.value.IrValue;
|
||||
|
||||
@@ -17,4 +21,19 @@ public class LoadInstr extends IrInstr {
|
||||
return getName() + " = load " + getType() + ", "
|
||||
+ getPointer().getType() + " " + getPointer().getName();
|
||||
}
|
||||
|
||||
public void toMips() {
|
||||
IrValue pointer = getPointer();
|
||||
Register reg = MipsBuilder.getRegister(pointer);
|
||||
if (reg == null) { // 未分配寄存器情况
|
||||
reg = Register.K0;
|
||||
}
|
||||
loadValueToReg(pointer, reg);
|
||||
Register resultReg = MipsBuilder.getRegister(this);
|
||||
if (resultReg == null) {
|
||||
resultReg = Register.K1;
|
||||
}
|
||||
new MipsLs(MipsLsType.LW, resultReg, reg, 0);
|
||||
saveResult(this, resultReg);
|
||||
}
|
||||
}
|
||||
|
||||
9
midend/llvm/instr/PutChInstr.java
Normal file → Executable file
9
midend/llvm/instr/PutChInstr.java
Normal file → Executable file
@@ -2,6 +2,9 @@ package midend.llvm.instr;
|
||||
|
||||
import midend.llvm.type.IrInterType;
|
||||
import midend.llvm.value.IrValue;
|
||||
import backend.mips.Register;
|
||||
import backend.mips.instr.fake.MipsLi;
|
||||
import backend.mips.instr.MipsSyscall;
|
||||
|
||||
public class PutChInstr extends IrInstr {
|
||||
public PutChInstr(String name, IrValue putValue) {
|
||||
@@ -16,4 +19,10 @@ public class PutChInstr extends IrInstr {
|
||||
public static String putChDecl() {
|
||||
return "declare void @putch(i32)";
|
||||
}
|
||||
|
||||
public void toMips() {
|
||||
loadValueToReg(getUse(0), Register.A0);
|
||||
new MipsLi(Register.V0, 11);
|
||||
new MipsSyscall();
|
||||
}
|
||||
}
|
||||
|
||||
9
midend/llvm/instr/PutIntInstr.java
Normal file → Executable file
9
midend/llvm/instr/PutIntInstr.java
Normal file → Executable file
@@ -2,6 +2,9 @@ package midend.llvm.instr;
|
||||
|
||||
import midend.llvm.type.IrInterType;
|
||||
import midend.llvm.value.IrValue;
|
||||
import backend.mips.Register;
|
||||
import backend.mips.instr.fake.MipsLi;
|
||||
import backend.mips.instr.MipsSyscall;
|
||||
|
||||
public class PutIntInstr extends IrInstr {
|
||||
public PutIntInstr(String name, IrValue putValue) {
|
||||
@@ -16,4 +19,10 @@ public class PutIntInstr extends IrInstr {
|
||||
public static String putIntDecl() {
|
||||
return "declare void @putint(i32)";
|
||||
}
|
||||
|
||||
public void toMips() {
|
||||
loadValueToReg(getUse(0), Register.A0);
|
||||
new MipsLi(Register.V0, 1);
|
||||
new MipsSyscall();
|
||||
}
|
||||
}
|
||||
|
||||
10
midend/llvm/instr/PutStrInstr.java
Normal file → Executable file
10
midend/llvm/instr/PutStrInstr.java
Normal file → Executable file
@@ -2,7 +2,11 @@ package midend.llvm.instr;
|
||||
|
||||
import midend.llvm.type.IrInterType;
|
||||
import midend.llvm.type.IrPointerType;
|
||||
import backend.mips.instr.fake.MipsLa;
|
||||
import midend.llvm.constant.IrConstantStr;
|
||||
import backend.mips.instr.fake.MipsLi;
|
||||
import backend.mips.instr.MipsSyscall;
|
||||
import backend.mips.Register;
|
||||
|
||||
public class PutStrInstr extends IrInstr {
|
||||
private IrConstantStr strVal;
|
||||
@@ -23,4 +27,10 @@ public class PutStrInstr extends IrInstr {
|
||||
+ ptrType.getPointeeType() + ", " + ptrType +
|
||||
" " + strVal.getName() + ", i32 0, i32 0))";
|
||||
}
|
||||
|
||||
public void toMips() {
|
||||
new MipsLa(Register.A0, strVal.getMipsLabel());
|
||||
new MipsLi(Register.V0, 4);
|
||||
new MipsSyscall();
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user