mirror of
https://github.com/cc65/cc65.git
synced 2025-03-01 11:29:27 +00:00
Made int+pointer work in constant expressions.
Fixed codegen for cast type addition in constant expressions. Calls on swapstk in 'i+ptr' is avoided when possible.
This commit is contained in:
parent
aa6fdf58b8
commit
f5972dfd08
295
src/cc65/expr.c
295
src/cc65/expr.c
@ -3045,6 +3045,9 @@ static void parseadd (ExprDesc* Expr)
|
|||||||
CodeMark Mark; /* Remember code position */
|
CodeMark Mark; /* Remember code position */
|
||||||
Type* lhst; /* Type of left hand side */
|
Type* lhst; /* Type of left hand side */
|
||||||
Type* rhst; /* Type of right hand side */
|
Type* rhst; /* Type of right hand side */
|
||||||
|
int lscale;
|
||||||
|
int rscale;
|
||||||
|
int AddDone; /* No need to generate runtime code */
|
||||||
|
|
||||||
ED_Init (&Expr2);
|
ED_Init (&Expr2);
|
||||||
Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR;
|
Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR;
|
||||||
@ -3055,44 +3058,133 @@ static void parseadd (ExprDesc* Expr)
|
|||||||
/* Get the left hand side type, initialize operation flags */
|
/* Get the left hand side type, initialize operation flags */
|
||||||
lhst = Expr->Type;
|
lhst = Expr->Type;
|
||||||
flags = 0;
|
flags = 0;
|
||||||
|
lscale = rscale = 1;
|
||||||
|
AddDone = 0;
|
||||||
|
|
||||||
/* Check for constness on both sides */
|
/* We can only do constant expressions for:
|
||||||
if (ED_IsConst (Expr)) {
|
** - integer addition:
|
||||||
|
** - numeric + numeric
|
||||||
|
** - (integer)(base + offset) + numeric
|
||||||
|
** - numeric + (integer)(base + offset)
|
||||||
|
** - pointer offset:
|
||||||
|
** - (pointer)numeric + numeric * scale
|
||||||
|
** - (base + offset) + numeric * scale
|
||||||
|
** - (pointer)numeric + (integer)(base + offset) * 1
|
||||||
|
** - numeric * scale + (pointer)numeric
|
||||||
|
** - numeric * scale + (base + offset)
|
||||||
|
** - (integer)(base + offset) * 1 + (pointer)numeric
|
||||||
|
*/
|
||||||
|
if (ED_IsQuasiConst (Expr)) {
|
||||||
|
|
||||||
/* The left hand side is a constant of some sort. Good. Get rhs */
|
/* The left hand side is a constant of some sort. Good. Get rhs */
|
||||||
ExprWithCheck (hie9, &Expr2);
|
ExprWithCheck (hie9, &Expr2);
|
||||||
if (ED_IsConstAbs (&Expr2)) {
|
|
||||||
|
|
||||||
/* Right hand side is a constant numeric value. Get the rhs type */
|
/* Right hand side is constant. Get the rhs type */
|
||||||
rhst = Expr2.Type;
|
rhst = Expr2.Type;
|
||||||
|
if (ED_IsQuasiConst (&Expr2)) {
|
||||||
|
|
||||||
/* Both expressions are constants. Check for pointer arithmetic */
|
/* Both expressions are constants. Check for pointer arithmetic */
|
||||||
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 */
|
||||||
Expr->IVal += Expr2.IVal * CheckedPSizeOf (lhst);
|
rscale = CheckedPSizeOf (lhst);
|
||||||
/* Result type is a pointer */
|
/* Operate on pointers, result type is a pointer */
|
||||||
|
flags = CF_PTR;
|
||||||
} else if (IsClassInt (lhst) && IsClassPtr (rhst)) {
|
} else if (IsClassInt (lhst) && IsClassPtr (rhst)) {
|
||||||
/* Left is int, right is pointer, must scale lhs */
|
/* Left is int, right is pointer, must scale lhs */
|
||||||
Expr->IVal = Expr->IVal * CheckedPSizeOf (rhst) + Expr2.IVal;
|
lscale = CheckedPSizeOf (rhst);
|
||||||
/* Result type is a pointer */
|
/* Operate on pointers, result type is a pointer */
|
||||||
Expr->Type = Expr2.Type;
|
flags = CF_PTR;
|
||||||
} else if (IsClassInt (lhst) && IsClassInt (rhst)) {
|
} else if (IsClassInt (lhst) && IsClassInt (rhst)) {
|
||||||
/* Integer addition */
|
/* Integer addition */
|
||||||
Expr->IVal += Expr2.IVal;
|
flags = CF_INT;
|
||||||
typeadjust (Expr, &Expr2, 1);
|
|
||||||
|
|
||||||
/* Limit the calculated value to the range of its type */
|
|
||||||
LimitExprValue (Expr);
|
|
||||||
} else {
|
} else {
|
||||||
/* OOPS */
|
/* OOPS */
|
||||||
Error ("Invalid operands for binary operator '+'");
|
AddDone = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ED_IsAbs (&Expr2) &&
|
||||||
|
(ED_IsAbs (Expr) || lscale == 1)) {
|
||||||
|
if (IsClassInt (lhst) && IsClassInt (rhst)) {
|
||||||
|
typeadjust (Expr, &Expr2, 1);
|
||||||
|
}
|
||||||
|
Expr->IVal = Expr->IVal * lscale + Expr2.IVal * rscale;
|
||||||
|
AddDone = 1;
|
||||||
|
} else if (ED_IsAbs (Expr) &&
|
||||||
|
(ED_IsAbs (&Expr2) || rscale == 1)) {
|
||||||
|
if (IsClassInt (lhst) && IsClassInt (rhst)) {
|
||||||
|
typeadjust (&Expr2, Expr, 1);
|
||||||
|
}
|
||||||
|
Expr2.IVal = Expr->IVal * lscale + Expr2.IVal * rscale;
|
||||||
|
/* Adjust the flags */
|
||||||
|
Expr2.Flags |= Expr->Flags & ~E_MASK_KEEP_SUBEXPR;
|
||||||
|
/* Get the symbol and the name */
|
||||||
|
*Expr = Expr2;
|
||||||
|
AddDone = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AddDone) {
|
||||||
|
/* Adjust the result */
|
||||||
|
if (IsClassPtr (lhst)) {
|
||||||
|
/* Result type is a pointer */
|
||||||
|
Expr->Type = PtrConversion (lhst);
|
||||||
|
} else if (IsClassPtr (rhst)) {
|
||||||
|
/* Result type is a pointer */
|
||||||
|
Expr->Type = PtrConversion (rhst);
|
||||||
|
} else {
|
||||||
|
/* Limit the calculated value to the range of its type */
|
||||||
|
LimitExprValue (Expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The result is always an rvalue */
|
||||||
|
ED_MarkExprAsRVal (Expr);
|
||||||
|
} else {
|
||||||
|
/* Decide the order */
|
||||||
|
if (!ED_IsAbs (&Expr2) && rscale > 1) {
|
||||||
|
/* Rhs needs scaling but is not numeric. Load it. */
|
||||||
|
LoadExpr (CF_NONE, &Expr2);
|
||||||
|
/* Scale rhs */
|
||||||
|
g_scale (CF_INT, rscale);
|
||||||
|
/* Generate the code for the add */
|
||||||
|
if (ED_IsAbs (Expr)) {
|
||||||
|
/* Numeric constant */
|
||||||
|
g_inc (flags | CF_CONST, Expr->IVal);
|
||||||
|
} else if (ED_IsLocStack (Expr)) {
|
||||||
|
/* Local stack address */
|
||||||
|
g_addaddr_local (flags, Expr->IVal);
|
||||||
|
} else {
|
||||||
|
/* Static address */
|
||||||
|
g_addaddr_static (flags | GlobalModeFlags (Expr), Expr->Name, Expr->IVal);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Lhs is not numeric. Load it. */
|
||||||
|
LoadExpr (CF_NONE, Expr);
|
||||||
|
/* Scale lhs if necessary */
|
||||||
|
if (lscale != 1) {
|
||||||
|
g_scale (CF_INT, lscale);
|
||||||
|
}
|
||||||
|
/* Generate the code for the add */
|
||||||
|
if (ED_IsAbs (&Expr2)) {
|
||||||
|
/* Numeric constant */
|
||||||
|
g_inc (flags | CF_CONST, Expr2.IVal);
|
||||||
|
} else if (ED_IsLocStack (&Expr2)) {
|
||||||
|
/* Local stack address */
|
||||||
|
g_addaddr_local (flags, Expr2.IVal);
|
||||||
|
} else {
|
||||||
|
/* Static address */
|
||||||
|
g_addaddr_static (flags | GlobalModeFlags (&Expr2), Expr2.Name, Expr2.IVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Result is an rvalue in primary register */
|
||||||
|
ED_FinalizeRValLoad (Expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* lhs is a constant and rhs is not constant. Load rhs into
|
/* lhs is constant and rhs is not constant. Load rhs into the
|
||||||
** the primary.
|
** primary.
|
||||||
*/
|
*/
|
||||||
|
GetCodePos (&Mark);
|
||||||
LoadExpr (CF_NONE, &Expr2);
|
LoadExpr (CF_NONE, &Expr2);
|
||||||
|
|
||||||
/* Beware: The check above (for lhs) lets not only pass numeric
|
/* Beware: The check above (for lhs) lets not only pass numeric
|
||||||
@ -3100,11 +3192,8 @@ static void parseadd (ExprDesc* Expr)
|
|||||||
** with an offset. We have to check for that here.
|
** with an offset. We have to check for that here.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* First, get the rhs type. */
|
|
||||||
rhst = Expr2.Type;
|
|
||||||
|
|
||||||
/* Setup flags */
|
/* Setup flags */
|
||||||
if (ED_IsLocNone (Expr)) {
|
if (ED_IsAbs (Expr)) {
|
||||||
/* A numerical constant */
|
/* A numerical constant */
|
||||||
flags |= CF_CONST;
|
flags |= CF_CONST;
|
||||||
} else {
|
} else {
|
||||||
@ -3115,62 +3204,72 @@ static void parseadd (ExprDesc* Expr)
|
|||||||
/* Check for pointer arithmetic */
|
/* Check for pointer arithmetic */
|
||||||
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 */
|
||||||
g_scale (CF_INT, CheckedPSizeOf (lhst));
|
rscale = CheckedPSizeOf (lhst);
|
||||||
|
g_scale (CF_INT, rscale);
|
||||||
/* Operate on pointers, result type is a pointer */
|
/* Operate on pointers, result type is a pointer */
|
||||||
flags |= CF_PTR;
|
flags |= CF_PTR;
|
||||||
/* Generate the code for the add */
|
|
||||||
if (ED_GetLoc (Expr) == E_LOC_NONE) {
|
|
||||||
/* Numeric constant */
|
|
||||||
g_inc (flags, Expr->IVal);
|
|
||||||
} else {
|
|
||||||
/* Constant address */
|
|
||||||
g_addaddr_static (flags, Expr->Name, Expr->IVal);
|
|
||||||
}
|
|
||||||
} else if (IsClassInt (lhst) && IsClassPtr (rhst)) {
|
} else if (IsClassInt (lhst) && IsClassPtr (rhst)) {
|
||||||
|
|
||||||
/* Left is int, right is pointer, must scale lhs. */
|
/* Left is int, right is pointer, must scale lhs. */
|
||||||
unsigned ScaleFactor = CheckedPSizeOf (rhst);
|
lscale = CheckedPSizeOf (rhst);
|
||||||
|
|
||||||
/* Operate on pointers, result type is a pointer */
|
/* Operate on pointers, result type is a pointer */
|
||||||
flags |= CF_PTR;
|
flags |= CF_PTR;
|
||||||
Expr->Type = Expr2.Type;
|
Expr->Type = Expr2.Type;
|
||||||
|
|
||||||
/* Since we do already have rhs in the primary, if lhs is
|
|
||||||
** not a numeric constant, and the scale factor is not one
|
|
||||||
** (no scaling), we must take the long way over the stack.
|
|
||||||
*/
|
|
||||||
if (ED_IsLocNone (Expr)) {
|
|
||||||
/* Numeric constant, scale lhs */
|
|
||||||
Expr->IVal *= ScaleFactor;
|
|
||||||
/* Generate the code for the add */
|
|
||||||
g_inc (flags, Expr->IVal);
|
|
||||||
} else if (ScaleFactor == 1) {
|
|
||||||
/* Constant address but no need to scale */
|
|
||||||
g_addaddr_static (flags, Expr->Name, Expr->IVal);
|
|
||||||
} else {
|
|
||||||
/* Constant address that must be scaled */
|
|
||||||
g_push (TypeOf (Expr2.Type), 0); /* rhs --> stack */
|
|
||||||
g_getimmed (flags, Expr->Name, Expr->IVal);
|
|
||||||
g_scale (CF_PTR, ScaleFactor);
|
|
||||||
g_add (CF_PTR, 0);
|
|
||||||
}
|
|
||||||
} else if (IsClassInt (lhst) && IsClassInt (rhst)) {
|
} else if (IsClassInt (lhst) && IsClassInt (rhst)) {
|
||||||
/* Integer addition */
|
/* Integer addition */
|
||||||
flags |= typeadjust (Expr, &Expr2, 1);
|
flags |= typeadjust (Expr, &Expr2, 1);
|
||||||
/* Generate the code for the add */
|
|
||||||
if (ED_IsLocNone (Expr)) {
|
|
||||||
/* Numeric constant */
|
|
||||||
g_inc (flags, Expr->IVal);
|
|
||||||
} else {
|
|
||||||
/* Constant address */
|
|
||||||
g_addaddr_static (flags, Expr->Name, Expr->IVal);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
/* OOPS */
|
/* OOPS */
|
||||||
Error ("Invalid operands for binary operator '+'");
|
AddDone = -1;
|
||||||
flags = CF_INT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Generate the code for the add */
|
||||||
|
if (!AddDone) {
|
||||||
|
if (ED_IsAbs (Expr) &&
|
||||||
|
Expr->IVal >= 0 &&
|
||||||
|
Expr->IVal * lscale < 256) {
|
||||||
|
/* Numeric constant */
|
||||||
|
g_inc (flags, Expr->IVal * lscale);
|
||||||
|
AddDone = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AddDone) {
|
||||||
|
if (ED_IsLocQuasiConst (&Expr2) &&
|
||||||
|
rscale == 1 &&
|
||||||
|
CheckedSizeOf (rhst) == SIZEOF_CHAR) {
|
||||||
|
/* Change the order back */
|
||||||
|
RemoveCode (&Mark);
|
||||||
|
/* Load lhs */
|
||||||
|
LoadExpr (CF_NONE, Expr);
|
||||||
|
/* Use new flags */
|
||||||
|
flags = CF_CHAR | GlobalModeFlags (&Expr2);
|
||||||
|
/* Add the variable */
|
||||||
|
if (ED_IsLocStack (&Expr2)) {
|
||||||
|
g_addlocal (flags, Expr2.IVal);
|
||||||
|
} else {
|
||||||
|
g_addstatic (flags, Expr2.Name, Expr2.IVal);
|
||||||
|
}
|
||||||
|
} else if (ED_IsAbs (Expr)) {
|
||||||
|
/* Numeric constant */
|
||||||
|
g_inc (flags, Expr->IVal * lscale);
|
||||||
|
} else if (lscale == 1) {
|
||||||
|
if (ED_IsLocStack (Expr)) {
|
||||||
|
/* Constant address */
|
||||||
|
g_addaddr_local (flags, Expr->IVal);
|
||||||
|
} else {
|
||||||
|
g_addaddr_static (flags, Expr->Name, Expr->IVal);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Since we do already have rhs in the primary, if lhs is
|
||||||
|
** not a numeric constant, and the scale factor is not one
|
||||||
|
** (no scaling), we must take the long way over the stack.
|
||||||
|
*/
|
||||||
|
g_push (TypeOf (Expr2.Type), 0); /* rhs --> stack */
|
||||||
|
LoadExpr (CF_NONE, Expr);
|
||||||
|
g_scale (CF_PTR, lscale);
|
||||||
|
g_add (CF_PTR, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
/* Array and function types must be converted to pointer types */
|
/* Array and function types must be converted to pointer types */
|
||||||
Expr->Type = PtrConversion (Expr->Type);
|
Expr->Type = PtrConversion (Expr->Type);
|
||||||
|
|
||||||
@ -3181,20 +3280,21 @@ static void parseadd (ExprDesc* Expr)
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* 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 */
|
||||||
GetCodePos (&Mark);
|
GetCodePos (&Mark);
|
||||||
g_push (TypeOf (Expr->Type), 0); /* --> stack */
|
flags = TypeOf (Expr->Type); /* default codegen type */
|
||||||
|
g_push (flags, 0); /* --> stack */
|
||||||
|
|
||||||
/* Evaluate the rhs */
|
/* Evaluate the rhs */
|
||||||
MarkedExprWithCheck (hie9, &Expr2);
|
MarkedExprWithCheck (hie9, &Expr2);
|
||||||
|
|
||||||
|
/* Get the rhs type */
|
||||||
|
rhst = Expr2.Type;
|
||||||
|
|
||||||
/* Check for a constant rhs expression */
|
/* Check for a constant rhs expression */
|
||||||
if (ED_IsConstAbs (&Expr2) && ED_CodeRangeIsEmpty (&Expr2)) {
|
if (ED_IsConstAbs (&Expr2) && ED_CodeRangeIsEmpty (&Expr2)) {
|
||||||
|
|
||||||
/* Right hand side is a constant. Get the rhs type */
|
/* Rhs is a constant. Remove pushed lhs from stack. */
|
||||||
rhst = Expr2.Type;
|
|
||||||
|
|
||||||
/* Remove pushed value from stack */
|
|
||||||
RemoveCode (&Mark);
|
RemoveCode (&Mark);
|
||||||
|
|
||||||
/* Check for pointer arithmetic */
|
/* Check for pointer arithmetic */
|
||||||
@ -3214,8 +3314,7 @@ static void parseadd (ExprDesc* Expr)
|
|||||||
flags = typeadjust (Expr, &Expr2, 1);
|
flags = typeadjust (Expr, &Expr2, 1);
|
||||||
} else {
|
} else {
|
||||||
/* OOPS */
|
/* OOPS */
|
||||||
Error ("Invalid operands for binary operator '+'");
|
AddDone = -1;
|
||||||
flags = CF_INT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate code for the add */
|
/* Generate code for the add */
|
||||||
@ -3223,23 +3322,37 @@ static void parseadd (ExprDesc* Expr)
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Not constant, load into the primary */
|
/* Lhs and rhs are not so constant. Check for pointer arithmetic. */
|
||||||
LoadExpr (CF_NONE, &Expr2);
|
|
||||||
|
|
||||||
/* lhs and rhs are not constant. Get the rhs type. */
|
|
||||||
rhst = Expr2.Type;
|
|
||||||
|
|
||||||
/* Check for pointer arithmetic */
|
|
||||||
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 */
|
||||||
g_scale (CF_INT, CheckedPSizeOf (lhst));
|
rscale = CheckedPSizeOf (lhst);
|
||||||
|
if (ED_IsAbs (&Expr2)) {
|
||||||
|
Expr2.IVal *= rscale;
|
||||||
|
/* Load rhs into the primary */
|
||||||
|
LoadExpr (CF_NONE, &Expr2);
|
||||||
|
} else {
|
||||||
|
/* Load rhs into the primary */
|
||||||
|
LoadExpr (CF_NONE, &Expr2);
|
||||||
|
g_scale (CF_INT, rscale);
|
||||||
|
}
|
||||||
/* Operate on pointers, result type is a pointer */
|
/* Operate on pointers, result type is a pointer */
|
||||||
flags = CF_PTR;
|
flags = CF_PTR;
|
||||||
} else if (IsClassInt (lhst) && IsClassPtr (rhst)) {
|
} else if (IsClassInt (lhst) && IsClassPtr (rhst)) {
|
||||||
/* Left is int, right is pointer, must scale lhs */
|
/* Left is int, right is pointer, must scale lhs */
|
||||||
g_tosint (TypeOf (lhst)); /* Make sure TOS is int */
|
lscale = CheckedPSizeOf (rhst);
|
||||||
g_swap (CF_INT); /* Swap TOS and primary */
|
if (ED_CodeRangeIsEmpty (&Expr2)) {
|
||||||
g_scale (CF_INT, CheckedPSizeOf (rhst));
|
RemoveCode (&Mark); /* Remove pushed value from stack */
|
||||||
|
g_scale (CF_INT, lscale);
|
||||||
|
g_push (CF_PTR, 0); /* --> stack */
|
||||||
|
LoadExpr (CF_NONE, &Expr2); /* Load rhs into primary register */
|
||||||
|
} else {
|
||||||
|
g_tosint (TypeOf (lhst)); /* Make sure TOS is int */
|
||||||
|
LoadExpr (CF_NONE, &Expr2); /* Load rhs into primary register */
|
||||||
|
if (lscale != 1) {
|
||||||
|
g_swap (CF_INT); /* Swap TOS and primary */
|
||||||
|
g_scale (CF_INT, CheckedPSizeOf (rhst));
|
||||||
|
}
|
||||||
|
}
|
||||||
/* Operate on pointers, result type is a pointer */
|
/* Operate on pointers, result type is a pointer */
|
||||||
flags = CF_PTR;
|
flags = CF_PTR;
|
||||||
Expr->Type = Expr2.Type;
|
Expr->Type = Expr2.Type;
|
||||||
@ -3254,10 +3367,12 @@ static void parseadd (ExprDesc* Expr)
|
|||||||
** when trying to apply another solution.
|
** when trying to apply another solution.
|
||||||
*/
|
*/
|
||||||
flags = typeadjust (Expr, &Expr2, 0) & ~CF_CONST;
|
flags = typeadjust (Expr, &Expr2, 0) & ~CF_CONST;
|
||||||
|
/* Load rhs into the primary */
|
||||||
|
LoadExpr (CF_NONE, &Expr2);
|
||||||
} else {
|
} else {
|
||||||
/* OOPS */
|
/* OOPS */
|
||||||
Error ("Invalid operands for binary operator '+'");
|
AddDone = -1;
|
||||||
flags = CF_INT;
|
/* We can't just goto End as that would leave the stack unbalanced */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate code for the add */
|
/* Generate code for the add */
|
||||||
@ -3265,10 +3380,20 @@ static void parseadd (ExprDesc* Expr)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Array and function types must be converted to pointer types */
|
||||||
|
Expr->Type = PtrConversion (Expr->Type);
|
||||||
|
|
||||||
/* Result is an rvalue in primary register */
|
/* Result is an rvalue in primary register */
|
||||||
ED_FinalizeRValLoad (Expr);
|
ED_FinalizeRValLoad (Expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (AddDone < 0) {
|
||||||
|
Error ("Invalid operands for binary operator '+'");
|
||||||
|
} else {
|
||||||
|
/* Array and function types must be converted to pointer types */
|
||||||
|
Expr->Type = PtrConversion (Expr->Type);
|
||||||
|
}
|
||||||
|
|
||||||
/* Condition code not set */
|
/* Condition code not set */
|
||||||
ED_MarkAsUntested (Expr);
|
ED_MarkAsUntested (Expr);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user