diff --git a/src/main/java/cn/edu/nju/software/backend/RiscBasicBlock.java b/src/main/java/cn/edu/nju/software/backend/RiscBasicBlock.java index f0c9fc1ca6e350a00ebe52aca1a2f3724e760bc4..b7203cc218784ccb673b04a84fa038c86b7e03f8 100644 --- a/src/main/java/cn/edu/nju/software/backend/RiscBasicBlock.java +++ b/src/main/java/cn/edu/nju/software/backend/RiscBasicBlock.java @@ -4,7 +4,6 @@ import cn.edu.nju.software.backend.regalloc.LValLiveTable; import cn.edu.nju.software.backend.regalloc.TempVarLiveTable; import cn.edu.nju.software.backend.riscinstruction.*; import cn.edu.nju.software.backend.riscinstruction.floatextension.RiscFlw; -import cn.edu.nju.software.backend.riscinstruction.floatextension.RiscFsw; import cn.edu.nju.software.backend.riscinstruction.operand.ImmediateValue; import cn.edu.nju.software.backend.riscinstruction.operand.IndirectRegister; import cn.edu.nju.software.backend.riscinstruction.operand.Register; @@ -47,7 +46,7 @@ public class RiscBasicBlock { } private void functionInit() { - generator.insertComment("reserve space"); + generator.insertComment("reserve space for all local variables in function"); int stackSize = allocator.getStackSize(); if (stackSize > 0) { if(stackSize <= 2048){ @@ -57,26 +56,54 @@ public class RiscBasicBlock { generator.addInstruction(new RiscSub(new Register("sp"), new Register("sp"), new Register("t0"))); } } - - if(!llvmFunctionValue.getName().equals("main")){ - generator.insertComment("save CallerSavedRegs"); + if(!llvmFunctionValue.getName().equals("main")){ //mainæ²¡æœ‰è°ƒç”¨å‡½æ•°ï¼Œä¹Ÿæ²¡æœ‰å‚æ•° saveCalleeSavedRegs(); - } - - generator.insertComment("save the parameters"); - if(!llvmFunctionValue.getName().equals("main")){ saveParams(); } } - //åŽ‹æ ˆå¼¹æ ˆï¼Œå¯„å˜å™¨ä¿å˜éƒ½è¿˜æ˜¯ä½¿ç”¨8byte(ra也是8byte),分é…8byte的空间,但是å˜å‚¨å’Œæ‹¿åŽ»åªç”¨åˆ°å…¶ä¸çš„4byte - //todo()这里åªèƒ½å¤„ç†RiscSpecificationsä¸argæ•°ç»„æŒ‡å®šçš„å‚æ•°ä¸ªæ•° - private void saveParams() { + public RiscInstrGenerator getGenerator() { + return generator; + } + /** + * ä¿å˜å‚æ•° + * 便¬¡æ£€æŸ¥å‚数的类系,如果是General,就从a0-a7ä¸å–出,如果是Float就从fa0-fa7ä¸å–出 + * å¦‚æžœå‚æ•°ä¸ªæ•°è¶…过8ä¸ªï¼Œä¾æ¬¡ä»Žæ ˆä¸å–出 + * 对于æ¯ä¸€å‡½æ•°çš„傿•°ï¼Œéƒ½ä¸ºå…¶åˆ†é…了一个LocalVar(%0,%1,...)åŽç»å¯¹äºŽä¼ å…¥çš„å‚æ•°çš„值的使用都是通过这个LocalVaræ¥å¼•用的 + * å› æ¤éœ€è¦å°†å‚数寄å˜å™¨ä¸çš„的值ä¿å˜åˆ°è¿™äº›LocalVarä¸ + */ + private void saveParams() { + generator.insertComment("save the parameters value in the regs"); + int preLen = getPredLen(); FunctionType functionType = (FunctionType) llvmFunctionValue.getType(); + String[] fArgs = RiscSpecifications.getFArgRegs(); + String[] args = RiscSpecifications.getArgRegs(); + int fptr = 0; + int ptr = 0; + int order = 0; //order 相对于prelençš„åç§»é‡ï¼Œåˆ†åˆ«å¯¹åº”第一个被å˜å…¥æ ˆä¸çš„傿•°ï¼Œç¬¬äºŒä¸ªè¢«å˜å…¥æ ˆä¸çš„傿•°... + for (int i = 0; i < functionType.getFParametersCount(); i++) { + if (functionType.getFParameter(i) instanceof FloatType) { + if(fptr >= RiscSpecifications.getFArgRegs().length){ + fetchFromStack(functionType.getFParameter(i), i, preLen, order++); + } else { + allocator.storeLocalVarIntoMemory(new LocalVar(functionType.getFParameter(i), i +""), fArgs[fptr++]); + } + } else if (functionType.getFParameter(i) instanceof IntType || functionType.getFParameter(i) instanceof Pointer){ + if(ptr >= RiscSpecifications.getArgRegs().length){ + fetchFromStack(functionType.getFParameter(i), i, preLen, order++); + } else { + allocator.storeLocalVarIntoMemory(new LocalVar(functionType.getFParameter(i), i +""), args[ptr++]); + } + } else {assert false;} + } + } - - // èŽ·å–æ‰€æœ‰ IntType å’Œ FloatType çš„å‚æ•°ä¸ªæ•° + /** + * 获å–ç¬¬ä¸€ä¸ªå‚æ•°ç›¸å¯¹äºŽæ ˆåº•çš„åç§»é‡ + */ + public int getPredLen(){ + FunctionType functionType = (FunctionType) llvmFunctionValue.getType(); int intTypeCount = functionType.getFParameters().stream() .filter(IntType.class::isInstance) .mapToInt(typeRef -> 1) @@ -85,100 +112,52 @@ public class RiscBasicBlock { .filter(FloatType.class::isInstance) .mapToInt(typeRef -> 1) .sum(); - int pointerTypeCount = functionType.getFParameters().stream() .filter(Pointer.class::isInstance) .mapToInt(typeRef -> 1) .sum(); - int intAndPointerCount = intTypeCount + pointerTypeCount; - - int preLen = ( - ((intAndPointerCount > RiscSpecifications.getArgRegs().length) ? (intAndPointerCount - RiscSpecifications.getArgRegs().length) : 0) + + return ( + ((intAndPointerCount > RiscSpecifications.getArgRegs().length) ? (intAndPointerCount - RiscSpecifications.getArgRegs().length) : 0) + ((floatTypeCount > RiscSpecifications.getFArgRegs().length) ? (floatTypeCount - RiscSpecifications.getFArgRegs().length) : 0) ) * 8 + (RiscSpecifications.getCallerSavedRegs().length - 1) * 8; - - //èŽ·å–æ‰€æœ‰intTypeå’ŒPointerTypeçš„å‚æ•°ä¸ªæ•° - - //èŽ·å–æ‰€æœ‰intTypeå’ŒPointerTypeçš„å‚æ•° - int fptr = 0; - int ptr = 0; - int order = 0; - for (int i = 0; i < functionType.getFParametersCount(); i++) { - - if (functionType.getFParameter(i) instanceof FloatType) { - if(fptr >= RiscSpecifications.getFArgRegs().length){ - fetchFromStack(functionType.getFParameter(i), i, preLen, order); - order++; - continue; - } - generator.addInstruction(new RiscFsw(new Register(RiscSpecifications.getFArgRegs()[fptr]), allocator.getAddrOfLocalVar(new LocalVar(functionType.getFParameter(i), i +"")))); - fptr++; - } else if (functionType.getFParameter(i) instanceof IntType) { - if(ptr >= RiscSpecifications.getArgRegs().length){ - fetchFromStack(functionType.getFParameter(i), i, preLen, order); - order++; - continue; - } - generator.addInstruction(new RiscSw(new Register(RiscSpecifications.getArgRegs()[ptr]), allocator.getAddrOfLocalVar(new LocalVar(functionType.getFParameter(i), i +"")))); - ptr++; - } else if(functionType.getFParameter(i) instanceof Pointer){ - if(ptr >= RiscSpecifications.getArgRegs().length){ - fetchFromStack(functionType.getFParameter(i), i, preLen, order); - order++; - continue; - } - generator.addInstruction(new RiscSd(new Register(RiscSpecifications.getArgRegs()[ptr]), allocator.getAddrOfLocalVar(new LocalVar(functionType.getFParameter(i), i +"")))); - ptr++; - } else { - assert false; - } - } } private void fetchFromStack(TypeRef type, int i, int preLen, int order) { + String destReg = "t0"; if (type instanceof IntType) { - generator.addInstruction(new RiscLw(new Register("t0"), allocator.getRegWithOffset(allocator.getStackSize() + preLen - order * 8, "sp", "t1"))); - generator.addInstruction(new RiscSw(new Register("t0"), allocator.getRegWithOffset(allocator.getOffset(new LocalVar(type, i + "")), "sp", "t1"))); + generator.addInstruction(new RiscLw(new Register("t0"), allocator.getRegWithOffset(allocator.getStackSize() + preLen - order * 8, "sp", "t4"))); + destReg = "t0"; } else if (type instanceof FloatType) { - generator.addInstruction(new RiscFlw(new Register("ft0"), allocator.getRegWithOffset(allocator.getStackSize() + preLen - order * 8, "sp", "t1"))); - generator.addInstruction(new RiscFsw(new Register("ft0"), allocator.getRegWithOffset(allocator.getOffset(new LocalVar(type, i + "")), "sp", "t1"))); + generator.addInstruction(new RiscFlw(new Register("ft0"), allocator.getRegWithOffset(allocator.getStackSize() + preLen - order * 8, "sp", "t4"))); + destReg = "ft0"; } else if(type instanceof Pointer){ - generator.addInstruction(new RiscLd(new Register("t0"), allocator.getRegWithOffset(allocator.getStackSize() + preLen - order * 8, "sp", "t1"))); - generator.addInstruction(new RiscSd(new Register("t0"), allocator.getRegWithOffset(allocator.getOffset(new LocalVar(type, i + "")),"sp", "t1"))); - } else { - assert false; - } + generator.addInstruction(new RiscLd(new Register("t0"), allocator.getRegWithOffset(allocator.getStackSize() + preLen - order * 8, "sp", "t4"))); + destReg = "t0"; + } else {assert false;} + allocator.storeLocalVarIntoMemory(new LocalVar(type, i + ""), destReg); } private void saveCalleeSavedRegs() { - generator.addInstruction(new RiscComment("save callee saved regs")); - + generator.insertComment("save CallerSavedRegs"); String[] calleeSavedRegs = RiscSpecifications.getCalleeSavedRegs(); - generator.addInstruction(new RiscAddi(new Register("sp"), new Register("sp"), new ImmediateValue(-8L * calleeSavedRegs.length))); - for (int i = 0; i < calleeSavedRegs.length; i++) { - RiscInstruction riscSw = new RiscSd(new Register(calleeSavedRegs[i]), new IndirectRegister("sp", i * 8)); - generator.addInstruction(riscSw); + generator.addInstruction(new RiscSd(new Register(calleeSavedRegs[i]), new IndirectRegister("sp", i * 8))); } } - public RiscInstrGenerator getGenerator() { - return generator; - } - public void dumpToConsole() { - System.out.println(basicBlockRef.getName() + ":"); - -// assert !riscInstructions.isEmpty(); //todo() why here fail - for(RiscInstruction riscInstruction : riscInstructions){ if(riscInstruction instanceof RiscComment){ - continue; + if(RiscSpecifications.getIsDebug()){ + System.out.println(riscInstruction.emitCode()); + } + } + else { + System.out.println(riscInstruction.emitCode()); } - System.out.println(riscInstruction.emitCode()); } } diff --git a/src/main/java/cn/edu/nju/software/backend/RiscSpecifications.java b/src/main/java/cn/edu/nju/software/backend/RiscSpecifications.java index e6d8837ebdbe2a4b3c8915d6953b2e5017bb2371..a5f132af1ba93c6292ecc7ec2843e044cde5978d 100644 --- a/src/main/java/cn/edu/nju/software/backend/RiscSpecifications.java +++ b/src/main/java/cn/edu/nju/software/backend/RiscSpecifications.java @@ -16,6 +16,7 @@ public record RiscSpecifications() { private static final String[] argRegs = new String[] {"a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7"}; private static final String[] fArgRegs = new String[] {"fa0", "fa1", "fa2", "fa3", "fa4", "fa5", "fa6", "fa7"}; private static final String[] tempVarRegs = new String[] {"s0","s1","s2","s3","s4","s5","fs0","fs1","fs2"}; + private static final boolean isDebug = false; public static String[] getCallerSavedRegs() { return callerSavedRegs; @@ -68,4 +69,8 @@ public record RiscSpecifications() { public static int getBoolSize() { return BOOL_SIZE; } + + public static boolean getIsDebug() { + return isDebug; + } } diff --git a/src/main/java/cn/edu/nju/software/backend/regalloc/Allocator.java b/src/main/java/cn/edu/nju/software/backend/regalloc/Allocator.java index f4ca92f5f76119c40e1cd753a0c88520c5d1c5c1..2449ad4f004f9616d2e872b10be7f04fbc7f2b8f 100644 --- a/src/main/java/cn/edu/nju/software/backend/regalloc/Allocator.java +++ b/src/main/java/cn/edu/nju/software/backend/regalloc/Allocator.java @@ -393,9 +393,8 @@ public class Allocator { /** * 将局部å˜é‡ï¼ˆå½“å‰å˜å‚¨åœ¨regä¸ï¼‰ä¿å˜è¿›å…¥å†…å˜(需è¦ä¿å˜çš„å˜é‡åªå¯èƒ½æ˜¯localVar) - * @param variable - * @param regName - * @return + * @param variable è¦ä¿å˜çš„å˜é‡ + * @param regName 当å‰å¯¹åº”的值所在的寄å˜å™¨ */ public void storeLocalVarIntoMemory(ValueRef variable, String regName){ TypeRef type = variable.getType(); @@ -409,4 +408,33 @@ public class Allocator { assert false; } } + + /** + * 将内å˜ä¸çš„局部å˜é‡åŠ è½½åˆ°å¯„å˜å™¨ä¸ï¼ˆåªå¯èƒ½æ˜¯localVar) + * @param variable è¦åŠ è½½çš„å˜é‡ + * @param regName åŠ è½½åˆ°çš„å¯„å˜å™¨ + */ + public void loadLocalVarFromMemory(ValueRef variable, String regName){ + TypeRef type = variable.getType(); + if(type instanceof FloatType){ + generator.addInstruction(new RiscFlw(new Register(regName), getAddrOfLocalVar(variable))); + } else if(type instanceof IntType || type instanceof BoolType){ + generator.addInstruction(new RiscLw(new Register(regName), getAddrOfLocalVar(variable))); + } else if(type instanceof Pointer){ + generator.addInstruction(new RiscLd(new Register(regName), getAddrOfLocalVar(variable))); + } else { + assert false; + } + } + + /** + * 将内å˜ä¸çš„localVarä¸çš„值拷è´åˆ°å¦ä¸€ä¸ªlocalVar对应的内å˜ä¸ + * @param src + * @param dest + * @param regName 用于ä¸é—´å˜å‚¨å€¼çš„寄å˜å™¨ + */ + public void cpLocalVarBetweenMemory(ValueRef src, ValueRef dest, String regName){ + loadLocalVarFromMemory(src, regName); + storeLocalVarIntoMemory(dest, regName); + } } diff --git a/src/main/java/cn/edu/nju/software/backend/riscinstruction/RiscSubw.java b/src/main/java/cn/edu/nju/software/backend/riscinstruction/RiscSubw.java new file mode 100644 index 0000000000000000000000000000000000000000..8e893c13a9f58cc275c6de42737cc3029290e3ab --- /dev/null +++ b/src/main/java/cn/edu/nju/software/backend/riscinstruction/RiscSubw.java @@ -0,0 +1,10 @@ +package cn.edu.nju.software.backend.riscinstruction; + +import cn.edu.nju.software.backend.riscinstruction.operand.Operand; +import cn.edu.nju.software.backend.riscinstruction.util.RiscOpcode; + +public class RiscSubw extends DefaultInstruction { + public RiscSubw(Operand rd, Operand rs1, Operand rs2) { + super(RiscOpcode.SUBW, rd, rs1, rs2); + } +} diff --git a/src/main/java/cn/edu/nju/software/backend/riscinstruction/RiscXor.java b/src/main/java/cn/edu/nju/software/backend/riscinstruction/RiscXor.java index 3dfb65045a9906408175bc0f72bf56c16cfaff34..daab70f06be315f601d54a7cbd28dcaa60bf5600 100644 --- a/src/main/java/cn/edu/nju/software/backend/riscinstruction/RiscXor.java +++ b/src/main/java/cn/edu/nju/software/backend/riscinstruction/RiscXor.java @@ -4,7 +4,6 @@ import cn.edu.nju.software.backend.riscinstruction.operand.Operand; import cn.edu.nju.software.backend.riscinstruction.util.RiscOpcode; public class RiscXor extends DefaultInstruction{ - public RiscXor(Operand rd, Operand rs1, Operand rs2) { super(RiscOpcode.XOR, rd, rs1, rs2); } diff --git a/src/main/java/cn/edu/nju/software/backend/riscinstruction/util/RiscOpcode.java b/src/main/java/cn/edu/nju/software/backend/riscinstruction/util/RiscOpcode.java index b7b2df2ccc0473e84aeb20e67e4b879021716c4f..c71e88a0724afbff87c7e2becce2d4daf69bb16f 100644 --- a/src/main/java/cn/edu/nju/software/backend/riscinstruction/util/RiscOpcode.java +++ b/src/main/java/cn/edu/nju/software/backend/riscinstruction/util/RiscOpcode.java @@ -40,5 +40,5 @@ public enum RiscOpcode { FMV_X_W, REM, FCVT_S_W, - FCVT_W_S, LA, LD, SD, FLD, FSD, FCVT_D_W, FCVT_W_D, FMV_D_X, FMV_X_D, FSUB_D, FMUL_D, FDIV_D, FADD_D, FEQ_D, FLE_D, FLT_D, LUI, ORI, SLLI, FCVT_D_L, FCVT_L_D, JR, BNE, ADDW, SRLI, SRL, SRA, SLL, SRAI + FCVT_W_S, LA, LD, SD, FLD, FSD, FCVT_D_W, FCVT_W_D, FMV_D_X, FMV_X_D, FSUB_D, FMUL_D, FDIV_D, FADD_D, FEQ_D, FLE_D, FLT_D, LUI, ORI, SLLI, FCVT_D_L, FCVT_L_D, JR, BNE, ADDW, SRLI, SRL, SRA, SLL, SUBW, SRAI }