+/*-----------------------------------------------------------------*/
+/* optimizeSWAP :- optimize for nibble/byte/word swaps */
+/*-----------------------------------------------------------------*/
+ast *
+optimizeSWAP (ast * root)
+{
+ /* will look for trees of the form
+ (?expr << 4) | (?expr >> 4) or
+ (?expr >> 4) | (?expr << 4) will make that
+ into a SWAP : operation ..
+ note : by 4 I mean (number of bits required to hold the
+ variable /2 ) */
+ /* if the root operations is not a | operation the not */
+ if (!IS_BITOR (root))
+ return root;
+
+ /* (?expr << 4) | (?expr >> 4) */
+ if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
+ || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
+ {
+
+ if (!SPEC_USIGN (TETYPE (root->left->left)))
+ return root;
+
+ if (!IS_AST_LIT_VALUE (root->left->right) ||
+ !IS_AST_LIT_VALUE (root->right->right))
+ return root;
+
+ /* make sure it is the same expression */
+ if (!isAstEqual (root->left->left,
+ root->right->left))
+ return root;
+
+ if (AST_LIT_VALUE (root->left->right) !=
+ (getSize (TTYPE (root->left->left)) * 4))
+ return root;
+
+ if (AST_LIT_VALUE (root->right->right) !=
+ (getSize (TTYPE (root->left->left)) * 4))
+ return root;
+
+ /* make sure the port supports SWAP */
+ if (port->hasExtBitOp
+ && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
+ return root;
+
+ /* found it : create the AST */
+ return newNode (SWAP, root->left->left, NULL);
+ }
+
+
+ /* not found return root */
+ return root;
+}
+