📄 code.c
字号:
/****************************************************/
/* File: code.c */
/* TM Code emitting utilities */
/* implementation for the TINY compiler */
/* Compiler Construction: Principles and Practice */
/* Kenneth C. Louden */
/****************************************************/
#include "Globals.h"
#include "Code.h"
/* TM location number for current instruction emission */
//static int emitLoc = 0 ;
int emitLoc;
/* Highest TM location emitted so far
For use in conjunction with emitSkip,
emitBackup, and emitRestore */
static int highEmitLoc = 0;
INSTRUCTION instruction;
INSTRUCTION iMem [IADDR_SIZE];
map<string,int> mStart;
/********************************************/
int opClass( int c )
{
if ( c <= opRRLim)
return ( opclRR );
else if ( c <= opRMLim)
return ( opclRM );
else
return ( opclRA );
} /* opClass */
/* Procedure emitComment prints a comment line
* with comment c in the code file
*/
void emitComment(const char * c )
{
if (TraceCode)
fprintf(code,"* %s\n",c);
}
/* Procedure emitRO emits a register-only
* TM instruction
* op = the opcode
* r = target register
* s = 1st source register
* t = 2nd source register
* c = a comment to be printed if TraceCode is TRUE
*/
void emitRO( int op, int r, int s, int t, const char *c, int size)
{
instruction.SetInstruction(op, r, s, t, size);
iMem[emitLoc] = instruction;
fprintf(code,"%3d: %d %d,%d,%d ",emitLoc++,op,r,s,t);
if (TraceCode)
fprintf(code,"\t%s",c) ;
fprintf(code,"\n") ;
if (highEmitLoc < emitLoc)
highEmitLoc = emitLoc ;
} /* emitRO */
/* Procedure emitRM emits a register-to-memory
* TM instruction
* op = the opcode
* r = target register
* d = the offset
* s = the base register
* c = a comment to be printed if TraceCode is TRUE
*/
void emitRM( int op, int r, int d, int s, const char *c, int size, int trans)
{
instruction.SetInstruction(op, r, d, s, size, trans);
iMem[emitLoc] = instruction;
if(op == opENT)
mStart[c] = emitLoc;
fprintf(code,"%3d: %5s %d,%d(%d) ",emitLoc++,op,r,d,s);
if (TraceCode)
fprintf(code,"\t%s",c) ;
fprintf(code,"\n") ;
if (highEmitLoc < emitLoc)
highEmitLoc = emitLoc ;
} /* emitRM */
void emitRM2( int op, int r, double d, int s, const char *c, int size, int trans)
{
instruction.SetInstruction2(op, r, d, s, size, trans);
iMem[emitLoc] = instruction;
if(op == opENT)
mStart[c] = emitLoc;
fprintf(code,"%3d: %5s %d,%f(%d) ",emitLoc++,op,r,d,s);
if (TraceCode)
fprintf(code,"\t%s",c) ;
fprintf(code,"\n") ;
if (highEmitLoc < emitLoc)
highEmitLoc = emitLoc ;
} /* emitRM2 */
/* Function emitSkip skips "howMany" code
* locations for later backpatch. It also
* returns the current code position
*/
int emitSkip( int howMany)
{
int i = emitLoc;
emitLoc += howMany ;
if (highEmitLoc < emitLoc)
highEmitLoc = emitLoc ;
return i;
} /* emitSkip */
/* Procedure emitBackup backs up to
* loc = a previously skipped location
*/
void emitBackup( int loc)
{
if (loc > highEmitLoc)
emitComment("BUG in emitBackup");
emitLoc = loc ;
} /* emitBackup */
/* Procedure emitRestore restores the current
* code position to the highest previously
* unemitted position
*/
void emitRestore(void)
{
emitLoc = highEmitLoc;
}
/* Procedure emitRM_Abs converts an absolute reference
* to a pc-relative reference when emitting a
* register-to-memory TM instruction
* op = the opcode
* r = target register
* a = the absolute location in memory
* c = a comment to be printed if TraceCode is TRUE
*/
void emitRM_Abs( int op, int r, int a, const char * c)
{
instruction.SetInstruction(op, r, a-(emitLoc+1), pc);
iMem[emitLoc] = instruction;
fprintf(code,"%3d: %5s %d,%d(%d) ",
emitLoc,op,r,a-(emitLoc+1),pc);
++emitLoc ;
if (TraceCode)
fprintf(code,"\t%s",c) ;
fprintf(code,"\n") ;
if (highEmitLoc < emitLoc)
highEmitLoc = emitLoc ;
} /* emitRM_Abs */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -