From 12ec031f9abbe662764da054fdf28be816752bcf Mon Sep 17 00:00:00 2001 From: cuz Date: Tue, 22 May 2001 13:58:56 +0000 Subject: [PATCH] Polishing and minor corrections git-svn-id: svn://svn.cc65.org/cc65/trunk@741 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/cc65/codeinfo.c | 40 ++++++----- src/cc65/coptind.c | 37 ++++------ src/cc65/opcodes.c | 12 ++-- src/cc65/opcodes.h | 3 +- src/cc65/stmt.c | 166 ++++++++++++++++++++++++++------------------ src/cc65/symtab.c | 8 +++ src/cc65/symtab.h | 3 + 7 files changed, 154 insertions(+), 115 deletions(-) diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index 028c82b9e..162864422 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -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). diff --git a/src/cc65/coptind.c b/src/cc65/coptind.c index 035a4852e..c8f52e429 100644 --- a/src/cc65/coptind.c +++ b/src/cc65/coptind.c @@ -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) { - - 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 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) { - /* 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; diff --git a/src/cc65/opcodes.c b/src/cc65/opcodes.c index 95eb5cdae..abd2f01e8 100644 --- a/src/cc65/opcodes.c +++ b/src/cc65/opcodes.c @@ -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 }, }; diff --git a/src/cc65/opcodes.h b/src/cc65/opcodes.h index 20c8eece8..41c117dce 100644 --- a/src/cc65/opcodes.h +++ b/src/cc65/opcodes.h @@ -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 */ diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 7260dd1f7..866c859d9 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -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); - - /* 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); - } - } else { + /* Parse the loop body */ + Statement (); - /* Do loop */ - Statement (); - Consume (TOK_WHILE, "`while' expected"); - test (loop, 1); - ConsumeSemi (); - 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 { + /* 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 (); } diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 5431cf0dc..6f01b1094 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -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 */ { diff --git a/src/cc65/symtab.h b/src/cc65/symtab.h index 9627224cd..317d8f8b8 100644 --- a/src/cc65/symtab.h +++ b/src/cc65/symtab.h @@ -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 */ -- 2.39.5