private void initInputFromRegisters() {
		final int REG_SEL_CNT = 3;
		// FIXME fix indirect addressing (aka 110-register)
		// Control byte format: xxDDDSSS or CCCCCSSS.
		// Also 00DDD10X means inc/dec, so DDD==SSS.
		/* Briefly: this code checks if opNOPs pattern
		 * is not 00XXX10X (not_incdec_comb).
		 * not_incdec_comb==0 means usage of DDD as source.
		 * not_incdec_comb==1 means usage of SSS as source. */
		NOTNode incdec_3rd_bit_inv = new NOTNode();
		incdec_3rd_bit_inv.connectSrc(opNOPs[2], 0, 0);
		ORNode not_incdec_pre1 = new ORNode();
		ORNode not_incdec_pre2 = new ORNode();
		ORNode not_incdec_comb = new ORNode();
		not_incdec_pre1.connectSrc(opNOPs[1], 0, 0);
		not_incdec_pre1.connectSrc(incdec_3rd_bit_inv, 0, 1);
		not_incdec_pre2.connectSrc(opNOPs[BITNESS-2], 0, 0);
		not_incdec_pre2.connectSrc(opNOPs[BITNESS-1], 0, 1);
		not_incdec_comb.connectSrc(not_incdec_pre1, 0, 0);
		not_incdec_comb.connectSrc(not_incdec_pre2, 0, 1);
		MultiMux incdec_sel = new MultiMux(REG_SEL_CNT);
		for (int i = 0; i < 2*REG_SEL_CNT; i++) {
			incdec_sel.connectSrc(opNOPs[i], 0, i);
		}
		incdec_sel.connectSrc(not_incdec_comb, 0, 2*REG_SEL_CNT);
		
		/* If it is memory store operation, then use A as source. */
		MultiOR mem_store_check = new MultiOR(REG_SEL_CNT);
		NOTNode rev_4bit = new NOTNode();
		rev_4bit.connectSrc(opNOPs[3], 0, 0);
		is_mem_store.connectSrc(is_mem_instr, 0, 0);
		is_mem_store.connectSrc(rev_4bit, 0, 1);
		for (int i = 0; i < REG_SEL_CNT; i++) {
			mem_store_check.connectSrc(incdec_sel, i, i);
			mem_store_check.connectSrc(is_mem_store, 0, i+REG_SEL_CNT);
		}
		
		ALU_in_mux_A = new MultiMux[(1<<REG_SEL_CNT) - 1];
		ALU_in_mux_A[0] = new MultiMux(BITNESS);
		ALU_in_mux_A[0].connectSrc(mem_store_check, 0, 2*BITNESS);
		for (int i = 1; i < ALU_in_mux_A.length; i++) {
			ALU_in_mux_A[i] = new MultiMux(BITNESS);
			// heap-like organization of indexes
			for (int j = 0; j < BITNESS; j++) {
				ALU_in_mux_A[(i-1)/2].connectSrc(ALU_in_mux_A[i], j, j + ((i+1)%2)*BITNESS);
			}
			// Adding small magic number to prevent rounding errors.
			int level = (int)Math.floor(Math.log(i+1)/Math.log(2) + 1e-10);
			ALU_in_mux_A[i].connectSrc(mem_store_check, level, 2*BITNESS);
		}
		
		// connecting ALU inputs
		// For rotations we should pass 1 as second op for ALU.
		// In other cases it should be A register.
		NOTNode not_rot = new NOTNode();
		not_rot.connectSrc(comb_rot_ctrl[4], 0, 0);
		for (int j = 1; j < BITNESS; j++) {
			ANDNode temp_con = new ANDNode();
			temp_con.connectSrc(not_rot, 0, 0);
			temp_con.connectSrc(A, j, 1);
			temp_con.connectDst(0, alu, j+BITNESS);
		}
		ORNode temp_con = new ORNode();
		temp_con.connectSrc(comb_rot_ctrl[4], 0, 0);
		temp_con.connectSrc(A, 0, 1);
		temp_con.connectDst(0, alu, BITNESS);
		/* If it is memory load operation, then use memory as source. */
		MultiMux mem_reg_sel = new MultiMux(BITNESS);
		is_mem_load.connectSrc(is_mem_instr, 0, 0);
		is_mem_load.connectSrc(opNOPs[3], 0, 1);
		mem_reg_sel.connectSrc(is_mem_load, 0, 2*BITNESS);
		/* Source could be data bytes or registers pair. */
		reg_pair_sel.connectSrc(opNOPs[4], 0, 4*BITNESS);// 1 -> DE, 0 -> BC
		MultiMux source_sel = new MultiMux(2*BITNESS);
		source_sel.connectSrc(opNOPs[5], 0, 4*BITNESS);
		for (int j = 0; j < BITNESS; j++) {
			reg_pair_sel.connectSrc(E, j, j);
			reg_pair_sel.connectSrc(C, j, j+2*BITNESS);
			reg_pair_sel.connectSrc(D, j, j+BITNESS);
			reg_pair_sel.connectSrc(B, j, j+3*BITNESS);
			source_sel.connectSrc(inNOPs_A[j], 0, j);
			source_sel.connectSrc(reg_pair_sel, j, j+2*BITNESS);
			source_sel.connectSrc(inNOPs_B[j], 0, j+BITNESS);
			source_sel.connectSrc(reg_pair_sel, j+BITNESS, j+3*BITNESS);
			mem_ro.connectSrc(source_sel, j, j);
			mem_ro.connectSrc(source_sel, j+BITNESS, j+BITNESS);
			mem_reg_sel.connectSrc(mem_ro, j, j);
			mem_reg_sel.connectSrc(ALU_in_mux_A[0], j, j+BITNESS);
			mem_reg_sel.connectDst(j, alu, j);
		}
		for (int j = 0; j < BITNESS; j++) {
			alu_ctrl.connectSrc(opNOPs[j], 0, j);
		}
		for (int j = 0; j < ALU.NUM_CMD_BITS; j++) {
			alu_ctrl.connectDst(j, alu, j+2*BITNESS);
		}
		
		// connecting registers
		for (int j = 0; j < BITNESS; j++) {
			// 000
			B.connectDst(j, ALU_in_mux_A[ALU_in_mux_A.length-1], j+BITNESS);
			// 100
			H.connectDst(j, ALU_in_mux_A[ALU_in_mux_A.length-1], j);
			// 010
			D.connectDst(j, ALU_in_mux_A[ALU_in_mux_A.length-2], j+BITNESS);
			// 110
			inNOPs_A[j].connectDst(0, ALU_in_mux_A[ALU_in_mux_A.length-2], j);
			// 001
			C.connectDst(j, ALU_in_mux_A[ALU_in_mux_A.length-3], j+BITNESS);
			// 101
			L.connectDst(j, ALU_in_mux_A[ALU_in_mux_A.length-3], j);
			// 011
			E.connectDst(j, ALU_in_mux_A[ALU_in_mux_A.length-4], j+BITNESS);
			// 111
			A.connectDst(j, ALU_in_mux_A[ALU_in_mux_A.length-4], j);
		}
	}