public void visit_dup2_x2(final Instruction inst) {
		// 0 1 2 3 -> 2 3 0 1 2 3
		// 0 1 2-3 -> 2-3 0 1 2-3
		// 0-1 2 3 -> 2 3 0-1 2 3
		// 0-1 2-3 -> 2-3 0-1 2-3

		if (Tree.USE_STACK) {
			saveStack();

			final Expr[] s23 = stack.pop2();
			final Expr[] s01 = stack.pop2();

			if ((s01.length == 2) && (s23.length == 2)) {
				// 0 1 2 3 -> 2 3 0 1 2 3
				final StackExpr[] s = new StackExpr[] { (StackExpr) s01[0],
						(StackExpr) s01[1], (StackExpr) s23[0],
						(StackExpr) s23[1] };
				manip(s, new int[] { 2, 3, 0, 1, 2, 3 }, StackManipStmt.DUP2_X2);
			} else if ((s01.length == 2) && (s23.length == 1)) {
				// 0 1 2-3 -> 2-3 0 1 2-3
				final StackExpr[] s = new StackExpr[] { (StackExpr) s01[0],
						(StackExpr) s01[1], (StackExpr) s23[0] };
				manip(s, new int[] { 2, 0, 1, 2 }, StackManipStmt.DUP2_X2);
			} else if ((s01.length == 1) && (s23.length == 2)) {
				// 0-1 2 3 -> 2 3 0-1 2 3
				final StackExpr[] s = new StackExpr[] { (StackExpr) s01[0],
						(StackExpr) s23[0], (StackExpr) s23[1] };
				manip(s, new int[] { 1, 2, 0, 1, 2 }, StackManipStmt.DUP2_X2);
			} else if ((s01.length == 1) && (s23.length == 2)) {
				// 0-1 2-3 -> 2-3 0-1 2-3
				final StackExpr[] s = new StackExpr[] { (StackExpr) s01[0],
						(StackExpr) s23[0] };
				manip(s, new int[] { 1, 0, 1 }, StackManipStmt.DUP2_X2);
			}
		} else {
			final Expr[] s23 = stack.pop2();
			final Expr[] s01 = stack.pop2();

			if ((s01.length == 2) && (s23.length == 2)) {
				// 0 1 2 3 -> 2 3 0 1 2 3
				final LocalExpr t0 = newStackLocal(stack.height(), s01[0]
						.type());
				final LocalExpr t1 = newStackLocal(stack.height() + 1, s01[1]
						.type());
				final LocalExpr t2 = newStackLocal(stack.height() + 2, s23[0]
						.type());
				final LocalExpr t3 = newStackLocal(stack.height() + 3, s23[1]
						.type());

				if (!t0.equalsExpr(s01[0])) {
					addStore(t0, s01[0]);
				}

				if (!t1.equalsExpr(s01[1])) {
					addStore(t1, s01[1]);
				}

				if (!t2.equalsExpr(s23[0])) {
					addStore(t2, s23[0]);
				}

				if (!t3.equalsExpr(s23[1])) {
					addStore(t3, s23[1]);
				}

				Expr copy = (Expr) t2.clone();
				copy.setDef(null);
				stack.push(copy);

				copy = (Expr) t3.clone();
				copy.setDef(null);
				stack.push(copy);

				copy = (Expr) t0.clone();
				copy.setDef(null);
				stack.push(copy);

				copy = (Expr) t1.clone();
				copy.setDef(null);
				stack.push(copy);

				copy = (Expr) t2.clone();
				copy.setDef(null);
				stack.push(copy);

				copy = (Expr) t3.clone();
				copy.setDef(null);
				stack.push(copy);
			} else if ((s01.length == 2) && (s23.length == 1)) {
				// 0 1 2-3 -> 2-3 0 1 2-3
				final LocalExpr t0 = newStackLocal(stack.height(), s01[0]
						.type());
				final LocalExpr t1 = newStackLocal(stack.height() + 1, s01[1]
						.type());
				final LocalExpr t2 = newStackLocal(stack.height() + 2, s23[0]
						.type());

				if (!t0.equalsExpr(s01[0])) {
					addStore(t0, s01[0]);
				}

				if (!t1.equalsExpr(s01[1])) {
					addStore(t1, s01[1]);
				}

				if (!t2.equalsExpr(s23[0])) {
					addStore(t2, s23[0]);
				}

				Expr copy = (Expr) t2.clone();
				copy.setDef(null);
				stack.push(copy);

				copy = (Expr) t0.clone();
				copy.setDef(null);
				stack.push(copy);

				copy = (Expr) t1.clone();
				copy.setDef(null);
				stack.push(copy);

				copy = (Expr) t2.clone();
				copy.setDef(null);
				stack.push(copy);
			} else if ((s01.length == 1) && (s23.length == 2)) {
				// 0-1 2 3 -> 2 3 0-1 2 3
				final LocalExpr t0 = newStackLocal(stack.height(), s01[0]
						.type());
				final LocalExpr t2 = newStackLocal(stack.height() + 2, s23[0]
						.type());
				final LocalExpr t3 = newStackLocal(stack.height() + 3, s23[1]
						.type());

				if (!t0.equalsExpr(s01[0])) {
					addStore(t0, s01[0]);
				}

				if (!t2.equalsExpr(s23[0])) {
					addStore(t2, s23[0]);
				}

				if (!t3.equalsExpr(s23[1])) {
					addStore(t3, s23[1]);
				}

				Expr copy = (Expr) t2.clone();
				copy.setDef(null);
				stack.push(copy);

				copy = (Expr) t3.clone();
				copy.setDef(null);
				stack.push(copy);

				copy = (Expr) t0.clone();
				copy.setDef(null);
				stack.push(copy);

				copy = (Expr) t2.clone();
				copy.setDef(null);
				stack.push(copy);

				copy = (Expr) t3.clone();
				copy.setDef(null);
				stack.push(copy);
			} else if ((s01.length == 1) && (s23.length == 2)) {
				// 0-1 2-3 -> 2-3 0-1 2-3
				final LocalExpr t0 = newStackLocal(stack.height(), s01[0]
						.type());
				final LocalExpr t2 = newStackLocal(stack.height() + 2, s23[0]
						.type());

				if (!t0.equalsExpr(s01[0])) {
					addStore(t0, s01[0]);
				}

				if (!t2.equalsExpr(s23[0])) {
					addStore(t2, s23[0]);
				}

				Expr copy = (Expr) t2.clone();
				copy.setDef(null);
				stack.push(copy);

				copy = (Expr) t0.clone();
				copy.setDef(null);
				stack.push(copy);

				copy = (Expr) t2.clone();
				copy.setDef(null);
				stack.push(copy);
			}
		}
	}