예제 #1
0
 /// <summary>
 /// 获取寄存器,isResult为true,则说明需要返回的是存放结果的寄存器
 /// </summary>
 /// <param name="f">四元式</param>
 /// <param name="varTable">变量表</param>
 /// <param name="isResult">指定获取的寄存器是否是用来存放计算结果</param>
 /// <param name="cmdList">汇编指令列表</param>
 /// <returns>寄存器名</returns>
 private string getReg(FourExp f, VarTable varTable, bool isResult, List<AssemblerIns> cmdList)
 {
     //返回B或者C所在的寄存器
     if (isResult)
     {
         if ((f.Arg1 != "") && (varTable.GetAddrInfo(f.Arg1) != ""))
         {
             string regB = varTable.GetAddrInfo(f.Arg1);
             if ((varTable.GetPeekActInfo(f.Arg1) == false) || f.Arg1 == f.Result || regUseTable.GetContent(regB).Count == 1)
             {
                 return regB;
             }
         }
         if ((f.Arg2 != "") && (varTable.GetAddrInfo(f.Arg2) != ""))
         {
             string regC = varTable.GetAddrInfo(f.Arg1);
             if ((varTable.GetPeekActInfo(f.Arg2) == false) || f.Arg2 == f.Result || regUseTable.GetContent(regC).Count == 1)
             {
                 return regC;
             }
         }
     }
     //返回未占用寄存器
     foreach (string regName in registers)
     {
         if (regUseTable.GetContent(regName) == null)
         {
             return regName;
         }
     }
     //随机返回一个已占用的寄存器
     Random r = new Random();
     while (true)
     {
         int i = r.Next(registers.Length);
         string reg = registers[i];
         List<string> varList = new List<string>() { f.Arg1, f.Arg2, f.Result };
         if (!regUseTable.Contains(reg, varList))
         {
             //调整变量表和寄存器表中的相关域
             doAdjust(reg, varTable, cmdList);
             return reg;
         }
     }
 }
예제 #2
0
        /// <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
            {
                //错误处理
            }
        }
예제 #3
0
 /// <summary>
 /// 翻译跳转指令
 /// </summary>
 /// <param name="f">四元式</param>
 /// <param name="operation">汇编指令的操作助记符</param>
 /// <param name="varTable">变量表</param>
 /// <param name="cmdList">汇编指令列表</param>
 private void doJump(FourExp f, string operation, VarTable varTable, List<AssemblerIns> cmdList)
 {
     string reg1 = "", reg2 = "";
     reg1 = varTable.GetAddrInfo(f.Arg1);
     reg2 = varTable.GetAddrInfo(f.Arg2);
     if (reg1 == "")
     {
         reg1 = getReg(f, varTable, false, cmdList);
         cmdList.Add(AssemblerFac.GenLW(reg1, varTable.GetAddr(f.Arg1).ToString(), "$ZERO"));
         regUseTable.GetContent(reg1).Add(f.Arg1);
         varTable.SetAddrInfo(f.Arg1, reg1);
     }
     if (reg2 == "")
     {
         reg2 = getReg(f, varTable, false, cmdList);
         cmdList.Add(AssemblerFac.GenLW(reg2, varTable.GetAddr(f.Arg2).ToString(), "$ZERO"));
         regUseTable.GetContent(reg2).Add(f.Arg2);
         varTable.SetAddrInfo(f.Arg2, reg2);
     }
     cmdList.Add(AssemblerFac.GenSLT("$T0", reg1, reg2));
     cmdList.Add(AssemblerFac.GenJUMP(operation, "$T0", f.TargetLabel.ToString()));
     adjustAfterJump(f, reg1, reg2, varTable, cmdList);
 }