1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-23 19:29:37 +00:00

Polishing and minor corrections

git-svn-id: svn://svn.cc65.org/cc65/trunk@741 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2001-05-22 13:58:56 +00:00
parent 0e80187cec
commit 12ec031f9a
7 changed files with 153 additions and 114 deletions

View File

@ -86,23 +86,29 @@ static const FuncInfo FuncInfoTable[] = {
{ "decax7", REG_AX, REG_AX },
{ "decax8", REG_AX, REG_AX },
{ "decaxy", REG_AXY, REG_AX },
{ "decsp2", REG_NONE, REG_A },
{ "decsp3", REG_NONE, REG_A },
{ "decsp4", REG_NONE, REG_A },
{ "decsp5", REG_NONE, REG_A },
{ "decsp6", REG_NONE, REG_A },
{ "decsp7", REG_NONE, REG_A },
{ "decsp8", REG_NONE, REG_A },
{ "decsp1", REG_NONE, REG_Y },
{ "decsp2", REG_NONE, REG_A },
{ "decsp3", REG_NONE, REG_A },
{ "decsp4", REG_NONE, REG_A },
{ "decsp5", REG_NONE, REG_A },
{ "decsp6", REG_NONE, REG_A },
{ "decsp7", REG_NONE, REG_A },
{ "decsp8", REG_NONE, REG_A },
{ "incsp1", REG_NONE, REG_NONE },
{ "incsp2", REG_NONE, REG_Y },
{ "incsp3", REG_NONE, REG_Y },
{ "incsp4", REG_NONE, REG_Y },
{ "incsp5", REG_NONE, REG_Y },
{ "incsp6", REG_NONE, REG_Y },
{ "incsp7", REG_NONE, REG_Y },
{ "incsp8", REG_NONE, REG_Y },
{ "incsp2", REG_NONE, REG_Y },
{ "incsp3", REG_NONE, REG_Y },
{ "incsp4", REG_NONE, REG_Y },
{ "incsp5", REG_NONE, REG_Y },
{ "incsp6", REG_NONE, REG_Y },
{ "incsp7", REG_NONE, REG_Y },
{ "incsp8", REG_NONE, REG_Y },
{ "ldaui", REG_AX, REG_AXY },
{ "ldauidx", REG_AXY, REG_AX },
{ "ldax0sp", REG_Y, REG_AX },
{ "ldaxi", REG_AX, REG_AXY },
{ "ldaxidx", REG_AXY, REG_AX },
{ "ldaxysp", REG_Y, REG_AX },
{ "leaasp", REG_A, REG_AX },
{ "pusha", REG_A, REG_Y },
{ "pusha0", REG_A, REG_XY },
{ "pushax", REG_AX, REG_Y },
@ -157,11 +163,11 @@ void GetFuncInfo (const char* Name, unsigned char* Use, unsigned char* Chg)
if (Name[0] == '_') {
/* Search in the symbol table, skip the leading underscore */
SymEntry* E = FindSym (Name+1);
SymEntry* E = FindGlobalSym (Name+1);
/* Did we find it in the top level table? */
if (E && E->Owner->PrevTab == 0 && IsTypeFunc (E->Type)) {
if (E && IsTypeFunc (E->Type)) {
/* A function may use the A or A/X registers if it is a fastcall
* function. If it is not a fastcall function but a variadic one,
* it will use the Y register (the parameter size is passed here).

View File

@ -588,38 +588,32 @@ unsigned OptUnusedLoads (CodeSeg* S)
/* Remove loads of registers where the value loaded is not used later. */
{
unsigned Changes = 0;
unsigned I;
/* Get the number of entries, bail out if we have not enough */
unsigned Count = GetCodeEntryCount (S);
if (Count < 2) {
return 0;
}
/* Walk over the entries */
I = 0;
while (I < Count-1) {
unsigned I = 0;
while (I < GetCodeEntryCount (S)) {
CodeEntry* N;
/* Get next entry */
CodeEntry* E = GetCodeEntry (S, I);
/* Check if it's a register load */
if ((E->Info & OF_LOAD) != 0) {
/* Check if it's a register load or transfer insn */
if ((E->Info & (OF_LOAD | OF_XFR)) != 0 &&
(N = GetNextCodeEntry (S, I)) != 0 &&
(N->Info & OF_FBRA) == 0) {
unsigned char R;
/* Get the next instruction, it must not be a conditional branch */
CodeEntry* N = GetCodeEntry (S, I+1);
if ((N->Info & OF_CBRA) != 0) {
goto NextEntry;
}
/* Check which sort of load it is */
/* Check which sort of load or transfer it is */
unsigned R;
switch (E->OPC) {
case OPC_TXA:
case OPC_TYA:
case OPC_LDA: R = REG_A; break;
case OPC_TAX:
case OPC_LDX: R = REG_X; break;
case OPC_TAY:
case OPC_LDY: R = REG_Y; break;
default: goto NextEntry; /* OOPS */
default: goto NextEntry; /* OOPS */
}
/* Get register usage and check if the register value is used later */
@ -627,7 +621,6 @@ unsigned OptUnusedLoads (CodeSeg* S)
/* Register value is not used, remove the load */
DelCodeEntry (S, I);
--Count;
/* Remember, we had changes */
++Changes;

View File

@ -121,14 +121,14 @@ const OPCDesc OPCTable[OPC_COUNT] = {
{ OPC_STA, "sta", 0, REG_A, REG_NONE, OF_NONE },
{ OPC_STX, "stx", 0, REG_X, REG_NONE, OF_NONE },
{ OPC_STY, "sty", 0, REG_Y, REG_NONE, OF_NONE },
{ OPC_TAX, "tax", 1, REG_A, REG_X, OF_NONE },
{ OPC_TAY, "tay", 1, REG_A, REG_Y, OF_NONE },
{ OPC_TAX, "tax", 1, REG_A, REG_X, OF_XFR },
{ OPC_TAY, "tay", 1, REG_A, REG_Y, OF_XFR },
{ OPC_TRB, "trb", 0, REG_A, REG_NONE, OF_NONE },
{ OPC_TSB, "tsb", 0, REG_A, REG_NONE, OF_NONE },
{ OPC_TSX, "tsx", 1, REG_NONE, REG_X, OF_NONE },
{ OPC_TXA, "txa", 1, REG_X, REG_A, OF_NONE },
{ OPC_TXS, "txs", 1, REG_X, REG_NONE, OF_NONE },
{ OPC_TYA, "tya", 1, REG_A, REG_A, OF_NONE },
{ OPC_TSX, "tsx", 1, REG_NONE, REG_X, OF_XFR },
{ OPC_TXA, "txa", 1, REG_X, REG_A, OF_XFR },
{ OPC_TXS, "txs", 1, REG_X, REG_NONE, OF_XFR },
{ OPC_TYA, "tya", 1, REG_A, REG_A, OF_XFR },
};

View File

@ -162,9 +162,10 @@ typedef enum {
#define OF_CBRA 0x0002U /* Conditional branch */
#define OF_ZBRA 0x0004U /* Branch on zero flag condition */
#define OF_FBRA 0x0008U /* Branch on cond set by a load */
#define OF_LBRA 0x0010U /* Jump/branch is long */
#define OF_LBRA 0x0010U /* Jump/branch is long */
#define OF_RET 0x0020U /* Return from function */
#define OF_LOAD 0x0040U /* Register load */
#define OF_XFR 0x0080 /* Transfer instruction */
#define OF_BRA (OF_UBRA|OF_CBRA) /* Operation is a jump/branch */
#define OF_DEAD (OF_UBRA|OF_RET) /* Dead end - no exec behind this point */

View File

@ -51,8 +51,8 @@
static int doif (void)
/* Handle 'if' statement here */
static int DoIf (void)
/* Handle an 'if' statement */
{
int flab1;
int flab2;
@ -108,57 +108,84 @@ static int doif (void)
static void dowhile (char wtype)
/* Handle 'while' statement here */
static void DoDo (void)
/* Handle the 'do' statement */
{
int loop;
int lab;
/* Get the loop control labels */
unsigned loop = GetLocalLabel ();
unsigned lab = GetLocalLabel ();
/* Skip the while token */
NextToken ();
loop = GetLocalLabel ();
lab = GetLocalLabel ();
/* Add the loop to the loop stack */
AddLoop (oursp, loop, lab, 0, 0);
/* Define the head label */
g_defcodelabel (loop);
if (wtype == 'w') {
/* While loop */
test (lab, 0);
/* Parse the loop body */
Statement ();
/* If the statement following the while loop is empty, that is, we have
* something like "while (1) ;", the test function ommitted the jump as
* an optimization. Since we know, the condition codes are set, we can
* do another small optimization here, and use a conditional jump
* instead an absolute one.
*/
if (CurTok.Tok == TOK_SEMI) {
/* Shortcut */
NextToken ();
/* Use a conditional jump */
g_truejump (CF_NONE, loop);
} else {
/* There is code inside the while loop */
Statement ();
g_jump (loop);
g_defcodelabel (lab);
}
/* Parse the end condition */
Consume (TOK_WHILE, "`while' expected");
test (loop, 1);
ConsumeSemi ();
/* Define the break label */
g_defcodelabel (lab);
/* Remove the loop from the loop stack */
DelLoop ();
}
static void DoWhile (void)
/* Handle the 'while' statement */
{
/* Get the loop control labels */
unsigned loop = GetLocalLabel ();
unsigned lab = GetLocalLabel ();
/* Skip the while token */
NextToken ();
/* Add the loop to the loop stack */
AddLoop (oursp, loop, lab, 0, 0);
/* Define the head label */
g_defcodelabel (loop);
/* Test the loop condition */
test (lab, 0);
/* If the statement following the while loop is empty, that is, we have
* something like "while (1) ;", the test function ommitted the jump as
* an optimization. Since we know, the condition codes are set, we can
* do another small optimization here, and use a conditional jump
* instead an absolute one.
*/
if (CurTok.Tok == TOK_SEMI) {
/* Use a conditional jump */
g_truejump (CF_NONE, loop);
/* Shortcut */
NextToken ();
} else {
/* Do loop */
Statement ();
Consume (TOK_WHILE, "`while' expected");
test (loop, 1);
ConsumeSemi ();
g_defcodelabel (lab);
/* There is code inside the while loop, parse the body */
Statement ();
g_jump (loop);
g_defcodelabel (lab);
}
/* Remove the loop from the loop stack */
DelLoop ();
}
static void DoReturn (void)
/* Handle 'return' statement here */
/* Handle the 'return' statement */
{
struct expent lval;
@ -188,8 +215,8 @@ static void DoReturn (void)
static void dobreak (void)
/* Handle 'break' statement here */
static void DoBreak (void)
/* Handle the 'break' statement */
{
LoopDesc* L;
@ -215,8 +242,8 @@ static void dobreak (void)
static void docontinue (void)
/* Handle 'continue' statement here */
static void DoContinue (void)
/* Handle the 'continue' statement */
{
LoopDesc* L;
@ -254,7 +281,7 @@ static void docontinue (void)
static void cascadeswitch (struct expent* eval)
static void CascadeSwitch (struct expent* eval)
/* Handle a switch statement for chars with a cmp cascade for the selector */
{
unsigned ExitLab; /* Exit label */
@ -339,9 +366,9 @@ static void cascadeswitch (struct expent* eval)
if (Val < -32768 || Val > 32767) {
Error ("Range error");
}
break;
break;
case T_UINT:
case T_UINT:
if (Val < 0 || Val > 65535) {
Error ("Range error");
}
@ -382,9 +409,9 @@ static void cascadeswitch (struct expent* eval)
/* Handle the pathologic case: DEFAULT followed by CASE */
if (CurTok.Tok == TOK_CASE) {
if (CodeLab == 0) {
CodeLab = GetLocalLabel ();
CodeLab = GetLocalLabel ();
}
g_jump (CodeLab);
g_jump (CodeLab);
}
/* Skip the colon */
@ -432,7 +459,7 @@ static void cascadeswitch (struct expent* eval)
static void tableswitch (struct expent* eval)
static void TableSwitch (struct expent* eval)
/* Handle a switch statement via table based selector */
{
/* Entry for one case in a switch statement */
@ -542,10 +569,10 @@ static void tableswitch (struct expent* eval)
static void doswitch (void)
/* Handle 'switch' statement here */
static void DoSwitch (void)
/* Handle a 'switch' statement */
{
struct expent eval; /* Switch statement expression */
struct expent eval; /* Switch statement expression */
/* Eat the "switch" */
NextToken ();
@ -560,16 +587,16 @@ static void doswitch (void)
/* Now decide which sort of switch we will create: */
if (IsTypeChar (eval.e_tptr) || (CodeSizeFactor >= 200 && IsClassInt (eval.e_tptr))) {
cascadeswitch (&eval);
CascadeSwitch (&eval);
} else {
tableswitch (&eval);
TableSwitch (&eval);
}
}
static void dofor (void)
/* Handle 'for' statement here */
static void DoFor (void)
/* Handle a 'for' statement */
{
int loop;
int lab;
@ -685,37 +712,37 @@ int Statement (void)
return CompoundStatement ();
case TOK_IF:
return doif ();
return DoIf ();
case TOK_WHILE:
dowhile ('w');
break;
DoWhile ();
break;
case TOK_DO:
dowhile ('d');
break;
DoDo ();
break;
case TOK_SWITCH:
doswitch ();
break;
DoSwitch ();
break;
case TOK_RETURN:
DoReturn ();
ConsumeSemi ();
return 1;
DoReturn ();
ConsumeSemi ();
return 1;
case TOK_BREAK:
dobreak ();
DoBreak ();
ConsumeSemi ();
return 1;
case TOK_CONTINUE:
docontinue ();
DoContinue ();
ConsumeSemi ();
return 1;
case TOK_FOR:
dofor ();
DoFor ();
break;
case TOK_GOTO:
@ -724,7 +751,7 @@ int Statement (void)
return 1;
case TOK_SEMI:
/* ignore it. */
/* Ignore it */
NextToken ();
break;
@ -733,6 +760,7 @@ int Statement (void)
break;
default:
/* Actual statement */
expression (&lval);
ConsumeSemi ();
}

View File

@ -441,6 +441,14 @@ SymEntry* FindSym (const char* Name)
SymEntry* FindGlobalSym (const char* Name)
/* Find the symbol with the given name in the global symbol table only */
{
return FindSymInTable (SymTab0, Name, HashStr (Name));
}
SymEntry* FindLocalSym (const char* Name)
/* Find the symbol with the given name in the current symbol table only */
{

View File

@ -117,6 +117,9 @@ void LeaveStructLevel (void);
SymEntry* FindSym (const char* Name);
/* Find the symbol with the given name */
SymEntry* FindGlobalSym (const char* Name);
/* Find the symbol with the given name in the global symbol table only */
SymEntry* FindLocalSym (const char* Name);
/* Find the symbol with the given name in the current symbol table only */