⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arm.c

📁 一个非常小的C语言编译器!!! !!! !!! !!!!
💻 C
字号:
//=============================================////  Rcode Class Implementation    "arm.C"    ////=============================================////                             Tan Watanabe, UEC#include "sub.h"#include "arm.h"//============== RegInf Class Implementation =========//  RegInf reg_tbl;    Reg_symP     reg_sp,    // Stack pointer register    reg_ri,    // Return integer value register    reg_gi0,   // First callee save register    reg_ti0,   // First caller save register    reg_fi0,   // First formal parameter integer register    reg_ai0,   // First actual parameter integer register    reg_tail[6]  = { NULL, NULL, NULL, NULL, NULL, NULL },    reg_linkTail = NULL;  Reg_symP  	reg_ai[REG_param],	reg_fi[REG_param];  int    reg_index[12];  // Reg index used for each register kind.  static String reg_statName[] = {"unused","hold","noHold","saved"};  //--------------------//void RegInf::Initiation(){  int i;  reg_sp  = reg_tail[regSp] = RegGet(regSp); // Head of register chain.  reg_ri  = reg_tail[regRi] = RegGet(regRi);  reg_gi0 = reg_tail[regGi] = RegGet(regGi);  reg_ti0 = reg_tail[regTi] = RegGet(regTi);  reg_fi0 = reg_tail[regFi] = RegGet(regFi);  reg_ai0 = reg_tail[regAi] = RegGet(regAi);  reg_ai[0] = reg_ai0;                         //## 010901  reg_fi[0] = reg_fi0;                         //## 010901  for (i = 1; i < REG_param; i++) {            //## 010901    reg_ai[i] = RegGet(regAi);                 //## 010901    reg_ai[i-1]->RegP()->regChain = reg_ai[i]; //## 010901    reg_fi[i] = RegGet(regFi);                 //## 010901    reg_fi[i-1]->RegP()->regChain = reg_fi[i]; //## 010901  }                                            //## 010901} //---- Initiation end ----////--------------------//Reg_symP RegInf::RegGet(  // Get Rcode register of pKind as   Reg_kind pKind)         //   a tail register of that kind.{  static String lKindName[] = {    "%gi", "%ti", "%ri", "%fi", "%ai", "%sp" };  Reg_symP lRegSym, lTail, lTemp;  RegInfP  lReg;  int      lNumb;   // Register number relative in the given kind.  char     lRegName[8];    lTail = reg_tail[pKind];  lNumb = ((lTail == NULL) ? 0 : lTail->RegP()->regNumb + 1);  strcat(strcpy(lRegName, lKindName[pKind]),Itoaf(lNumb)); // Make reg name.  lRegSym = sym_tbl.SearchOrAdd(lRegName, strlen(lRegName), tknReg);  // lTemp = sym_tbl.GeneratedVar();  lReg = new RegInf;  lRegSym->RegPSet(lReg);  lReg->regKind = pKind;  lReg->regNumb = lNumb;  // lReg->MrgSaveSet(lTemp);  if (lTail != NULL)          // Make chain from previous register.    lTail->RegP()->regChain = lRegSym;  if (reg_linkTail != NULL)    reg_linkTail->RegP()->regLink = lRegSym;  // Link to the tail.  reg_tail[pKind] = lRegSym;  reg_linkTail = lRegSym;  return lRegSym;} //---- RegGet end ----////--------------------//Reg_symP RegInf::RegAlloc(    // Allocate Rcode register.          Reg_symP pReg, SymbolP pVar, int pConst, Reg_contents pCont){   Reg_symP lReg, lAlloc;   int      i;   if (pReg->RegP()->RegStat() == regReserved) // If resereved register,        lAlloc = pReg;                         //   allocate it.   else lAlloc = NULL;   for (i = 0, lReg = pReg; // Allocate reg having the same contents if there is.	(lReg != NULL)&&(lAlloc == NULL)&&(i < REG_numMax); i++) {     lReg->RegP()->reusable = false;     if (((pVar != NULL)&&  //##030309	  (lReg->RegP()->BoundVar() == pVar)&&	  (lReg->RegP()->RegCont() != regOther)&& //## 011003	  //##031208 ((lReg->RegP()->RegCont() == pCont)||	  (((lReg->RegP()->RegCont() == pCont)&&    //##031208	    (lReg->RegP()->RegStat() != regHold))|| //##031208	   ((lReg->RegP()->RegValue() == regConstVal)&&	    (pCont == regSymVal)&&	    (lReg->RegP()->RegStat() != regHold)&& //##030309	    (lReg->RegP()->RegStat() != regUnused))))|| //##030309	 ((pVar == NULL)&&	  (lReg->RegP()->RegCont() == regConstVal)&&	  (lReg->RegP()->RegValue() == pConst)&&	  (lReg->RegP()->RegStat() != regHold)&& //##030309	  (lReg->RegP()->RegStat() != regUnused))) { //##030309       lAlloc = lReg;       // Allocate lReg having the same contents.       lAlloc->RegP()->reusable = true;     }else       lReg = lReg->RegP()->regChain;     // Examine the next.   }   if (lAlloc == NULL) {     for (i = 0, lReg = pReg;          (lReg != NULL)&&(lAlloc == NULL)&&(i < REG_numMax); i++) { //## 021219       if ((lReg->RegP()->BoundVar() == NULL)&&  // Find unbounded &	   (lReg->RegP()->RegStat() != regHold)) // no-hold one.         lAlloc = lReg;       else         lReg = lReg->RegP()->regChain;     // Examine the next.     } //## 021219   }   if (lAlloc == NULL) {                  // Not yet allocated.     lAlloc = RegGet(pReg->RegP()->RegKind());  // Get a new register.     lAlloc->RegP()->reusable = false;   }   lAlloc->RegP()->RegContSet(pCont);     // Record the contents inf.   if (pVar != NULL) {     lAlloc->RegP()->BoundVarSet(pVar);   // Bind a variable   }else     lAlloc->RegP()->RegValueSet(pConst); // or record a value.   lAlloc->RegP()->RegStatSet(regHold);   // Hold the register.   return lAlloc;                         // Return the allocated register.} //---- RegAlloc end ----////--------------------//void RegInf::RegFree(Reg_symP pReg)      // Free pReg.{  SymbolP lSym;    lSym = pReg->RegP()->BoundVar();  if (lSym != NULL)    lSym->VarP()->AllocRegSet(NULL);  pReg->RegP()->BoundVarSet(NULL);  pReg->RegP()->RegContSet(regEmpty);  pReg->RegP()->RegStatSet(regUnused);  pReg->RegP()->reusable = false;} //---- RegFree end ----////--------------------//void RegInf::RegFreeAll()               // Free all registers.{  int l;  Reg_symP lReg;    for (lReg = reg_sp; lReg != NULL; lReg = lReg->RegP()->regLink)    RegFree(lReg);} //---- RegFreeAll end ----////--------------------//void RegInf::Print()   // Print symbol information for debug.{  fprintf(prtFile, "rc %s ma %s bv %s ms %s ", regChain->NameStr(),    MrgAlloc()->NameStr(), BoundVar()->NameStr(), MrgSave()->NameStr());} //---- Print end ----////========== Rcode Implementations ==========////--------------------//void GenCode(      // Generate Rcode and corresponding machine code.     Ac_form  pForm, Sym_opCodeT pOpCode,     Reg_symP pReg1, Reg_symP    pReg2, Reg_symP pReg3,     SymbolP  pSym,  int pInt) {  int lComma;  // Generate machine code to objFile.  MachineCode(pForm, pOpCode, pReg1, pReg2, pReg3, pSym, pInt);  // Print Rcode to prtFile.  if (pOpCode == opLabel) {        fprintf(prtFile, "\n %s: ", pSym->NameStr());    return;  }  lComma = false;  fprintf(prtFile, "\n         %s  ", sym_opCodeName[pOpCode]);  if (pReg1 != NULL) {    fprintf(prtFile, "%s", pReg1->NameStr());    lComma = true;  }  if (pReg2 != NULL) {    if (lComma)      fprintf(prtFile, ",");    fprintf(prtFile, "%s", pReg2->NameStr());    lComma = true;  }  if (pReg3 != NULL) {    if (lComma)      fprintf(prtFile, ",");    fprintf(prtFile, "%s", pReg3->NameStr());    lComma = true;  }  if (pSym != NULL) {    if (lComma)      fprintf(prtFile, ",");    fprintf(prtFile, "%s", pSym->NameStr());    lComma = true;  }  switch (pForm) {  case acRc:  case acSc:  case acRrc:  case acRsc:    fprintf(prtFile, ",%d", pInt);    break;  case acC:    fprintf(prtFile, "%d", pInt);    break;  default:    break;  }  fprintf(prtFile, ";  %c", TKN_tab);} //---- GenCode end ----////--------------------//void Rcode::Initiation(){  ac_labelGenIndex = 0;  // Reset the index of generated labels.  ac_curr = &ac_head;} //---- Initiation end ----////--------------------//SymbolP Rcode::LabelGen()    // Generate a label of a form "_labxxx"{                              //   where, xxx is 001, 002, 003, ...  char    lLabelName[12];  SymbolP lSym;    ac_labelGenIndex++;  strcat(strcpy(lLabelName, "_lab"), Itoaf(ac_labelGenIndex));  lSym = lSym->SearchOrAdd(lLabelName, strlen(lLabelName), tknLabel);  return lSym;} //---- LabelGen end ----////--------------------//Reg_symP Rcode::Load( // Load value or address of variable/parameter.  SymbolP  pVar,        //   Variable or parameter symbol.  Reg_symP pCand,       //   Candidate register.  Reg_symP pIndexReg,   //   Index regiser (unscaled). NULL if none.  int      pValue,      //   Displacement.  Ac_lrT   pType)       //   lValue or rValue.{  Reg_symP     lReg, lSymAddr, lVarAddr, lCand;  Reg_contents lCont;  Sym_opCodeT  lOpCode;    if (pIndexReg == NULL) { // Const, simple var or const subscripted var.    if (pVar == NULL) {    // Constant.      lReg = reg_tbl.RegAlloc(pCand, NULL, pValue, regConstVal);      if (lReg->RegP()->reusable == false)  // Omit if reusable.        GenCode(acRc, opLoad, lReg, NULL, NULL, NULL, pValue);    }else {    // Simple variable without subscript.      if (pType == lValue) {  // Left value. Load address.        lCont   = (pValue == 0 ? regSymAddr : regOther);        lOpCode = ((pVar->Kind() == tknParam) ? opLoad : opLoada);        lSymAddr = reg_tbl.RegAlloc(pCand, pVar, 0, lCont);        if (lSymAddr->RegP()->reusable == false)           GenCode(acRsc, lOpCode, lSymAddr, NULL, NULL, pVar, pValue);        return lSymAddr;      } // lValue end      lCont = (pValue == 0 ? regSymVal : regOther);      lReg = reg_tbl.RegAlloc(pCand, pVar, pValue, lCont);      if (lReg->RegP()->reusable == false) // Omit if reusable.        GenCode(acRsc, opLoad, lReg, NULL, NULL, pVar, pValue);    } // end of simple variable.  }else {   // Subscripted var with non-constant index.    lCont = (pValue == 0 ? regSymAddr : regOther);    lOpCode = ((pVar->Kind() == tknParam) ? opLoad : opLoada); // Gian    lSymAddr = reg_tbl.RegAlloc(reg_gi0, pVar, pValue, lCont);    if (lSymAddr->RegP()->reusable == false)       GenCode(acRsc, lOpCode, lSymAddr, NULL, NULL, pVar, pValue);    lCand = (pType == lValue ? pCand : reg_gi0);    lVarAddr = reg_tbl.RegAlloc(lCand, NULL, 0, regOther);    GenCode(acRrr, opAdda, lVarAddr, lSymAddr, pIndexReg, NULL, 0);    if (pType == lValue)      return lVarAddr;    lReg = reg_tbl.RegAlloc(pCand, NULL, 0, regOther);    GenCode(acRr, opLoad, lReg, lVarAddr, NULL, NULL, 0);  }  return lReg;  // Return the register containing value/address of variable.} //---- Load end ----////--------------------//void Rcode::Store(    // Store pRightpart to pLeftPart.  SymbolP  pLeftPart,   //   Address register or simple variable.  Reg_symP pRightPart)  //   Register containing right part exp.{  if (pLeftPart->Kind() == tknReg)    GenCode(acRr, opStore, pRightPart, pLeftPart, NULL, NULL, 0);  else { // Left part is a simple variable    GenCode(acRs, opStore, pRightPart, NULL, NULL, pLeftPart, 0);    //## 021219 BEGIN    if ((pLeftPart->Kind() == tknVar)||(pLeftPart->Kind() == tknParam)) {      Reg_symP lReg; // Unbound the variable from other registers.      for (lReg = reg_sp; lReg != NULL; lReg = lReg->RegP()->regLink) {        if ((lReg->RegP()->BoundVar() == pLeftPart)&&            (pRightPart != lReg))          lReg->RegP()->BoundVarSet(NULL);       }    }    //## 021219 END    pRightPart->RegP()->BoundVarSet(pLeftPart);    pRightPart->RegP()->RegContSet(regSymVal);  }} //---- Store end ----////====== Global symbols ======//  Rcode  ac_head;  RcodeP ac_curr;  int      ac_labelGenIndex; // Generated label index.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -