X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fcodeent.c;h=8c73081b6705f6416fbf1d0a42f9dcf0646b9cf8;hb=6b3e515573e5165aefaff9e59ac42f3567e6ab25;hp=233080712a6d795e0554d671c95b740e9a20d60c;hpb=3ac1a08baf4ecdaa85cb5d2aa8e14ec0697852c8;p=cc65 diff --git a/src/cc65/codeent.c b/src/cc65/codeent.c index 233080712..8c73081b6 100644 --- a/src/cc65/codeent.c +++ b/src/cc65/codeent.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2001-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ +/* (C) 2001-2009, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -34,7 +34,6 @@ #include -#include /* common */ #include "chartype.h" @@ -44,12 +43,13 @@ #include "xsprintf.h" /* cc65 */ +#include "codeent.h" #include "codeinfo.h" #include "error.h" #include "global.h" #include "codelab.h" #include "opcodes.h" -#include "codeent.h" +#include "output.h" @@ -144,7 +144,7 @@ static void SetUseChgInfo (CodeEntry* E, const OPCDesc* D) * lookup the information about this function and use it. The jump itself * does not change any registers, so we don't need to use the data from D. */ - if ((E->Info & (OF_BRA | OF_CALL)) != 0 && E->JumpTo == 0) { + if ((E->Info & (OF_UBRA | OF_CALL)) != 0 && E->JumpTo == 0) { /* A subroutine call or jump to external symbol (function exit) */ GetFuncInfo (E->Arg, &E->Use, &E->Chg); } else { @@ -394,14 +394,26 @@ void CE_SetNumArg (CodeEntry* E, long Num) -int CE_KnownImm (const CodeEntry* E) -/* Return true if the argument of E is a known immediate value */ +int CE_IsConstImm (const CodeEntry* E) +/* Return true if the argument of E is a constant immediate value */ { return (E->AM == AM65_IMM && (E->Flags & CEF_NUMARG) != 0); } +int CE_IsKnownImm (const CodeEntry* E, unsigned long Num) +/* Return true if the argument of E is a constant immediate value that is + * equal to Num. + */ +{ + return E->AM == AM65_IMM && + (E->Flags & CEF_NUMARG) != 0 && + E->Num == Num; +} + + + int CE_UseLoadFlags (const CodeEntry* E) /* Return true if the instruction uses any flags that are set by a load of * a register (N and Z). @@ -519,33 +531,36 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) case OP65_AND: if (RegValIsKnown (In->RegA)) { - if (CE_KnownImm (E)) { - Out->RegA = In->RegA & (short) E->Num; - } else if (E->AM == AM65_ZP) { - switch (GetKnownReg (E->Use & REG_ZP, In)) { - case REG_TMP1: - Out->RegA = In->RegA & In->Tmp1; - break; - case REG_PTR1_LO: - Out->RegA = In->RegA & In->Ptr1Lo; - break; - case REG_PTR1_HI: - Out->RegA = In->RegA & In->Ptr1Hi; - break; - case REG_SREG_LO: - Out->RegA = In->RegA & In->SRegLo; - break; - case REG_SREG_HI: - Out->RegA = In->RegA & In->SRegHi; - break; - default: - Out->RegA = UNKNOWN_REGVAL; - break; - } - } else { - Out->RegA = UNKNOWN_REGVAL; - } - } + if (CE_IsConstImm (E)) { + Out->RegA = In->RegA & (short) E->Num; + } else if (E->AM == AM65_ZP) { + switch (GetKnownReg (E->Use & REG_ZP, In)) { + case REG_TMP1: + Out->RegA = In->RegA & In->Tmp1; + break; + case REG_PTR1_LO: + Out->RegA = In->RegA & In->Ptr1Lo; + break; + case REG_PTR1_HI: + Out->RegA = In->RegA & In->Ptr1Hi; + break; + case REG_SREG_LO: + Out->RegA = In->RegA & In->SRegLo; + break; + case REG_SREG_HI: + Out->RegA = In->RegA & In->SRegHi; + break; + default: + Out->RegA = UNKNOWN_REGVAL; + break; + } + } else { + Out->RegA = UNKNOWN_REGVAL; + } + } else if (CE_IsKnownImm (E, 0)) { + /* A and $00 does always give zero */ + Out->RegA = 0; + } break; case OP65_ASL: @@ -651,7 +666,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) break; case REG_SREG_LO: Out->SRegLo = (In->SRegLo - 1) & 0xFF; - break; + break; case REG_SREG_HI: Out->SRegHi = (In->SRegHi - 1) & 0xFF; break; @@ -676,7 +691,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) case OP65_EOR: if (RegValIsKnown (In->RegA)) { - if (CE_KnownImm (E)) { + if (CE_IsConstImm (E)) { Out->RegA = In->RegA ^ (short) E->Num; } else if (E->AM == AM65_ZP) { switch (GetKnownReg (E->Use & REG_ZP, In)) { @@ -810,7 +825,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) if (In->RegA == 0xFF) { Out->RegA = 0xFF; } - if (In->RegX == 0xFF) { + if (In->RegX == 0xFF) { Out->RegX = 0xFF; } } else if (FindBoolCmpCond (E->Arg) != CMP_INV) { @@ -825,7 +840,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) break; case OP65_LDA: - if (CE_KnownImm (E)) { + if (CE_IsConstImm (E)) { Out->RegA = (unsigned char) E->Num; } else if (E->AM == AM65_ZP) { switch (GetKnownReg (E->Use & REG_ZP, In)) { @@ -855,7 +870,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) break; case OP65_LDX: - if (CE_KnownImm (E)) { + if (CE_IsConstImm (E)) { Out->RegX = (unsigned char) E->Num; } else if (E->AM == AM65_ZP) { switch (GetKnownReg (E->Use & REG_ZP, In)) { @@ -863,7 +878,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) Out->RegX = In->Tmp1; break; case REG_PTR1_LO: - Out->RegX = In->Ptr1Lo; + Out->RegX = In->Ptr1Lo; break; case REG_PTR1_HI: Out->RegX = In->Ptr1Hi; @@ -885,7 +900,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) break; case OP65_LDY: - if (CE_KnownImm (E)) { + if (CE_IsConstImm (E)) { Out->RegY = (unsigned char) E->Num; } else if (E->AM == AM65_ZP) { switch (GetKnownReg (E->Use & REG_ZP, In)) { @@ -916,7 +931,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) case OP65_LSR: if (E->AM == AM65_ACC && RegValIsKnown (In->RegA)) { - Out->RegA = (In->RegA >> 1) & 0xFF; + Out->RegA = (In->RegA >> 1) & 0xFF; } else if (E->AM == AM65_ZP) { switch (GetKnownReg (E->Chg & REG_ZP, In)) { case REG_TMP1: @@ -946,7 +961,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) case OP65_ORA: if (RegValIsKnown (In->RegA)) { - if (CE_KnownImm (E)) { + if (CE_IsConstImm (E)) { Out->RegA = In->RegA | (short) E->Num; } else if (E->AM == AM65_ZP) { switch (GetKnownReg (E->Use & REG_ZP, In)) { @@ -969,11 +984,14 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) Out->RegA = UNKNOWN_REGVAL; break; } - } else { - /* A is now unknown */ - Out->RegA = UNKNOWN_REGVAL; - } - } + } else { + /* A is now unknown */ + Out->RegA = UNKNOWN_REGVAL; + } + } else if (CE_IsKnownImm (E, 0xFF)) { + /* ORA with 0xFF does always give 0xFF */ + Out->RegA = 0xFF; + } break; case OP65_PHA: @@ -1022,7 +1040,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) Out->SRegLo = UNKNOWN_REGVAL; break; case REG_SREG_HI: - Out->SRegHi = UNKNOWN_REGVAL; + Out->SRegHi = UNKNOWN_REGVAL; break; } } else if (E->AM == AM65_ZPX) { @@ -1350,82 +1368,83 @@ static char* RegContentDesc (const RegContents* RC, char* Buf) -void CE_Output (const CodeEntry* E, FILE* F) -/* Output the code entry to a file */ +void CE_Output (const CodeEntry* E) +/* Output the code entry to the output file */ { const OPCDesc* D; unsigned Chars; + int Space; const char* Target; /* If we have a label, print that */ unsigned LabelCount = CollCount (&E->Labels); unsigned I; for (I = 0; I < LabelCount; ++I) { - CL_Output (CollConstAt (&E->Labels, I), F); + CL_Output (CollConstAt (&E->Labels, I)); } /* Get the opcode description */ D = GetOPCDesc (E->OPC); /* Print the mnemonic */ - Chars = fprintf (F, "\t%s", D->Mnemo); + Chars = WriteOutput ("\t%s", D->Mnemo); + + /* Space to leave before the operand */ + Space = 9 - Chars; /* Print the operand */ switch (E->AM) { - case AM_IMP: case AM65_IMP: /* implicit */ break; case AM65_ACC: /* accumulator */ - Chars += fprintf (F, "%*sa", 9-Chars, ""); + Chars += WriteOutput ("%*sa", Space, ""); break; - case AM_IMM: case AM65_IMM: /* immidiate */ - Chars += fprintf (F, "%*s#%s", 9-Chars, "", E->Arg); + Chars += WriteOutput ("%*s#%s", Space, "", E->Arg); break; - case AM_ABS: case AM65_ZP: case AM65_ABS: /* zeropage and absolute */ - Chars += fprintf (F, "%*s%s", 9-Chars, "", E->Arg); + Chars += WriteOutput ("%*s%s", Space, "", E->Arg); break; case AM65_ZPX: case AM65_ABSX: /* zeropage,X and absolute,X */ - Chars += fprintf (F, "%*s%s,x", 9-Chars, "", E->Arg); + Chars += WriteOutput ("%*s%s,x", Space, "", E->Arg); break; case AM65_ABSY: /* absolute,Y */ - Chars += fprintf (F, "%*s%s,y", 9-Chars, "", E->Arg); + Chars += WriteOutput ("%*s%s,y", Space, "", E->Arg); break; case AM65_ZPX_IND: /* (zeropage,x) */ - Chars += fprintf (F, "%*s(%s,x)", 9-Chars, "", E->Arg); + Chars += WriteOutput ("%*s(%s,x)", Space, "", E->Arg); break; case AM65_ZP_INDY: /* (zeropage),y */ - Chars += fprintf (F, "%*s(%s),y", 9-Chars, "", E->Arg); + Chars += WriteOutput ("%*s(%s),y", Space, "", E->Arg); break; case AM65_ZP_IND: /* (zeropage) */ - Chars += fprintf (F, "%*s(%s)", 9-Chars, "", E->Arg); + Chars += WriteOutput ("%*s(%s)", Space, "", E->Arg); break; case AM65_BRA: /* branch */ Target = E->JumpTo? E->JumpTo->Name : E->Arg; - Chars += fprintf (F, "%*s%s", 9-Chars, "", Target); + Chars += WriteOutput ("%*s%s", Space, "", Target); break; default: @@ -1434,28 +1453,26 @@ void CE_Output (const CodeEntry* E, FILE* F) } /* Print usage info if requested by the debugging flag */ - if (Debug) { + if (Debug) { char Use [128]; char Chg [128]; - fprintf (F, - "%*s; USE: %-12s CHG: %-12s SIZE: %u", - 30-Chars, "", - RegInfoDesc (E->Use, Use), - RegInfoDesc (E->Chg, Chg), - E->Size); + WriteOutput ("%*s; USE: %-12s CHG: %-12s SIZE: %u", + (int)(30-Chars), "", + RegInfoDesc (E->Use, Use), + RegInfoDesc (E->Chg, Chg), + E->Size); if (E->RI) { char RegIn[32]; char RegOut[32]; - fprintf (F, - " In %s Out %s", - RegContentDesc (&E->RI->In, RegIn), - RegContentDesc (&E->RI->Out, RegOut)); + WriteOutput (" In %s Out %s", + RegContentDesc (&E->RI->In, RegIn), + RegContentDesc (&E->RI->Out, RegOut)); } } /* Terminate the line */ - fprintf (F, "\n"); + WriteOutput ("\n"); }