mips without optimize
This commit is contained in:
70
midend/llvm/instr/AllocateInstr.java
Normal file → Executable file
70
midend/llvm/instr/AllocateInstr.java
Normal file → Executable 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
85
midend/llvm/instr/AluInstr.java
Normal file → Executable 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
104
midend/llvm/instr/AluType.java
Normal file → Executable 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
81
midend/llvm/instr/BranchInstr.java
Normal file → Executable 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
165
midend/llvm/instr/CallInstr.java
Normal file → Executable 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
90
midend/llvm/instr/CmpInstr.java
Normal file → Executable 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
96
midend/llvm/instr/CmpType.java
Normal file → Executable 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
73
midend/llvm/instr/ExtendInstr.java
Normal file → Executable 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
143
midend/llvm/instr/GepInstr.java
Normal file → Executable 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
43
midend/llvm/instr/GetIntInstr.java
Normal file → Executable 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
103
midend/llvm/instr/IrInstr.java
Normal file → Executable 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
36
midend/llvm/instr/IrInstrType.java
Normal file → Executable 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
45
midend/llvm/instr/JumpInstr.java
Normal file → Executable 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
59
midend/llvm/instr/LoadInstr.java
Normal file → Executable 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
47
midend/llvm/instr/PutChInstr.java
Normal file → Executable 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
47
midend/llvm/instr/PutIntInstr.java
Normal file → Executable 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
62
midend/llvm/instr/PutStrInstr.java
Normal file → Executable 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
58
midend/llvm/instr/ReturnInstr.java
Normal file → Executable 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
68
midend/llvm/instr/StoreInstr.java
Normal file → Executable 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
81
midend/llvm/instr/TruncInstr.java
Normal file → Executable 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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user