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

📄 mips.c

📁 一个非常小的C语言编译器!!! !!! !!! !!!!
💻 C
字号:
//=================================================////   Mips Object Code Implementation    "mips.C"   ////=================================================////                                  Tan Watanabe, UEC//                      modified by Mitsugu G. Suzuki#include "sub.h"#include "arm.h"#include "mips.h"#define PARAM_areaSize 24 // (REG_param - REG_paramReg)*4MachineReg mrg_reg;Reg_symP   mrg_mips[32],  // Mips machine register pointer  mrg_zero,   mrg_rval, mrg_param, mrg_temp, mrg_saved,   mrg_stackp, mrg_raddr;String mipsOpCode[] = { // Mips operation code corresponding to Rcode.  //opProg,   opPend,   opSubp,   opEnd,    "       ","       ","       ","       ",  //opExport, opImport, opEntry,  opLabel,    ".globl ",".extern",".ent   ","       ",  //opAdd,    opAdda,   opSub,    opMult,   opDiv,   "add    ","addu   ","sub    ","__smuls","__sdivs",  //opMod,   "__sdivs",  //opJump,   opCall,   opReturn, opLoad,   opLoada,  opStore,    "j      ","jal    ","jr     ","lw     ","la     ","sw     ",  //opStack,   "sw     ",  //opComp,   opBreq,   opBrne,   opBrgt,   opBrge,   opBrle,   opBrlt,   "       ","beq    ","bne    ","bgt    ","bge    ","ble    ","blt    ",  //opProlog, opEpilog, opSect,   opDword,  opDbyte,  opDstr,   "       ","       ","       ",".word  ",".word  ",".asciiz",  // opDconst, opDparam   "       ","       " };  //--------------------//Reg_symP MachineReg::MrgInit(String pRegName, int pRegNumb){                            // Initiate the specified machine register.  Reg_symP    lRegSym;  MachineRegP lReg;    lRegSym = sym_tbl.SearchOrAdd(pRegName, strlen(pRegName), tknMrg);  lReg    = new MachineReg;  lRegSym->MrgPSet(lReg);  lReg->mrgNumb = pRegNumb;  return lRegSym;} //---- RegInit end ----//  //--------------------//void MachineReg::Initiation()  // Initiate all machine registers.{                              // Registers of the same kind make a ring.  int li;  Reg_symP lRegSym, lRegx, lRegy;    mrg_mips[31] = MrgInit("$31", 31);  for (li = 30; li >= 0; li--) {  // Generate machine registers.    mrg_mips[li] = MrgInit(StrSyn("$",Itoaf(li)), li);    mrg_mips[li]->MrgP()->mrgChain = mrg_mips[li+1];  }  mrg_zero   = mrg_mips[0];   // Zero reg.  mrg_rval   = mrg_mips[2];   // Return value reg.  mrg_param  = mrg_mips[4];   // Parameter reg list head.  mrg_temp   = mrg_mips[8];   // Temporal reg list head.  mrg_saved  = mrg_mips[16];  // Callee save reg list head.  mrg_stackp = mrg_mips[29];  // Stack pointer.  mrg_raddr  = mrg_mips[31];  // Return address reg.  mrg_mips[ 7]->MrgP()->mrgChain = mrg_param;    // Ring of param reg.  mrg_mips[15]->MrgP()->mrgChain = mrg_mips[24]; // Ring of temporal reg.  mrg_mips[23]->MrgP()->mrgChain = mrg_saved;    // Ring of saved reg.  mrg_mips[25]->MrgP()->mrgChain = mrg_temp;     // Ring of temporal reg.} //---- Initiation end ----////--------------------//Reg_symP MachineReg::MrgSearch( // Search machine reg to be allocated.  Reg_symP pArmReg,    // Rcode register  int      pLevel)     // 1: Search unused reg, 2: search noHolg reg.{  Reg_symP    lReg, lMrgReg;  MachineRegP lMrgInf;  int         lc;          // Search count    if (pArmReg->RegP()->MrgAlloc() != NULL)      lReg = pArmReg->RegP()->MrgAlloc();    // Set search start point.  else if (pArmReg->RegP()->RegKind() == regTi)       lReg = mrg_temp;    // Search point for temporal register.  else lReg = mrg_saved;   // Search point for other register.  lMrgReg = NULL;  for (lc = 1; (lMrgReg == NULL)&&(lc <= MRG_searchLim); lc++) {    lMrgInf = lReg->MrgP();      if (pLevel == 1) {     // Use unused or already allocated reg.      if ((lMrgInf->ArmReg() == NULL)||(lMrgInf->ArmReg() == pArmReg)||          (lMrgInf->ArmReg()->RegP()->RegStat() == regUnused))        lMrgReg = lReg;      // Unused register is found.    }else if (pLevel == 2) { // Use noHold register.      if (lMrgInf->ArmReg()->RegP()->RegStat() == regNoHold)        lMrgReg = lReg;      }    lReg = lMrgInf->mrgChain;  // Advance to the next one in the register ring.  }  return lMrgReg;} //---- MrgSearch end ----////--------------------//Reg_symP MipsReg(       // Allocate Mips register to Rcode register.  Reg_symP  pArmReg,    //   Rcode register for allocation.  Mrg_usage pUsage)     //   Use mode or set mode.{  Reg_symP    lReg, lMrgReg, lArmReg, lSaveReg;  MachineReg* lMrgInf;  int         lSearch;    if (pArmReg == NULL)    return NULL;  if (pArmReg->Kind() == tknMrg) // It is already a machine register.    return pArmReg;  if (((pArmReg->RegP()->RegKind() == regAi)||      // Parameter register.      (pArmReg->RegP()->RegKind() == regFi)) &&	  (pArmReg->RegP()->RegNumb() < REG_param))    lMrgReg = mrg_mips[4+pArmReg->RegP()->RegNumb()];  else if ((pArmReg->RegP()->MrgAlloc() == NULL)|| // Not yet allocated.      (pArmReg->RegP()->MrgAlloc()->MrgP()->ArmReg() != pArmReg)) {    lMrgReg = mrg_reg.MrgSearch(pArmReg, 1);    // Search free reg.    if (lMrgReg == NULL) {  // Not found. Snatch some register.      lMrgReg = mrg_reg.MrgSearch(pArmReg, 2);  // Search noHold reg.      // A register that is still noHold is not used at present.      //lSaveReg = lMrgReg->MrgP()->ArmReg();      //MachineCode(acRs, opStore, lMrgReg, NULL, NULL,       //            lSaveReg->RegP()->MrgSave(), 0);      //lSaveReg->RegP()->RegStatSet(regSaved);    }  }    // (pArmReg->RegP()->MrgAlloc()->MrgP()->ArmReg() != pArmReg) end  else // Already allocated. Use it.    lMrgReg = pArmReg->RegP()->MrgAlloc();  lMrgReg->MrgP()->ArmRegSet(pArmReg);  //if ((pUsage == mrgUse)&&(pArmReg->RegP()->RegStat() == regSaved))   //  MachineCode(acRs, opLoad, lMrgReg, NULL, NULL,   //              pArmReg->RegP()->MrgSave(),0);  pArmReg->RegP()->MrgAllocSet(lMrgReg);  pArmReg->RegP()->RegStatSet(regHold);  //fprintf(prtFile," ALLOC %s to %s ",lMrgReg->NameStr(),pArmReg->NameStr());  return lMrgReg;}  //---- MipsReg end ----////--------------------//String MipsLab(    // Change Rcode label to Mips label.  SymbolP pLab)    //   Rcode label.{  static char lName[TKN_lim];    //  strcpy(lName, pLab->NameStr());  //  if (lName[0] == '_')  // Change "_labxxx"  //    lName[0] = '$';     //     to "$labxxx".  if (strcmp(pLab->NameStr(), "main") == 0) { // main() is not modified    return pLab->NameStr();  } else {    strcpy(lName, "_");    strncat(lName, pLab->NameStr(), TKN_lim - 1);    return lName;  }} //---- MipsLab end ----////--------------------//void MachineReg::Print()   // Print machine reg information for debug.{  fprintf(prtFile, "rc %s ar %s mn %d ", mrgChain->NameStr(),    ArmReg()->NameStr(), mrgNumb);} //---- Print end ----////--------------------//void MachineCode(Ac_form pForm, Sym_opCodeT pOpCode,Reg_symP pReg1,      Reg_symP pReg2, Reg_symP pReg3, SymbolP pSym, int pInt) {                 // Generate MIPS machine code.  Reg_symP        lReg1, lReg2, lReg3;  static Reg_symP lSym, lRegPrev1, lRegPrev2, lRegPrev3, lLabel = NULL;  static String   lOpName, lOperand, lSymName;  int lTmp;  int lInsNop = 0; // force insert nop    if ((lLabel != NULL)&&(pOpCode != opDword)&&(pOpCode != opDparam))    fprintf(objFile, "\n%s:", MipsLab(lLabel));  // Previous label.  if (pOpCode == opLabel) {  // Record the label in order to output it    lLabel = pSym;           // in front of the next instruction.    return;  }  lOpName = mipsOpCode[pOpCode];  lReg1 = MipsReg(pReg1, (pOpCode==opStore?mrgUse:mrgSet));  lReg2 = MipsReg(pReg2, mrgUse);  lReg3 = MipsReg(pReg3, mrgUse);  if (pReg2 != NULL)    pReg2->RegP()->RegStatSet(regNoHold);  if (pReg3 != NULL)    pReg3->RegP()->RegStatSet(regNoHold);  switch (pOpCode) {  case opLoad:    if (pForm == acRc) lOpName = "li     ";    else lInsNop = 1; // Gian  case opLoada:     //    if ((pSym != NULL)&&(pSym->Kind() == tknParam)&&(pOpCode == opLoada))    //      lOpName = mipsOpCode[opLoad];  case opStore:    fprintf(objFile, "\n         %s  %s", lOpName, lReg1->NameStr());    if (pSym == NULL) {      if (pReg2 == NULL)            fprintf(objFile, ",%d", pInt);      else fprintf(objFile, ",%d(%s)", pInt, lReg2->NameStr());    }else { // pSym != NULL      //lSymName = pSym->NameStr();      lSymName = MipsLab(pSym);      if (pSym->Kind() == tknParam)         lSymName = StrSyn(Itoaf((pSym->VarP()->Index()-1)*4+56+PARAM_areaSize),"($sp)");      if (pReg2 == NULL) {        if (pInt == 0) /* If subscript is 0, omit subscript computation. */	  fprintf(objFile, ",%s", lSymName);        else {    // With constant subscript          if (pSym->Kind() == tknVar)            fprintf(objFile, ",%s+%d", lSymName, pInt);          else {  // Parameter with constant subscript.            fprintf(objFile, ",%s", lSymName);            fprintf(objFile, "\n         addu     %s,%s,%d",                     lReg1->NameStr(),lReg1->NameStr(), pInt);          }        } // pInt != 0      }  // pReg2 == NULL      else        fprintf(objFile, ",%s(%s)", lSymName, lReg2->NameStr());    }    if (lInsNop) {      fprintf(objFile, "\n         nop");    }    pReg1->RegP()->RegStatSet((pOpCode==opStore ? regNoHold : regHold));    break;  case opStack:    fprintf(objFile, "\n         %s  %s", lOpName, lReg1->NameStr());	fprintf(objFile, ",%d($sp)", pInt);  	break;  case opAdda:    fprintf(objFile, "\n         sll      %s,%s,2",             lReg3->NameStr(), lReg3->NameStr());    pReg3->RegP()->RegContSet(regOther);  case opAdd:  case opSub:    fprintf(objFile, "\n         %s  %s,%s,%s", lOpName,            lReg1->NameStr(), lReg2->NameStr(), lReg3->NameStr());    pReg1->RegP()->RegStatSet(regHold);    pReg1->RegP()->RegContSet(regOther);    break;  case opMult:  case opDiv:  case opMod:    fprintf(objFile, "\n         addu     $v0,$0,%s", lReg2->NameStr());    fprintf(objFile, "\n         addu     $v1,$0,%s", lReg3->NameStr());    fprintf(objFile, "\n         jal      %s", lOpName);    fprintf(objFile, "\n         nop");    fprintf(objFile, "\n         addu     %s,$0,%s", lReg1->NameStr(),		(pOpCode == opMod) ? "$v1" : "$v0");    pReg1->RegP()->RegStatSet(regHold);    pReg1->RegP()->RegContSet(regOther);    break;  case opComp:    lRegPrev2 = lReg2;    lRegPrev3 = lReg3;    pReg1->RegP()->RegStatSet(regHold);    break;  case opBreq:  case opBrne:    fprintf(objFile, "\n         %s  %s,%s,%s", lOpName,      lRegPrev2->NameStr(), lRegPrev3->NameStr(), MipsLab(pSym));    pReg1->RegP()->RegStatSet(regNoHold);    break;  case opBrgt:  case opBrge:  case opBrle:  case opBrlt:    if ((pOpCode == opBrgt) || (pOpCode == opBrle)) {      fprintf(objFile, "\n         slt      $1,%s,%s",lRegPrev3->NameStr(),	      lRegPrev2->NameStr());    } else {      fprintf(objFile, "\n         slt      $1,%s,%s",lRegPrev2->NameStr(),	      lRegPrev3->NameStr());    }    if ((pOpCode == opBrgt) || (pOpCode == opBrlt)) {      fprintf(objFile, "\n         bne      $1,$0,%s",MipsLab(pSym));    } else {      fprintf(objFile, "\n         beq      $1,$0,%s",MipsLab(pSym));    }    fprintf(objFile, "\n         nop");    pReg1->RegP()->RegStatSet(regNoHold);    break;  case opJump:    fprintf(objFile, "\n         %s  %s", lOpName, MipsLab(pSym));    fprintf(objFile, "\n         nop");    break;  case opEnd:    fprintf(objFile, "\n"); // nothing!    break;  case opImport:  case opExport:  case opEntry:    fprintf(objFile, "\n         %s  %s", lOpName, MipsLab(pSym));    break;  case opCall:    fprintf(objFile, "\n         %s  %s", lOpName, MipsLab(pSym));    fprintf(objFile, "\n         nop");    break;  case opReturn:    fprintf(objFile, "\n         jr       $31");    fprintf(objFile, "\n         nop");    break;  case opProlog:    //    fprintf(objFile, "\n         .ent     %s", pSym->NameStr());    fprintf(objFile, "\n%s:", MipsLab(pSym));    fprintf(objFile, "\n         subu     $sp,%d", 72+PARAM_areaSize);      // Push stack    fprintf(objFile, "\n         sw       $31,%d($sp)", 48+PARAM_areaSize); // Return addr    fprintf(objFile, "\n         sd       $22,%d($sp)", 40+PARAM_areaSize); // Callee save    fprintf(objFile, "\n         sd       $20,%d($sp)", 32+PARAM_areaSize);    fprintf(objFile, "\n         sd       $18,%d($sp)", 24+PARAM_areaSize);    fprintf(objFile, "\n         sd       $16,%d($sp)", 16+PARAM_areaSize);    fprintf(objFile, "\n         sd       $6,%d($sp)", 64+PARAM_areaSize);    fprintf(objFile, "\n         sd       $4,%d($sp)", 56+PARAM_areaSize);    //    fprintf(objFile, "\n         .frame   $sp,72,$31");    //    fprintf(objFile, "\n         .mask    0x80ff0000,-24");    break;  case opEpilog:    if (pReg1 != NULL)           // Return value      fprintf(objFile, "\n         addu     $2,%s,$0", lReg1->NameStr());    fprintf(objFile, "\n         lw       $31,%d($sp)", 48+PARAM_areaSize); // Return addr    fprintf(objFile, "\n         ld       $22,%d($sp)", 40+PARAM_areaSize); // Callee save    fprintf(objFile, "\n         ld       $20,%d($sp)", 32+PARAM_areaSize);    fprintf(objFile, "\n         ld       $18,%d($sp)", 24+PARAM_areaSize);    fprintf(objFile, "\n         ld       $16,%d($sp)", 16+PARAM_areaSize);    fprintf(objFile, "\n         addu     $sp,%d", 72+PARAM_areaSize);      // Pop stack    break;  case opSect:    if (pInt == acSectText)         fprintf(objFile, "\n         .text");    else fprintf(objFile, "\n         .data");    break;  case opDword:    //fprintf(objFile, "\n         .comm    %s,%d",    //    lLabel->NameStr(), pInt);    if (pInt <= 4) {	fprintf(objFile,  "\n%s: .word 0", MipsLab(lLabel));    } else {	fprintf(objFile,  "\n%s: .space %d", MipsLab(lLabel), pInt);    }    break;  case opSubp:  case opLabel:   case opDconst: case opDparam: case opProg: case opPend:  default:    break;  } //---- switch(pOpCode) end  lLabel = NULL;} //---- MachineCode end ----//

⌨️ 快捷键说明

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