1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-24 11:31:31 +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 }, { "decax7", REG_AX, REG_AX },
{ "decax8", REG_AX, REG_AX }, { "decax8", REG_AX, REG_AX },
{ "decaxy", REG_AXY, REG_AX }, { "decaxy", REG_AXY, REG_AX },
{ "decsp2", REG_NONE, REG_A }, { "decsp1", REG_NONE, REG_Y },
{ "decsp3", REG_NONE, REG_A }, { "decsp2", REG_NONE, REG_A },
{ "decsp4", REG_NONE, REG_A }, { "decsp3", REG_NONE, REG_A },
{ "decsp5", REG_NONE, REG_A }, { "decsp4", REG_NONE, REG_A },
{ "decsp6", REG_NONE, REG_A }, { "decsp5", REG_NONE, REG_A },
{ "decsp7", REG_NONE, REG_A }, { "decsp6", REG_NONE, REG_A },
{ "decsp8", REG_NONE, REG_A }, { "decsp7", REG_NONE, REG_A },
{ "decsp8", REG_NONE, REG_A },
{ "incsp1", REG_NONE, REG_NONE }, { "incsp1", REG_NONE, REG_NONE },
{ "incsp2", REG_NONE, REG_Y }, { "incsp2", REG_NONE, REG_Y },
{ "incsp3", REG_NONE, REG_Y }, { "incsp3", REG_NONE, REG_Y },
{ "incsp4", REG_NONE, REG_Y }, { "incsp4", REG_NONE, REG_Y },
{ "incsp5", REG_NONE, REG_Y }, { "incsp5", REG_NONE, REG_Y },
{ "incsp6", REG_NONE, REG_Y }, { "incsp6", REG_NONE, REG_Y },
{ "incsp7", REG_NONE, REG_Y }, { "incsp7", REG_NONE, REG_Y },
{ "incsp8", REG_NONE, REG_Y }, { "incsp8", REG_NONE, REG_Y },
{ "ldaui", REG_AX, REG_AXY },
{ "ldauidx", REG_AXY, REG_AX },
{ "ldax0sp", REG_Y, REG_AX }, { "ldax0sp", REG_Y, REG_AX },
{ "ldaxi", REG_AX, REG_AXY },
{ "ldaxidx", REG_AXY, REG_AX },
{ "ldaxysp", REG_Y, REG_AX }, { "ldaxysp", REG_Y, REG_AX },
{ "leaasp", REG_A, REG_AX },
{ "pusha", REG_A, REG_Y }, { "pusha", REG_A, REG_Y },
{ "pusha0", REG_A, REG_XY }, { "pusha0", REG_A, REG_XY },
{ "pushax", REG_AX, REG_Y }, { "pushax", REG_AX, REG_Y },
@ -157,10 +163,10 @@ void GetFuncInfo (const char* Name, unsigned char* Use, unsigned char* Chg)
if (Name[0] == '_') { if (Name[0] == '_') {
/* Search in the symbol table, skip the leading underscore */ /* 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? */ /* 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 /* 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, * function. If it is not a fastcall function but a variadic one,

View File

@ -588,38 +588,32 @@ unsigned OptUnusedLoads (CodeSeg* S)
/* Remove loads of registers where the value loaded is not used later. */ /* Remove loads of registers where the value loaded is not used later. */
{ {
unsigned Changes = 0; 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 */ /* Walk over the entries */
I = 0; unsigned I = 0;
while (I < Count-1) { while (I < GetCodeEntryCount (S)) {
CodeEntry* N;
/* Get next entry */ /* Get next entry */
CodeEntry* E = GetCodeEntry (S, I); CodeEntry* E = GetCodeEntry (S, I);
/* Check if it's a register load */ /* Check if it's a register load or transfer insn */
if ((E->Info & OF_LOAD) != 0) { if ((E->Info & (OF_LOAD | OF_XFR)) != 0 &&
(N = GetNextCodeEntry (S, I)) != 0 &&
(N->Info & OF_FBRA) == 0) {
unsigned char R; /* Check which sort of load or transfer it is */
unsigned 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 */
switch (E->OPC) { switch (E->OPC) {
case OPC_TXA:
case OPC_TYA:
case OPC_LDA: R = REG_A; break; case OPC_LDA: R = REG_A; break;
case OPC_TAX:
case OPC_LDX: R = REG_X; break; case OPC_LDX: R = REG_X; break;
case OPC_TAY:
case OPC_LDY: R = REG_Y; break; 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 */ /* 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 */ /* Register value is not used, remove the load */
DelCodeEntry (S, I); DelCodeEntry (S, I);
--Count;
/* Remember, we had changes */ /* Remember, we had changes */
++Changes; ++Changes;

View File

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

View File

@ -165,6 +165,7 @@ typedef enum {
#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_RET 0x0020U /* Return from function */
#define OF_LOAD 0x0040U /* Register load */ #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_BRA (OF_UBRA|OF_CBRA) /* Operation is a jump/branch */
#define OF_DEAD (OF_UBRA|OF_RET) /* Dead end - no exec behind this point */ #define OF_DEAD (OF_UBRA|OF_RET) /* Dead end - no exec behind this point */

View File

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