X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fshiftexpr.c;h=6920590e8660e6e5ec8b08882f7a887862a3803e;hb=35e1184901ca38bdb2e56d154ed3b71f6096eacc;hp=f7b680ed9ae19cfeb676588cf60eb749a0da37db;hpb=76e31df5f83b23e56afca6493f95f5460b2d5822;p=cc65 diff --git a/src/cc65/shiftexpr.c b/src/cc65/shiftexpr.c index f7b680ed9..6920590e8 100644 --- a/src/cc65/shiftexpr.c +++ b/src/cc65/shiftexpr.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 2004 Ullrich von Bassewitz */ +/* (C) 2004-2006 Ullrich von Bassewitz */ /* Römerstraße 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -47,13 +47,13 @@ /*****************************************************************************/ -/* Data */ +/* Data */ /*****************************************************************************/ /*****************************************************************************/ -/* Code */ +/* Code */ /*****************************************************************************/ @@ -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 (); - ltype = TypeOf (Expr->Type); + 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,26 +167,25 @@ void ShiftExpr (struct ExprDesc* Expr) } /* Both operands are constant, remove the generated code */ - RemoveCode (Mark1); - pop (ltype); + RemoveCode (&Mark1); /* Done */ goto Next; } - /* If we're shifting an integer or unsigned to the left, the + /* If we're shifting an integer or unsigned to the right, the * lhs has a const address, and the shift count is larger than 8, * we can load just the high byte as a char with the correct * signedness, and reduce the shift count by 8. If the remaining * shift count is zero, we're done. */ - if (Tok == TOK_SHL && + if (Tok == TOK_SHR && IsTypeInt (Expr->Type) && ED_IsLVal (Expr) && (ED_IsLocConst (Expr) || ED_IsLocStack (Expr)) && Expr2.IVal >= 8) { - type* OldType; + Type* OldType; /* Increase the address by one and decrease the shift count */ ++Expr->IVal; @@ -191,10 +202,9 @@ void ShiftExpr (struct ExprDesc* Expr) } /* Remove the generated load code */ - RemoveCode (Mark1); - pop (ltype); + RemoveCode (&Mark1); - /* Generate again code for the load */ + /* Generate again code for the load, this time with the new type */ LoadExpr (CF_NONE, Expr); /* Reset the type */ @@ -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; - default: 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; } }