/// <summary> /// 生成数据段 /// </summary> /// <param name="varNameList">变量名列表</param> /// <param name="varTable">变量表</param> /// <param name="cmdList">汇编指令列表</param> private void genDataIns(List <string> varNameList, VarTable varTable, List <AssemblerIns> cmdList) { foreach (string varName in varNameList) { if (varTable.GetType(varName) == VariableType.INT || varTable.GetType(varName) == VariableType.CHAR || varTable.GetType(varName) == VariableType.BOOL) { short varValue = (short)varTable.GetValue(varName); short varAddr = varTable.GetAddr(varName); cmdList.Add(AssemblerFac.GenLUI("$T0", varValue.ToString())); cmdList.Add(AssemblerFac.GenSRL("$T0", "$T0", Convert.ToString(16))); cmdList.Add(AssemblerFac.GenSW("$T0", varAddr.ToString(), "$ZERO")); } else { int value = varTable.GetValue(varName); short high = (short)(value >> 16); short varAddr = varTable.GetAddr(varName); cmdList.Add(AssemblerFac.GenLUI("$T0", high.ToString())); short low = (short)(value & 0xffff); cmdList.Add(AssemblerFac.GenORI("$T0", "$T0", low.ToString())); cmdList.Add(AssemblerFac.GenSW("$T0", varAddr.ToString(), "$ZERO")); } } }
/// <summary> /// 将四元式翻译为汇编指令 /// </summary> /// <param name="f">四元式</param> /// <param name="varTable">变量表</param> /// <param name="cmdList">汇编指令列表</param> private void convert(FourExp f, VarTable varTable, List <AssemblerIns> cmdList) { #region Label FourExp if (f.Op == FourExpOperation.label) { cmdList.Add(AssemblerFac.GenLABEL(f.LabelName)); } #endregion #region Jump Operation if (f.Op >= FourExpOperation.jmp && f.Op <= FourExpOperation.jle) { string operation = ""; switch (f.Op) { case FourExpOperation.jmp: operation = Mnemonic.J.ToString(); cmdList.Add(AssemblerFac.GenJ(f.TargetLabel)); break; case FourExpOperation.je: operation = Mnemonic.BEQ.ToString(); doJump(f, operation, varTable, cmdList); break; case FourExpOperation.jne: operation = Mnemonic.BNE.ToString(); doJump(f, operation, varTable, cmdList); break; case FourExpOperation.jg: operation = Mnemonic.BGTZ.ToString(); doJump(f, operation, varTable, cmdList); break; case FourExpOperation.jge: operation = Mnemonic.BGEZ.ToString(); doJump(f, operation, varTable, cmdList); break; case FourExpOperation.jl: operation = Mnemonic.BLTZ.ToString(); doJump(f, operation, varTable, cmdList); break; case FourExpOperation.jle: operation = Mnemonic.BLEZ.ToString(); doJump(f, operation, varTable, cmdList); break; default: //错误处理 break; } } #endregion #region Move Operation else if (f.Op == FourExpOperation.mov) { string regB = ""; if (isNumber(f.Arg1)) { regB = getReg(f, varTable, false, cmdList); int value = Convert.ToInt32(f.Arg1); if (value <= 32767 && value >= -32768) { cmdList.Add(AssemblerFac.GenLUI(regB, value.ToString())); cmdList.Add(AssemblerFac.GenSRL(regB, regB, 16 + "")); } else { short high = Convert.ToInt16(value >> 16); cmdList.Add(AssemblerFac.GenLUI(regB, high + "")); short low = Convert.ToInt16(value & 0xffff); cmdList.Add(AssemblerFac.GenORI(regB, regB, low + "")); } } else { if (varTable.GetAddrInfo(f.Arg1) == "") { regB = getReg(f, varTable, false, cmdList); cmdList.Add(AssemblerFac.GenLW(regB, varTable.GetAddr(f.Arg1).ToString(), "$ZERO")); regUseTable.GetContent(regB).Add(f.Arg1); varTable.SetAddrInfo(f.Arg1, regB); } else { regB = varTable.GetAddrInfo(f.Arg1); } } regUseTable.GetContent(regB).Add(f.Result); varTable.SetAddrInfo(f.Result, regB); if (varTable.Contains(f.Arg1) && varTable.GetPeekActInfo(f.Arg1) == false) { cmdList.Add(AssemblerFac.GenSW(regB, varTable.GetAddr(f.Arg1).ToString(), "$ZERO")); varTable.SetAddrInfo(f.Arg1, ""); regUseTable.GetContent(regB).Remove(f.Arg1); } if (varTable.Contains(f.Result) && varTable.GetPeekActInfo(f.Result) == false) { cmdList.Add(AssemblerFac.GenSW(regB, varTable.GetAddr(f.Result).ToString(), "$ZERO")); varTable.SetAddrInfo(f.Result, ""); regUseTable.GetContent(regB).Remove(f.Result); } } #endregion #region Arithmetical or Logical Operation else if (f.Op <= FourExpOperation.or)//数学或逻辑运算 { //获取第一个参数的寄存器 string regA, regB, regC; if (isNumber(f.Arg1)) { regB = getReg(f, varTable, false, cmdList); int value = Convert.ToInt32(f.Arg1); if (value <= 32767 && value >= -32768) { cmdList.Add(AssemblerFac.GenLUI(regB, value.ToString())); cmdList.Add(AssemblerFac.GenSRL(regB, regB, 16 + "")); } else { short high = Convert.ToInt16(value >> 16); cmdList.Add(AssemblerFac.GenLUI(regB, high + "")); short low = Convert.ToInt16(value & 0xffff); cmdList.Add(AssemblerFac.GenORI(regB, regB, low + "")); } } else { if (varTable.GetAddrInfo(f.Arg1) == "") { regB = getReg(f, varTable, false, cmdList); varTable.SetAddrInfo(f.Arg1, regB); regUseTable.Add(regB, f.Arg1); cmdList.Add(AssemblerFac.GenLW(regB, varTable.GetAddr(f.Arg1).ToString(), "$ZERO")); } else { regB = varTable.GetAddrInfo(f.Arg1); } } //获取第二个参数的寄存器 if (isNumber(f.Arg1)) { regC = getReg(f, varTable, false, cmdList); int value = Convert.ToInt32(f.Arg2); if (value <= 32767 && value >= -32768) { cmdList.Add(AssemblerFac.GenLUI(regC, value.ToString())); cmdList.Add(AssemblerFac.GenSRL(regC, regC, 16 + "")); } else { short high = Convert.ToInt16(value >> 16); cmdList.Add(AssemblerFac.GenLUI(regC, high + "")); short low = Convert.ToInt16(value & 0xffff); cmdList.Add(AssemblerFac.GenORI(regC, regC, low + "")); } } else { if (varTable.GetAddrInfo(f.Arg2) == "") { regC = getReg(f, varTable, false, cmdList); varTable.SetAddrInfo(f.Arg2, regC); regUseTable.Add(regC, f.Arg2); cmdList.Add(AssemblerFac.GenLW(regC, varTable.GetAddr(f.Arg2).ToString(), "$ZERO")); } else { regC = varTable.GetAddrInfo(f.Arg2); } } //获取计算结果的寄存器 regA = getReg(f, varTable, true, cmdList); varTable.SetAddrInfo(f.Result, regA); regUseTable.Add(regA, f.Result); if (regA == regB) { foreach (string var in regUseTable.GetContent(regB)) { cmdList.Add(AssemblerFac.GenSW(regB, varTable.GetAddr(var).ToString(), "$ZERO")); varTable.SetAddrInfo(var, ""); regUseTable.GetContent(regB).Remove(var); } } if (regA == regC) { foreach (string var in regUseTable.GetContent(regC)) { cmdList.Add(AssemblerFac.GenSW(regC, varTable.GetAddr(var).ToString(), "$ZERO")); varTable.SetAddrInfo(var, ""); regUseTable.GetContent(regC).Remove(var); } } string operation = ""; switch (f.Op) { case FourExpOperation.add: operation = Mnemonic.ADD.ToString(); break; case FourExpOperation.sub: operation = Mnemonic.SUB.ToString(); break; //case FourExpOperation.mul: // break; //case FourExpOperation.div: // break; case FourExpOperation.and: operation = Mnemonic.AND.ToString(); break; case FourExpOperation.or: operation = Mnemonic.OR.ToString(); break; case FourExpOperation.xor: operation = Mnemonic.XOR.ToString(); break; case FourExpOperation.nor: operation = Mnemonic.NOR.ToString(); break; default: //错误处理 break; } cmdList.Add(AssemblerFac.GenMathOrLog(operation, regA, regB, regC)); if (varTable.Contains(f.Arg1) && (varTable.GetAddrInfo(f.Arg1) != null) && (varTable.GetPeekActInfo(f.Arg1) == false)) { cmdList.Add(AssemblerFac.GenSW(regB, varTable.GetAddr(f.Arg1).ToString(), "$ZERO")); varTable.SetAddrInfo(f.Arg1, ""); regUseTable.GetContent(regB).Remove(f.Arg1); } if (varTable.Contains(f.Arg2) && (varTable.GetAddrInfo(f.Arg2) != null) && (varTable.GetPeekActInfo(f.Arg2) == false)) { cmdList.Add(AssemblerFac.GenSW(regC, varTable.GetAddr(f.Arg2).ToString(), "$ZERO")); varTable.SetAddrInfo(f.Arg2, ""); regUseTable.GetContent(regC).Remove(f.Arg2); } if (varTable.Contains(f.Result) && varTable.GetPeekActInfo(f.Result) == false) { cmdList.Add(AssemblerFac.GenSW(regA, varTable.GetAddr(f.Result).ToString(), "$ZERO")); varTable.SetAddrInfo(f.Result, ""); regUseTable.GetContent(regA).Remove(f.Result); } } #endregion #region Not or Neg Operation else if (f.Op == FourExpOperation.neg) { string regB; if (isNumber(f.Arg1)) { regB = getReg(f, varTable, false, cmdList); int value = Convert.ToInt32(f.Arg1); if (value <= 32767 && value >= -32768) { cmdList.Add(AssemblerFac.GenLUI(regB, value.ToString())); cmdList.Add(AssemblerFac.GenSRL(regB, regB, 16 + "")); } else { short high = Convert.ToInt16(value >> 16); cmdList.Add(AssemblerFac.GenLUI(regB, high + "")); short low = Convert.ToInt16(value & 0xffff); cmdList.Add(AssemblerFac.GenORI(regB, regB, low + "")); } } else { regB = varTable.GetAddrInfo(f.Arg1); if (regB == "") { regB = getReg(f, varTable, false, cmdList); cmdList.Add(AssemblerFac.GenLW(regB, varTable.GetAddr(f.Arg1).ToString(), "$ZERO")); varTable.SetAddrInfo(f.Arg1, regB); regUseTable.GetContent(regB).Add(f.Arg1); } } string regA = varTable.GetAddrInfo(f.Result); if (regA == "") { regA = getReg(f, varTable, true, cmdList); varTable.SetAddrInfo(f.Result, regA); regUseTable.GetContent(regA).Add(f.Result); } cmdList.Add(AssemblerFac.GenSUB(regA, "$ZERO", regB)); if (varTable.Contains(f.Arg1) && varTable.GetPeekActInfo(f.Arg1) == false) { cmdList.Add(AssemblerFac.GenSW(regB, varTable.GetAddr(f.Arg1).ToString(), "$ZERO")); varTable.SetAddrInfo(f.Arg1, ""); regUseTable.GetContent(regB).Remove(f.Arg1); } if (varTable.Contains(f.Arg1) && varTable.GetPeekActInfo(f.Result) == false) { cmdList.Add(AssemblerFac.GenSW(regA, varTable.GetAddr(f.Result).ToString(), "$ZERO")); varTable.SetAddrInfo(f.Result, ""); regUseTable.GetContent(regA).Remove(f.Result); } } else if (f.Op == FourExpOperation.not) { string regB; if (isNumber(f.Arg1)) { regB = getReg(f, varTable, false, cmdList); int value = Convert.ToInt32(f.Arg1); if (value <= 32767 && value >= -32768) { cmdList.Add(AssemblerFac.GenLUI(regB, value.ToString())); cmdList.Add(AssemblerFac.GenSRL(regB, regB, 16 + "")); } else { short high = Convert.ToInt16(value >> 16); cmdList.Add(AssemblerFac.GenLUI(regB, high + "")); short low = Convert.ToInt16(value & 0xffff); cmdList.Add(AssemblerFac.GenORI(regB, regB, low + "")); } } else { regB = varTable.GetAddrInfo(f.Arg1); if (regB == "") { regB = getReg(f, varTable, false, cmdList); cmdList.Add(AssemblerFac.GenLW(regB, varTable.GetAddr(f.Arg1).ToString(), "$ZERO")); varTable.SetAddrInfo(f.Arg1, regB); regUseTable.GetContent(regB).Add(f.Arg1); } } string regA = varTable.GetAddrInfo(f.Result); if (regA == "") { regA = getReg(f, varTable, true, cmdList); varTable.SetAddrInfo(f.Result, regA); regUseTable.GetContent(regA).Add(f.Result); } cmdList.Add(AssemblerFac.GenXORI(regA, regB, Convert.ToString(1)));//a = NOT b => a = b xor 1 if (varTable.Contains(f.Arg1) && varTable.GetPeekActInfo(f.Arg1) == false) { cmdList.Add(AssemblerFac.GenSW(regB, varTable.GetAddr(f.Arg1).ToString(), "$ZERO")); varTable.SetAddrInfo(f.Arg1, ""); regUseTable.GetContent(regB).Remove(f.Arg1); } if (varTable.Contains(f.Result) && varTable.GetPeekActInfo(f.Result) == false) { cmdList.Add(AssemblerFac.GenSW(regA, varTable.GetAddr(f.Result).ToString(), "$ZERO")); varTable.SetAddrInfo(f.Result, ""); regUseTable.GetContent(regA).Remove(f.Result); } } #endregion #region Rightshift or Leftshift else if (f.Op == FourExpOperation.leftshift || f.Op == FourExpOperation.rightshift) { } #endregion else { //错误处理 } }