예제 #1
0
void Compiler::EmitFunction(FunctionSymbol p)
{
	BBlock bb;
	int varsize;

	Export((Symbol)p);
	DefineLabel((Symbol)p);

	LayoutFrame(p, 2);
	/*
		pushl %ebp
		movl %esp, %ebp
	*/
	varsize = p->locals.size();
	EmitPrologue(varsize);

	bb = p->entryBB;
	while (true)
	{
		if (bb->ref != 0) DefineLabel(bb->sym);

		EmitBBlock(bb);

		if (bb != p->exitBB)
			bb = bb->next;
		else
			break;

	}
	/*
		movl %sebp, %esp
		popl %ebp
	*/
	EmitEpilogue(varsize);
}
예제 #2
0
short Directives()
{	
	int t;
	
	SkipWhiteSpace();

	if (*FilePtr != '.')
		return 0;

	DataCharPtr = FilePtr;

	if (QToken(".eof"))
	{
		// mark end of label array as end of bss
		
		strcpy(Name, "_________eof_________");
		Section = SECT_bss;
		DefineLabel(label_Local);

		SourceFileCheckEOF(LastTokenPtr() - FileTop);

		EndFile = 1;
		return 1;
	}


	GetToken();	
	t = ScanAsmToken();

	switch(t)
	{

//---------------------------------------------------------

	case 0:
		Error(Error_Skip, "Illegal directive '%s'",Name);


//---------------------------------------------------------

	case dir_sourcefile:
	{		
		int file;
		
		SkipWhiteSpace();
		GetLFileName();	

//		SetCSourceFile(Name);
		file = SetSLD_Name(Name);

		SetCSourceFile(Name, file);
		return 1;
	}

//---------------------------------------------------------


	case dir_model:
	{	
		int model=0;
	
		if (Token("full"))				// Get return type
			model = MODEL_full;
		else if (Token("half"))				// Get return type
			model = MODEL_half;
		else if (Token("compact"))			// Get return type
			model = MODEL_compact;
		else if (Token("mini"))				// Get return type
			model = MODEL_mini;
		else if (Token("tiny"))				// Get return type
			model = MODEL_tiny;
		else 
			Error(Error_Fatal, "invalid model type");

		// if model is not set then set it
			
		if (!CurrentModel)
			CurrentModel = model;
		else
		{
			if (model != CurrentModel)
				Error(Error_Fatal, "multiple architectual models defined");
		}

		return 1;
	}

//---------------------------------------------------------

	case dir_ctor:
	{
		SYMBOL* ref;
		imm = GetExpression();				// Get the number
		ref = GetLastSymbolRef();

		if(pass_count > 1)
		{
			if (!ref)
				Error(Error_Fatal, "Constructor has bad reference");

			ArraySet(&CtorArrayImm, CtorCount, imm);
			ArraySet(&CtorArray, CtorCount++, (int) ref);
		}
		return 1;		
	}

//---------------------------------------------------------

	case dir_dtor:
	{		
		SYMBOL* ref;
		imm = GetExpression();				// Get the number
		ref = GetLastSymbolRef();

		if(pass_count > 1)
		{
			if (!ref)
				Error(Error_Fatal, "Destructor has bad reference");

			ArraySet(&DtorArrayImm, DtorCount, imm);
			ArraySet(&DtorArray, DtorCount++, (int) ref);
		}
		return 1;		
	}


//---------------------------------------------------------

	case dir_sourcedir:
	{		
		SkipWhiteSpace();
		GetLFileName();	
		SetCSourceDir(Name);
		return 1;
	}

//---------------------------------------------------------

	case dir_line:
	{
		int v;
		
		SkipWhiteSpace();
		v = GetNum();	
		SetCSourceLine(v);
		SetSLD_Line(v);

		return 1;
	}

//---------------------------------------------------------

	case dir_dlab:
	{
		if (!ArgUseStabs)
		{
			SkipLine();			// Skip excess debug labels
			return 1;
		}

		// Define a label

		Section = SECT_code;

		GetAsmName();
		DefineLabel(label_Local);
		return 1;
	}

//---------------------------------------------------------

	case dir_library:
	{
		SkipLine();
		return 1;
	}

//---------------------------------------------------------

	case dir_exit:
	{
		if (NextToken("\""))
		{
			GetStringName(1024);

			Error(Error_Fatal, "User: %s", Name);
			return 1;
		}
	
	
		Error(Error_Fatal, "Exiting with user error");
		return 1;
	}

//---------------------------------------------------------

	case dir_asm_on:
	{
		return 1;
	}

//---------------------------------------------------------

	case dir_asm_off:
	{
/*		if (QToken(".asm_off"))
		{
			return 1;
		}
*/
		return 1;
	}

//---------------------------------------------------------

	case dir_AllowFarBranches:
	{
		AllowFarBranches = 1;
		return 1;
	}

//---------------------------------------------------------

	case dir_bp:
	{
		return 1;
	}

//---------------------------------------------------------

	case dir_localscope:
	{
		SkipWhiteSpace();

		if (Token("+"))
		{
			LocalScope++;
			return 1;
		}

		if (Token("reset"))
		{
			LocalScope = 1;
			return 1;
		}

		Error(Error_Fatal, "Bad .localscope type");
		return 1;
	}

//---------------------------------------------------------

	case dir_func:
	{	
		Function_Return_Type = RET_void;

		GetName();

		ReplaceChar(Name, '.', '_');

		Function_Param_Count = -1;

		if (Token(","))
		{
			Function_Param_Count = GetNum();

			if (Token(","))				// Get param count
			{				
				if (Token("int"))				// Get return type
					Function_Return_Type = RET_int;
				else if (Token("float"))
					Function_Return_Type = RET_float;
				else if (Token("double"))
					Function_Return_Type = RET_double;
				else if (Token("void"))
					Function_Return_Type = RET_void;
				else if (Token("?"))
					Function_Return_Type = RET_double;	//patch fix
			}
		}

		DefineLabel(label_Function);		
		return 1;
	}

//---------------------------------------------------------

	case dir_local:
	{
		GetName();
		return 1;
	}

//---------------------------------------------------------

	case dir_vec_elt:
	{
		GetName();
		return 1;
	}

//---------------------------------------------------------

	case dir_syscall:
	{
		char SysCallName[256];
		char istr[4096];
		char *iptr = 0;
		
		int v, p, r;
		
		p = 0;
		r = RET_void;
		
		GetName();
		strcpy(SysCallName,Name);
	
		SkipWhiteSpace();

		v = GetExpression();

		if (Token(","))				// Get param count
		{
			p = GetExpression();

			NeedToken(",");
			
			if (Token("int"))				// Get return type
				r = RET_int;
			else if (Token("float"))
				r = RET_float;
			else if (Token("double"))
				r = RET_double;
			else if (Token("void"))
				r = RET_void;

			if (Token(","))				// Get interface
			{
				GetStringName(2048);
				strcpy(istr,Name);
				iptr = istr;
			}

		}

		if (Pass == 1)
			MapSysCall(SysCallName, v, p, r, iptr);

		return 1;
	}

//---------------------------------------------------------

	case dir_lfile:
	{
		SkipWhiteSpace();
		GetLFileName();
		
		strcpy(CurrentFile, Name);
//		CurrentFileLine = GetLineNumber(FileTop,GetPrevFilePtr());
		
		AddFileSym(Name, LocalScope+1);
		
		GetRelPath(CurrentFile);
		return 1;
	}

//---------------------------------------------------------

	case dir_org:
	{
		int v = GetExpression();

		if (v >= MAX_CODE_MEM)
			Error(Error_Fatal, ".org has illegal address");

		CodeIP = v;
//!		CodePtr = &CodeMem[v];
		printf("*Warning* org %x\n", v);
		return 1;
	}


//---------------------------------------------------------

	case dir_set:
	{
		
		SkipWhiteSpace();

		// Catch Thunks
		
		if (Token("%"))
		{
			SYMBOL *ThunkSym;
			int v;

			v = GetDecNum(5);
			
			if (GetDecNumDigitCount() == 0)
				Error(Error_Fatal, "Missing Thunk Number");

			NeedToken("=");
			SkipWhiteSpace();

			GetName();			// Get the name of the thunk alias
			GetEnumValue(Name);	// Evaluate the symbol


			ThunkSym = GetLastSymbolRef();

			//N_FUN 141 4935 '_Z7XPClosev:F(0,6)'

			StabsEmit("N_THUNK %d %d '%s'\n", v, ThunkSym, Name);

			RegisterThunk(v, ThunkSym);
			return 1;
		}
		
		// Catch normal sets
		
		GetName();							// Get the new type Name	
		NeedToken("=");
		RedefENum(Name, GetExpression());	
		return 1;
	}

//---------------------------------------------------------

	case dir_debug:
	{
		DEBUG = (short)GetExpression();	
		return 1;
	}


//---------------------------------------------------------

	case dir_info:
	{
		INFO = (short)GetExpression();	
		return 1;
	}

//---------------------------------------------------------

	case dir_list:
	{
		LIST = (short)GetExpression();	
		return 1;
	}

//---------------------------------------------------------

	case dir_show:
	{
		int exp = GetExpression();
		
		if (Pass == 1)
			printf("%d",exp);

		if (!Token(";"))
			if (Pass == 1) printf("\n");
	
		return 1;
	}

//---------------------------------------------------------

	case dir_print:
	//if (QToken(".print") || QToken(".?"))
	{
		int exp;
		char v;
	
		if (Token("\""))
		{
			while(1)	
			{
				v = *FilePtr;
				
				if (v == 0 || v == '"')
					break;
				
				printf("%c",v);

				FilePtr++;
			}

			NeedToken("\"");

			if (!Token(";"))
				printf("\n");

			return 1;
		}

		exp = GetExpression();

		printf("%d",exp);

		if (!Token(";"))
			printf("\n");
	
		return 1;
	}

//---------------------------------------------------------

	case dir_ifdef:
	{
		GetName();							// Get the new type Name	
		SkipWhiteSpace();
		
		if (!SymbolExists(Name, section_Script, -1))
		{
			if (NextToken("{"))
			{
				SkipPair('{','}');
			}
		}
		return 1;
	}

//---------------------------------------------------------

	case dir_ifdefglobal:
	{
		GetName();							// Get the new type Name	
		SkipWhiteSpace();
		
		if (!SymbolExists(Name, section_Enum, 0))
		{
			if (NextToken("{"))
			{
				SkipPair('{','}');
			}
		}
		return 1;
	}

//---------------------------------------------------------

	case dir_ifndefglobal:
	{
		GetName();							// Get the new type Name	
		SkipWhiteSpace();
		
		if (SymbolExists(Name, section_Enum, 0))
		{
			if (NextToken("{"))
			{
				SkipPair('{','}');
			}
		}
		return 1;
	}

//---------------------------------------------------------

	case dir_ifndef:
	{
		GetName();							// Get the new type Name	
		SkipWhiteSpace();
		
		if (SymbolExists(Name, section_Script, -1))
		{
			if (NextToken("{"))
			{
				SkipPair('{','}');
			}
		}
		return 1;
	}

//---------------------------------------------------------

	case dir_if:
	{

		if (!GetExpression())
		{
			SkipWhiteSpace();

			if (NextToken("{"))
			{
				SkipPair('{','}');
			}
		}
		return 1;
	}


//---------------------------------------------------------

	case dir_do:
	{

		// If we have a '{' just ignore it an keep going
		
		if (Token("{"))
			return 1;
	
		// Must be an expression then

		// if false then skip to while

		if (!GetExpression())
		{
			SearchScopeForward();
			NeedToken(".enddo");
		}
			
		return 1;
	}

//---------------------------------------------------------

	case dir_enddo:
	{
		FilePtr = SearchScope(FilePtr);			
		return 1;
	}


//---------------------------------------------------------

	case dir_while:
	{
		if (GetExpression())
		{
			FilePtr = SearchScope(FilePtr);
		}
		return 1;
	}

//---------------------------------------------------------

	case dir_enum:
	{
		AsmEnums();
		return 1;
	}


//---------------------------------------------------------

	case dir_breakpoint:
	{
		SkipWhiteSpace();
		return 1;
	}

//---------------------------------------------------------

	case dir_globals_in_code:
	{
		GlobalsInCode = 1;
		SkipWhiteSpace();
		return 1;
	}

//---------------------------------------------------------

	case dir_globl:
//	if (QToken(".globl") || QToken(".global") || QToken(".weak"))
	{
		unsigned int n;
		
		GetAsmName();

		if (GlobalsInCode && (Section == SECT_code))
		{
//!			*CodePtr++ = '*';

			ArraySet(&CodeMemArray, CodeIP, '*');
			CodeIP++;

			for (n=0;n<strlen(Name);n++)
			{
//!				*CodePtr++ = Name[n];

				ArraySet(&CodeMemArray, CodeIP, Name[n]);
				CodeIP++;
			}
	
//!			*CodePtr++ = '*';

			ArraySet(&CodeMemArray, CodeIP, '*');
			CodeIP++;
		}

		if (LIST)
			printf("Found global '%s'\n",Name);

		DefineLabelGlobal();

//#ifdef INCLUDE_JAVAGEN
//		if (JavaPass)
//			JavaGen_Global(Name);
//#endif
		
		SkipWhiteSpace();
		return 1;
	}

//---------------------------------------------------------

	case dir_extern:
//	if (QToken(".extern") || QToken(".extrn"))
	{
		GetAsmName();

		if (LIST)
			printf("Found external '%s'\n",Name);

		// SHOULD DO NOTHING 
		//ExternDecl(Name);

		SkipWhiteSpace();
		return 1;
	}

//---------------------------------------------------------

	case dir_byte:
	{
		SetAsmDataChar();

		do
		{
			imm = GetExpression();					// Get the number

			WriteDataTypeArray(dir_byte, 1);
			WriteByte(imm);
		}
		while (QToken(","));

		return 1;

	}

//---------------------------------------------------------

	case dir_half:
	{
		SetAsmDataChar();

		do
		{
			imm = GetExpression();					// Get the number

			WriteDataTypeArray(dir_half, 2);
			WriteWord(imm);
		}
		while (QToken(","));

		return 1;
	}

//---------------------------------------------------------

	case dir_word:
	{
		SYMBOL *ref;
		
		if (Section != SECT_data)
			Error(Error_Skip,"data word in not in data section");

		SetAsmDataChar();
		
		do
		{
			imm = GetExpression();				// Get the number

			WriteDataTypeArray(dir_word, 4);

			ref = GetLastSymbolRef();
			WriteLongRef(imm, ref);

		}
		while (QToken(","));
		return 1;
	}

//---------------------------------------------------------

	case dir_space:
	{
		SetAsmDataChar();

		imm = GetExpression();					// Get the number

		if (LIST)
			printf("space %d\n",imm);
	
		if (!imm)
			return 1;

		WriteDataTypeArray(dir_space, imm);
		
		do
		{
			WriteByteSpace(0);
		}
		while(--imm);

		return 1;
	}

//---------------------------------------------------------

	case dir_string:
	{
		SetAsmDataChar();

		WriteDataTypeArray(dir_string, 1);

		GetStrings();
		return 1;
	}

//---------------------------------------------------------

	case dir_comm:
	{
		int LastSect = Section;

		SetAsmDataChar();

		Section = SECT_bss;

		GetAsmName();
		
		//!! make this global too

		DefineLabelGlobal();
		DefineLabel(label_Local);
		
		NeedToken(",");
				
		imm = GetExpression();					// Get the number

		if (LIST)
			printf("comm %d to .bss\n",imm);
	
		if (imm == 0)
			return 1;

		WriteDataTypeArray(dir_comm, imm);
		
		BssIP += imm;

		Section = LastSect;

		return 1;
	}

//---------------------------------------------------------

	case dir_lcomm:
	{
		int LastSect = Section;

		SetAsmDataChar();

		Section = SECT_bss;

		GetAsmName();
		DefineLabel(label_Local);
		
		NeedToken(",");
				
		imm = GetExpression();					// Get the number

		if (LIST)
			printf("lcomm %d to .bss\n",imm);
	
		if (imm == 0)
			return 1;

		WriteDataTypeArray(dir_lcomm, imm);
		
		BssIP += imm;

		Section = LastSect;

		return 1;
	}

//---------------------------------------------------------

	case dir_align:
	{
		imm = GetExpression();					// Get the number

		if (Section == SECT_code)
			return 1;

		AddAlignRef(imm);
		return 1;
	}


//---------------------------------------------------------

	case dir_bss:
	{
		Section = SECT_bss;

		if (LIST)
			printf("** Section .bss IP = %x\n",BssIP);

		return 1;
	}

//---------------------------------------------------------

	case dir_data:
	{
		Section = SECT_data;

		if (LIST)
			printf("** Section .data IP = %x\n",DataIP);

		return 1;
	}

//---------------------------------------------------------

	case dir_code:
//	if (QToken(".code") || QToken(".text"))
	{
		Section = SECT_code;

		if (LIST)
			printf("** Section .code IP = %x\n",CodeIP);

		return 1;
	}

//---------------------------------------------------------

	case dir_ent:
	{
		SkipLine();
		return 1;
	}


//---------------------------------------------------------

	case dir_end:
		return 1;

//---------------------------------------------------------

	case dir_stabs:
	{
		Parse_stabs();
		//SkipLine();
		return 1;
	}

//---------------------------------------------------------

	case dir_stabn:
	{
		Parse_stabn();
		//SkipLine();
		return 1;
	}

//---------------------------------------------------------

	case dir_stabd:
	{
		SkipLine();
		return 1;
	}

//---------------------------------------------------------

	}		// End of switch

	return 0;
}
예제 #3
0
/* ParseStatement - parse a statement */
void ParseStatement(ParseContext *c, Token tkn)
{
    /* dispatch on the statement keyword */
    switch (tkn) {
    case T_REM:
        /* just a comment so ignore the rest of the line */
        break;
    case T_DEF:
        ParseDef(c);
        break;
    case T_END_DEF:
        ParseEndDef(c);
        break;
    case T_DIM:
        ParseDim(c);
        break;
    case T_LET:
        ParseLet(c);
        break;
    case T_IF:
        ParseIf(c);
        break;
    case T_ELSE:
        ParseElse(c);
        break;
    case T_ELSE_IF:
        ParseElseIf(c);
        break;
    case T_END_IF:
        ParseEndIf(c);
        break;
    case T_END:
        ParseEnd(c);
        break;
    case T_FOR:
        ParseFor(c);
        break;
    case T_NEXT:
        ParseNext(c);
        break;
    case T_DO:
        ParseDo(c);
        break;
    case T_DO_WHILE:
        ParseDoWhile(c);
        break;
    case T_DO_UNTIL:
        ParseDoUntil(c);
        break;
    case T_LOOP:
        ParseLoop(c);
        break;
    case T_LOOP_WHILE:
        ParseLoopWhile(c);
        break;
    case T_LOOP_UNTIL:
        ParseLoopUntil(c);
        break;
    case T_STOP:
        ParseStop(c);
        break;
    case T_GOTO:
        ParseGoto(c);
        break;
    case T_RETURN:
        ParseReturn(c);
        break;
    case T_PRINT:
        ParsePrint(c);
        break;
    case T_IDENTIFIER:
        if (SkipSpaces(c) == ':') {
            DefineLabel(c, c->token, codeaddr(c));
            break;
        }
        UngetC(c);
    default:
        SaveToken(c, tkn);
        ParseImpliedLetOrFunctionCall(c);
        break;
    }
}