mips without optimize
This commit is contained in:
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user