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
9 changed files with 181 additions and 142 deletions
|
@ -6,9 +6,9 @@
|
|||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2000-2001 Ullrich von Bassewitz */
|
||||
/* Wacholderweg 14 */
|
||||
/* D-70597 Stuttgart */
|
||||
/* (C) 2000-2004 Ullrich von Bassewitz */
|
||||
/* Römerstraße 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* */
|
||||
/* */
|
||||
|
@ -37,12 +37,13 @@
|
|||
#include "check.h"
|
||||
|
||||
/* cc65 */
|
||||
#include "asmcode.h"
|
||||
#include "codeopt.h"
|
||||
#include "codeseg.h"
|
||||
#include "dataseg.h"
|
||||
#include "segments.h"
|
||||
#include "stackptr.h"
|
||||
#include "symtab.h"
|
||||
#include "asmcode.h"
|
||||
|
||||
|
||||
|
||||
|
@ -52,28 +53,45 @@
|
|||
|
||||
|
||||
|
||||
CodeMark GetCodePos (void)
|
||||
void GetCodePos (CodeMark* M)
|
||||
/* 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 */
|
||||
{
|
||||
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
|
||||
* (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 */
|
||||
/* Wacholderweg 14 */
|
||||
/* D-70597 Stuttgart */
|
||||
/* (C) 2000-2004 Ullrich von Bassewitz */
|
||||
/* Römerstraße 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* */
|
||||
/* */
|
||||
|
@ -52,7 +52,10 @@
|
|||
|
||||
|
||||
/* 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 */
|
||||
|
||||
void RemoveCode (CodeMark M);
|
||||
void RemoveCode (const CodeMark* M);
|
||||
/* 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
|
||||
* (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);
|
||||
/* Write the final output to a file */
|
||||
|
||||
|
|
|
@ -494,7 +494,7 @@ static void FunctionCall (ExprDesc* Expr)
|
|||
int IsFuncPtr; /* Flag */
|
||||
int StdFunc; /* Standard function index */
|
||||
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 IsFastCall = 0; /* True if it's a fast call function */
|
||||
int PtrOnStack = 0; /* True if a pointer copy is on stack */
|
||||
|
@ -530,7 +530,7 @@ static void FunctionCall (ExprDesc* Expr)
|
|||
ED_MakeRValExpr (Expr);
|
||||
|
||||
/* Remember the code position */
|
||||
Mark = GetCodePos ();
|
||||
GetCodePos (&Mark);
|
||||
|
||||
/* Push the pointer onto the stack and remember the offset */
|
||||
g_push (CF_PTR, 0);
|
||||
|
@ -567,8 +567,7 @@ static void FunctionCall (ExprDesc* Expr)
|
|||
* stack pointer.
|
||||
*/
|
||||
if (ParamSize == 0) {
|
||||
RemoveCode (Mark);
|
||||
pop (CF_PTR);
|
||||
RemoveCode (&Mark);
|
||||
PtrOnStack = 0;
|
||||
} else {
|
||||
/* Load from the saved copy */
|
||||
|
@ -850,8 +849,7 @@ static void ArrayRef (ExprDesc* Expr)
|
|||
ConstBaseAddr = (ED_IsLocConst (Expr) || ED_IsLocStack (Expr));
|
||||
|
||||
/* If we have a constant base, we delay the address fetch */
|
||||
Mark1 = GetCodePos ();
|
||||
Mark2 = 0; /* Silence gcc */
|
||||
GetCodePos (&Mark1);
|
||||
if (!ConstBaseAddr) {
|
||||
/* Get a pointer to the array into the primary */
|
||||
LoadExpr (CF_NONE, Expr);
|
||||
|
@ -860,7 +858,7 @@ static void ArrayRef (ExprDesc* Expr)
|
|||
* bit, even if this value is greater, since we cannot handle
|
||||
* other than 16bit stuff when doing indexing.
|
||||
*/
|
||||
Mark2 = GetCodePos ();
|
||||
GetCodePos (&Mark2);
|
||||
g_push (CF_PTR, 0);
|
||||
}
|
||||
|
||||
|
@ -908,8 +906,7 @@ static void ArrayRef (ExprDesc* Expr)
|
|||
* since we can generate expression+offset.
|
||||
*/
|
||||
if (!ConstBaseAddr) {
|
||||
RemoveCode (Mark2);
|
||||
pop (CF_PTR);
|
||||
RemoveCode (&Mark2);
|
||||
} else {
|
||||
/* Get an array pointer into the primary */
|
||||
LoadExpr (CF_NONE, Expr);
|
||||
|
@ -923,7 +920,7 @@ static void ArrayRef (ExprDesc* Expr)
|
|||
SubScript.IVal *= CheckedSizeOf (ElementType);
|
||||
|
||||
/* Remove the address load code */
|
||||
RemoveCode (Mark1);
|
||||
RemoveCode (&Mark1);
|
||||
|
||||
/* 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
|
||||
|
@ -964,7 +961,7 @@ static void ArrayRef (ExprDesc* Expr)
|
|||
} else {
|
||||
|
||||
/* Array subscript is not constant. Load it into the primary */
|
||||
Mark2 = GetCodePos ();
|
||||
GetCodePos (&Mark2);
|
||||
LoadExpr (CF_NONE, &SubScript);
|
||||
|
||||
/* Do scaling */
|
||||
|
@ -1031,7 +1028,7 @@ static void ArrayRef (ExprDesc* Expr)
|
|||
} else {
|
||||
Flags = CF_INT;
|
||||
}
|
||||
RemoveCode (Mark2);
|
||||
RemoveCode (&Mark2);
|
||||
|
||||
/* Get a pointer to the array into the primary. */
|
||||
LoadExpr (CF_NONE, Expr);
|
||||
|
@ -1592,11 +1589,12 @@ void hie10 (ExprDesc* Expr)
|
|||
ConsumeRParen ();
|
||||
} else {
|
||||
/* Remember the output queue pointer */
|
||||
CodeMark Mark = GetCodePos ();
|
||||
CodeMark Mark;
|
||||
GetCodePos (&Mark);
|
||||
hie10 (Expr);
|
||||
Size = CheckedSizeOf (Expr->Type);
|
||||
/* Remove any generated code */
|
||||
RemoveCode (Mark);
|
||||
RemoveCode (&Mark);
|
||||
}
|
||||
ED_MakeConstAbs (Expr, Size, type_size_t);
|
||||
ED_MarkAsUntested (Expr);
|
||||
|
@ -1660,16 +1658,16 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */
|
|||
NextToken ();
|
||||
|
||||
/* Get the lhs on stack */
|
||||
Mark1 = GetCodePos ();
|
||||
GetCodePos (&Mark1);
|
||||
ltype = TypeOf (Expr->Type);
|
||||
if (ED_IsConstAbs (Expr)) {
|
||||
/* Constant value */
|
||||
Mark2 = GetCodePos ();
|
||||
GetCodePos (&Mark2);
|
||||
g_push (ltype | CF_CONST, Expr->IVal);
|
||||
} else {
|
||||
/* Value not constant */
|
||||
LoadExpr (CF_NONE, Expr);
|
||||
Mark2 = GetCodePos ();
|
||||
GetCodePos (&Mark2);
|
||||
g_push (ltype, 0);
|
||||
}
|
||||
|
||||
|
@ -1685,8 +1683,7 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */
|
|||
if (ED_IsConstAbs (Expr) && rconst) {
|
||||
|
||||
/* Both operands are constant, remove the generated code */
|
||||
RemoveCode (Mark1);
|
||||
pop (ltype);
|
||||
RemoveCode (&Mark1);
|
||||
|
||||
/* Evaluate the result */
|
||||
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");
|
||||
}
|
||||
if ((Gen->Flags & GEN_NOPUSH) != 0) {
|
||||
RemoveCode (Mark2);
|
||||
pop (ltype);
|
||||
RemoveCode (&Mark2);
|
||||
ltype |= CF_REG; /* Value is in register */
|
||||
}
|
||||
}
|
||||
|
@ -1756,16 +1752,16 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
|
|||
NextToken ();
|
||||
|
||||
/* Get the lhs on stack */
|
||||
Mark1 = GetCodePos ();
|
||||
GetCodePos (&Mark1);
|
||||
ltype = TypeOf (Expr->Type);
|
||||
if (ED_IsConstAbs (Expr)) {
|
||||
/* Constant value */
|
||||
Mark2 = GetCodePos ();
|
||||
GetCodePos (&Mark2);
|
||||
g_push (ltype | CF_CONST, Expr->IVal);
|
||||
} else {
|
||||
/* Value not constant */
|
||||
LoadExpr (CF_NONE, Expr);
|
||||
Mark2 = GetCodePos ();
|
||||
GetCodePos (&Mark2);
|
||||
g_push (ltype, 0);
|
||||
}
|
||||
|
||||
|
@ -1797,8 +1793,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
|
|||
if (ED_IsConstAbs (Expr) && rconst) {
|
||||
|
||||
/* Both operands are constant, remove the generated code */
|
||||
RemoveCode (Mark1);
|
||||
pop (ltype);
|
||||
RemoveCode (&Mark1);
|
||||
|
||||
/* Evaluate the result */
|
||||
Expr->IVal = kcalc (tok, Expr->IVal, Expr2.IVal);
|
||||
|
@ -1813,8 +1808,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
|
|||
if (rconst) {
|
||||
flags |= CF_CONST;
|
||||
if ((Gen->Flags & GEN_NOPUSH) != 0) {
|
||||
RemoveCode (Mark2);
|
||||
pop (ltype);
|
||||
RemoveCode (&Mark2);
|
||||
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. */
|
||||
LoadExpr (CF_NONE, Expr); /* --> primary register */
|
||||
Mark = GetCodePos ();
|
||||
GetCodePos (&Mark);
|
||||
g_push (TypeOf (Expr->Type), 0); /* --> stack */
|
||||
|
||||
/* Evaluate the rhs */
|
||||
|
@ -2020,8 +2014,7 @@ static void parseadd (ExprDesc* Expr)
|
|||
rhst = Expr2.Type;
|
||||
|
||||
/* Remove pushed value from stack */
|
||||
RemoveCode (Mark);
|
||||
pop (TypeOf (Expr->Type));
|
||||
RemoveCode (&Mark);
|
||||
|
||||
/* Check for pointer arithmetic */
|
||||
if (IsClassPtr (lhst) && IsClassInt (rhst)) {
|
||||
|
@ -2121,9 +2114,9 @@ static void parsesub (ExprDesc* Expr)
|
|||
rscale = 1; /* Scale by 1, that is, don't scale */
|
||||
|
||||
/* Remember the output queue position, then bring the value onto the stack */
|
||||
Mark1 = GetCodePos ();
|
||||
GetCodePos (&Mark1);
|
||||
LoadExpr (CF_NONE, Expr); /* --> primary register */
|
||||
Mark2 = GetCodePos ();
|
||||
GetCodePos (&Mark2);
|
||||
g_push (TypeOf (lhst), 0); /* --> stack */
|
||||
|
||||
/* Parse the right hand side */
|
||||
|
@ -2136,8 +2129,7 @@ static void parsesub (ExprDesc* Expr)
|
|||
if (ED_IsConstAbs (Expr)) {
|
||||
|
||||
/* Both sides are constant, remove generated code */
|
||||
RemoveCode (Mark1);
|
||||
pop (TypeOf (lhst)); /* Clean up the stack */
|
||||
RemoveCode (&Mark1);
|
||||
|
||||
/* Check for pointer arithmetic */
|
||||
if (IsClassPtr (lhst) && IsClassInt (rhst)) {
|
||||
|
@ -2171,8 +2163,7 @@ static void parsesub (ExprDesc* Expr)
|
|||
/* Left hand side is not constant, right hand side is.
|
||||
* Remove pushed value from stack.
|
||||
*/
|
||||
RemoveCode (Mark2);
|
||||
pop (TypeOf (lhst));
|
||||
RemoveCode (&Mark2);
|
||||
|
||||
if (IsClassPtr (lhst) && IsClassInt (rhst)) {
|
||||
/* Left is pointer, right is int, must scale rhs */
|
||||
|
@ -2691,7 +2682,7 @@ static void opeq (const GenDesc* Gen, ExprDesc* Expr)
|
|||
LoadExpr (CF_NONE, Expr);
|
||||
|
||||
/* Bring the lhs on stack */
|
||||
Mark = GetCodePos ();
|
||||
GetCodePos (&Mark);
|
||||
g_push (flags, 0);
|
||||
|
||||
/* Evaluate the rhs */
|
||||
|
@ -2700,8 +2691,7 @@ static void opeq (const GenDesc* Gen, ExprDesc* Expr)
|
|||
* flag set, don't push the lhs.
|
||||
*/
|
||||
if (Gen->Flags & GEN_NOPUSH) {
|
||||
RemoveCode (Mark);
|
||||
pop (flags);
|
||||
RemoveCode (&Mark);
|
||||
}
|
||||
if (MustScale) {
|
||||
/* lhs is a pointer, scale rhs */
|
||||
|
|
|
@ -65,8 +65,11 @@ void ShiftExpr (struct ExprDesc* Expr)
|
|||
CodeMark Mark1;
|
||||
CodeMark Mark2;
|
||||
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 ltype, rtype, flags;
|
||||
unsigned GenFlags; /* Generator flags */
|
||||
unsigned ltype;
|
||||
int rconst; /* Operand is a constant */
|
||||
|
||||
|
||||
|
@ -85,20 +88,26 @@ void ShiftExpr (struct ExprDesc* Expr)
|
|||
Tok = CurTok.Tok;
|
||||
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 */
|
||||
ExprBits = SizeOf (Expr->Type) * 8;
|
||||
ExprBits = SizeOf (ResultType) * 8;
|
||||
|
||||
/* Get the lhs on stack */
|
||||
Mark1 = GetCodePos ();
|
||||
GetCodePos (&Mark1);
|
||||
ltype = TypeOf (Expr->Type);
|
||||
if (ED_IsConstAbs (Expr)) {
|
||||
/* Constant value */
|
||||
Mark2 = GetCodePos ();
|
||||
GetCodePos (&Mark2);
|
||||
g_push (ltype | CF_CONST, Expr->IVal);
|
||||
} else {
|
||||
/* Value not constant */
|
||||
LoadExpr (CF_NONE, Expr);
|
||||
Mark2 = GetCodePos ();
|
||||
GetCodePos (&Mark2);
|
||||
g_push (ltype, 0);
|
||||
}
|
||||
|
||||
|
@ -120,7 +129,11 @@ void ShiftExpr (struct ExprDesc* Expr)
|
|||
|
||||
} 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
|
||||
* the operand, the behaviour is undefined according to the
|
||||
|
@ -137,8 +150,7 @@ void ShiftExpr (struct ExprDesc* Expr)
|
|||
if (Expr2.IVal == 0) {
|
||||
|
||||
/* Result is already in Expr, remove the generated code */
|
||||
RemoveCode (Mark1);
|
||||
pop (ltype);
|
||||
RemoveCode (&Mark1);
|
||||
|
||||
/* Done */
|
||||
goto Next;
|
||||
|
@ -155,8 +167,7 @@ void ShiftExpr (struct ExprDesc* Expr)
|
|||
}
|
||||
|
||||
/* Both operands are constant, remove the generated code */
|
||||
RemoveCode (Mark1);
|
||||
pop (ltype);
|
||||
RemoveCode (&Mark1);
|
||||
|
||||
/* Done */
|
||||
goto Next;
|
||||
|
@ -191,8 +202,7 @@ void ShiftExpr (struct ExprDesc* Expr)
|
|||
}
|
||||
|
||||
/* Remove the generated load code */
|
||||
RemoveCode (Mark1);
|
||||
pop (ltype);
|
||||
RemoveCode (&Mark1);
|
||||
|
||||
/* Generate again code for the load */
|
||||
LoadExpr (CF_NONE, Expr);
|
||||
|
@ -203,46 +213,26 @@ void ShiftExpr (struct ExprDesc* Expr)
|
|||
/* If the shift count is now zero, we're done */
|
||||
if (Expr2.IVal == 0) {
|
||||
/* 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 */
|
||||
switch (Tok) {
|
||||
case TOK_SHL: g_asl (flags, Expr2.IVal); break;
|
||||
case TOK_SHR: g_asr (flags, Expr2.IVal); break;
|
||||
case TOK_SHL: g_asl (GenFlags, Expr2.IVal); break;
|
||||
case TOK_SHR: g_asr (GenFlags, Expr2.IVal); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
Loaded:
|
||||
MakeRVal:
|
||||
/* We have a rvalue in the primary now */
|
||||
ED_MakeRValExpr (Expr);
|
||||
|
||||
Next:
|
||||
/* Get the type of the result */
|
||||
Expr->Type = IntPromotion (Expr->Type);
|
||||
/* Set the type of the result */
|
||||
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 */
|
||||
/*****************************************************************************/
|
||||
|
@ -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 */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -151,7 +151,7 @@ static void ParseArg (ArgDesc* Arg, type* Type)
|
|||
Arg->ArgType = Type;
|
||||
|
||||
/* Remember the current code position */
|
||||
Arg->Start = GetCodePos ();
|
||||
GetCodePos (&Arg->Start);
|
||||
|
||||
/* Read the expression we're going to pass to the function */
|
||||
ExprWithCheck (hie1, &Arg->Expr);
|
||||
|
@ -174,7 +174,8 @@ static void ParseArg (ArgDesc* Arg, type* Type)
|
|||
}
|
||||
|
||||
/* 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 */
|
||||
Arg->Flags |= TypeOf (Arg->Expr.Type);
|
||||
|
@ -202,19 +203,19 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
|||
unsigned Label;
|
||||
|
||||
/* Remember where we are now */
|
||||
Start = GetCodePos ();
|
||||
GetCodePos (&Start);
|
||||
|
||||
/* Argument #1 */
|
||||
ParseArg (&Arg1, Arg1Type);
|
||||
g_push (Arg1.Flags, Arg1.Expr.IVal);
|
||||
Arg1.End = GetCodePos ();
|
||||
GetCodePos (&Arg1.End);
|
||||
ParamSize += SizeOf (Arg1Type);
|
||||
ConsumeComma ();
|
||||
|
||||
/* Argument #2 */
|
||||
ParseArg (&Arg2, Arg2Type);
|
||||
g_push (Arg2.Flags, Arg2.Expr.IVal);
|
||||
Arg2.End = GetCodePos ();
|
||||
GetCodePos (&Arg2.End);
|
||||
ParamSize += SizeOf (Arg2Type);
|
||||
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
|
||||
* argument, which is what memcpy returns.
|
||||
*/
|
||||
RemoveCode (Arg1.Push);
|
||||
RemoveCode (&Arg1.Push);
|
||||
|
||||
/* Set the function result to the first argument */
|
||||
*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);
|
||||
|
||||
/* Drop the generated code */
|
||||
RemoveCode (Start);
|
||||
RemoveCode (&Start);
|
||||
|
||||
/* We need a label */
|
||||
Label = GetLocalLabel ();
|
||||
|
@ -332,7 +333,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
|||
int Offs = ED_GetStackOffs (&Arg1.Expr, 0);
|
||||
|
||||
/* Drop the generated code */
|
||||
RemoveCode (Start);
|
||||
RemoveCode (&Start);
|
||||
|
||||
/* We need a label */
|
||||
Label = GetLocalLabel ();
|
||||
|
@ -406,7 +407,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
|||
int Offs = ED_GetStackOffs (&Arg2.Expr, 0);
|
||||
|
||||
/* Drop the generated code */
|
||||
RemoveCode (Start);
|
||||
RemoveCode (&Start);
|
||||
|
||||
/* We need a label */
|
||||
Label = GetLocalLabel ();
|
||||
|
@ -497,12 +498,12 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
|||
unsigned Label;
|
||||
|
||||
/* Remember where we are now */
|
||||
Start = GetCodePos ();
|
||||
GetCodePos (&Start);
|
||||
|
||||
/* Argument #1 */
|
||||
ParseArg (&Arg1, Arg1Type);
|
||||
g_push (Arg1.Flags, Arg1.Expr.IVal);
|
||||
Arg1.End = GetCodePos ();
|
||||
GetCodePos (&Arg1.End);
|
||||
ParamSize += SizeOf (Arg1Type);
|
||||
ConsumeComma ();
|
||||
|
||||
|
@ -516,7 +517,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
|||
} else {
|
||||
/* Push the argument */
|
||||
g_push (Arg2.Flags, Arg2.Expr.IVal);
|
||||
Arg2.End = GetCodePos ();
|
||||
GetCodePos (&Arg2.End);
|
||||
ParamSize += SizeOf (Arg2Type);
|
||||
}
|
||||
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
|
||||
* argument, which is what memset returns.
|
||||
*/
|
||||
RemoveCode (Arg1.Push);
|
||||
RemoveCode (&Arg1.Push);
|
||||
|
||||
/* Set the function result to the first argument */
|
||||
*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);
|
||||
|
||||
/* Drop the generated code */
|
||||
RemoveCode (Start);
|
||||
RemoveCode (&Start);
|
||||
|
||||
/* We need a label */
|
||||
Label = GetLocalLabel ();
|
||||
|
@ -617,7 +618,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
|||
int Offs = ED_GetStackOffs (&Arg1.Expr, 0);
|
||||
|
||||
/* Drop the generated code */
|
||||
RemoveCode (Start);
|
||||
RemoveCode (&Start);
|
||||
|
||||
/* We need a label */
|
||||
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
|
||||
* argument.
|
||||
*/
|
||||
RemoveCode (Arg1.Push);
|
||||
RemoveCode (&Arg1.Push);
|
||||
|
||||
/* We need a label */
|
||||
Label = GetLocalLabel ();
|
||||
|
@ -716,12 +717,12 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
|||
Arg2Type[1] = GetDefaultChar () | T_QUAL_CONST;
|
||||
|
||||
/* Remember where we are now */
|
||||
Start = GetCodePos ();
|
||||
GetCodePos (&Start);
|
||||
|
||||
/* Argument #1 */
|
||||
ParseArg (&Arg1, Arg1Type);
|
||||
g_push (Arg1.Flags, Arg1.Expr.IVal);
|
||||
Arg1.End = GetCodePos ();
|
||||
GetCodePos (&Arg1.End);
|
||||
ParamSize += SizeOf (Arg1Type);
|
||||
ConsumeComma ();
|
||||
|
||||
|
@ -767,7 +768,7 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
|||
}
|
||||
|
||||
/* Drop the generated code */
|
||||
RemoveCode (Start);
|
||||
RemoveCode (&Start);
|
||||
|
||||
/* We need labels */
|
||||
L1 = GetLocalLabel ();
|
||||
|
@ -801,7 +802,7 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
|||
int Offs = ED_GetStackOffs (&Arg2.Expr, 0);
|
||||
|
||||
/* Drop the generated code */
|
||||
RemoveCode (Start);
|
||||
RemoveCode (&Start);
|
||||
|
||||
/* We need labels */
|
||||
L1 = GetLocalLabel ();
|
||||
|
@ -844,7 +845,7 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
|||
int Offs = ED_GetStackOffs (&Arg1.Expr, 0);
|
||||
|
||||
/* Drop the generated code */
|
||||
RemoveCode (Start);
|
||||
RemoveCode (&Start);
|
||||
|
||||
/* We need labels */
|
||||
L1 = GetLocalLabel ();
|
||||
|
|
|
@ -418,7 +418,7 @@ static void ForStatement (void)
|
|||
ConsumeSemi ();
|
||||
|
||||
/* Remember the start of the increment expression */
|
||||
IncExprStart = GetCodePos();
|
||||
GetCodePos (&IncExprStart);
|
||||
|
||||
/* Label for the increment expression */
|
||||
g_defcodelabel (IncLabel);
|
||||
|
@ -433,7 +433,7 @@ static void ForStatement (void)
|
|||
g_jump (TestLabel);
|
||||
|
||||
/* Remember the end of the increment expression */
|
||||
IncExprEnd = GetCodePos();
|
||||
GetCodePos (&IncExprEnd);
|
||||
|
||||
/* Skip the closing paren */
|
||||
ConsumeRParen ();
|
||||
|
@ -447,7 +447,9 @@ static void ForStatement (void)
|
|||
* the loop body.
|
||||
*/
|
||||
if (HaveIncExpr) {
|
||||
MoveCode (IncExprStart, IncExprEnd, GetCodePos());
|
||||
CodeMark Here;
|
||||
GetCodePos (&Here);
|
||||
MoveCode (&IncExprStart, &IncExprEnd, &Here);
|
||||
} else {
|
||||
/* Jump back to the increment expression */
|
||||
g_jump (IncLabel);
|
||||
|
@ -520,7 +522,7 @@ int Statement (int* PendingToken)
|
|||
{
|
||||
ExprDesc Expr;
|
||||
int GotBreak;
|
||||
CodeMark Start;
|
||||
CodeMark Start, End;
|
||||
|
||||
/* Assume no pending token */
|
||||
if (PendingToken) {
|
||||
|
@ -593,7 +595,7 @@ int Statement (int* PendingToken)
|
|||
|
||||
default:
|
||||
/* Remember the current code position */
|
||||
Start = GetCodePos ();
|
||||
GetCodePos (&Start);
|
||||
/* Actual statement */
|
||||
ExprWithCheck (hie0, &Expr);
|
||||
/* 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);
|
||||
}
|
||||
/* 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");
|
||||
}
|
||||
CheckSemi (PendingToken);
|
||||
|
|
|
@ -109,7 +109,7 @@ void SwitchStatement (void)
|
|||
/* Remember the current code position. We will move the switch code
|
||||
* to this position later.
|
||||
*/
|
||||
CaseCodeStart = GetCodePos();
|
||||
GetCodePos (&CaseCodeStart);
|
||||
|
||||
/* Opening curly brace */
|
||||
ConsumeLCurly ();
|
||||
|
@ -232,7 +232,7 @@ void SwitchStatement (void)
|
|||
|
||||
} else {
|
||||
|
||||
CodeMark SwitchCodeStart;
|
||||
CodeMark SwitchCodeStart, SwitchCodeEnd;
|
||||
|
||||
/* 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
|
||||
|
@ -246,7 +246,7 @@ void SwitchStatement (void)
|
|||
}
|
||||
|
||||
/* Remember the current position */
|
||||
SwitchCodeStart = GetCodePos();
|
||||
GetCodePos (&SwitchCodeStart);
|
||||
|
||||
/* Output the switch code label */
|
||||
g_defcodelabel (SwitchCodeLabel);
|
||||
|
@ -255,7 +255,8 @@ void SwitchStatement (void)
|
|||
g_switch (Nodes, DefaultLabel? DefaultLabel : ExitLabel, Depth);
|
||||
|
||||
/* Move the code to the front */
|
||||
MoveCode (SwitchCodeStart, GetCodePos(), CaseCodeStart);
|
||||
GetCodePos (&SwitchCodeEnd);
|
||||
MoveCode (&SwitchCodeStart, &SwitchCodeEnd, &CaseCodeStart);
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue