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.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
import backend.BackEnd;
|
||||||
import frontend.lexer.Lexer;
|
import frontend.lexer.Lexer;
|
||||||
import frontend.lexer.TokenStream;
|
import frontend.lexer.TokenStream;
|
||||||
import frontend.parser.Parser;
|
import frontend.parser.Parser;
|
||||||
@@ -15,6 +17,7 @@ public class Compiler {
|
|||||||
try {
|
try {
|
||||||
String content = new String(Files.readAllBytes(Paths.get("testfile.txt")));
|
String content = new String(Files.readAllBytes(Paths.get("testfile.txt")));
|
||||||
String llvmFile = "llvm_ir.txt";
|
String llvmFile = "llvm_ir.txt";
|
||||||
|
String mipsFile = "mips.txt";
|
||||||
String errorFile = "error.txt";
|
String errorFile = "error.txt";
|
||||||
Lexer lexer = new Lexer(content);
|
Lexer lexer = new Lexer(content);
|
||||||
lexer.lex(errors);
|
lexer.lex(errors);
|
||||||
@@ -33,7 +36,10 @@ public class Compiler {
|
|||||||
} else {
|
} else {
|
||||||
Midend midend = new Midend(parser.getCompUnit());
|
Midend midend = new Midend(parser.getCompUnit());
|
||||||
midend.generateLLvmIr();
|
midend.generateLLvmIr();
|
||||||
midend.writeToFile(llvmFile);
|
// midend.writeToFile(llvmFile);
|
||||||
|
BackEnd backEnd = new BackEnd(midend.getModule());
|
||||||
|
backEnd.toMips();
|
||||||
|
backEnd.writeToFile(mipsFile);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
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();
|
visitor.visit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IrModule getModule() {
|
||||||
|
return module;
|
||||||
|
}
|
||||||
|
|
||||||
public void writeToFile(String fileName) {
|
public void writeToFile(String fileName) {
|
||||||
try {
|
try {
|
||||||
Files.write(Paths.get(fileName), module.toString().getBytes());
|
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.ArrayList;
|
||||||
import java.util.HashMap;
|
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.constant.IrConstantStr;
|
||||||
import midend.llvm.value.IrFuncValue;
|
import midend.llvm.value.IrFuncValue;
|
||||||
import midend.llvm.value.IrGlobalValue;
|
import midend.llvm.value.IrGlobalValue;
|
||||||
@@ -79,7 +86,6 @@ public class IrModule {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: toString()方法编写
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (String decl : decls) {
|
for (String decl : decls) {
|
||||||
@@ -97,4 +103,23 @@ public class IrModule {
|
|||||||
// System.out.println(funcs.size());
|
// System.out.println(funcs.size());
|
||||||
return sb.toString();
|
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() {
|
public String toString() {
|
||||||
return "";
|
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 java.util.ArrayList;
|
||||||
|
|
||||||
|
import backend.mips.instr.data.MipsSpace;
|
||||||
|
import backend.mips.instr.data.MipsWord;
|
||||||
import midend.llvm.type.IrInterType;
|
import midend.llvm.type.IrInterType;
|
||||||
import midend.llvm.type.IrArrayType;
|
import midend.llvm.type.IrArrayType;
|
||||||
|
|
||||||
@@ -44,4 +46,19 @@ public class IrConstantArray extends IrConstant {
|
|||||||
}
|
}
|
||||||
return sb.toString();
|
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;
|
package midend.llvm.constant;
|
||||||
|
|
||||||
|
import backend.mips.instr.data.MipsWord;
|
||||||
import midend.llvm.type.IrInterType;
|
import midend.llvm.type.IrInterType;
|
||||||
|
|
||||||
public class IrConstantInt extends IrConstant {
|
public class IrConstantInt extends IrConstant {
|
||||||
@@ -17,4 +18,8 @@ public class IrConstantInt extends IrConstant {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "i32 " + value;
|
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;
|
package midend.llvm.constant;
|
||||||
|
|
||||||
|
import backend.mips.instr.data.MipsAsciiz;
|
||||||
import midend.llvm.type.IrArrayType;
|
import midend.llvm.type.IrArrayType;
|
||||||
import midend.llvm.type.IrPointerType;
|
import midend.llvm.type.IrPointerType;
|
||||||
import midend.llvm.type.IrInterType;
|
import midend.llvm.type.IrInterType;
|
||||||
@@ -50,4 +51,8 @@ public class IrConstantStr extends IrConstant {
|
|||||||
sb.append("\\00\"");
|
sb.append("\\00\"");
|
||||||
return sb.toString();
|
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;
|
package midend.llvm.instr;
|
||||||
|
|
||||||
|
import backend.mips.MipsBuilder;
|
||||||
|
import midend.llvm.type.IrArrayType;
|
||||||
import midend.llvm.type.IrPointerType;
|
import midend.llvm.type.IrPointerType;
|
||||||
import midend.llvm.type.IrType;
|
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 {
|
public class AllocateInstr extends IrInstr {
|
||||||
private IrType pointeeType;
|
private IrType pointeeType;
|
||||||
@@ -18,4 +25,25 @@ public class AllocateInstr extends IrInstr {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return getName() + " = alloca " + this.pointeeType;
|
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;
|
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.type.IrInterType;
|
||||||
import midend.llvm.value.IrValue;
|
import midend.llvm.value.IrValue;
|
||||||
|
|
||||||
@@ -21,4 +28,34 @@ public class AluInstr extends IrInstr {
|
|||||||
return getName() + " = " + alutype.toString() + " " + getType()
|
return getName() + " = " + alutype.toString() + " " + getType()
|
||||||
+ " " + getUse(0).getName() + ", " + getUse(1).getName();
|
+ " " + 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.IrBasicBlock;
|
||||||
import midend.llvm.value.IrValue;
|
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;
|
import midend.llvm.type.IrInterType;
|
||||||
|
|
||||||
public class BranchInstr extends IrInstr {
|
public class BranchInstr extends IrInstr {
|
||||||
@@ -30,4 +36,13 @@ public class BranchInstr extends IrInstr {
|
|||||||
", label %" + getFalseBB().getName();
|
", 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 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.IrFuncValue;
|
||||||
import midend.llvm.value.IrValue;
|
import midend.llvm.value.IrValue;
|
||||||
|
|
||||||
@@ -45,4 +53,65 @@ public class CallInstr extends IrInstr {
|
|||||||
sb.append(")");
|
sb.append(")");
|
||||||
return sb.toString();
|
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;
|
package midend.llvm.instr;
|
||||||
|
|
||||||
import midend.llvm.value.IrValue;
|
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 midend.llvm.type.IrInterType;
|
||||||
|
import backend.mips.MipsBuilder;
|
||||||
|
|
||||||
public class CmpInstr extends IrInstr {
|
public class CmpInstr extends IrInstr {
|
||||||
private CmpType cmpType;
|
private CmpType cmpType;
|
||||||
@@ -29,4 +33,26 @@ public class CmpInstr extends IrInstr {
|
|||||||
return getName() + " = " + "icmp " + cmpType.toString()
|
return getName() + " = " + "icmp " + cmpType.toString()
|
||||||
+ " i32 " + getLhs().getName() + ", " + getRhs().getName();
|
+ " 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;
|
package midend.llvm.instr;
|
||||||
|
|
||||||
|
import backend.mips.MipsBuilder;
|
||||||
|
import backend.mips.Register;
|
||||||
import midend.llvm.type.IrType;
|
import midend.llvm.type.IrType;
|
||||||
import midend.llvm.value.IrValue;
|
import midend.llvm.value.IrValue;
|
||||||
|
|
||||||
@@ -28,4 +30,13 @@ public class ExtendInstr extends IrInstr {
|
|||||||
return getName() + " = zext " + getSrc().getType()
|
return getName() + " = zext " + getSrc().getType()
|
||||||
+ " " + getSrc().getName() + " to " + getTargetType();
|
+ " " + 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;
|
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.IrArrayType;
|
||||||
import midend.llvm.type.IrPointerType;
|
import midend.llvm.type.IrPointerType;
|
||||||
import midend.llvm.type.IrType;
|
import midend.llvm.type.IrType;
|
||||||
@@ -54,4 +59,28 @@ public class GepInstr extends IrInstr {
|
|||||||
return targetType;
|
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;
|
package midend.llvm.instr;
|
||||||
|
|
||||||
|
import backend.mips.Register;
|
||||||
|
import backend.mips.instr.MipsSyscall;
|
||||||
|
import backend.mips.instr.fake.MipsLi;
|
||||||
import midend.llvm.type.IrInterType;
|
import midend.llvm.type.IrInterType;
|
||||||
|
|
||||||
public class GetIntInstr extends IrInstr {
|
public class GetIntInstr extends IrInstr {
|
||||||
@@ -14,4 +17,10 @@ public class GetIntInstr extends IrInstr {
|
|||||||
public static String getIntDecl() {
|
public static String getIntDecl() {
|
||||||
return "declare i32 @getint()";
|
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.use.IrUser;
|
||||||
import midend.llvm.value.IrBasicBlock;
|
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;
|
import midend.llvm.type.IrType;
|
||||||
|
|
||||||
public class IrInstr extends IrUser {
|
public class IrInstr extends IrUser {
|
||||||
@@ -25,4 +35,41 @@ public class IrInstr extends IrUser {
|
|||||||
public void setBBlock(IrBasicBlock block) {
|
public void setBBlock(IrBasicBlock block) {
|
||||||
this.block = 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;
|
package midend.llvm.instr;
|
||||||
|
|
||||||
import midend.llvm.value.IrBasicBlock;
|
import midend.llvm.value.IrBasicBlock;
|
||||||
|
import backend.mips.instr.MipsJump;
|
||||||
|
import backend.mips.instr.type.MipsJumpType;
|
||||||
import midend.llvm.type.IrInterType;
|
import midend.llvm.type.IrInterType;
|
||||||
|
|
||||||
public class JumpInstr extends IrInstr {
|
public class JumpInstr extends IrInstr {
|
||||||
@@ -16,5 +18,8 @@ public class JumpInstr extends IrInstr {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "br label " + "%" + getTargetBlock().getName();
|
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;
|
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.type.IrPointerType;
|
||||||
import midend.llvm.value.IrValue;
|
import midend.llvm.value.IrValue;
|
||||||
|
|
||||||
@@ -17,4 +21,19 @@ public class LoadInstr extends IrInstr {
|
|||||||
return getName() + " = load " + getType() + ", "
|
return getName() + " = load " + getType() + ", "
|
||||||
+ getPointer().getType() + " " + getPointer().getName();
|
+ 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.type.IrInterType;
|
||||||
import midend.llvm.value.IrValue;
|
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 class PutChInstr extends IrInstr {
|
||||||
public PutChInstr(String name, IrValue putValue) {
|
public PutChInstr(String name, IrValue putValue) {
|
||||||
@@ -16,4 +19,10 @@ public class PutChInstr extends IrInstr {
|
|||||||
public static String putChDecl() {
|
public static String putChDecl() {
|
||||||
return "declare void @putch(i32)";
|
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.type.IrInterType;
|
||||||
import midend.llvm.value.IrValue;
|
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 class PutIntInstr extends IrInstr {
|
||||||
public PutIntInstr(String name, IrValue putValue) {
|
public PutIntInstr(String name, IrValue putValue) {
|
||||||
@@ -16,4 +19,10 @@ public class PutIntInstr extends IrInstr {
|
|||||||
public static String putIntDecl() {
|
public static String putIntDecl() {
|
||||||
return "declare void @putint(i32)";
|
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.IrInterType;
|
||||||
import midend.llvm.type.IrPointerType;
|
import midend.llvm.type.IrPointerType;
|
||||||
|
import backend.mips.instr.fake.MipsLa;
|
||||||
import midend.llvm.constant.IrConstantStr;
|
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 {
|
public class PutStrInstr extends IrInstr {
|
||||||
private IrConstantStr strVal;
|
private IrConstantStr strVal;
|
||||||
@@ -23,4 +27,10 @@ public class PutStrInstr extends IrInstr {
|
|||||||
+ ptrType.getPointeeType() + ", " + ptrType +
|
+ ptrType.getPointeeType() + ", " + ptrType +
|
||||||
" " + strVal.getName() + ", i32 0, i32 0))";
|
" " + 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