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

		db("      dup_x2");

		if (Tree.USE_STACK) {
			saveStack();

			final StackExpr s2 = (StackExpr) stack.pop1();
			final Expr[] s01 = stack.pop2();

			if (s01.length == 2) {
				// 0 1 2 -> 2 0 1 2
				final StackExpr[] s = new StackExpr[] { (StackExpr) s01[0],
						(StackExpr) s01[1], s2 };
				manip(s, new int[] { 2, 0, 1, 2 }, StackManipStmt.DUP_X2);
			} else {
				// 0-1 2 -> 2 0-1 2
				final StackExpr[] s = new StackExpr[] { (StackExpr) s01[0], s2 };
				manip(s, new int[] { 1, 0, 1 }, StackManipStmt.DUP_X2);
			}

		} else {
			final Expr s2 = stack.pop1();
			final Expr[] s01 = stack.pop2();

			db("        s2: " + s2);
			db("        s01: " + s01[0] + (s01.length > 1 ? " " + s01[1] : ""));

			if (s01.length == 2) {
				// 0 1 2 -> 2 0 1 2
				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, s2
						.type());

				db("        t0: " + t0);
				db("        t1: " + t1);
				db("        t2: " + t2);

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

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

				if (!t2.equalsExpr(s2)) {
					db("          t2 <- s2");
					addStore(t2, s2);
				}

				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 {
				// 0-1 2 -> 2 0-1 2
				final LocalExpr t0 = newStackLocal(stack.height(), s01[0]
						.type());
				final LocalExpr t2 = newStackLocal(stack.height() + 2, s2
						.type());

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

				if (!t2.equalsExpr(s2)) {
					addStore(t2, s2);
				}

				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);
			}
		}
	}