mips without optimize

This commit is contained in:
colden
2025-12-12 20:14:00 +08:00
parent 84827838e2
commit c94bebf37b
130 changed files with 5462 additions and 4182 deletions

70
midend/llvm/instr/AllocateInstr.java Normal file → Executable file
View File

@@ -1,21 +1,49 @@
package midend.llvm.instr;
import midend.llvm.type.IrPointerType;
import midend.llvm.type.IrType;
public class AllocateInstr extends IrInstr {
private IrType pointeeType;
public AllocateInstr(IrType pointeeType, String name) { // name即为局部变量的name因为要声明一个局部变量
super(new IrPointerType(pointeeType), name, IrInstrType.ALLOCA);
this.pointeeType = pointeeType;
}
public IrType getPointeeType() {
return pointeeType;
}
public String toString() {
return getName() + " = alloca " + this.pointeeType;
}
}
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;
public AllocateInstr(IrType pointeeType, String name) { // name即为局部变量的name因为要声明一个局部变量
super(new IrPointerType(pointeeType), name, IrInstrType.ALLOCA);
this.pointeeType = pointeeType;
}
public IrType getPointeeType() {
return pointeeType;
}
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);
}
}
}

85
midend/llvm/instr/AluInstr.java Normal file → Executable file
View File

@@ -1,24 +1,61 @@
package midend.llvm.instr;
import midend.llvm.type.IrInterType;
import midend.llvm.value.IrValue;
public class AluInstr extends IrInstr {
private AluType alutype;
public AluInstr(String name, String op, IrValue left, IrValue right) {
super(IrInterType.INT32, name, IrInstrType.ALU);
this.alutype = AluType.getAluType(op);
addUse(left);
addUse(right);
}
public AluType getAluType() {
return alutype;
}
public String toString() {
return getName() + " = " + alutype.toString() + " " + getType()
+ " " + getUse(0).getName() + ", " + getUse(1).getName();
}
}
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;
public class AluInstr extends IrInstr {
private AluType alutype;
public AluInstr(String name, String op, IrValue left, IrValue right) {
super(IrInterType.INT32, name, IrInstrType.ALU);
this.alutype = AluType.getAluType(op);
addUse(left);
addUse(right);
}
public AluType getAluType() {
return alutype;
}
public String toString() {
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);
}
}

104
midend/llvm/instr/AluType.java Normal file → Executable file
View File

@@ -1,53 +1,53 @@
package midend.llvm.instr;
public enum AluType {
ADD,
SUB,
MUL,
SDIV,
SREM,
AND,
OR;
public static AluType getAluType(String op) {
switch (op) {
case "+":
return ADD;
case "-":
return SUB;
case "*":
return MUL;
case "/":
return SDIV;
case "%":
return SREM;
case "&":
return AND;
case "|":
return OR;
default:
return null;
}
}
public String toString() {
switch (this) {
case ADD:
return "add";
case SUB:
return "sub";
case MUL:
return "mul";
case SDIV:
return "sdiv";
case SREM:
return "srem";
case AND:
return "and";
case OR:
return "or";
default:
return null;
}
}
package midend.llvm.instr;
public enum AluType {
ADD,
SUB,
MUL,
SDIV,
SREM,
AND,
OR;
public static AluType getAluType(String op) {
switch (op) {
case "+":
return ADD;
case "-":
return SUB;
case "*":
return MUL;
case "/":
return SDIV;
case "%":
return SREM;
case "&":
return AND;
case "|":
return OR;
default:
return null;
}
}
public String toString() {
switch (this) {
case ADD:
return "add";
case SUB:
return "sub";
case MUL:
return "mul";
case SDIV:
return "sdiv";
case SREM:
return "srem";
case AND:
return "and";
case OR:
return "or";
default:
return null;
}
}
}

81
midend/llvm/instr/BranchInstr.java Normal file → Executable file
View File

@@ -1,33 +1,48 @@
package midend.llvm.instr;
import midend.llvm.value.IrBasicBlock;
import midend.llvm.value.IrValue;
import midend.llvm.type.IrInterType;
public class BranchInstr extends IrInstr {
public BranchInstr(String name, IrValue cond, IrBasicBlock trueBB, IrBasicBlock falseBB) {
super(IrInterType.VOID, name, IrInstrType.BR);
addUse(cond);
addUse(trueBB);
addUse(falseBB);
}
public IrValue getCond() {
return getUse(0);
}
public IrBasicBlock getTrueBB() {
return (IrBasicBlock) getUse(1);
}
public IrBasicBlock getFalseBB() {
return (IrBasicBlock) getUse(2);
}
public String toString() {
return "br i1 " + getCond().getName() +
", label %" + getTrueBB().getName() +
", label %" + getFalseBB().getName();
}
}
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 {
public BranchInstr(String name, IrValue cond, IrBasicBlock trueBB, IrBasicBlock falseBB) {
super(IrInterType.VOID, name, IrInstrType.BR);
addUse(cond);
addUse(trueBB);
addUse(falseBB);
}
public IrValue getCond() {
return getUse(0);
}
public IrBasicBlock getTrueBB() {
return (IrBasicBlock) getUse(1);
}
public IrBasicBlock getFalseBB() {
return (IrBasicBlock) getUse(2);
}
public String toString() {
return "br i1 " + getCond().getName() +
", label %" + getTrueBB().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());
}
}

165
midend/llvm/instr/CallInstr.java Normal file → Executable file
View File

@@ -1,48 +1,117 @@
package midend.llvm.instr;
import java.util.ArrayList;
import midend.llvm.value.IrFuncValue;
import midend.llvm.value.IrValue;
public class CallInstr extends IrInstr {
public CallInstr(String name, IrFuncValue func, ArrayList<IrValue> args) {
super(func.getRetType(), name, IrInstrType.CALL);
addUse(func);
for (IrValue arg : args) {
addUse(arg);
}
}
public boolean callVoid() {
return getType().isVoid();
}
public IrFuncValue getCalledFunc() {
return (IrFuncValue) getUse(0);
}
public ArrayList<IrValue> getArgs() {
ArrayList<IrValue> args = new ArrayList<>();
for (int i = 1; i < getNumUses(); i++) {
args.add(getUse(i));
}
return args;
}
public String toString() {
StringBuilder sb = new StringBuilder();
if (!callVoid()) {
sb.append(getName() + " = ");
}
sb.append("call " + getType() + " " + getCalledFunc().getName() + "(");
for (int i = 1; i < getNumUses(); i++) {
sb.append(getUse(i).getType() + " " + getUse(i).getName());
if (i < getNumUses() - 1) {
sb.append(", ");
}
}
sb.append(")");
return sb.toString();
}
}
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;
public class CallInstr extends IrInstr {
public CallInstr(String name, IrFuncValue func, ArrayList<IrValue> args) {
super(func.getRetType(), name, IrInstrType.CALL);
addUse(func);
for (IrValue arg : args) {
addUse(arg);
}
}
public boolean callVoid() {
return getType().isVoid();
}
public IrFuncValue getCalledFunc() {
return (IrFuncValue) getUse(0);
}
public ArrayList<IrValue> getArgs() {
ArrayList<IrValue> args = new ArrayList<>();
for (int i = 1; i < getNumUses(); i++) {
args.add(getUse(i));
}
return args;
}
public String toString() {
StringBuilder sb = new StringBuilder();
if (!callVoid()) {
sb.append(getName() + " = ");
}
sb.append("call " + getType() + " " + getCalledFunc().getName() + "(");
for (int i = 1; i < getNumUses(); i++) {
sb.append(getUse(i).getType() + " " + getUse(i).getName());
if (i < getNumUses() - 1) {
sb.append(", ");
}
}
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);
}
}
}

90
midend/llvm/instr/CmpInstr.java Normal file → Executable file
View File

@@ -1,32 +1,58 @@
package midend.llvm.instr;
import midend.llvm.value.IrValue;
import midend.llvm.type.IrInterType;
public class CmpInstr extends IrInstr {
private CmpType cmpType;
public CmpInstr(String name, String op, IrValue lhs, IrValue rhs) {
super(IrInterType.BOOL, name, IrInstrType.CMP);
cmpType = CmpType.getCmpType(op);
addUse(lhs);
addUse(rhs);
}
public CmpType getCmpType() {
return cmpType;
}
public IrValue getLhs() {
return getUse(0);
}
public IrValue getRhs() {
return getUse(1);
}
public String toString() {
return getName() + " = " + "icmp " + cmpType.toString()
+ " i32 " + getLhs().getName() + ", " + getRhs().getName();
}
}
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;
public CmpInstr(String name, String op, IrValue lhs, IrValue rhs) {
super(IrInterType.BOOL, name, IrInstrType.CMP);
cmpType = CmpType.getCmpType(op);
addUse(lhs);
addUse(rhs);
}
public CmpType getCmpType() {
return cmpType;
}
public IrValue getLhs() {
return getUse(0);
}
public IrValue getRhs() {
return getUse(1);
}
public String toString() {
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);
}
}

96
midend/llvm/instr/CmpType.java Normal file → Executable file
View File

@@ -1,48 +1,48 @@
package midend.llvm.instr;
public enum CmpType {
EQ,
NE,
SGT,
SGE,
SLT,
SLE;
public static CmpType getCmpType(String op) {
switch (op) {
case "==":
return EQ;
case "!=":
return NE;
case ">":
return SGT;
case ">=":
return SGE;
case "<":
return SLT;
case "<=":
return SLE;
default:
return null;
}
}
public String toString() {
switch (this) {
case EQ:
return "eq";
case NE:
return "ne";
case SGT:
return "sgt";
case SGE:
return "sge";
case SLT:
return "slt";
case SLE:
return "sle";
default:
return null;
}
}
}
package midend.llvm.instr;
public enum CmpType {
EQ,
NE,
SGT,
SGE,
SLT,
SLE;
public static CmpType getCmpType(String op) {
switch (op) {
case "==":
return EQ;
case "!=":
return NE;
case ">":
return SGT;
case ">=":
return SGE;
case "<":
return SLT;
case "<=":
return SLE;
default:
return null;
}
}
public String toString() {
switch (this) {
case EQ:
return "eq";
case NE:
return "ne";
case SGT:
return "sgt";
case SGE:
return "sge";
case SLT:
return "slt";
case SLE:
return "sle";
default:
return null;
}
}
}

73
midend/llvm/instr/ExtendInstr.java Normal file → Executable file
View File

@@ -1,31 +1,42 @@
package midend.llvm.instr;
import midend.llvm.type.IrType;
import midend.llvm.value.IrValue;
public class ExtendInstr extends IrInstr {
private IrType targetType;
public ExtendInstr(String name, IrType targetType, IrValue src) {
super(targetType, name, IrInstrType.EXTEND);
this.targetType = targetType;
addUse(src);
}
public IrValue getSrc() {
return getUse(0);
}
public IrType getTargetType() {
return this.targetType;
}
public IrType getSrcType() {
return getSrc().getType();
}
public String toString() {
return getName() + " = zext " + getSrc().getType()
+ " " + getSrc().getName() + " to " + getTargetType();
}
}
package midend.llvm.instr;
import backend.mips.MipsBuilder;
import backend.mips.Register;
import midend.llvm.type.IrType;
import midend.llvm.value.IrValue;
public class ExtendInstr extends IrInstr {
private IrType targetType;
public ExtendInstr(String name, IrType targetType, IrValue src) {
super(targetType, name, IrInstrType.EXTEND);
this.targetType = targetType;
addUse(src);
}
public IrValue getSrc() {
return getUse(0);
}
public IrType getTargetType() {
return this.targetType;
}
public IrType getSrcType() {
return getSrc().getType();
}
public String toString() {
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);
}
}

143
midend/llvm/instr/GepInstr.java Normal file → Executable file
View File

@@ -1,57 +1,86 @@
package midend.llvm.instr;
import midend.llvm.type.IrArrayType;
import midend.llvm.type.IrPointerType;
import midend.llvm.type.IrType;
import midend.llvm.value.IrValue;
public class GepInstr extends IrInstr {
public GepInstr(IrValue pointer, IrValue offset, String name) {
super(new IrPointerType(getTargetType(pointer)), name, IrInstrType.GEP);
addUse(pointer);
addUse(offset);
}
public IrValue getPointer() {
return getUse(0);
}
public IrValue getOffset() {
return getUse(1);
}
public String toString() {
IrValue pointer = this.getPointer();
IrValue offset = this.getOffset();
IrPointerType pointerType = (IrPointerType) pointer.getType();
IrType targetType = pointerType.getPointeeType();
if (targetType instanceof IrArrayType arrayType) {
return getName() + " = getelementptr inbounds " +
arrayType + ", " +
pointerType + " " +
pointer.getName() + ", i32 0, " +
offset.getType() + " " +
offset.getName();
} else {
return getName() + " = getelementptr inbounds " +
targetType + ", " +
pointerType + " " +
pointer.getName() + ", " +
offset.getType() + " " +
offset.getName();
}
}
public static IrType getTargetType(IrValue pointer) {
IrType targetType = ((IrPointerType) pointer.getType()).getPointeeType();
if (targetType instanceof IrArrayType arrayType) {
return arrayType.getElementType();
} else if (targetType instanceof IrPointerType pointerType) {
return pointerType.getPointeeType();
} else {
return targetType;
}
}
}
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;
import midend.llvm.value.IrValue;
public class GepInstr extends IrInstr {
public GepInstr(IrValue pointer, IrValue offset, String name) {
super(new IrPointerType(getTargetType(pointer)), name, IrInstrType.GEP);
addUse(pointer);
addUse(offset);
}
public IrValue getPointer() {
return getUse(0);
}
public IrValue getOffset() {
return getUse(1);
}
public String toString() {
IrValue pointer = this.getPointer();
IrValue offset = this.getOffset();
IrPointerType pointerType = (IrPointerType) pointer.getType();
IrType targetType = pointerType.getPointeeType();
if (targetType instanceof IrArrayType arrayType) {
return getName() + " = getelementptr inbounds " +
arrayType + ", " +
pointerType + " " +
pointer.getName() + ", i32 0, " +
offset.getType() + " " +
offset.getName();
} else {
return getName() + " = getelementptr inbounds " +
targetType + ", " +
pointerType + " " +
pointer.getName() + ", " +
offset.getType() + " " +
offset.getName();
}
}
public static IrType getTargetType(IrValue pointer) {
IrType targetType = ((IrPointerType) pointer.getType()).getPointeeType();
if (targetType instanceof IrArrayType arrayType) {
return arrayType.getElementType();
} else if (targetType instanceof IrPointerType pointerType) {
return pointerType.getPointeeType();
} else {
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);
}
}

43
midend/llvm/instr/GetIntInstr.java Normal file → Executable file
View File

@@ -1,17 +1,26 @@
package midend.llvm.instr;
import midend.llvm.type.IrInterType;
public class GetIntInstr extends IrInstr {
public GetIntInstr(String name) {
super(IrInterType.INT32, name, IrInstrType.IO);
}
public String toString() {
return getName() + " = call i32 @getint()";
}
public static String getIntDecl() {
return "declare i32 @getint()";
}
}
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 {
public GetIntInstr(String name) {
super(IrInterType.INT32, name, IrInstrType.IO);
}
public String toString() {
return getName() + " = call i32 @getint()";
}
public static String getIntDecl() {
return "declare i32 @getint()";
}
public void toMips() {
new MipsLi(Register.V0, 5);
new MipsSyscall();
saveResult(this, Register.V0);
}
}

103
midend/llvm/instr/IrInstr.java Normal file → Executable file
View File

@@ -1,28 +1,75 @@
package midend.llvm.instr;
import midend.llvm.use.IrUser;
import midend.llvm.value.IrBasicBlock;
import midend.llvm.type.IrType;
public class IrInstr extends IrUser {
private IrInstrType type;
private IrBasicBlock block;
public IrInstr(IrType type, String name, IrInstrType instrType) {
super(type, name);
this.type = instrType;
this.block = null;
}
public IrInstrType getInstrType() {
return type;
}
public IrBasicBlock getBBlock() {
return block;
}
public void setBBlock(IrBasicBlock block) {
this.block = block;
}
}
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 {
private IrInstrType type;
private IrBasicBlock block;
public IrInstr(IrType type, String name, IrInstrType instrType) {
super(type, name);
this.type = instrType;
this.block = null;
}
public IrInstrType getInstrType() {
return type;
}
public IrBasicBlock getBBlock() {
return block;
}
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);
}
}

36
midend/llvm/instr/IrInstrType.java Normal file → Executable file
View File

@@ -1,18 +1,18 @@
package midend.llvm.instr;
public enum IrInstrType {
ALU,
CMP,
CALL,
ALLOCA,
LOAD,
STORE,
GEP,
PHI,
EXTEND,
TRUNC,
BR,
RET,
JUMP,
IO
}
package midend.llvm.instr;
public enum IrInstrType {
ALU,
CMP,
CALL,
ALLOCA,
LOAD,
STORE,
GEP,
PHI,
EXTEND,
TRUNC,
BR,
RET,
JUMP,
IO
}

45
midend/llvm/instr/JumpInstr.java Normal file → Executable file
View File

@@ -1,20 +1,25 @@
package midend.llvm.instr;
import midend.llvm.value.IrBasicBlock;
import midend.llvm.type.IrInterType;
public class JumpInstr extends IrInstr {
public JumpInstr(IrBasicBlock targetBlock) {
super(IrInterType.VOID, "jump", IrInstrType.JUMP);
addUse(targetBlock);
}
public IrBasicBlock getTargetBlock() {
return (IrBasicBlock) getUse(0);
}
public String toString() {
return "br label " + "%" + getTargetBlock().getName();
}
}
// TODO:所有的指令的基本块设置还需完善
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 {
public JumpInstr(IrBasicBlock targetBlock) {
super(IrInterType.VOID, "jump", IrInstrType.JUMP);
addUse(targetBlock);
}
public IrBasicBlock getTargetBlock() {
return (IrBasicBlock) getUse(0);
}
public String toString() {
return "br label " + "%" + getTargetBlock().getName();
}
public void toMips() {
new MipsJump(MipsJumpType.J, getTargetBlock().getMipsLabel()); //TODO: 该用JAL吗
}
}

59
midend/llvm/instr/LoadInstr.java Normal file → Executable file
View File

@@ -1,20 +1,39 @@
package midend.llvm.instr;
import midend.llvm.type.IrPointerType;
import midend.llvm.value.IrValue;
public class LoadInstr extends IrInstr {
public LoadInstr(IrValue pointer, String name) {
super(((IrPointerType) pointer.getType()).getPointeeType(), name, IrInstrType.LOAD);
addUse(pointer);
}
public IrValue getPointer() {
return getUse(0);
}
public String toString() {
return getName() + " = load " + getType() + ", "
+ getPointer().getType() + " " + getPointer().getName();
}
}
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;
public class LoadInstr extends IrInstr {
public LoadInstr(IrValue pointer, String name) {
super(((IrPointerType) pointer.getType()).getPointeeType(), name, IrInstrType.LOAD);
addUse(pointer);
}
public IrValue getPointer() {
return getUse(0);
}
public String toString() {
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);
}
}

47
midend/llvm/instr/PutChInstr.java Normal file → Executable file
View File

@@ -1,19 +1,28 @@
package midend.llvm.instr;
import midend.llvm.type.IrInterType;
import midend.llvm.value.IrValue;
public class PutChInstr extends IrInstr {
public PutChInstr(String name, IrValue putValue) {
super(IrInterType.VOID, name, IrInstrType.IO);
addUse(putValue);
}
public String toString() {
return "call void @putch(i32 " + getUses().get(0).getName() + ")";
}
public static String putChDecl() {
return "declare void @putch(i32)";
}
}
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) {
super(IrInterType.VOID, name, IrInstrType.IO);
addUse(putValue);
}
public String toString() {
return "call void @putch(i32 " + getUses().get(0).getName() + ")";
}
public static String putChDecl() {
return "declare void @putch(i32)";
}
public void toMips() {
loadValueToReg(getUse(0), Register.A0);
new MipsLi(Register.V0, 11);
new MipsSyscall();
}
}

47
midend/llvm/instr/PutIntInstr.java Normal file → Executable file
View File

@@ -1,19 +1,28 @@
package midend.llvm.instr;
import midend.llvm.type.IrInterType;
import midend.llvm.value.IrValue;
public class PutIntInstr extends IrInstr {
public PutIntInstr(String name, IrValue putValue) {
super(IrInterType.VOID, name, IrInstrType.IO);
addUse(putValue);
}
public String toString() {
return "call void @putint(i32 " + getUses().get(0).getName() + ")";
}
public static String putIntDecl() {
return "declare void @putint(i32)";
}
}
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) {
super(IrInterType.VOID, name, IrInstrType.IO);
addUse(putValue);
}
public String toString() {
return "call void @putint(i32 " + getUses().get(0).getName() + ")";
}
public static String putIntDecl() {
return "declare void @putint(i32)";
}
public void toMips() {
loadValueToReg(getUse(0), Register.A0);
new MipsLi(Register.V0, 1);
new MipsSyscall();
}
}

62
midend/llvm/instr/PutStrInstr.java Normal file → Executable file
View File

@@ -1,26 +1,36 @@
package midend.llvm.instr;
import midend.llvm.type.IrInterType;
import midend.llvm.type.IrPointerType;
import midend.llvm.constant.IrConstantStr;
public class PutStrInstr extends IrInstr {
private IrConstantStr strVal;
public PutStrInstr(String name, IrConstantStr putValue) {
super(IrInterType.VOID, name, IrInstrType.IO);
addUse(putValue);
strVal = putValue;
}
public static String putStrDecl() {
return "declare void @putstr(i8*)";
}
public String toString() {
IrPointerType ptrType = (IrPointerType) strVal.getType();
return "call void @putstr(i8* getelementptr inbounds ("
+ ptrType.getPointeeType() + ", " + ptrType +
" " + strVal.getName() + ", i32 0, i32 0))";
}
}
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;
public PutStrInstr(String name, IrConstantStr putValue) {
super(IrInterType.VOID, name, IrInstrType.IO);
addUse(putValue);
strVal = putValue;
}
public static String putStrDecl() {
return "declare void @putstr(i8*)";
}
public String toString() {
IrPointerType ptrType = (IrPointerType) strVal.getType();
return "call void @putstr(i8* getelementptr inbounds ("
+ 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();
}
}

58
midend/llvm/instr/ReturnInstr.java Normal file → Executable file
View File

@@ -1,20 +1,38 @@
package midend.llvm.instr;
import midend.llvm.type.IrInterType;
import midend.llvm.value.IrValue;
public class ReturnInstr extends IrInstr {
public ReturnInstr(IrValue retValue) {
super(IrInterType.VOID, "ret", IrInstrType.RET);
addUse(retValue);
}
public IrValue getRetValue() {
return getUse(0);
}
public String toString() {
return getName() + (getRetValue() == null ? " void" :
" " + getRetValue().getType() + " " + getRetValue().getName());
}
}
package midend.llvm.instr;
import backend.mips.MipsBuilder;
import backend.mips.Register;
import backend.mips.instr.MipsJump;
import backend.mips.instr.fake.MipsMove;
import backend.mips.instr.type.MipsJumpType;
import midend.llvm.type.IrInterType;
import midend.llvm.value.IrValue;
public class ReturnInstr extends IrInstr {
public ReturnInstr(IrValue retValue) {
super(IrInterType.VOID, "ret", IrInstrType.RET);
addUse(retValue);
}
public IrValue getRetValue() {
return getUse(0);
}
public String toString() {
return getName()
+ (getRetValue() == null ? " void" : " " + getRetValue().getType() + " " + getRetValue().getName());
}
public void toMips() {
if (getRetValue() != null) {
Register reg = MipsBuilder.getRegister(getRetValue());
if (reg == null) {
loadValueToReg(getRetValue(), Register.V0);
} else {
new MipsMove(Register.V0, reg);
}
}
new MipsJump(MipsJumpType.JR, Register.RA);
}
}

68
midend/llvm/instr/StoreInstr.java Normal file → Executable file
View File

@@ -1,25 +1,43 @@
package midend.llvm.instr;
import midend.llvm.value.IrValue;
import midend.llvm.type.IrInterType;
public class StoreInstr extends IrInstr {
public StoreInstr(IrValue value, IrValue pointer) {
super(IrInterType.VOID, "store", IrInstrType.STORE);
addUse(value);
addUse(pointer);
}
public IrValue getValue() {
return getUse(0);
}
public IrValue getPointer() {
return getUse(1);
}
public String toString() {
return getName() + " " + getValue().getType() + " " + getValue().getName()
+ ", " + getPointer().getType() + " " + getPointer().getName();
}
}
package midend.llvm.instr;
import midend.llvm.value.IrValue;
import backend.mips.MipsBuilder;
import backend.mips.Register;
import midend.llvm.type.IrInterType;
import backend.mips.instr.MipsLs;
import backend.mips.instr.type.MipsLsType;
public class StoreInstr extends IrInstr {
public StoreInstr(IrValue value, IrValue pointer) {
super(IrInterType.VOID, "store", IrInstrType.STORE);
addUse(value);
addUse(pointer);
}
public IrValue getValue() {
return getUse(0);
}
public IrValue getPointer() {
return getUse(1);
}
public String toString() {
return getName() + " " + getValue().getType() + " " + getValue().getName()
+ ", " + getPointer().getType() + " " + getPointer().getName();
}
public void toMips() {
Register valueReg = MipsBuilder.getRegister(getValue());
if (valueReg == null) {
valueReg = Register.K0;
}
loadValueToReg(getValue(), valueReg);
Register pointerReg = MipsBuilder.getRegister(getPointer());
if (pointerReg == null) {
pointerReg = Register.K1;
}
loadValueToReg(getPointer(), pointerReg);
new MipsLs(MipsLsType.SW, valueReg, pointerReg, 0);
}
}

81
midend/llvm/instr/TruncInstr.java Normal file → Executable file
View File

@@ -1,31 +1,50 @@
package midend.llvm.instr;
import midend.llvm.type.IrType;
import midend.llvm.value.IrValue;
public class TruncInstr extends IrInstr {
private IrType targetType;
public TruncInstr(IrType targetType, IrValue value, String name) {
super(targetType, name, IrInstrType.TRUNC);
addUse(value);
this.targetType = targetType;
}
public IrValue getSrc() {
return getUse(0);
}
public IrType getTargetType() {
return targetType;
}
public IrType getSrcType() {
return getSrc().getType();
}
public String toString() {
return getName() + " = trunc " + getSrcType()
+ " " + getSrc().getName() + " to " + getTargetType();
}
}
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.type.IrType;
import midend.llvm.value.IrValue;
public class TruncInstr extends IrInstr {
private IrType targetType;
public TruncInstr(IrType targetType, IrValue value, String name) {
super(targetType, name, IrInstrType.TRUNC);
addUse(value);
this.targetType = targetType;
}
public IrValue getSrc() {
return getUse(0);
}
public IrType getTargetType() {
return targetType;
}
public IrType getSrcType() {
return getSrc().getType();
}
public String toString() {
return getName() + " = trunc " + getSrcType()
+ " " + getSrc().getName() + " to " + getTargetType();
}
public void toMips() {
Register reg = MipsBuilder.getRegister(getSrc());
if (reg == null) {
reg = Register.K0;
}
loadValueToReg(getSrc(), reg);
if (this.targetType.isInt8()) {
new MipsAlu(MipsAluType.ANDI, reg, reg, 0xFF);
} else if (this.targetType.isBool()) {
new MipsAlu(MipsAluType.ANDI, reg, reg, 0x1);
}
saveResult(this, reg);
}
}