package midend.llvm.value; import java.util.ArrayList; import java.util.HashMap; import midend.llvm.type.IrType; import midend.llvm.IrBuilder; import midend.llvm.instr.ReturnInstr; import midend.llvm.type.IrFuncType; import backend.mips.MipsBuilder; import backend.mips.Register; import backend.mips.instr.MipsLabel; public class IrFuncValue extends IrValue { private ArrayList params; private ArrayList bblocks; private HashMap valueRegisterMap; private HashMap valueOffsetMap; public IrFuncValue(String name, IrType retType) { super(new IrFuncType(retType), name); params = new ArrayList<>(); bblocks = new ArrayList<>(); valueRegisterMap = new HashMap<>(); valueOffsetMap = new HashMap<>(); } public ArrayList getParams() { return params; } public ArrayList getBBlocks() { return bblocks; } public IrBasicBlock getBBlock(int index) { return bblocks.get(index); } public void addParam(IrValue param) { params.add(param); } public void addBBlock(IrBasicBlock bblock) { bblocks.add(bblock); } public Register getRegister(IrValue value) { return valueRegisterMap.get(value); } public int getOffset(IrValue value) { return valueOffsetMap.get(value); } public void setRegister(IrValue value, Register reg) { valueRegisterMap.put(value, reg); } public void setOffset(IrValue value, int offset) { valueOffsetMap.put(value, offset); } public HashMap getValueRegisterMap() { return valueRegisterMap; } public HashMap getValueOffsetMap() { return valueOffsetMap; } public boolean isMain() { return getName().equals("@main"); } public IrType getRetType() { return ((IrFuncType) getType()).getReturnType(); } public String toString() { StringBuilder sb = new StringBuilder(); sb.append("define dso_local " + this.getRetType() + " " + this.getName() + "("); for (int i = 0; i < params.size(); i++) { sb.append(params.get(i).getType() + " " + params.get(i).getName()); if (i < params.size() - 1) { sb.append(", "); } } sb.append(") {\n"); for (IrBasicBlock bblock : bblocks) { sb.append(bblock.toString() + "\n"); } sb.append("}\n"); return sb.toString(); } public void checkReturn() { IrBasicBlock currentBB = IrBuilder.getCurrentBB(); if (!currentBB.lastIsReturn()) { ReturnInstr returnInstr = new ReturnInstr(null); // 确保没有return的情况只有void IrBuilder.addInstr(returnInstr); } } public void toMips() { new MipsLabel(getMipsLabel()); MipsBuilder.enterNewFunc(this); int num = 0; ArrayList paramRegs = new ArrayList<>(); paramRegs.add(Register.A1); paramRegs.add(Register.A2); paramRegs.add(Register.A3); for (IrValue param : params) { num++; if (num <= 3) { MipsBuilder.allocaRegister(param, paramRegs.get(num - 1)); } MipsBuilder.allocaOffset(param); } for (IrBasicBlock bblock : bblocks) { bblock.toMips(); } } }