mirror of
https://github.com/cc65/cc65.git
synced 2024-09-30 08:57:49 +00:00
Simplify code generated for the ?: operator when type conversion code for the
second operand is necessary. Instead of generating interleaved code with several jumps, just move the code to the right place. git-svn-id: svn://svn.cc65.org/cc65/trunk@4105 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
84710f7227
commit
944057238e
@ -2538,7 +2538,7 @@ static void hieOrPP (ExprDesc *Expr)
|
|||||||
static void hieAnd (ExprDesc* Expr, unsigned TrueLab, int* BoolOp)
|
static void hieAnd (ExprDesc* Expr, unsigned TrueLab, int* BoolOp)
|
||||||
/* Process "exp && exp" */
|
/* Process "exp && exp" */
|
||||||
{
|
{
|
||||||
int lab;
|
int FalseLab;
|
||||||
ExprDesc Expr2;
|
ExprDesc Expr2;
|
||||||
|
|
||||||
hie2 (Expr);
|
hie2 (Expr);
|
||||||
@ -2548,7 +2548,7 @@ static void hieAnd (ExprDesc* Expr, unsigned TrueLab, int* BoolOp)
|
|||||||
*BoolOp = 1;
|
*BoolOp = 1;
|
||||||
|
|
||||||
/* Get a label that we will use for false expressions */
|
/* Get a label that we will use for false expressions */
|
||||||
lab = GetLocalLabel ();
|
FalseLab = GetLocalLabel ();
|
||||||
|
|
||||||
/* If the expr hasn't set condition codes, set the force-test flag */
|
/* If the expr hasn't set condition codes, set the force-test flag */
|
||||||
if (!ED_IsTested (Expr)) {
|
if (!ED_IsTested (Expr)) {
|
||||||
@ -2559,7 +2559,7 @@ static void hieAnd (ExprDesc* Expr, unsigned TrueLab, int* BoolOp)
|
|||||||
LoadExpr (CF_FORCECHAR, Expr);
|
LoadExpr (CF_FORCECHAR, Expr);
|
||||||
|
|
||||||
/* Generate the jump */
|
/* Generate the jump */
|
||||||
g_falsejump (CF_NONE, lab);
|
g_falsejump (CF_NONE, FalseLab);
|
||||||
|
|
||||||
/* Parse more boolean and's */
|
/* Parse more boolean and's */
|
||||||
while (CurTok.Tok == TOK_BOOL_AND) {
|
while (CurTok.Tok == TOK_BOOL_AND) {
|
||||||
@ -2576,7 +2576,7 @@ static void hieAnd (ExprDesc* Expr, unsigned TrueLab, int* BoolOp)
|
|||||||
|
|
||||||
/* Do short circuit evaluation */
|
/* Do short circuit evaluation */
|
||||||
if (CurTok.Tok == TOK_BOOL_AND) {
|
if (CurTok.Tok == TOK_BOOL_AND) {
|
||||||
g_falsejump (CF_NONE, lab);
|
g_falsejump (CF_NONE, FalseLab);
|
||||||
} else {
|
} else {
|
||||||
/* Last expression - will evaluate to true */
|
/* Last expression - will evaluate to true */
|
||||||
g_truejump (CF_NONE, TrueLab);
|
g_truejump (CF_NONE, TrueLab);
|
||||||
@ -2584,7 +2584,7 @@ static void hieAnd (ExprDesc* Expr, unsigned TrueLab, int* BoolOp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Define the false jump label here */
|
/* Define the false jump label here */
|
||||||
g_defcodelabel (lab);
|
g_defcodelabel (FalseLab);
|
||||||
|
|
||||||
/* The result is an rvalue in primary */
|
/* The result is an rvalue in primary */
|
||||||
ED_MakeRValExpr (Expr);
|
ED_MakeRValExpr (Expr);
|
||||||
@ -2670,8 +2670,9 @@ static void hieOr (ExprDesc *Expr)
|
|||||||
static void hieQuest (ExprDesc* Expr)
|
static void hieQuest (ExprDesc* Expr)
|
||||||
/* Parse the ternary operator */
|
/* Parse the ternary operator */
|
||||||
{
|
{
|
||||||
int labf;
|
int FalseLab;
|
||||||
int labt;
|
int TrueLab;
|
||||||
|
CodeMark TrueCodeEnd;
|
||||||
ExprDesc Expr2; /* Expression 2 */
|
ExprDesc Expr2; /* Expression 2 */
|
||||||
ExprDesc Expr3; /* Expression 3 */
|
ExprDesc Expr3; /* Expression 3 */
|
||||||
int Expr2IsNULL; /* Expression 2 is a NULL pointer */
|
int Expr2IsNULL; /* Expression 2 is a NULL pointer */
|
||||||
@ -2694,8 +2695,8 @@ static void hieQuest (ExprDesc* Expr)
|
|||||||
ED_MarkForTest (Expr);
|
ED_MarkForTest (Expr);
|
||||||
}
|
}
|
||||||
LoadExpr (CF_NONE, Expr);
|
LoadExpr (CF_NONE, Expr);
|
||||||
labf = GetLocalLabel ();
|
FalseLab = GetLocalLabel ();
|
||||||
g_falsejump (CF_NONE, labf);
|
g_falsejump (CF_NONE, FalseLab);
|
||||||
|
|
||||||
/* Parse second expression. Remember for later if it is a NULL pointer
|
/* Parse second expression. Remember for later if it is a NULL pointer
|
||||||
* expression, then load it into the primary.
|
* expression, then load it into the primary.
|
||||||
@ -2708,14 +2709,19 @@ static void hieQuest (ExprDesc* Expr)
|
|||||||
ED_MakeRValExpr (&Expr2);
|
ED_MakeRValExpr (&Expr2);
|
||||||
Expr2.Type = PtrConversion (Expr2.Type);
|
Expr2.Type = PtrConversion (Expr2.Type);
|
||||||
}
|
}
|
||||||
labt = GetLocalLabel ();
|
|
||||||
|
/* Remember the current code position */
|
||||||
|
GetCodePos (&TrueCodeEnd);
|
||||||
|
|
||||||
|
/* Jump around the evaluation of the third expression */
|
||||||
|
TrueLab = GetLocalLabel ();
|
||||||
ConsumeColon ();
|
ConsumeColon ();
|
||||||
g_jump (labt);
|
g_jump (TrueLab);
|
||||||
|
|
||||||
/* Jump here if the first expression was false */
|
/* Jump here if the first expression was false */
|
||||||
g_defcodelabel (labf);
|
g_defcodelabel (FalseLab);
|
||||||
|
|
||||||
/* Parse second expression. Remember for later if it is a NULL pointer
|
/* Parse third expression. Remember for later if it is a NULL pointer
|
||||||
* expression, then load it into the primary.
|
* expression, then load it into the primary.
|
||||||
*/
|
*/
|
||||||
ExprWithCheck (hie1, &Expr3);
|
ExprWithCheck (hie1, &Expr3);
|
||||||
@ -2742,27 +2748,27 @@ static void hieQuest (ExprDesc* Expr)
|
|||||||
*/
|
*/
|
||||||
if (IsClassInt (Expr2.Type) && IsClassInt (Expr3.Type)) {
|
if (IsClassInt (Expr2.Type) && IsClassInt (Expr3.Type)) {
|
||||||
|
|
||||||
|
CodeMark CvtCodeStart;
|
||||||
|
CodeMark CvtCodeEnd;
|
||||||
|
|
||||||
|
|
||||||
/* Get common type */
|
/* Get common type */
|
||||||
ResultType = promoteint (Expr2.Type, Expr3.Type);
|
ResultType = promoteint (Expr2.Type, Expr3.Type);
|
||||||
|
|
||||||
/* Convert the third expression to this type if needed */
|
/* Convert the third expression to this type if needed */
|
||||||
TypeConversion (&Expr3, ResultType);
|
TypeConversion (&Expr3, ResultType);
|
||||||
|
|
||||||
/* Setup a new label so that the expr3 code will jump around
|
/* Emit conversion code for the second expression, but remember
|
||||||
* the type cast code for expr2.
|
* where it starts end ends.
|
||||||
*/
|
*/
|
||||||
labf = GetLocalLabel (); /* Get new label */
|
GetCodePos (&CvtCodeStart);
|
||||||
g_jump (labf); /* Jump around code */
|
|
||||||
|
|
||||||
/* The jump for expr2 goes here */
|
|
||||||
g_defcodelabel (labt);
|
|
||||||
|
|
||||||
/* Create the typecast code for expr2 */
|
|
||||||
TypeConversion (&Expr2, ResultType);
|
TypeConversion (&Expr2, ResultType);
|
||||||
|
GetCodePos (&CvtCodeEnd);
|
||||||
|
|
||||||
/* Jump here around the typecase code. */
|
/* If we had conversion code, move it to the right place */
|
||||||
g_defcodelabel (labf);
|
if (!CodeRangeIsEmpty (&CvtCodeStart, &CvtCodeEnd)) {
|
||||||
labt = 0; /* Mark other label as invalid */
|
MoveCode (&CvtCodeStart, &CvtCodeEnd, &TrueCodeEnd);
|
||||||
|
}
|
||||||
|
|
||||||
} else if (IsClassPtr (Expr2.Type) && IsClassPtr (Expr3.Type)) {
|
} else if (IsClassPtr (Expr2.Type) && IsClassPtr (Expr3.Type)) {
|
||||||
/* Must point to same type */
|
/* Must point to same type */
|
||||||
@ -2785,10 +2791,8 @@ static void hieQuest (ExprDesc* Expr)
|
|||||||
ResultType = Expr2.Type; /* Doesn't matter here */
|
ResultType = Expr2.Type; /* Doesn't matter here */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we don't have the label defined until now, do it */
|
/* Define the final label */
|
||||||
if (labt) {
|
g_defcodelabel (TrueLab);
|
||||||
g_defcodelabel (labt);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Setup the target expression */
|
/* Setup the target expression */
|
||||||
ED_MakeRValExpr (Expr);
|
ED_MakeRValExpr (Expr);
|
||||||
|
Loading…
Reference in New Issue
Block a user