Files
MY_COMPILER/midend/llvm/instr/GepInstr.java
2025-12-12 20:14:00 +08:00

87 lines
3.0 KiB
Java
Executable File

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);
}
}