mirror of
https://github.com/cc65/cc65.git
synced 2025-01-10 19:29:45 +00:00
Fixed a code generation bug
git-svn-id: svn://svn.cc65.org/cc65/trunk@1215 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
ad1951c068
commit
c6fe12ef6b
@ -224,7 +224,7 @@ const char* MakeHexArg (unsigned Num)
|
|||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
static char Buf[16];
|
static char Buf[16];
|
||||||
xsprintf (Buf, sizeof (Buf), "$%02X", (char) Num);
|
xsprintf (Buf, sizeof (Buf), "$%02X", (unsigned char) Num);
|
||||||
return Buf;
|
return Buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,6 +376,46 @@ int CE_KnownImm (const CodeEntry* E)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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).
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
/* A branch will use the flags */
|
||||||
|
if (E->Info & OF_FBRA) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call of a boolean transformer routine will also use the flags */
|
||||||
|
if (E->OPC == OP65_JSR) {
|
||||||
|
/* Get the condition that is evaluated and check it */
|
||||||
|
switch (FindBoolCmpCond (E->Arg)) {
|
||||||
|
case CMP_EQ:
|
||||||
|
case CMP_NE:
|
||||||
|
case CMP_GT:
|
||||||
|
case CMP_GE:
|
||||||
|
case CMP_LT:
|
||||||
|
case CMP_LE:
|
||||||
|
case CMP_UGT:
|
||||||
|
case CMP_ULE:
|
||||||
|
case CMP_INV:
|
||||||
|
/* Will use the N or Z flags */
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
|
||||||
|
case CMP_UGE: /* Uses only carry */
|
||||||
|
case CMP_ULT: /* Dito */
|
||||||
|
default: /* No bool transformer subroutine */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Anything else */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void CE_FreeRegInfo (CodeEntry* E)
|
void CE_FreeRegInfo (CodeEntry* E)
|
||||||
/* Free an existing register info struct */
|
/* Free an existing register info struct */
|
||||||
{
|
{
|
||||||
|
@ -196,6 +196,11 @@ INLINE int CE_IsCall (const CodeEntry* E, const char* Name)
|
|||||||
# define CE_IsCall(E, Name) ((E)->OPC == OP65_JSR && strcmp ((E)->Arg, (Name)) == 0)
|
# define CE_IsCall(E, Name) ((E)->OPC == OP65_JSR && strcmp ((E)->Arg, (Name)) == 0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
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).
|
||||||
|
*/
|
||||||
|
|
||||||
void CE_FreeRegInfo (CodeEntry* E);
|
void CE_FreeRegInfo (CodeEntry* E);
|
||||||
/* Free an existing register info struct */
|
/* Free an existing register info struct */
|
||||||
|
|
||||||
|
@ -56,6 +56,11 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Table with the compare suffixes */
|
||||||
|
static const char CmpSuffixTab [][4] = {
|
||||||
|
"eq", "ne", "gt", "ge", "lt", "le", "ugt", "uge", "ult", "ule"
|
||||||
|
};
|
||||||
|
|
||||||
/* Table listing the function names and code info values for known internally
|
/* Table listing the function names and code info values for known internally
|
||||||
* used functions. This table should get auto-generated in the future.
|
* used functions. This table should get auto-generated in the future.
|
||||||
*/
|
*/
|
||||||
@ -584,3 +589,59 @@ unsigned GetKnownReg (unsigned Use, const RegContents* RC)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static cmp_t FindCmpCond (const char* Code, unsigned CodeLen)
|
||||||
|
/* Search for a compare condition by the given code using the given length */
|
||||||
|
{
|
||||||
|
unsigned I;
|
||||||
|
|
||||||
|
/* Linear search */
|
||||||
|
for (I = 0; I < sizeof (CmpSuffixTab) / sizeof (CmpSuffixTab [0]); ++I) {
|
||||||
|
if (strncmp (Code, CmpSuffixTab [I], CodeLen) == 0) {
|
||||||
|
/* Found */
|
||||||
|
return I;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Not found */
|
||||||
|
return CMP_INV;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cmp_t FindBoolCmpCond (const char* Name)
|
||||||
|
/* Check if the given string is the name of one of the boolean transformer
|
||||||
|
* subroutine, and if so, return the condition that is evaluated by this
|
||||||
|
* routine. Return CMP_INV if the condition is not recognised.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
/* Check for the correct subroutine name */
|
||||||
|
if (strncmp (Name, "bool", 4) == 0) {
|
||||||
|
/* Name is ok, search for the code in the table */
|
||||||
|
return FindCmpCond (Name+4, strlen(Name)-4);
|
||||||
|
} else {
|
||||||
|
/* Not found */
|
||||||
|
return CMP_INV;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cmp_t FindTosCmpCond (const char* Name)
|
||||||
|
/* Check if this is a call to one of the TOS compare functions (tosgtax).
|
||||||
|
* Return the condition code or CMP_INV on failure.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
unsigned Len = strlen (Name);
|
||||||
|
|
||||||
|
/* Check for the correct subroutine name */
|
||||||
|
if (strncmp (Name, "tos", 3) == 0 && strcmp (Name+Len-2, "ax") == 0) {
|
||||||
|
/* Name is ok, search for the code in the table */
|
||||||
|
return FindCmpCond (Name+3, Len-3-2);
|
||||||
|
} else {
|
||||||
|
/* Not found */
|
||||||
|
return CMP_INV;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -103,6 +103,23 @@ struct ZPInfo {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Defines for the conditions in a compare */
|
||||||
|
typedef enum {
|
||||||
|
CMP_INV = -1,
|
||||||
|
CMP_EQ,
|
||||||
|
CMP_NE,
|
||||||
|
CMP_GT,
|
||||||
|
CMP_GE,
|
||||||
|
CMP_LT,
|
||||||
|
CMP_LE,
|
||||||
|
CMP_UGT,
|
||||||
|
CMP_UGE,
|
||||||
|
CMP_ULT,
|
||||||
|
CMP_ULE
|
||||||
|
} cmp_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -143,6 +160,17 @@ unsigned GetKnownReg (unsigned Use, const struct RegContents* RC);
|
|||||||
* register in question does not have a known value, return REG_NONE.
|
* register in question does not have a known value, return REG_NONE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
cmp_t FindBoolCmpCond (const char* Name);
|
||||||
|
/* Check if the given string is the name of one of the boolean transformer
|
||||||
|
* subroutine, and if so, return the condition that is evaluated by this
|
||||||
|
* routine. Return CMP_INV if the condition is not recognised.
|
||||||
|
*/
|
||||||
|
|
||||||
|
cmp_t FindTosCmpCond (const char* Name);
|
||||||
|
/* Check if this is a call to one of the TOS compare functions (tosgtax).
|
||||||
|
* Return the condition code or CMP_INV on failure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* End of codeinfo.h */
|
/* End of codeinfo.h */
|
||||||
|
@ -49,26 +49,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Defines for the conditions in a compare */
|
|
||||||
typedef enum {
|
|
||||||
CMP_INV = -1,
|
|
||||||
CMP_EQ,
|
|
||||||
CMP_NE,
|
|
||||||
CMP_GT,
|
|
||||||
CMP_GE,
|
|
||||||
CMP_LT,
|
|
||||||
CMP_LE,
|
|
||||||
CMP_UGT,
|
|
||||||
CMP_UGE,
|
|
||||||
CMP_ULT,
|
|
||||||
CMP_ULE
|
|
||||||
} cmp_t;
|
|
||||||
|
|
||||||
/* Table with the compare suffixes */
|
|
||||||
static const char CmpSuffixTab [][4] = {
|
|
||||||
"eq", "ne", "gt", "ge", "lt", "le", "ugt", "uge", "ult", "ule"
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Table used to invert a condition, indexed by condition */
|
/* Table used to invert a condition, indexed by condition */
|
||||||
static const unsigned char CmpInvertTab [] = {
|
static const unsigned char CmpInvertTab [] = {
|
||||||
CMP_NE, CMP_EQ,
|
CMP_NE, CMP_EQ,
|
||||||
@ -89,59 +69,6 @@ static const char CmpSignedTab [] = {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static cmp_t FindCmpCond (const char* Code, unsigned CodeLen)
|
|
||||||
/* Search for a compare condition by the given code using the given length */
|
|
||||||
{
|
|
||||||
unsigned I;
|
|
||||||
|
|
||||||
/* Linear search */
|
|
||||||
for (I = 0; I < sizeof (CmpSuffixTab) / sizeof (CmpSuffixTab [0]); ++I) {
|
|
||||||
if (strncmp (Code, CmpSuffixTab [I], CodeLen) == 0) {
|
|
||||||
/* Found */
|
|
||||||
return I;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Not found */
|
|
||||||
return CMP_INV;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static cmp_t FindBoolCmpCond (const char* Name)
|
|
||||||
/* Map a condition suffix to a code. Return the code or CMP_INV on failure */
|
|
||||||
{
|
|
||||||
/* Check for the correct subroutine name */
|
|
||||||
if (strncmp (Name, "bool", 4) == 0) {
|
|
||||||
/* Name is ok, search for the code in the table */
|
|
||||||
return FindCmpCond (Name+4, strlen(Name)-4);
|
|
||||||
} else {
|
|
||||||
/* Not found */
|
|
||||||
return CMP_INV;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static cmp_t FindTosCmpCond (const char* Name)
|
|
||||||
/* Check if this is a call to one of the TOS compare functions (tosgtax).
|
|
||||||
* Return the condition code or CMP_INV on failure.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
unsigned Len = strlen (Name);
|
|
||||||
|
|
||||||
/* Check for the correct subroutine name */
|
|
||||||
if (strncmp (Name, "tos", 3) == 0 && strcmp (Name+Len-2, "ax") == 0) {
|
|
||||||
/* Name is ok, search for the code in the table */
|
|
||||||
return FindCmpCond (Name+3, Len-3-2);
|
|
||||||
} else {
|
|
||||||
/* Not found */
|
|
||||||
return CMP_INV;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond)
|
static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond)
|
||||||
/* Helper function for the replacement of routines that return a boolean
|
/* Helper function for the replacement of routines that return a boolean
|
||||||
* followed by a conditional jump. Instead of the boolean value, the condition
|
* followed by a conditional jump. Instead of the boolean value, the condition
|
||||||
|
@ -655,7 +655,7 @@ unsigned OptCondBranches (CodeSeg* S)
|
|||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Remove unused loads and stores */
|
/* Remove unused loads and stores */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
@ -675,24 +675,24 @@ unsigned OptUnusedLoads (CodeSeg* S)
|
|||||||
CodeEntry* E = CS_GetEntry (S, I);
|
CodeEntry* E = CS_GetEntry (S, I);
|
||||||
|
|
||||||
/* Check if it's a register load or transfer insn */
|
/* Check if it's a register load or transfer insn */
|
||||||
if ((E->Info & (OF_LOAD | OF_XFR | OF_REG_INCDEC)) != 0 &&
|
if ((E->Info & (OF_LOAD | OF_XFR | OF_REG_INCDEC)) != 0 &&
|
||||||
(N = CS_GetNextEntry (S, I)) != 0 &&
|
(N = CS_GetNextEntry (S, I)) != 0 &&
|
||||||
(N->Info & OF_FBRA) == 0) {
|
!CE_UseLoadFlags (N)) {
|
||||||
|
|
||||||
/* Check which sort of load or transfer it is */
|
/* Check which sort of load or transfer it is */
|
||||||
unsigned R;
|
unsigned R;
|
||||||
switch (E->OPC) {
|
switch (E->OPC) {
|
||||||
case OP65_DEA:
|
case OP65_DEA:
|
||||||
case OP65_INA:
|
case OP65_INA:
|
||||||
case OP65_LDA:
|
case OP65_LDA:
|
||||||
case OP65_TXA:
|
case OP65_TXA:
|
||||||
case OP65_TYA: R = REG_A; break;
|
case OP65_TYA: R = REG_A; break;
|
||||||
case OP65_DEX:
|
case OP65_DEX:
|
||||||
case OP65_INX:
|
case OP65_INX:
|
||||||
case OP65_LDX:
|
case OP65_LDX:
|
||||||
case OP65_TAX: R = REG_X; break;
|
case OP65_TAX: R = REG_X; break;
|
||||||
case OP65_DEY:
|
case OP65_DEY:
|
||||||
case OP65_INY:
|
case OP65_INY:
|
||||||
case OP65_LDY:
|
case OP65_LDY:
|
||||||
case OP65_TAY: R = REG_Y; break;
|
case OP65_TAY: R = REG_Y; break;
|
||||||
default: goto NextEntry; /* OOPS */
|
default: goto NextEntry; /* OOPS */
|
||||||
@ -799,7 +799,7 @@ unsigned OptDupLoads (CodeSeg* S)
|
|||||||
CE_KnownImm (E) && /* Value to be loaded is known */
|
CE_KnownImm (E) && /* Value to be loaded is known */
|
||||||
In->RegA == (long) E->Num && /* Both are equal */
|
In->RegA == (long) E->Num && /* Both are equal */
|
||||||
(N = CS_GetNextEntry (S, I)) != 0 && /* There is a next entry */
|
(N = CS_GetNextEntry (S, I)) != 0 && /* There is a next entry */
|
||||||
(N->Info & OF_FBRA) == 0) { /* Which is not a cond branch */
|
!CE_UseLoadFlags (N)) { /* Which does not use the flags */
|
||||||
Delete = 1;
|
Delete = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -809,7 +809,7 @@ unsigned OptDupLoads (CodeSeg* S)
|
|||||||
CE_KnownImm (E) && /* Value to be loaded is known */
|
CE_KnownImm (E) && /* Value to be loaded is known */
|
||||||
In->RegX == (long) E->Num && /* Both are equal */
|
In->RegX == (long) E->Num && /* Both are equal */
|
||||||
(N = CS_GetNextEntry (S, I)) != 0 && /* There is a next entry */
|
(N = CS_GetNextEntry (S, I)) != 0 && /* There is a next entry */
|
||||||
(N->Info & OF_FBRA) == 0) { /* Which is not a cond branch */
|
!CE_UseLoadFlags (N)) { /* Which does not use the flags */
|
||||||
Delete = 1;
|
Delete = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -819,7 +819,7 @@ unsigned OptDupLoads (CodeSeg* S)
|
|||||||
CE_KnownImm (E) && /* Value to be loaded is known */
|
CE_KnownImm (E) && /* Value to be loaded is known */
|
||||||
In->RegY == (long) E->Num && /* Both are equal */
|
In->RegY == (long) E->Num && /* Both are equal */
|
||||||
(N = CS_GetNextEntry (S, I)) != 0 && /* There is a next entry */
|
(N = CS_GetNextEntry (S, I)) != 0 && /* There is a next entry */
|
||||||
(N->Info & OF_FBRA) == 0) { /* Which is not a cond branch */
|
!CE_UseLoadFlags (N)) { /* Which does not use the flags */
|
||||||
Delete = 1;
|
Delete = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -908,37 +908,37 @@ unsigned OptDupLoads (CodeSeg* S)
|
|||||||
if (In->RegA >= 0 &&
|
if (In->RegA >= 0 &&
|
||||||
In->RegA == In->RegX &&
|
In->RegA == In->RegX &&
|
||||||
(N = CS_GetNextEntry (S, I)) != 0 &&
|
(N = CS_GetNextEntry (S, I)) != 0 &&
|
||||||
(N->Info & OF_FBRA) == 0) {
|
!CE_UseLoadFlags (N)) {
|
||||||
/* Value is identical and not followed by a branch */
|
/* Value is identical and not followed by a branch */
|
||||||
Delete = 1;
|
Delete = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP65_TAY:
|
case OP65_TAY:
|
||||||
if (In->RegA >= 0 &&
|
if (In->RegA >= 0 &&
|
||||||
In->RegA == In->RegY &&
|
In->RegA == In->RegY &&
|
||||||
(N = CS_GetNextEntry (S, I)) != 0 &&
|
(N = CS_GetNextEntry (S, I)) != 0 &&
|
||||||
(N->Info & OF_FBRA) == 0) {
|
!CE_UseLoadFlags (N)) {
|
||||||
/* Value is identical and not followed by a branch */
|
/* Value is identical and not followed by a branch */
|
||||||
Delete = 1;
|
Delete = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP65_TXA:
|
case OP65_TXA:
|
||||||
if (In->RegX >= 0 &&
|
if (In->RegX >= 0 &&
|
||||||
In->RegX == In->RegA &&
|
In->RegX == In->RegA &&
|
||||||
(N = CS_GetNextEntry (S, I)) != 0 &&
|
(N = CS_GetNextEntry (S, I)) != 0 &&
|
||||||
(N->Info & OF_FBRA) == 0) {
|
!CE_UseLoadFlags (N)) {
|
||||||
/* Value is identical and not followed by a branch */
|
/* Value is identical and not followed by a branch */
|
||||||
Delete = 1;
|
Delete = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP65_TYA:
|
case OP65_TYA:
|
||||||
if (In->RegY >= 0 &&
|
if (In->RegY >= 0 &&
|
||||||
In->RegY == In->RegA &&
|
In->RegY == In->RegA &&
|
||||||
(N = CS_GetNextEntry (S, I)) != 0 &&
|
(N = CS_GetNextEntry (S, I)) != 0 &&
|
||||||
(N->Info & OF_FBRA) == 0) {
|
!CE_UseLoadFlags (N)) {
|
||||||
/* Value is identical and not followed by a branch */
|
/* Value is identical and not followed by a branch */
|
||||||
Delete = 1;
|
Delete = 1;
|
||||||
}
|
}
|
||||||
@ -1003,7 +1003,7 @@ unsigned OptStoreLoad (CodeSeg* S)
|
|||||||
(E->OPC == OP65_STY && N->OPC == OP65_LDY)) &&
|
(E->OPC == OP65_STY && N->OPC == OP65_LDY)) &&
|
||||||
strcmp (E->Arg, N->Arg) == 0 &&
|
strcmp (E->Arg, N->Arg) == 0 &&
|
||||||
(X = CS_GetNextEntry (S, I+1)) != 0 &&
|
(X = CS_GetNextEntry (S, I+1)) != 0 &&
|
||||||
(X->Info & OF_FBRA) == 0) {
|
!CE_UseLoadFlags (X)) {
|
||||||
|
|
||||||
/* Register has already the correct value, remove the load */
|
/* Register has already the correct value, remove the load */
|
||||||
CS_DelEntry (S, I+1);
|
CS_DelEntry (S, I+1);
|
||||||
@ -1061,7 +1061,7 @@ unsigned OptTransfers (CodeSeg* S)
|
|||||||
if ((X = CS_GetNextEntry (S, I+1)) == 0) {
|
if ((X = CS_GetNextEntry (S, I+1)) == 0) {
|
||||||
goto NextEntry;
|
goto NextEntry;
|
||||||
}
|
}
|
||||||
if ((X->Info & OF_FBRA) != 0) {
|
if (CE_UseLoadFlags (X)) {
|
||||||
if (I == 0) {
|
if (I == 0) {
|
||||||
/* No preceeding entry */
|
/* No preceeding entry */
|
||||||
goto NextEntry;
|
goto NextEntry;
|
||||||
|
@ -281,16 +281,16 @@ unsigned assignadjust (type* lhst, ExprDesc* rhs)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void DefineData (ExprDesc* lval)
|
void DefineData (ExprDesc* Expr)
|
||||||
/* Output a data definition for the given expression */
|
/* Output a data definition for the given expression */
|
||||||
{
|
{
|
||||||
unsigned flags = lval->Flags;
|
unsigned Flags = Expr->Flags;
|
||||||
|
|
||||||
switch (flags & E_MCTYPE) {
|
switch (Flags & E_MCTYPE) {
|
||||||
|
|
||||||
case E_TCONST:
|
case E_TCONST:
|
||||||
/* Number */
|
/* Number */
|
||||||
g_defdata (TypeOf (lval->Type) | CF_CONST, lval->ConstVal, 0);
|
g_defdata (TypeOf (Expr->Type) | CF_CONST, Expr->ConstVal, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case E_TREGISTER:
|
case E_TREGISTER:
|
||||||
@ -305,33 +305,33 @@ void DefineData (ExprDesc* lval)
|
|||||||
case E_TGLAB:
|
case E_TGLAB:
|
||||||
case E_TLLAB:
|
case E_TLLAB:
|
||||||
/* Local or global symbol */
|
/* Local or global symbol */
|
||||||
g_defdata (GlobalModeFlags (flags), lval->Name, lval->ConstVal);
|
g_defdata (GlobalModeFlags (Flags), Expr->Name, Expr->ConstVal);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case E_TLIT:
|
case E_TLIT:
|
||||||
/* a literal of some kind */
|
/* a literal of some kind */
|
||||||
g_defdata (CF_STATIC, LiteralPoolLabel, lval->ConstVal);
|
g_defdata (CF_STATIC, LiteralPoolLabel, Expr->ConstVal);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Internal ("Unknown constant type: %04X", flags);
|
Internal ("Unknown constant type: %04X", Flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void lconst (unsigned flags, ExprDesc* lval)
|
static void lconst (unsigned Flags, ExprDesc* Expr)
|
||||||
/* Load primary reg with some constant value. */
|
/* Load the primary register with some constant value. */
|
||||||
{
|
{
|
||||||
switch (lval->Flags & E_MCTYPE) {
|
switch (Expr->Flags & E_MCTYPE) {
|
||||||
|
|
||||||
case E_TLOFFS:
|
case E_TLOFFS:
|
||||||
g_leasp (lval->ConstVal);
|
g_leasp (Expr->ConstVal);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case E_TCONST:
|
case E_TCONST:
|
||||||
/* Number constant */
|
/* Number constant */
|
||||||
g_getimmed (flags | TypeOf (lval->Type) | CF_CONST, lval->ConstVal, 0);
|
g_getimmed (Flags | TypeOf (Expr->Type) | CF_CONST, Expr->ConstVal, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case E_TREGISTER:
|
case E_TREGISTER:
|
||||||
@ -346,18 +346,18 @@ static void lconst (unsigned flags, ExprDesc* lval)
|
|||||||
case E_TGLAB:
|
case E_TGLAB:
|
||||||
case E_TLLAB:
|
case E_TLLAB:
|
||||||
/* Local or global symbol, load address */
|
/* Local or global symbol, load address */
|
||||||
flags |= GlobalModeFlags (lval->Flags);
|
Flags |= GlobalModeFlags (Expr->Flags);
|
||||||
flags &= ~CF_CONST;
|
Flags &= ~CF_CONST;
|
||||||
g_getimmed (flags, lval->Name, lval->ConstVal);
|
g_getimmed (Flags, Expr->Name, Expr->ConstVal);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case E_TLIT:
|
case E_TLIT:
|
||||||
/* Literal string */
|
/* Literal string */
|
||||||
g_getimmed (CF_STATIC, LiteralPoolLabel, lval->ConstVal);
|
g_getimmed (CF_STATIC, LiteralPoolLabel, Expr->ConstVal);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Internal ("Unknown constant type: %04X", lval->Flags);
|
Internal ("Unknown constant type: %04X", Expr->Flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -411,9 +411,10 @@ static int kcalc (int tok, long val1, long val2)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static GenDesc* FindGen (token_t Tok, GenDesc** Table)
|
static const GenDesc* FindGen (token_t Tok, const GenDesc** Table)
|
||||||
|
/* Find a token in a generator table */
|
||||||
{
|
{
|
||||||
GenDesc* G;
|
const GenDesc* G;
|
||||||
while ((G = *Table) != 0) {
|
while ((G = *Table) != 0) {
|
||||||
if (G->Tok == Tok) {
|
if (G->Tok == Tok) {
|
||||||
return G;
|
return G;
|
||||||
@ -1760,7 +1761,7 @@ static int hie10 (ExprDesc* lval)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int hie_internal (GenDesc** ops, /* List of generators */
|
static int hie_internal (const GenDesc** ops, /* List of generators */
|
||||||
ExprDesc* lval, /* parent expr's lval */
|
ExprDesc* lval, /* parent expr's lval */
|
||||||
int (*hienext) (ExprDesc*),
|
int (*hienext) (ExprDesc*),
|
||||||
int* UsedGen) /* next higher level */
|
int* UsedGen) /* next higher level */
|
||||||
@ -1770,7 +1771,7 @@ static int hie_internal (GenDesc** ops, /* List of generators */
|
|||||||
ExprDesc lval2;
|
ExprDesc lval2;
|
||||||
CodeMark Mark1;
|
CodeMark Mark1;
|
||||||
CodeMark Mark2;
|
CodeMark Mark2;
|
||||||
GenDesc* Gen;
|
const GenDesc* Gen;
|
||||||
token_t tok; /* The operator token */
|
token_t tok; /* The operator token */
|
||||||
unsigned ltype, type;
|
unsigned ltype, type;
|
||||||
int rconst; /* Operand is a constant */
|
int rconst; /* Operand is a constant */
|
||||||
@ -1870,8 +1871,8 @@ static int hie_internal (GenDesc** ops, /* List of generators */
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int hie_compare (GenDesc** ops, /* List of generators */
|
static int hie_compare (const GenDesc** ops, /* List of generators */
|
||||||
ExprDesc* lval, /* parent expr's lval */
|
ExprDesc* lval, /* parent expr's lval */
|
||||||
int (*hienext) (ExprDesc*))
|
int (*hienext) (ExprDesc*))
|
||||||
/* Helper function for the compare operators */
|
/* Helper function for the compare operators */
|
||||||
{
|
{
|
||||||
@ -1879,7 +1880,7 @@ static int hie_compare (GenDesc** ops, /* List of generators */
|
|||||||
ExprDesc lval2;
|
ExprDesc lval2;
|
||||||
CodeMark Mark1;
|
CodeMark Mark1;
|
||||||
CodeMark Mark2;
|
CodeMark Mark2;
|
||||||
GenDesc* Gen;
|
const GenDesc* Gen;
|
||||||
token_t tok; /* The operator token */
|
token_t tok; /* The operator token */
|
||||||
unsigned ltype;
|
unsigned ltype;
|
||||||
int rconst; /* Operand is a constant */
|
int rconst; /* Operand is a constant */
|
||||||
@ -1997,7 +1998,7 @@ static int hie_compare (GenDesc** ops, /* List of generators */
|
|||||||
static int hie9 (ExprDesc *lval)
|
static int hie9 (ExprDesc *lval)
|
||||||
/* Process * and / operators. */
|
/* Process * and / operators. */
|
||||||
{
|
{
|
||||||
static GenDesc* hie9_ops [] = {
|
static const GenDesc* hie9_ops [] = {
|
||||||
&GenMUL, &GenDIV, &GenMOD, 0
|
&GenMUL, &GenDIV, &GenMOD, 0
|
||||||
};
|
};
|
||||||
int UsedGen;
|
int UsedGen;
|
||||||
@ -2421,7 +2422,7 @@ static int hie8 (ExprDesc* lval)
|
|||||||
static int hie7 (ExprDesc *lval)
|
static int hie7 (ExprDesc *lval)
|
||||||
/* Parse << and >>. */
|
/* Parse << and >>. */
|
||||||
{
|
{
|
||||||
static GenDesc* hie7_ops [] = {
|
static const GenDesc* hie7_ops [] = {
|
||||||
&GenASL, &GenASR, 0
|
&GenASL, &GenASR, 0
|
||||||
};
|
};
|
||||||
int UsedGen;
|
int UsedGen;
|
||||||
@ -2434,7 +2435,7 @@ static int hie7 (ExprDesc *lval)
|
|||||||
static int hie6 (ExprDesc *lval)
|
static int hie6 (ExprDesc *lval)
|
||||||
/* process greater-than type comparators */
|
/* process greater-than type comparators */
|
||||||
{
|
{
|
||||||
static GenDesc* hie6_ops [] = {
|
static const GenDesc* hie6_ops [] = {
|
||||||
&GenLT, &GenLE, &GenGE, &GenGT, 0
|
&GenLT, &GenLE, &GenGE, &GenGT, 0
|
||||||
};
|
};
|
||||||
return hie_compare (hie6_ops, lval, hie7);
|
return hie_compare (hie6_ops, lval, hie7);
|
||||||
@ -2444,7 +2445,7 @@ static int hie6 (ExprDesc *lval)
|
|||||||
|
|
||||||
static int hie5 (ExprDesc *lval)
|
static int hie5 (ExprDesc *lval)
|
||||||
{
|
{
|
||||||
static GenDesc* hie5_ops[] = {
|
static const GenDesc* hie5_ops[] = {
|
||||||
&GenEQ, &GenNE, 0
|
&GenEQ, &GenNE, 0
|
||||||
};
|
};
|
||||||
return hie_compare (hie5_ops, lval, hie6);
|
return hie_compare (hie5_ops, lval, hie6);
|
||||||
@ -2455,7 +2456,7 @@ static int hie5 (ExprDesc *lval)
|
|||||||
static int hie4 (ExprDesc* lval)
|
static int hie4 (ExprDesc* lval)
|
||||||
/* Handle & (bitwise and) */
|
/* Handle & (bitwise and) */
|
||||||
{
|
{
|
||||||
static GenDesc* hie4_ops [] = {
|
static const GenDesc* hie4_ops [] = {
|
||||||
&GenAND, 0
|
&GenAND, 0
|
||||||
};
|
};
|
||||||
int UsedGen;
|
int UsedGen;
|
||||||
@ -2468,7 +2469,7 @@ static int hie4 (ExprDesc* lval)
|
|||||||
static int hie3 (ExprDesc *lval)
|
static int hie3 (ExprDesc *lval)
|
||||||
/* Handle ^ (bitwise exclusive or) */
|
/* Handle ^ (bitwise exclusive or) */
|
||||||
{
|
{
|
||||||
static GenDesc* hie3_ops [] = {
|
static const GenDesc* hie3_ops [] = {
|
||||||
&GenXOR, 0
|
&GenXOR, 0
|
||||||
};
|
};
|
||||||
int UsedGen;
|
int UsedGen;
|
||||||
@ -2481,7 +2482,7 @@ static int hie3 (ExprDesc *lval)
|
|||||||
static int hie2 (ExprDesc *lval)
|
static int hie2 (ExprDesc *lval)
|
||||||
/* Handle | (bitwise or) */
|
/* Handle | (bitwise or) */
|
||||||
{
|
{
|
||||||
static GenDesc* hie2_ops [] = {
|
static const GenDesc* hie2_ops [] = {
|
||||||
&GenOR, 0
|
&GenOR, 0
|
||||||
};
|
};
|
||||||
int UsedGen;
|
int UsedGen;
|
||||||
@ -2810,7 +2811,7 @@ static int hieQuest (ExprDesc *lval)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void opeq (GenDesc* Gen, ExprDesc *lval, int k)
|
static void opeq (const GenDesc* Gen, ExprDesc *lval, int k)
|
||||||
/* Process "op=" operators. */
|
/* Process "op=" operators. */
|
||||||
{
|
{
|
||||||
ExprDesc lval2;
|
ExprDesc lval2;
|
||||||
@ -2891,7 +2892,7 @@ static void opeq (GenDesc* Gen, ExprDesc *lval, int k)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void addsubeq (GenDesc* Gen, ExprDesc *lval, int k)
|
static void addsubeq (const GenDesc* Gen, ExprDesc *lval, int k)
|
||||||
/* Process the += and -= operators */
|
/* Process the += and -= operators */
|
||||||
{
|
{
|
||||||
ExprDesc lval2;
|
ExprDesc lval2;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user