]> git.sur5r.net Git - cc65/blobdiff - src/cc65/shiftexpr.c
Removed unneeded include files.
[cc65] / src / cc65 / shiftexpr.c
index f7b680ed9ae19cfeb676588cf60eb749a0da37db..6920590e8660e6e5ec8b08882f7a887862a3803e 100644 (file)
@@ -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                                                 */
 
 
 /*****************************************************************************/
-/*                                  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;
     }
 }