mirror of
https://github.com/cc65/cc65.git
synced 2024-09-28 10:55:43 +00:00
Cleanup in ShiftExpr.
Changed GetCodePos to also remember the stack pointer at the given location, this removes the necessity to manipulate the stack when removing code. Since CodeMark is now a struct, the API for most asmcode functions has changed. git-svn-id: svn://svn.cc65.org/cc65/trunk@3145 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
a4c4e995a3
commit
9df7321d90
@ -6,9 +6,9 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2001 Ullrich von Bassewitz */
|
/* (C) 2000-2004 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Römerstraße 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
@ -37,43 +37,61 @@
|
|||||||
#include "check.h"
|
#include "check.h"
|
||||||
|
|
||||||
/* cc65 */
|
/* cc65 */
|
||||||
|
#include "asmcode.h"
|
||||||
#include "codeopt.h"
|
#include "codeopt.h"
|
||||||
#include "codeseg.h"
|
#include "codeseg.h"
|
||||||
#include "dataseg.h"
|
#include "dataseg.h"
|
||||||
#include "segments.h"
|
#include "segments.h"
|
||||||
|
#include "stackptr.h"
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
#include "asmcode.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CodeMark GetCodePos (void)
|
void GetCodePos (CodeMark* M)
|
||||||
/* Get a marker pointing to the current output position */
|
/* Get a marker pointing to the current output position */
|
||||||
{
|
{
|
||||||
return CS_GetEntryCount (CS->Code);
|
M->Pos = CS_GetEntryCount (CS->Code);
|
||||||
|
M->SP = StackPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void RemoveCode (CodeMark M)
|
void RemoveCode (const CodeMark* M)
|
||||||
/* Remove all code after the given code marker */
|
/* Remove all code after the given code marker */
|
||||||
{
|
{
|
||||||
CS_DelCodeAfter (CS->Code, M);
|
CS_DelCodeAfter (CS->Code, M->Pos);
|
||||||
|
StackPtr = M->SP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void MoveCode (CodeMark Start, CodeMark End, CodeMark Target)
|
void MoveCode (const CodeMark* Start, const CodeMark* End, const CodeMark* Target)
|
||||||
/* Move the code between Start (inclusive) and End (exclusive) to
|
/* Move the code between Start (inclusive) and End (exclusive) to
|
||||||
* (before) Target.
|
* (before) Target. The code marks aren't updated.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
CS_MoveEntries (CS->Code, Start, End - Start, Target);
|
CS_MoveEntries (CS->Code, Start->Pos, End->Pos - Start->Pos, Target->Pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int CodeRangeIsEmpty (const CodeMark* Start, const CodeMark* End)
|
||||||
|
/* Return true if the given code range is empty (no code between Start and End) */
|
||||||
|
{
|
||||||
|
int Empty;
|
||||||
|
PRECONDITION (Start->Pos >= End->Pos);
|
||||||
|
Empty = (Start->Pos == End->Pos);
|
||||||
|
if (Empty) {
|
||||||
|
/* Safety */
|
||||||
|
CHECK (Start->SP == End->SP);
|
||||||
|
}
|
||||||
|
return Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2001 Ullrich von Bassewitz */
|
/* (C) 2000-2004 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Römerstraße 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
@ -52,7 +52,10 @@
|
|||||||
|
|
||||||
|
|
||||||
/* Marker for an assembler code position */
|
/* Marker for an assembler code position */
|
||||||
typedef unsigned CodeMark;
|
typedef struct {
|
||||||
|
unsigned Pos; /* Code position */
|
||||||
|
int SP; /* Stack pointer at this position */
|
||||||
|
} CodeMark;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -62,17 +65,20 @@ typedef unsigned CodeMark;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
CodeMark GetCodePos (void);
|
void GetCodePos (CodeMark* M);
|
||||||
/* Get a marker pointing to the current output position */
|
/* Get a marker pointing to the current output position */
|
||||||
|
|
||||||
void RemoveCode (CodeMark M);
|
void RemoveCode (const CodeMark* M);
|
||||||
/* Remove all code after the given code marker */
|
/* Remove all code after the given code marker */
|
||||||
|
|
||||||
void MoveCode (CodeMark Start, CodeMark End, CodeMark Target);
|
void MoveCode (const CodeMark* Start, const CodeMark* End, const CodeMark* Target);
|
||||||
/* Move the code between Start (inclusive) and End (exclusive) to
|
/* Move the code between Start (inclusive) and End (exclusive) to
|
||||||
* (before) Target.
|
* (before) Target. The code marks aren't updated.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
int CodeRangeIsEmpty (const CodeMark* Start, const CodeMark* End);
|
||||||
|
/* Return true if the given code range is empty (no code between Start and End) */
|
||||||
|
|
||||||
void WriteOutput (FILE* F);
|
void WriteOutput (FILE* F);
|
||||||
/* Write the final output to a file */
|
/* Write the final output to a file */
|
||||||
|
|
||||||
|
@ -494,7 +494,7 @@ static void FunctionCall (ExprDesc* Expr)
|
|||||||
int IsFuncPtr; /* Flag */
|
int IsFuncPtr; /* Flag */
|
||||||
int StdFunc; /* Standard function index */
|
int StdFunc; /* Standard function index */
|
||||||
unsigned ParamSize; /* Number of parameter bytes */
|
unsigned ParamSize; /* Number of parameter bytes */
|
||||||
CodeMark Mark = 0; /* Initialize to keep gcc silent */
|
CodeMark Mark;
|
||||||
int PtrOffs = 0; /* Offset of function pointer on stack */
|
int PtrOffs = 0; /* Offset of function pointer on stack */
|
||||||
int IsFastCall = 0; /* True if it's a fast call function */
|
int IsFastCall = 0; /* True if it's a fast call function */
|
||||||
int PtrOnStack = 0; /* True if a pointer copy is on stack */
|
int PtrOnStack = 0; /* True if a pointer copy is on stack */
|
||||||
@ -530,7 +530,7 @@ static void FunctionCall (ExprDesc* Expr)
|
|||||||
ED_MakeRValExpr (Expr);
|
ED_MakeRValExpr (Expr);
|
||||||
|
|
||||||
/* Remember the code position */
|
/* Remember the code position */
|
||||||
Mark = GetCodePos ();
|
GetCodePos (&Mark);
|
||||||
|
|
||||||
/* Push the pointer onto the stack and remember the offset */
|
/* Push the pointer onto the stack and remember the offset */
|
||||||
g_push (CF_PTR, 0);
|
g_push (CF_PTR, 0);
|
||||||
@ -567,8 +567,7 @@ static void FunctionCall (ExprDesc* Expr)
|
|||||||
* stack pointer.
|
* stack pointer.
|
||||||
*/
|
*/
|
||||||
if (ParamSize == 0) {
|
if (ParamSize == 0) {
|
||||||
RemoveCode (Mark);
|
RemoveCode (&Mark);
|
||||||
pop (CF_PTR);
|
|
||||||
PtrOnStack = 0;
|
PtrOnStack = 0;
|
||||||
} else {
|
} else {
|
||||||
/* Load from the saved copy */
|
/* Load from the saved copy */
|
||||||
@ -850,8 +849,7 @@ static void ArrayRef (ExprDesc* Expr)
|
|||||||
ConstBaseAddr = (ED_IsLocConst (Expr) || ED_IsLocStack (Expr));
|
ConstBaseAddr = (ED_IsLocConst (Expr) || ED_IsLocStack (Expr));
|
||||||
|
|
||||||
/* If we have a constant base, we delay the address fetch */
|
/* If we have a constant base, we delay the address fetch */
|
||||||
Mark1 = GetCodePos ();
|
GetCodePos (&Mark1);
|
||||||
Mark2 = 0; /* Silence gcc */
|
|
||||||
if (!ConstBaseAddr) {
|
if (!ConstBaseAddr) {
|
||||||
/* Get a pointer to the array into the primary */
|
/* Get a pointer to the array into the primary */
|
||||||
LoadExpr (CF_NONE, Expr);
|
LoadExpr (CF_NONE, Expr);
|
||||||
@ -860,7 +858,7 @@ static void ArrayRef (ExprDesc* Expr)
|
|||||||
* bit, even if this value is greater, since we cannot handle
|
* bit, even if this value is greater, since we cannot handle
|
||||||
* other than 16bit stuff when doing indexing.
|
* other than 16bit stuff when doing indexing.
|
||||||
*/
|
*/
|
||||||
Mark2 = GetCodePos ();
|
GetCodePos (&Mark2);
|
||||||
g_push (CF_PTR, 0);
|
g_push (CF_PTR, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -908,8 +906,7 @@ static void ArrayRef (ExprDesc* Expr)
|
|||||||
* since we can generate expression+offset.
|
* since we can generate expression+offset.
|
||||||
*/
|
*/
|
||||||
if (!ConstBaseAddr) {
|
if (!ConstBaseAddr) {
|
||||||
RemoveCode (Mark2);
|
RemoveCode (&Mark2);
|
||||||
pop (CF_PTR);
|
|
||||||
} else {
|
} else {
|
||||||
/* Get an array pointer into the primary */
|
/* Get an array pointer into the primary */
|
||||||
LoadExpr (CF_NONE, Expr);
|
LoadExpr (CF_NONE, Expr);
|
||||||
@ -923,7 +920,7 @@ static void ArrayRef (ExprDesc* Expr)
|
|||||||
SubScript.IVal *= CheckedSizeOf (ElementType);
|
SubScript.IVal *= CheckedSizeOf (ElementType);
|
||||||
|
|
||||||
/* Remove the address load code */
|
/* Remove the address load code */
|
||||||
RemoveCode (Mark1);
|
RemoveCode (&Mark1);
|
||||||
|
|
||||||
/* In case of an array, we can adjust the offset of the expression
|
/* In case of an array, we can adjust the offset of the expression
|
||||||
* already in Expr. If the base address was a constant, we can even
|
* already in Expr. If the base address was a constant, we can even
|
||||||
@ -964,7 +961,7 @@ static void ArrayRef (ExprDesc* Expr)
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Array subscript is not constant. Load it into the primary */
|
/* Array subscript is not constant. Load it into the primary */
|
||||||
Mark2 = GetCodePos ();
|
GetCodePos (&Mark2);
|
||||||
LoadExpr (CF_NONE, &SubScript);
|
LoadExpr (CF_NONE, &SubScript);
|
||||||
|
|
||||||
/* Do scaling */
|
/* Do scaling */
|
||||||
@ -1031,7 +1028,7 @@ static void ArrayRef (ExprDesc* Expr)
|
|||||||
} else {
|
} else {
|
||||||
Flags = CF_INT;
|
Flags = CF_INT;
|
||||||
}
|
}
|
||||||
RemoveCode (Mark2);
|
RemoveCode (&Mark2);
|
||||||
|
|
||||||
/* Get a pointer to the array into the primary. */
|
/* Get a pointer to the array into the primary. */
|
||||||
LoadExpr (CF_NONE, Expr);
|
LoadExpr (CF_NONE, Expr);
|
||||||
@ -1592,11 +1589,12 @@ void hie10 (ExprDesc* Expr)
|
|||||||
ConsumeRParen ();
|
ConsumeRParen ();
|
||||||
} else {
|
} else {
|
||||||
/* Remember the output queue pointer */
|
/* Remember the output queue pointer */
|
||||||
CodeMark Mark = GetCodePos ();
|
CodeMark Mark;
|
||||||
|
GetCodePos (&Mark);
|
||||||
hie10 (Expr);
|
hie10 (Expr);
|
||||||
Size = CheckedSizeOf (Expr->Type);
|
Size = CheckedSizeOf (Expr->Type);
|
||||||
/* Remove any generated code */
|
/* Remove any generated code */
|
||||||
RemoveCode (Mark);
|
RemoveCode (&Mark);
|
||||||
}
|
}
|
||||||
ED_MakeConstAbs (Expr, Size, type_size_t);
|
ED_MakeConstAbs (Expr, Size, type_size_t);
|
||||||
ED_MarkAsUntested (Expr);
|
ED_MarkAsUntested (Expr);
|
||||||
@ -1660,16 +1658,16 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */
|
|||||||
NextToken ();
|
NextToken ();
|
||||||
|
|
||||||
/* Get the lhs on stack */
|
/* Get the lhs on stack */
|
||||||
Mark1 = GetCodePos ();
|
GetCodePos (&Mark1);
|
||||||
ltype = TypeOf (Expr->Type);
|
ltype = TypeOf (Expr->Type);
|
||||||
if (ED_IsConstAbs (Expr)) {
|
if (ED_IsConstAbs (Expr)) {
|
||||||
/* Constant value */
|
/* Constant value */
|
||||||
Mark2 = GetCodePos ();
|
GetCodePos (&Mark2);
|
||||||
g_push (ltype | CF_CONST, Expr->IVal);
|
g_push (ltype | CF_CONST, Expr->IVal);
|
||||||
} else {
|
} else {
|
||||||
/* Value not constant */
|
/* Value not constant */
|
||||||
LoadExpr (CF_NONE, Expr);
|
LoadExpr (CF_NONE, Expr);
|
||||||
Mark2 = GetCodePos ();
|
GetCodePos (&Mark2);
|
||||||
g_push (ltype, 0);
|
g_push (ltype, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1685,8 +1683,7 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */
|
|||||||
if (ED_IsConstAbs (Expr) && rconst) {
|
if (ED_IsConstAbs (Expr) && rconst) {
|
||||||
|
|
||||||
/* Both operands are constant, remove the generated code */
|
/* Both operands are constant, remove the generated code */
|
||||||
RemoveCode (Mark1);
|
RemoveCode (&Mark1);
|
||||||
pop (ltype);
|
|
||||||
|
|
||||||
/* Evaluate the result */
|
/* Evaluate the result */
|
||||||
Expr->IVal = kcalc (Tok, Expr->IVal, Expr2.IVal);
|
Expr->IVal = kcalc (Tok, Expr->IVal, Expr2.IVal);
|
||||||
@ -1712,8 +1709,7 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */
|
|||||||
Error ("Modulo operation with zero");
|
Error ("Modulo operation with zero");
|
||||||
}
|
}
|
||||||
if ((Gen->Flags & GEN_NOPUSH) != 0) {
|
if ((Gen->Flags & GEN_NOPUSH) != 0) {
|
||||||
RemoveCode (Mark2);
|
RemoveCode (&Mark2);
|
||||||
pop (ltype);
|
|
||||||
ltype |= CF_REG; /* Value is in register */
|
ltype |= CF_REG; /* Value is in register */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1756,16 +1752,16 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
|
|||||||
NextToken ();
|
NextToken ();
|
||||||
|
|
||||||
/* Get the lhs on stack */
|
/* Get the lhs on stack */
|
||||||
Mark1 = GetCodePos ();
|
GetCodePos (&Mark1);
|
||||||
ltype = TypeOf (Expr->Type);
|
ltype = TypeOf (Expr->Type);
|
||||||
if (ED_IsConstAbs (Expr)) {
|
if (ED_IsConstAbs (Expr)) {
|
||||||
/* Constant value */
|
/* Constant value */
|
||||||
Mark2 = GetCodePos ();
|
GetCodePos (&Mark2);
|
||||||
g_push (ltype | CF_CONST, Expr->IVal);
|
g_push (ltype | CF_CONST, Expr->IVal);
|
||||||
} else {
|
} else {
|
||||||
/* Value not constant */
|
/* Value not constant */
|
||||||
LoadExpr (CF_NONE, Expr);
|
LoadExpr (CF_NONE, Expr);
|
||||||
Mark2 = GetCodePos ();
|
GetCodePos (&Mark2);
|
||||||
g_push (ltype, 0);
|
g_push (ltype, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1797,8 +1793,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
|
|||||||
if (ED_IsConstAbs (Expr) && rconst) {
|
if (ED_IsConstAbs (Expr) && rconst) {
|
||||||
|
|
||||||
/* Both operands are constant, remove the generated code */
|
/* Both operands are constant, remove the generated code */
|
||||||
RemoveCode (Mark1);
|
RemoveCode (&Mark1);
|
||||||
pop (ltype);
|
|
||||||
|
|
||||||
/* Evaluate the result */
|
/* Evaluate the result */
|
||||||
Expr->IVal = kcalc (tok, Expr->IVal, Expr2.IVal);
|
Expr->IVal = kcalc (tok, Expr->IVal, Expr2.IVal);
|
||||||
@ -1813,8 +1808,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
|
|||||||
if (rconst) {
|
if (rconst) {
|
||||||
flags |= CF_CONST;
|
flags |= CF_CONST;
|
||||||
if ((Gen->Flags & GEN_NOPUSH) != 0) {
|
if ((Gen->Flags & GEN_NOPUSH) != 0) {
|
||||||
RemoveCode (Mark2);
|
RemoveCode (&Mark2);
|
||||||
pop (ltype);
|
|
||||||
ltype |= CF_REG; /* Value is in register */
|
ltype |= CF_REG; /* Value is in register */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2010,7 +2004,7 @@ static void parseadd (ExprDesc* Expr)
|
|||||||
|
|
||||||
/* Left hand side is not constant. Get the value onto the stack. */
|
/* Left hand side is not constant. Get the value onto the stack. */
|
||||||
LoadExpr (CF_NONE, Expr); /* --> primary register */
|
LoadExpr (CF_NONE, Expr); /* --> primary register */
|
||||||
Mark = GetCodePos ();
|
GetCodePos (&Mark);
|
||||||
g_push (TypeOf (Expr->Type), 0); /* --> stack */
|
g_push (TypeOf (Expr->Type), 0); /* --> stack */
|
||||||
|
|
||||||
/* Evaluate the rhs */
|
/* Evaluate the rhs */
|
||||||
@ -2020,8 +2014,7 @@ static void parseadd (ExprDesc* Expr)
|
|||||||
rhst = Expr2.Type;
|
rhst = Expr2.Type;
|
||||||
|
|
||||||
/* Remove pushed value from stack */
|
/* Remove pushed value from stack */
|
||||||
RemoveCode (Mark);
|
RemoveCode (&Mark);
|
||||||
pop (TypeOf (Expr->Type));
|
|
||||||
|
|
||||||
/* Check for pointer arithmetic */
|
/* Check for pointer arithmetic */
|
||||||
if (IsClassPtr (lhst) && IsClassInt (rhst)) {
|
if (IsClassPtr (lhst) && IsClassInt (rhst)) {
|
||||||
@ -2121,9 +2114,9 @@ static void parsesub (ExprDesc* Expr)
|
|||||||
rscale = 1; /* Scale by 1, that is, don't scale */
|
rscale = 1; /* Scale by 1, that is, don't scale */
|
||||||
|
|
||||||
/* Remember the output queue position, then bring the value onto the stack */
|
/* Remember the output queue position, then bring the value onto the stack */
|
||||||
Mark1 = GetCodePos ();
|
GetCodePos (&Mark1);
|
||||||
LoadExpr (CF_NONE, Expr); /* --> primary register */
|
LoadExpr (CF_NONE, Expr); /* --> primary register */
|
||||||
Mark2 = GetCodePos ();
|
GetCodePos (&Mark2);
|
||||||
g_push (TypeOf (lhst), 0); /* --> stack */
|
g_push (TypeOf (lhst), 0); /* --> stack */
|
||||||
|
|
||||||
/* Parse the right hand side */
|
/* Parse the right hand side */
|
||||||
@ -2136,8 +2129,7 @@ static void parsesub (ExprDesc* Expr)
|
|||||||
if (ED_IsConstAbs (Expr)) {
|
if (ED_IsConstAbs (Expr)) {
|
||||||
|
|
||||||
/* Both sides are constant, remove generated code */
|
/* Both sides are constant, remove generated code */
|
||||||
RemoveCode (Mark1);
|
RemoveCode (&Mark1);
|
||||||
pop (TypeOf (lhst)); /* Clean up the stack */
|
|
||||||
|
|
||||||
/* Check for pointer arithmetic */
|
/* Check for pointer arithmetic */
|
||||||
if (IsClassPtr (lhst) && IsClassInt (rhst)) {
|
if (IsClassPtr (lhst) && IsClassInt (rhst)) {
|
||||||
@ -2171,8 +2163,7 @@ static void parsesub (ExprDesc* Expr)
|
|||||||
/* Left hand side is not constant, right hand side is.
|
/* Left hand side is not constant, right hand side is.
|
||||||
* Remove pushed value from stack.
|
* Remove pushed value from stack.
|
||||||
*/
|
*/
|
||||||
RemoveCode (Mark2);
|
RemoveCode (&Mark2);
|
||||||
pop (TypeOf (lhst));
|
|
||||||
|
|
||||||
if (IsClassPtr (lhst) && IsClassInt (rhst)) {
|
if (IsClassPtr (lhst) && IsClassInt (rhst)) {
|
||||||
/* Left is pointer, right is int, must scale rhs */
|
/* Left is pointer, right is int, must scale rhs */
|
||||||
@ -2691,17 +2682,16 @@ static void opeq (const GenDesc* Gen, ExprDesc* Expr)
|
|||||||
LoadExpr (CF_NONE, Expr);
|
LoadExpr (CF_NONE, Expr);
|
||||||
|
|
||||||
/* Bring the lhs on stack */
|
/* Bring the lhs on stack */
|
||||||
Mark = GetCodePos ();
|
GetCodePos (&Mark);
|
||||||
g_push (flags, 0);
|
g_push (flags, 0);
|
||||||
|
|
||||||
/* Evaluate the rhs */
|
/* Evaluate the rhs */
|
||||||
if (evalexpr (CF_NONE, hie1, &Expr2) == 0) {
|
if (evalexpr (CF_NONE, hie1, &Expr2) == 0) {
|
||||||
/* The resulting value is a constant. If the generator has the NOPUSH
|
/* The resulting value is a constant. If the generator has the NOPUSH
|
||||||
* flag set, don't push the lhs.
|
* flag set, don't push the lhs.
|
||||||
*/
|
*/
|
||||||
if (Gen->Flags & GEN_NOPUSH) {
|
if (Gen->Flags & GEN_NOPUSH) {
|
||||||
RemoveCode (Mark);
|
RemoveCode (&Mark);
|
||||||
pop (flags);
|
|
||||||
}
|
}
|
||||||
if (MustScale) {
|
if (MustScale) {
|
||||||
/* lhs is a pointer, scale rhs */
|
/* lhs is a pointer, scale rhs */
|
||||||
|
@ -47,13 +47,13 @@
|
|||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Data */
|
/* Data */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
@ -65,8 +65,11 @@ void ShiftExpr (struct ExprDesc* Expr)
|
|||||||
CodeMark Mark1;
|
CodeMark Mark1;
|
||||||
CodeMark Mark2;
|
CodeMark Mark2;
|
||||||
token_t Tok; /* The operator token */
|
token_t Tok; /* The operator token */
|
||||||
|
type* EffType; /* Effective lhs type */
|
||||||
|
type* ResultType; /* Type of the result */
|
||||||
unsigned ExprBits; /* Bits of the lhs operand */
|
unsigned ExprBits; /* Bits of the lhs operand */
|
||||||
unsigned ltype, rtype, flags;
|
unsigned GenFlags; /* Generator flags */
|
||||||
|
unsigned ltype;
|
||||||
int rconst; /* Operand is a constant */
|
int rconst; /* Operand is a constant */
|
||||||
|
|
||||||
|
|
||||||
@ -85,20 +88,26 @@ void ShiftExpr (struct ExprDesc* Expr)
|
|||||||
Tok = CurTok.Tok;
|
Tok = CurTok.Tok;
|
||||||
NextToken ();
|
NextToken ();
|
||||||
|
|
||||||
|
/* Get the type of the result */
|
||||||
|
ResultType = EffType = IntPromotion (Expr->Type);
|
||||||
|
|
||||||
|
/* Prepare the code generator flags */
|
||||||
|
GenFlags = TypeOf (ResultType);
|
||||||
|
|
||||||
/* Calculate the number of bits the lhs operand has */
|
/* Calculate the number of bits the lhs operand has */
|
||||||
ExprBits = SizeOf (Expr->Type) * 8;
|
ExprBits = SizeOf (ResultType) * 8;
|
||||||
|
|
||||||
/* Get the lhs on stack */
|
/* Get the lhs on stack */
|
||||||
Mark1 = GetCodePos ();
|
GetCodePos (&Mark1);
|
||||||
ltype = TypeOf (Expr->Type);
|
ltype = TypeOf (Expr->Type);
|
||||||
if (ED_IsConstAbs (Expr)) {
|
if (ED_IsConstAbs (Expr)) {
|
||||||
/* Constant value */
|
/* Constant value */
|
||||||
Mark2 = GetCodePos ();
|
GetCodePos (&Mark2);
|
||||||
g_push (ltype | CF_CONST, Expr->IVal);
|
g_push (ltype | CF_CONST, Expr->IVal);
|
||||||
} else {
|
} else {
|
||||||
/* Value not constant */
|
/* Value not constant */
|
||||||
LoadExpr (CF_NONE, Expr);
|
LoadExpr (CF_NONE, Expr);
|
||||||
Mark2 = GetCodePos ();
|
GetCodePos (&Mark2);
|
||||||
g_push (ltype, 0);
|
g_push (ltype, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +129,11 @@ void ShiftExpr (struct ExprDesc* Expr)
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* The rhs is a constant numeric value */
|
/* The rhs is a constant numeric value. */
|
||||||
|
GenFlags |= CF_CONST;
|
||||||
|
|
||||||
|
/* Remove the code that pushes the rhs onto the stack. */
|
||||||
|
RemoveCode (&Mark2);
|
||||||
|
|
||||||
/* If the shift count is greater or equal than the bit count of
|
/* If the shift count is greater or equal than the bit count of
|
||||||
* the operand, the behaviour is undefined according to the
|
* the operand, the behaviour is undefined according to the
|
||||||
@ -137,8 +150,7 @@ void ShiftExpr (struct ExprDesc* Expr)
|
|||||||
if (Expr2.IVal == 0) {
|
if (Expr2.IVal == 0) {
|
||||||
|
|
||||||
/* Result is already in Expr, remove the generated code */
|
/* Result is already in Expr, remove the generated code */
|
||||||
RemoveCode (Mark1);
|
RemoveCode (&Mark1);
|
||||||
pop (ltype);
|
|
||||||
|
|
||||||
/* Done */
|
/* Done */
|
||||||
goto Next;
|
goto Next;
|
||||||
@ -155,8 +167,7 @@ void ShiftExpr (struct ExprDesc* Expr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Both operands are constant, remove the generated code */
|
/* Both operands are constant, remove the generated code */
|
||||||
RemoveCode (Mark1);
|
RemoveCode (&Mark1);
|
||||||
pop (ltype);
|
|
||||||
|
|
||||||
/* Done */
|
/* Done */
|
||||||
goto Next;
|
goto Next;
|
||||||
@ -191,8 +202,7 @@ void ShiftExpr (struct ExprDesc* Expr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Remove the generated load code */
|
/* Remove the generated load code */
|
||||||
RemoveCode (Mark1);
|
RemoveCode (&Mark1);
|
||||||
pop (ltype);
|
|
||||||
|
|
||||||
/* Generate again code for the load */
|
/* Generate again code for the load */
|
||||||
LoadExpr (CF_NONE, Expr);
|
LoadExpr (CF_NONE, Expr);
|
||||||
@ -203,46 +213,26 @@ void ShiftExpr (struct ExprDesc* Expr)
|
|||||||
/* If the shift count is now zero, we're done */
|
/* If the shift count is now zero, we're done */
|
||||||
if (Expr2.IVal == 0) {
|
if (Expr2.IVal == 0) {
|
||||||
/* Be sure to mark the value as in the primary */
|
/* Be sure to mark the value as in the primary */
|
||||||
goto Loaded;
|
goto MakeRVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Otherwise generate code to push the value */
|
|
||||||
Mark2 = GetCodePos ();
|
|
||||||
g_push (ltype, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the right hand side is a constant, remove the push of the
|
|
||||||
* primary register.
|
|
||||||
*/
|
|
||||||
rtype = TypeOf (Expr2.Type);
|
|
||||||
flags = 0;
|
|
||||||
if (rconst) {
|
|
||||||
flags |= CF_CONST;
|
|
||||||
rtype |= CF_CONST;
|
|
||||||
RemoveCode (Mark2);
|
|
||||||
pop (ltype);
|
|
||||||
ltype |= CF_REG; /* Value is in register */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Determine the type of the operation result. */
|
|
||||||
flags |= g_typeadjust (ltype, rtype);
|
|
||||||
|
|
||||||
/* Generate code */
|
/* Generate code */
|
||||||
switch (Tok) {
|
switch (Tok) {
|
||||||
case TOK_SHL: g_asl (flags, Expr2.IVal); break;
|
case TOK_SHL: g_asl (GenFlags, Expr2.IVal); break;
|
||||||
case TOK_SHR: g_asr (flags, Expr2.IVal); break;
|
case TOK_SHR: g_asr (GenFlags, Expr2.IVal); break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Loaded:
|
MakeRVal:
|
||||||
/* We have a rvalue in the primary now */
|
/* We have a rvalue in the primary now */
|
||||||
ED_MakeRValExpr (Expr);
|
ED_MakeRValExpr (Expr);
|
||||||
|
|
||||||
Next:
|
Next:
|
||||||
/* Get the type of the result */
|
/* Set the type of the result */
|
||||||
Expr->Type = IntPromotion (Expr->Type);
|
Expr->Type = ResultType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,3 +55,20 @@ int StackPtr = 0;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void SP_Push (const type* T)
|
||||||
|
/* Adjust the stackpointer for a push of an argument of the given type */
|
||||||
|
{
|
||||||
|
StackPtr -= SizeOf (T);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void SP_Pop (const type* T)
|
||||||
|
/* Adjust the stackpointer for a pop of an argument of the given type */
|
||||||
|
{
|
||||||
|
StackPtr += SizeOf (T);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,6 +38,11 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* cc65 */
|
||||||
|
#include "datatype.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Data */
|
/* Data */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -55,6 +60,14 @@ extern int StackPtr;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void SP_Push (const type* T);
|
||||||
|
/* Adjust the stackpointer for a push of an argument of the given type */
|
||||||
|
|
||||||
|
void SP_Pop (const type* T);
|
||||||
|
/* Adjust the stackpointer for a pop of an argument of the given type */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* End of stackptr.h */
|
/* End of stackptr.h */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -151,7 +151,7 @@ static void ParseArg (ArgDesc* Arg, type* Type)
|
|||||||
Arg->ArgType = Type;
|
Arg->ArgType = Type;
|
||||||
|
|
||||||
/* Remember the current code position */
|
/* Remember the current code position */
|
||||||
Arg->Start = GetCodePos ();
|
GetCodePos (&Arg->Start);
|
||||||
|
|
||||||
/* Read the expression we're going to pass to the function */
|
/* Read the expression we're going to pass to the function */
|
||||||
ExprWithCheck (hie1, &Arg->Expr);
|
ExprWithCheck (hie1, &Arg->Expr);
|
||||||
@ -174,7 +174,8 @@ static void ParseArg (ArgDesc* Arg, type* Type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Remember the following code position */
|
/* Remember the following code position */
|
||||||
Arg->End = Arg->Push = GetCodePos ();
|
GetCodePos (&Arg->Push);
|
||||||
|
GetCodePos (&Arg->End);
|
||||||
|
|
||||||
/* Use the type of the argument for the push */
|
/* Use the type of the argument for the push */
|
||||||
Arg->Flags |= TypeOf (Arg->Expr.Type);
|
Arg->Flags |= TypeOf (Arg->Expr.Type);
|
||||||
@ -202,19 +203,19 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
|||||||
unsigned Label;
|
unsigned Label;
|
||||||
|
|
||||||
/* Remember where we are now */
|
/* Remember where we are now */
|
||||||
Start = GetCodePos ();
|
GetCodePos (&Start);
|
||||||
|
|
||||||
/* Argument #1 */
|
/* Argument #1 */
|
||||||
ParseArg (&Arg1, Arg1Type);
|
ParseArg (&Arg1, Arg1Type);
|
||||||
g_push (Arg1.Flags, Arg1.Expr.IVal);
|
g_push (Arg1.Flags, Arg1.Expr.IVal);
|
||||||
Arg1.End = GetCodePos ();
|
GetCodePos (&Arg1.End);
|
||||||
ParamSize += SizeOf (Arg1Type);
|
ParamSize += SizeOf (Arg1Type);
|
||||||
ConsumeComma ();
|
ConsumeComma ();
|
||||||
|
|
||||||
/* Argument #2 */
|
/* Argument #2 */
|
||||||
ParseArg (&Arg2, Arg2Type);
|
ParseArg (&Arg2, Arg2Type);
|
||||||
g_push (Arg2.Flags, Arg2.Expr.IVal);
|
g_push (Arg2.Flags, Arg2.Expr.IVal);
|
||||||
Arg2.End = GetCodePos ();
|
GetCodePos (&Arg2.End);
|
||||||
ParamSize += SizeOf (Arg2Type);
|
ParamSize += SizeOf (Arg2Type);
|
||||||
ConsumeComma ();
|
ConsumeComma ();
|
||||||
|
|
||||||
@ -239,7 +240,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
|||||||
/* Remove all of the generated code but the load of the first
|
/* Remove all of the generated code but the load of the first
|
||||||
* argument, which is what memcpy returns.
|
* argument, which is what memcpy returns.
|
||||||
*/
|
*/
|
||||||
RemoveCode (Arg1.Push);
|
RemoveCode (&Arg1.Push);
|
||||||
|
|
||||||
/* Set the function result to the first argument */
|
/* Set the function result to the first argument */
|
||||||
*Expr = Arg1.Expr;
|
*Expr = Arg1.Expr;
|
||||||
@ -263,7 +264,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
|||||||
int Reg2 = ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr);
|
int Reg2 = ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr);
|
||||||
|
|
||||||
/* Drop the generated code */
|
/* Drop the generated code */
|
||||||
RemoveCode (Start);
|
RemoveCode (&Start);
|
||||||
|
|
||||||
/* We need a label */
|
/* We need a label */
|
||||||
Label = GetLocalLabel ();
|
Label = GetLocalLabel ();
|
||||||
@ -332,7 +333,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
|||||||
int Offs = ED_GetStackOffs (&Arg1.Expr, 0);
|
int Offs = ED_GetStackOffs (&Arg1.Expr, 0);
|
||||||
|
|
||||||
/* Drop the generated code */
|
/* Drop the generated code */
|
||||||
RemoveCode (Start);
|
RemoveCode (&Start);
|
||||||
|
|
||||||
/* We need a label */
|
/* We need a label */
|
||||||
Label = GetLocalLabel ();
|
Label = GetLocalLabel ();
|
||||||
@ -406,7 +407,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
|||||||
int Offs = ED_GetStackOffs (&Arg2.Expr, 0);
|
int Offs = ED_GetStackOffs (&Arg2.Expr, 0);
|
||||||
|
|
||||||
/* Drop the generated code */
|
/* Drop the generated code */
|
||||||
RemoveCode (Start);
|
RemoveCode (&Start);
|
||||||
|
|
||||||
/* We need a label */
|
/* We need a label */
|
||||||
Label = GetLocalLabel ();
|
Label = GetLocalLabel ();
|
||||||
@ -497,12 +498,12 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
|||||||
unsigned Label;
|
unsigned Label;
|
||||||
|
|
||||||
/* Remember where we are now */
|
/* Remember where we are now */
|
||||||
Start = GetCodePos ();
|
GetCodePos (&Start);
|
||||||
|
|
||||||
/* Argument #1 */
|
/* Argument #1 */
|
||||||
ParseArg (&Arg1, Arg1Type);
|
ParseArg (&Arg1, Arg1Type);
|
||||||
g_push (Arg1.Flags, Arg1.Expr.IVal);
|
g_push (Arg1.Flags, Arg1.Expr.IVal);
|
||||||
Arg1.End = GetCodePos ();
|
GetCodePos (&Arg1.End);
|
||||||
ParamSize += SizeOf (Arg1Type);
|
ParamSize += SizeOf (Arg1Type);
|
||||||
ConsumeComma ();
|
ConsumeComma ();
|
||||||
|
|
||||||
@ -516,7 +517,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
|||||||
} else {
|
} else {
|
||||||
/* Push the argument */
|
/* Push the argument */
|
||||||
g_push (Arg2.Flags, Arg2.Expr.IVal);
|
g_push (Arg2.Flags, Arg2.Expr.IVal);
|
||||||
Arg2.End = GetCodePos ();
|
GetCodePos (&Arg2.End);
|
||||||
ParamSize += SizeOf (Arg2Type);
|
ParamSize += SizeOf (Arg2Type);
|
||||||
}
|
}
|
||||||
ConsumeComma ();
|
ConsumeComma ();
|
||||||
@ -542,7 +543,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
|||||||
/* Remove all of the generated code but the load of the first
|
/* Remove all of the generated code but the load of the first
|
||||||
* argument, which is what memset returns.
|
* argument, which is what memset returns.
|
||||||
*/
|
*/
|
||||||
RemoveCode (Arg1.Push);
|
RemoveCode (&Arg1.Push);
|
||||||
|
|
||||||
/* Set the function result to the first argument */
|
/* Set the function result to the first argument */
|
||||||
*Expr = Arg1.Expr;
|
*Expr = Arg1.Expr;
|
||||||
@ -568,7 +569,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
|||||||
int Reg = ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr);
|
int Reg = ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr);
|
||||||
|
|
||||||
/* Drop the generated code */
|
/* Drop the generated code */
|
||||||
RemoveCode (Start);
|
RemoveCode (&Start);
|
||||||
|
|
||||||
/* We need a label */
|
/* We need a label */
|
||||||
Label = GetLocalLabel ();
|
Label = GetLocalLabel ();
|
||||||
@ -617,7 +618,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
|||||||
int Offs = ED_GetStackOffs (&Arg1.Expr, 0);
|
int Offs = ED_GetStackOffs (&Arg1.Expr, 0);
|
||||||
|
|
||||||
/* Drop the generated code */
|
/* Drop the generated code */
|
||||||
RemoveCode (Start);
|
RemoveCode (&Start);
|
||||||
|
|
||||||
/* We need a label */
|
/* We need a label */
|
||||||
Label = GetLocalLabel ();
|
Label = GetLocalLabel ();
|
||||||
@ -643,7 +644,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
|||||||
/* Remove all of the generated code but the load of the first
|
/* Remove all of the generated code but the load of the first
|
||||||
* argument.
|
* argument.
|
||||||
*/
|
*/
|
||||||
RemoveCode (Arg1.Push);
|
RemoveCode (&Arg1.Push);
|
||||||
|
|
||||||
/* We need a label */
|
/* We need a label */
|
||||||
Label = GetLocalLabel ();
|
Label = GetLocalLabel ();
|
||||||
@ -716,12 +717,12 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
|||||||
Arg2Type[1] = GetDefaultChar () | T_QUAL_CONST;
|
Arg2Type[1] = GetDefaultChar () | T_QUAL_CONST;
|
||||||
|
|
||||||
/* Remember where we are now */
|
/* Remember where we are now */
|
||||||
Start = GetCodePos ();
|
GetCodePos (&Start);
|
||||||
|
|
||||||
/* Argument #1 */
|
/* Argument #1 */
|
||||||
ParseArg (&Arg1, Arg1Type);
|
ParseArg (&Arg1, Arg1Type);
|
||||||
g_push (Arg1.Flags, Arg1.Expr.IVal);
|
g_push (Arg1.Flags, Arg1.Expr.IVal);
|
||||||
Arg1.End = GetCodePos ();
|
GetCodePos (&Arg1.End);
|
||||||
ParamSize += SizeOf (Arg1Type);
|
ParamSize += SizeOf (Arg1Type);
|
||||||
ConsumeComma ();
|
ConsumeComma ();
|
||||||
|
|
||||||
@ -767,7 +768,7 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Drop the generated code */
|
/* Drop the generated code */
|
||||||
RemoveCode (Start);
|
RemoveCode (&Start);
|
||||||
|
|
||||||
/* We need labels */
|
/* We need labels */
|
||||||
L1 = GetLocalLabel ();
|
L1 = GetLocalLabel ();
|
||||||
@ -801,7 +802,7 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
|||||||
int Offs = ED_GetStackOffs (&Arg2.Expr, 0);
|
int Offs = ED_GetStackOffs (&Arg2.Expr, 0);
|
||||||
|
|
||||||
/* Drop the generated code */
|
/* Drop the generated code */
|
||||||
RemoveCode (Start);
|
RemoveCode (&Start);
|
||||||
|
|
||||||
/* We need labels */
|
/* We need labels */
|
||||||
L1 = GetLocalLabel ();
|
L1 = GetLocalLabel ();
|
||||||
@ -844,7 +845,7 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
|||||||
int Offs = ED_GetStackOffs (&Arg1.Expr, 0);
|
int Offs = ED_GetStackOffs (&Arg1.Expr, 0);
|
||||||
|
|
||||||
/* Drop the generated code */
|
/* Drop the generated code */
|
||||||
RemoveCode (Start);
|
RemoveCode (&Start);
|
||||||
|
|
||||||
/* We need labels */
|
/* We need labels */
|
||||||
L1 = GetLocalLabel ();
|
L1 = GetLocalLabel ();
|
||||||
@ -1057,7 +1058,7 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
|||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
@ -418,7 +418,7 @@ static void ForStatement (void)
|
|||||||
ConsumeSemi ();
|
ConsumeSemi ();
|
||||||
|
|
||||||
/* Remember the start of the increment expression */
|
/* Remember the start of the increment expression */
|
||||||
IncExprStart = GetCodePos();
|
GetCodePos (&IncExprStart);
|
||||||
|
|
||||||
/* Label for the increment expression */
|
/* Label for the increment expression */
|
||||||
g_defcodelabel (IncLabel);
|
g_defcodelabel (IncLabel);
|
||||||
@ -433,7 +433,7 @@ static void ForStatement (void)
|
|||||||
g_jump (TestLabel);
|
g_jump (TestLabel);
|
||||||
|
|
||||||
/* Remember the end of the increment expression */
|
/* Remember the end of the increment expression */
|
||||||
IncExprEnd = GetCodePos();
|
GetCodePos (&IncExprEnd);
|
||||||
|
|
||||||
/* Skip the closing paren */
|
/* Skip the closing paren */
|
||||||
ConsumeRParen ();
|
ConsumeRParen ();
|
||||||
@ -447,7 +447,9 @@ static void ForStatement (void)
|
|||||||
* the loop body.
|
* the loop body.
|
||||||
*/
|
*/
|
||||||
if (HaveIncExpr) {
|
if (HaveIncExpr) {
|
||||||
MoveCode (IncExprStart, IncExprEnd, GetCodePos());
|
CodeMark Here;
|
||||||
|
GetCodePos (&Here);
|
||||||
|
MoveCode (&IncExprStart, &IncExprEnd, &Here);
|
||||||
} else {
|
} else {
|
||||||
/* Jump back to the increment expression */
|
/* Jump back to the increment expression */
|
||||||
g_jump (IncLabel);
|
g_jump (IncLabel);
|
||||||
@ -520,7 +522,7 @@ int Statement (int* PendingToken)
|
|||||||
{
|
{
|
||||||
ExprDesc Expr;
|
ExprDesc Expr;
|
||||||
int GotBreak;
|
int GotBreak;
|
||||||
CodeMark Start;
|
CodeMark Start, End;
|
||||||
|
|
||||||
/* Assume no pending token */
|
/* Assume no pending token */
|
||||||
if (PendingToken) {
|
if (PendingToken) {
|
||||||
@ -593,7 +595,7 @@ int Statement (int* PendingToken)
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
/* Remember the current code position */
|
/* Remember the current code position */
|
||||||
Start = GetCodePos ();
|
GetCodePos (&Start);
|
||||||
/* Actual statement */
|
/* Actual statement */
|
||||||
ExprWithCheck (hie0, &Expr);
|
ExprWithCheck (hie0, &Expr);
|
||||||
/* Load the result only if it is an lvalue and the type is
|
/* Load the result only if it is an lvalue and the type is
|
||||||
@ -603,9 +605,10 @@ int Statement (int* PendingToken)
|
|||||||
LoadExpr (CF_NONE, &Expr);
|
LoadExpr (CF_NONE, &Expr);
|
||||||
}
|
}
|
||||||
/* If the statement didn't generate code, and is not of type
|
/* If the statement didn't generate code, and is not of type
|
||||||
* void, emit a warning
|
* void, emit a warning.
|
||||||
*/
|
*/
|
||||||
if (GetCodePos () == Start && !IsTypeVoid (Expr.Type)) {
|
GetCodePos (&End);
|
||||||
|
if (CodeRangeIsEmpty (&Start, &End) && !IsTypeVoid (Expr.Type)) {
|
||||||
Warning ("Statement has no effect");
|
Warning ("Statement has no effect");
|
||||||
}
|
}
|
||||||
CheckSemi (PendingToken);
|
CheckSemi (PendingToken);
|
||||||
|
@ -56,7 +56,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ void SwitchStatement (void)
|
|||||||
/* Remember the current code position. We will move the switch code
|
/* Remember the current code position. We will move the switch code
|
||||||
* to this position later.
|
* to this position later.
|
||||||
*/
|
*/
|
||||||
CaseCodeStart = GetCodePos();
|
GetCodePos (&CaseCodeStart);
|
||||||
|
|
||||||
/* Opening curly brace */
|
/* Opening curly brace */
|
||||||
ConsumeLCurly ();
|
ConsumeLCurly ();
|
||||||
@ -232,7 +232,7 @@ void SwitchStatement (void)
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
CodeMark SwitchCodeStart;
|
CodeMark SwitchCodeStart, SwitchCodeEnd;
|
||||||
|
|
||||||
/* If the last statement did not have a break, we may have an open
|
/* If the last statement did not have a break, we may have an open
|
||||||
* label (maybe from an if or similar). Emitting code and then moving
|
* label (maybe from an if or similar). Emitting code and then moving
|
||||||
@ -246,7 +246,7 @@ void SwitchStatement (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Remember the current position */
|
/* Remember the current position */
|
||||||
SwitchCodeStart = GetCodePos();
|
GetCodePos (&SwitchCodeStart);
|
||||||
|
|
||||||
/* Output the switch code label */
|
/* Output the switch code label */
|
||||||
g_defcodelabel (SwitchCodeLabel);
|
g_defcodelabel (SwitchCodeLabel);
|
||||||
@ -255,7 +255,8 @@ void SwitchStatement (void)
|
|||||||
g_switch (Nodes, DefaultLabel? DefaultLabel : ExitLabel, Depth);
|
g_switch (Nodes, DefaultLabel? DefaultLabel : ExitLabel, Depth);
|
||||||
|
|
||||||
/* Move the code to the front */
|
/* Move the code to the front */
|
||||||
MoveCode (SwitchCodeStart, GetCodePos(), CaseCodeStart);
|
GetCodePos (&SwitchCodeEnd);
|
||||||
|
MoveCode (&SwitchCodeStart, &SwitchCodeEnd, &CaseCodeStart);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user