Exemple #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);
                }
            }
        }
Exemple #2
0
 /// <summary>
 /// 跳转之后的调整
 /// </summary>
 /// <param name="f">四元式</param>
 /// <param name="reg1">寄存器1</param>
 /// <param name="reg2">寄存器2</param>
 /// <param name="varTable">变量表</param>
 /// <param name="cmdList">汇编指令列表</param>
 private void adjustAfterJump(FourExp f, string reg1, string reg2, VarTable varTable, List <AssemblerIns> cmdList)
 {
     if (varTable.GetPeekActInfo(f.Arg1) == false)
     {
         cmdList.Add(AssemblerFac.GenSW(reg1, varTable.GetAddr(f.Arg1).ToString(), "$ZERO"));
         varTable.SetAddrInfo(f.Arg1, "");
         regUseTable.GetContent(reg1).Remove(f.Arg1);
     }
     if (varTable.GetPeekActInfo(f.Arg2) == false)
     {
         cmdList.Add(AssemblerFac.GenSW(reg2, varTable.GetAddr(f.Arg2).ToString(), "$ZERO"));
         varTable.SetAddrInfo(f.Arg2, "");
         regUseTable.GetContent(reg2).Remove(f.Arg2);
     }
 }
Exemple #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);
        }
Exemple #4
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
            {
                //错误处理
            }
        }