pid_t waitpid(pid_t pid, int* status, int options)
{
  pid_t rc;
  uint64_t time;

  VT_MEMHOOKS_OFF();

  if ( DO_TRACE(waitpid) )
  {
    /* mark enter function */
    time = vt_pform_wtime();
    vt_enter(&time, libc_funcs[FUNCIDX(waitpid)].rid);
  }

  /* call (real) function */
  CALL_FUNC(waitpid, rc, (pid, status, options));

  if ( DO_TRACE(waitpid) )
  {
    /* mark leave function */
    time = vt_pform_wtime();
    vt_exit(&time);
  }

  VT_MEMHOOKS_ON();

  return rc;
}
pid_t wait(WAIT_STATUS_TYPE status)
{
  pid_t rc;
  uint64_t time;

  VT_MEMHOOKS_OFF();

  if ( DO_TRACE(wait) )
  {
    /* mark enter function */
    time = vt_pform_wtime();
    vt_enter(&time, libc_funcs[FUNCIDX(wait)].rid);
  }

  /* call (real) function */
  CALL_FUNC(wait, rc, (status));

  if ( DO_TRACE(wait) )
  {
    /* mark leave function */
    time = vt_pform_wtime();
    vt_exit(&time);
  }

  VT_MEMHOOKS_ON();

  return rc;
}
int system(const char* string)
{
  int rc;
  uint64_t time;

  VT_MEMHOOKS_OFF();

  if ( DO_TRACE(system) )
  {
    /* mark enter function */
    time = vt_pform_wtime();
    vt_enter(&time, libc_funcs[FUNCIDX(system)].rid);
  }

  /* call (real) function */
  CALL_FUNC(system, rc, (string));

  if ( DO_TRACE(system) )
  {
    /* mark leave function */
    time = vt_pform_wtime();
    vt_exit(&time);
  }

  VT_MEMHOOKS_ON();

  return rc;
}
int execvp(const char* path, char* const argv[])
{
  int rc;

  VT_MEMHOOKS_OFF();

  if ( DO_TRACE(execvp) )
  {
    /* mark enter function */
    uint64_t time = vt_pform_wtime();
    vt_enter(&time, libc_funcs[FUNCIDX(execvp)].rid);
  }

  /* close VT for current process */
  vt_close();

  /* call (real) function */
  CALL_FUNC(execvp, rc, (path, argv));

  vt_warning("execvp failed: %s", strerror(errno));
  return rc;
}
int execle(const char* path, const char* arg, ...)
{
  int rc;
  char* argv[100];
  char** envp;
  char* tmp;
  int i;
  va_list ap;

  VT_MEMHOOKS_OFF();

  va_start(ap, arg);

  i = 0;
  argv[i++] = (char*)arg;
  while((tmp = va_arg(ap, char*) ))
    argv[i++] = tmp;
  argv[i] = NULL;
  envp = va_arg(ap, char**);

  va_end(ap);

  if ( DO_TRACE(execle) )
  {
    /* mark enter function */
    uint64_t time = vt_pform_wtime();
    vt_enter(&time, libc_funcs[FUNCIDX(execle)].rid);
  }

  /* close VT for current process */
  vt_close();

  /* call (real) function */
  CALL_FUNC(execve, rc, (path, argv, envp));

  vt_warning("execle failed: %s", strerror(errno));
  return rc;
}
mlib_status
mlib_ImageAffineTable_u16nw(
	PARAMS_NW)
{
	DECLAREVAR;
	FP_TYPE buff_local[BUFF_SIZE], *buff = buff_local;
	FP_TYPE sat_off = SAT_OFF;
	mlib_s32 sbits, x_mask;
	mlib_s32 c2_flag = 0, c3_flag = 0;

#ifndef SRC_EXTEND
#if IMG_TYPE == 4
	mlib_s32 align = (mlib_s32)lineAddr[0] | ws->srcStride;

	c2_flag = ((n & 1) | (m & 3) | (nchan & 1) | (align & 7)) == 0;
	c3_flag = (n & 1) == 0 && (m & 1) == 0 && (nchan == 3) && (type == 1);
#endif /* IMG_TYPE == 4 */
#endif /* SRC_EXTEND */

	if (type < 4) {
#if IMG_TYPE == 4
		b_step = (nchan == 4) ? 2 : nchan;
		max_xsize *= b_step;
#ifdef MLIB_USE_FTOI_CLAMPING
		sat_off = -127.5;
#else /* MLIB_USE_FTOI_CLAMPING */
		sat_off = 0.5;
#endif /* MLIB_USE_FTOI_CLAMPING */
#endif /* IMG_TYPE == 4 */

		if (max_xsize > BUFF_SIZE) {
			buff = __mlib_malloc(max_xsize * sizeof (FP_TYPE));

			if (buff == NULL)
				return (MLIB_FAILURE);
		}
	}
#if FLT_BITS == 2
	filterX = table->dataH_f32;
	filterY = table->dataV_f32;
#else /* FLT_BITS == 2 */
	filterX = table->dataH_d64;
	filterY = table->dataV_d64;
#endif /* FLT_BITS == 2 */

	DIST_BITS();

#ifndef SRC_EXTEND
	switch (nchan) {
	    case 1:
		    sbits = 0;
		    break;
	    case 2:
		    sbits = 1;
		    break;
	    case 3:
		    sbits = 0;
		    break;
	    case 4:
		    sbits = 2;
		    break;
	    default:
		    sbits = 0;
		    break;
	}

#else /* SRC_EXTEND */
	sbits = 0;
#endif /* SRC_EXTEND */
	x_mask = ~((1 << sbits) - 1);
	x_shift -= sbits;

	ws->x_shift = x_shift;
	ws->x_mask = x_mask;
	ws->xf_shift = xf_shift;
	ws->xf_mask = xf_mask;
	ws->yf_shift = yf_shift;
	ws->yf_mask = yf_mask;

	for (j = yStart; j <= yFinish; j++) {
		old_size = size;
		CLIP(CHAN1);

		if (type < 4) {
#if IMG_TYPE == 4
/*
 * u8 via F32 image
 */

			if (c2_flag || c3_flag)
				b_step = (nchan == 4) ? 2 : nchan;
			else
				b_step = 1;

#ifdef __SUNPRO_C
#pragma pipeloop(0)
#endif /* __SUNPRO_C */
			for (i = b_step * old_size; i < b_step * size; i++) {
				buff[i] = sat_off;
			}

#else /* IMG_TYPE == 4 */
/*
 * process by one channel
 */
			b_step = 1;
#ifdef __SUNPRO_C
#pragma pipeloop(0)
#endif /* __SUNPRO_C */
			for (i = old_size; i < size; i++) {
				buff[i] = sat_off;
			}

#endif /* IMG_TYPE == 4 */
		} else {

/* mlib_f32 types */

			b_step = nchan;
#ifdef __SUNPRO_C
#pragma pipeloop(0)
#endif /* __SUNPRO_C */
			for (i = 0; i < size * nchan; i++) {
				dstPixelPtr[i] = (DTYPE) sat_off;
			}
		}

		ws->b_step = b_step;

/*
 * move to kernel center
 */
		x0 -= ws->x_move;
		y0 -= ws->y_move;

		ws->size = size;
		ws->x0 = x0;
		ws->y0 = y0;

		for (k = 0; k < nchan; k++) {
#if IMG_TYPE < 4
			DTYPE *dPtr = dstPixelPtr + k;
#endif /* IMG_TYPE < 4 */

			if (c2_flag && (k & 1))
				continue;

			if (c3_flag && k)
				continue;

			ws->k = k;

			if (type >= 4) {
				buff = (void *)(dstPixelPtr + k);
			}

			for (l = 0; l < n; l += kh) {

/* kernel lines */

				kh = n - l;

				if (kh >= 4 && (m & 3) == 0 &&
					!(c2_flag | c3_flag))
					kh = 4;
				else if (kh >= 2)
					kh = 2;

				for (off = 0; off < m; off += kw) {

/* offset in current kernel line */

					ws->x0 = x0 + (off << (x_shift +
						sbits));

					kw = m - off;

					if (kw > 2 * MAX_KER)
						kw = MAX_KER;
					else if (kw > MAX_KER)
						kw = kw / 2;

#ifndef SRC_EXTEND
#if IMG_TYPE == 4

					if (c3_flag) {
						kw = 2;
						FUNCNAME(c3_2_2)
							(buff, filterX + off,
							filterY + l,
							lineAddr + l, ws);
						continue;
					}

					if (c2_flag) {
						if (nchan == 2) {
							FUNCNAME(c2_2_4)
								(buff,
								filterX + off,
								filterY + l,
								lineAddr + l,
								ws);
						} else {
							FUNCNAME(c4_2_4)
								(buff,
								filterX + off,
								filterY + l,
								lineAddr + l,
								ws);
						}
					} else
#endif /* IMG_TYPE == 4 */
#endif /* SRC_EXTEND */

						CALL_FUNC(u16);
				}
			}

#if IMG_TYPE < 4
#ifdef __SUNPRO_C
#pragma pipeloop(0)
#endif /* __SUNPRO_C */
			for (i = 0; i < size; i++) {
				FP_TYPE val = buff[i] >> (SHIFT+SHIFT);

#if IMG_TYPE < 3 && defined(MLIB_USE_FTOI_CLAMPING)
				mlib_s32 ival;
#endif /* IMG_TYPE < 3 && defined(MLIB_USE_FTOI_CLAMPING) */

				SAT(dPtr[i * nchan], ival, val);

				buff[i] = sat_off;
			}

#endif /* IMG_TYPE < 4 */

#if IMG_TYPE == 4

			if (type == 1) {
				mlib_u8 *dp =
					(mlib_u8 *)dstData + nchan * xLeft + k;

				if (c3_flag) {
#ifdef __SUNPRO_C
#pragma pipeloop(0)
#endif /* __SUNPRO_C */
					for (i = 0; i < 3 * size; i++) {
						FP_TYPE val = (FP_TYPE) buff[i];

#ifdef MLIB_USE_FTOI_CLAMPING
						mlib_s32 ival;
#endif /* MLIB_USE_FTOI_CLAMPING */
						SAT8(dp[i], ival, val);

						buff[i] = sat_off;
					}
				} else if (c2_flag) {
#ifdef __SUNPRO_C
#pragma pipeloop(0)
#endif /* __SUNPRO_C */
					for (i = 0; i < size; i++) {
						FP_TYPE val0 =
							(FP_TYPE) buff[2 * i];
						FP_TYPE val1 =
							(FP_TYPE) buff[2 * i +
							1];
#ifdef MLIB_USE_FTOI_CLAMPING
						mlib_s32 ival0, ival1;
#endif /* MLIB_USE_FTOI_CLAMPING */
						SAT8(dp[i * nchan], ival0,
							val0);
						SAT8(dp[i * nchan + 1], ival1,
							val1);

						buff[2 * i] = sat_off;
						buff[2 * i + 1] = sat_off;
					}
				} else {
#ifdef __SUNPRO_C
#pragma pipeloop(0)
#endif /* __SUNPRO_C */
					for (i = 0; i < size; i++) {
						FP_TYPE val = (FP_TYPE) buff[i];

#ifdef MLIB_USE_FTOI_CLAMPING
						mlib_s32 ival;
#endif /* MLIB_USE_FTOI_CLAMPING */
						SAT8(dp[i * nchan], ival, val);

						buff[i] = sat_off;
					}
				}
			}
#endif /* IMG_TYPE == 4 */
		}
	}

	if (type < 4) {
		if (buff != buff_local)
			__mlib_free(buff);
	}

	return (MLIB_SUCCESS);
}
Exemple #7
0
mlib_status mlib_ImageLookUp(mlib_image       *dst,
                             const mlib_image *src,
                             const void       **table)
{
  mlib_s32 slb, dlb, xsize, ysize, nchan, ichan, bitoff_src;
  mlib_type stype, dtype;
  void *sa, *da;

  MLIB_IMAGE_CHECK(src);
  MLIB_IMAGE_CHECK(dst);
  MLIB_IMAGE_SIZE_EQUAL(src, dst);
  MLIB_IMAGE_CHAN_SRC1_OR_EQ(src, dst);

  stype = mlib_ImageGetType(src);
  dtype = mlib_ImageGetType(dst);
  ichan = mlib_ImageGetChannels(src);
  nchan = mlib_ImageGetChannels(dst);
  xsize = mlib_ImageGetWidth(src);
  ysize = mlib_ImageGetHeight(src);
  slb = mlib_ImageGetStride(src);
  dlb = mlib_ImageGetStride(dst);
  sa = mlib_ImageGetData(src);
  da = mlib_ImageGetData(dst);

  if (ichan == nchan) {
    if (dtype == MLIB_BYTE) {
      if (stype == MLIB_BYTE) {
        CALL_FUNC(U8, U8, mlib_u8);
      }
      else if (stype == MLIB_SHORT) {
        CALL_FUNC(S16, U8, mlib_u8);
      }
      else if (stype == MLIB_USHORT) {
        CALL_FUNC(U16, U8, mlib_u8);
      }
      else if (stype == MLIB_INT) {
        CALL_FUNC(S32, U8, mlib_u8);
      }
      else if (stype == MLIB_BIT) {
        if (nchan != 1)
          return MLIB_FAILURE;

        bitoff_src = mlib_ImageGetBitOffset(src); /* bits to first byte */
        return mlib_ImageLookUp_Bit_U8_1(sa, slb, da, dlb, xsize, ysize, nchan,
                                         bitoff_src, (const mlib_u8 **) table);
      }
    }
    else if (dtype == MLIB_SHORT) {
      if (stype == MLIB_BYTE) {
        CALL_FUNC(U8, S16, mlib_s16);
      }
      else if (stype == MLIB_SHORT) {
        CALL_FUNC(S16, S16, mlib_s16);
      }
      else if (stype == MLIB_USHORT) {
        CALL_FUNC(U16, S16, mlib_s16);
      }
      else if (stype == MLIB_INT) {
        CALL_FUNC(S32, S16, mlib_s16);
      }
    }
    else if (dtype == MLIB_USHORT) {
      if (stype == MLIB_BYTE) {
        CALL_FUNC(U8, U16, mlib_u16);
      }
      else if (stype == MLIB_SHORT) {
        CALL_FUNC(S16, U16, mlib_u16);
      }
      else if (stype == MLIB_USHORT) {
        CALL_FUNC(U16, U16, mlib_u16);
      }
      else if (stype == MLIB_INT) {
        CALL_FUNC(S32, U16, mlib_u16);
      }
    }
    else if (dtype == MLIB_INT) {
      if (stype == MLIB_BYTE) {
        CALL_FUNC(U8, S32, mlib_s32);
      }
      else if (stype == MLIB_SHORT) {
        CALL_FUNC(S16, S32, mlib_s32);
      }
      else if (stype == MLIB_USHORT) {
        CALL_FUNC(U16, S32, mlib_s32);
      }
      else if (stype == MLIB_INT) {
        if ((nchan >= 1) && (nchan <= 4)) {
          mlib_v_ImageLookUp_S32_S32(sa, slb, da, dlb, xsize, ysize, (const mlib_s32 **) table,
                                     nchan);
          return MLIB_SUCCESS;
        }
        else {
          return MLIB_FAILURE;
        }
      }
    }
    else if (dtype == MLIB_FLOAT) {
      if (stype == MLIB_BYTE) {
        CALL_FUNC(U8, S32, mlib_s32);
      }
      else if (stype == MLIB_SHORT) {
        CALL_FUNC(S16, S32, mlib_s32);
      }
      else if (stype == MLIB_USHORT) {
        CALL_FUNC(U16, S32, mlib_s32);
      }
      else if (stype == MLIB_INT) {
        if ((nchan >= 1) && (nchan <= 4)) {
          mlib_v_ImageLookUp_S32_S32(sa, slb, da, dlb, xsize, ysize, (const mlib_s32 **) table,
                                     nchan);
          return MLIB_SUCCESS;
        }
        else {
          return MLIB_FAILURE;
        }
      }
    }
    else if (dtype == MLIB_DOUBLE) {
      if (stype == MLIB_BYTE) {
        mlib_ImageLookUp_U8_D64(sa, slb, da, dlb / 8, xsize, ysize, nchan,
                                (const mlib_d64 **) table);
        return MLIB_SUCCESS;
      }
      else if (stype == MLIB_SHORT) {
        mlib_ImageLookUp_S16_D64(sa, slb / 2, da, dlb / 8, xsize, ysize, nchan,
                                 (const mlib_d64 **) table);
        return MLIB_SUCCESS;
      }
      else if (stype == MLIB_USHORT) {
        mlib_ImageLookUp_U16_D64(sa, slb / 2, da, dlb / 8, xsize, ysize, nchan,
                                 (const mlib_d64 **) table);
        return MLIB_SUCCESS;
      }
      else if (stype == MLIB_INT) {
        mlib_ImageLookUp_S32_D64(sa, slb / 4, da, dlb / 8, xsize, ysize, nchan,
                                 (const mlib_d64 **) table);
        return MLIB_SUCCESS;
      }
    }
  }
  else if (ichan == 1) {
    if (dtype == MLIB_BYTE) {
      if (stype == MLIB_BYTE) {
        CALL_SIFUNC(U8, U8, mlib_u8);
      }
      else if (stype == MLIB_SHORT) {
        CALL_SIFUNC(S16, U8, mlib_u8);
      }
      else if (stype == MLIB_USHORT) {
        CALL_SIFUNC(U16, U8, mlib_u8);
      }
      else if (stype == MLIB_INT) {
        CALL_SIFUNC(S32, U8, mlib_u8);
      }
      else if (stype == MLIB_BIT) {
        bitoff_src = mlib_ImageGetBitOffset(src); /* bits to first byte */

        if (nchan == 2) {
          return mlib_ImageLookUp_Bit_U8_2(sa, slb, da, dlb, xsize, ysize, nchan,
                                           bitoff_src, (const mlib_u8 **) table);
        }
        else if (nchan == 3) {
          return mlib_ImageLookUp_Bit_U8_3(sa, slb, da, dlb, xsize, ysize, nchan,
                                           bitoff_src, (const mlib_u8 **) table);
        }
        else {                              /* (nchan == 4) */
          return mlib_ImageLookUp_Bit_U8_4(sa, slb, da, dlb, xsize, ysize, nchan,
                                           bitoff_src, (const mlib_u8 **) table);
        }
      }
    }
    else if (dtype == MLIB_SHORT) {
      if (stype == MLIB_BYTE) {
        CALL_SIFUNC(U8, S16, mlib_s16);
      }
      else if (stype == MLIB_SHORT) {
        CALL_SIFUNC(S16, S16, mlib_s16);
      }
      else if (stype == MLIB_USHORT) {
        CALL_SIFUNC(U16, S16, mlib_s16);
      }
      else if (stype == MLIB_INT) {
        CALL_SIFUNC(S32, S16, mlib_s16);
      }
    }
    else if (dtype == MLIB_USHORT) {
      if (stype == MLIB_BYTE) {
        CALL_SIFUNC(U8, U16, mlib_u16);
      }
      else if (stype == MLIB_SHORT) {
        CALL_SIFUNC(S16, U16, mlib_u16);
      }
      else if (stype == MLIB_USHORT) {
        CALL_SIFUNC(U16, U16, mlib_u16);
      }
      else if (stype == MLIB_INT) {
        CALL_SIFUNC(S32, U16, mlib_u16);
      }
    }
    else if (dtype == MLIB_INT) {

      if (stype == MLIB_BYTE) {
        CALL_SIFUNC(U8, S32, mlib_s32);
      }
      else if (stype == MLIB_SHORT) {
        CALL_SIFUNC(S16, S32, mlib_s32);
      }
      else if (stype == MLIB_USHORT) {
        CALL_SIFUNC(U16, S32, mlib_s32);
      }
      else if (stype == MLIB_INT) {
        if ((nchan >= 1) && (nchan <= 4)) {
          mlib_v_ImageLookUpSI_S32_S32(sa, slb, da, dlb, xsize, ysize,
                                       (const mlib_s32 **) table, nchan);
          return MLIB_SUCCESS;
        }
        else {
          return MLIB_FAILURE;
        }
      }
    }
    else if (dtype == MLIB_FLOAT) {

      if (stype == MLIB_BYTE) {
        CALL_SIFUNC(U8, S32, mlib_s32);
      }
      else if (stype == MLIB_SHORT) {
        CALL_SIFUNC(S16, S32, mlib_s32);
      }
      else if (stype == MLIB_USHORT) {
        CALL_SIFUNC(U16, S32, mlib_s32);
      }
      else if (stype == MLIB_INT) {
        if ((nchan >= 1) && (nchan <= 4)) {
          mlib_v_ImageLookUpSI_S32_S32(sa, slb, da, dlb, xsize, ysize,
                                       (const mlib_s32 **) table, nchan);
          return MLIB_SUCCESS;
        }
        else {
          return MLIB_FAILURE;
        }
      }
    }
    else if (dtype == MLIB_DOUBLE) {
      if (stype == MLIB_BYTE) {
        mlib_ImageLookUpSI_U8_D64(sa, slb, da, dlb / 8, xsize, ysize, nchan,
                                  (const mlib_d64 **) table);
        return MLIB_SUCCESS;
      }
      else if (stype == MLIB_SHORT) {
        mlib_ImageLookUpSI_S16_D64(sa, slb / 2, da, dlb / 8, xsize, ysize, nchan,
                                   (const mlib_d64 **) table);
        return MLIB_SUCCESS;
      }
      else if (stype == MLIB_USHORT) {
        mlib_ImageLookUpSI_U16_D64(sa, slb / 2, da, dlb / 8, xsize, ysize, nchan,
                                   (const mlib_d64 **) table);
        return MLIB_SUCCESS;
      }
      else if (stype == MLIB_INT) {
        mlib_ImageLookUpSI_S32_D64(sa, slb / 4, da, dlb / 8, xsize, ysize, nchan,
                                   (const mlib_d64 **) table);
        return MLIB_SUCCESS;
      }
    }
  }

  return MLIB_FAILURE;
}
Exemple #8
0
int tuple_process(tuple_t tuple, unsigned char *pc,
		  int isNew, Register *reg)
{
  for (; ; pc = advance(pc)) {
  eval_loop: /* for jump instructions */
    switch (0xf0 & *(const unsigned char*)pc) {

    case 0x00: // some '8-bit' instruction
      switch (0x0f & *(const unsigned char*)pc) {

      case 0x00: // RETURN
#ifdef DEBUG_INSTRS
	printf("RETURN\n");
#endif
	return RET_RET;
	break;

      case 0x01: // NEXT
#ifdef DEBUG_INSTRS
	printf("NEXT\n");
#endif
	return RET_NEXT;
	break;

      case 0x02: // ELSE
	fprintf(stderr, "ELSE NOT IMPLEMENTED YET!\n");
	assert(0);
	break;

      case 0x08: // SEND
      case 0x09: // SEND
      case 0x0a: // SEND
      case 0x0b: // SEND
	{
	const unsigned char *old_pc = pc+3;
	Register send_reg = reg[SEND_MSG(pc)];
	Register send_rt = reg[SEND_RT(pc)];

#ifdef DEBUG_INSTRS
	printf("SEND\n");
#endif

	tuple_send((tuple_t)MELD_CONVERT_REG_TO_PTR(send_reg),
		   MELD_CONVERT_REG_TO_PTR(send_rt),
		   MELD_INT(eval(SEND_DELAY(pc), &tuple, &old_pc, reg)), isNew);
	break;
	}

      default:
	fprintf(stderr, "INVALID INSTRUCTION %u", *pc);
	assert(0);
	break;
      }
      break;

    case 0x20: // CALL
      {
      Register *dst = &reg[CALL_DST(pc)];
      Register args[CALL_ARGS(pc)];

      assert(CALL_ARGS(pc) <= 5);

#ifdef DEBUG_INSTRS
      printf("CALL %d (%d)\n", CALL_ID(pc), CALL_ARGS(pc));
#endif
        
      int i;
      const unsigned char *old_pc = pc+2;
      for (i = 0; i < CALL_ARGS(pc); i++) {
	unsigned char value = CALL_VAL(old_pc);
	old_pc++;
	args[i] = MELD_CONVERT_PTR_TO_REG(eval(value, &tuple, &old_pc, reg));
      }

      switch (CALL_ARGS(pc)) {
      default:
	break;
      case 0:
	*dst = CALL_FUNC(pc)();
	break;
      case 1:
	*dst = CALL_FUNC(pc)(args[0]);
	break;
      case 2:
	*dst = CALL_FUNC(pc)(args[0], args[1]);
	break;
      case 3:
	*dst = CALL_FUNC(pc)(args[0], args[1], args[2]);
	break;
      case 4:
	*dst = CALL_FUNC(pc)(args[0], args[1], args[2], args[3]);
	break;
      case 5:
	*dst = CALL_FUNC(pc)(args[0], args[1], args[2], args[3], args[4]);
	break;
      }
      break;
      }

    case 0x30: // MOVE
      {
      const unsigned char *old_pc = pc+2;

#ifdef DEBUG_INSTRS
      {
	char src = MOVE_SRC(pc);
	char dst = MOVE_DST(pc);

        printf("MOVE ");
        if(VAL_IS_TUPLE(src))
          printf("tuple");
        else if(VAL_IS_REG(src))
          printf("reg %d", VAL_REG(src));
        else if(VAL_IS_HOST(src))
          printf("host");
        else if(VAL_IS_FIELD(src))
          printf("FIELD");
        else if(VAL_IS_INT(src))
          printf("INT");
        else if(VAL_IS_FLOAT(src))
          printf("float");
	else if(VAL_IS_REVERSE(src))
	  printf("reverse");
        else printf("??");

        printf(" ");

        if(VAL_IS_TUPLE(dst))
          printf("tuple");
        else if(VAL_IS_REG(dst))
          printf("reg %d", VAL_REG(dst));
        else if(VAL_IS_HOST(dst))
          printf("host");
        else if(VAL_IS_FIELD(dst))
          printf("FIELD");
        else if(VAL_IS_INT(dst))
          printf("INT");
        else if(VAL_IS_FLOAT(dst))
          printf("float");
	else if(VAL_IS_REVERSE(dst))
	  printf("reverse");
        else printf("??");

	printf("\n");
      }
#endif
      size_t size = 0;

      Register *src = eval(MOVE_SRC(pc), &tuple, &old_pc, reg);
      Register *dst = eval_dst(MOVE_DST(pc), &old_pc, reg, &size);

      memcpy(dst, src, size);
      break;
      }

    case 0x40: // ALLOC
    case 0x50: // ALLOC
      {
      const unsigned char *old_pc = pc+2;
      tuple_t *dst;
      
#if defined(DEBUG_INSTRS) || defined(DEBUG_ALLOCS)
      {
        tuple_type type = ALLOC_TYPE(pc);
        printf("ALLOC %s\n", tuple_names[type]);
      }
#endif

      dst = eval(ALLOC_DST(pc), &tuple, &old_pc, reg);
			
      *dst = ALLOC_TUPLE(TYPE_SIZE(ALLOC_TYPE(pc)));
      memset(*dst, 0, TYPE_SIZE(ALLOC_TYPE(pc)));
      TUPLE_TYPE(*dst) = ALLOC_TYPE(pc);
      break;
      }

    case 0x60: // IF
    case 0x70: // IF
#ifdef DEBUG_INSTRS
      printf("IF reg %d ", IF_REG(pc));
#endif
      if (!reg[IF_REG(pc)]) {
#ifdef DEBUG_INSTRS
	printf("no\n");
#endif
	pc += IF_JUMP(pc);
	goto eval_loop;
      }

#ifdef DEBUG_INSTRS
      printf("yes\n");
#endif
      break;

    case 0x80: // REMOVE
    case 0x90: // REMOVE
      if (isNew > 0) {
        int reg_remove = REMOVE_REG(pc);
	int size = TYPE_SIZE(TUPLE_TYPE(MELD_CONVERT_REG_TO_PTR(reg[reg_remove])));

	tuple_handle(memcpy(malloc(size),MELD_CONVERT_REG_TO_PTR(reg[reg_remove]), size), -1, reg);
	reg[REMOVE_REG(pc)] = 0;
      }	
      break;

    case 0xa0: // ITER
      {
      const tuple_type type = ITER_TYPE(pc);
      int i, length;
      void **list;
      unsigned char *jump = pc + ITER_JUMP(pc);
      int size = TYPE_SIZE(type);
			
      /* produce a random ordering for all tuples of the appropriate type */
			
      if(TYPE_IS_PERSISTENT(type) && !TYPE_IS_AGG(type)) {
	/* persistent aggregate types not supported */
        persistent_set *persistents = &PERSISTENT[type];
        
        length = persistents->current;
        list = malloc(sizeof(tuple_t) * length);

        for(i = 0; i < length; i++) {
          int j = random() % (i + 1);
          
          list[i] = list[j];
          list[j] = persistents->array + i * size;
        }
      } else {
	/* non-persistent type */
	tuple_entry *entry = TUPLES[type].head;
		    
	length = queue_length(&TUPLES[ITER_TYPE(pc)]);
	list = malloc(sizeof(tuple_t) * length);
		    
	for (i = 0; i < length; i++) {
	  int j = random() % (i+1);

	  list[i] = list[j];
	  list[j] = entry->tuple;

	  entry = entry->next;
	}
      }
			
#ifdef DEBUG_INSTRS
      printf("ITER %s len=%d\n", tuple_names[type], length);
#endif

      if(length == 0) {
        /* no need to execute any further code, just jump! */
        pc = jump;
	goto eval_loop;
      }

      /* iterate over all tuples of the appropriate type */
      void *next_tuple;
      
      for (i = 0; i < length; i++) {
	next_tuple = list[i];

	unsigned char matched = 1;
	const unsigned char *tmppc;

        tmppc = pc + ITER_BASE;

        if(!ITER_MATCH_NONE(tmppc)) {
	  /* check to see if it matches */
          while (1) {
            const unsigned char *old_pc = tmppc + 2;
	    const unsigned char fieldnum = ITER_MATCH_FIELD(tmppc);
	    const unsigned char type_size = TYPE_ARG_SIZE(type, fieldnum);

            Register *field = GET_TUPLE_FIELD(next_tuple, fieldnum);
            Register *val = eval(ITER_MATCH_VAL(tmppc), &tuple, &old_pc, reg);
            
            matched = matched && (memcmp(field, val, type_size) == 0);

            if(ITER_MATCH_END(tmppc))
              break;

            tmppc = old_pc;
          }
	}

#ifdef DEBUG_INSTRS
	printf("MATCHED: %d %d\n", matched, length);
#endif
          
	if (matched) {
	  if (RET_RET == tuple_process(next_tuple, advance(pc), isNew, reg)) {
	    free(list);
	    return RET_RET;
	  }
	}
      }

      free(list);

      /* advance the pc to the end of the loop */
      pc = jump;
      goto eval_loop;
      break;
      }

    case 0xc0: // OP
    case 0xd0: // OP
    case 0xe0: // OP
    case 0xf0: // OP
      {
      const unsigned char *old_pc = pc+3;
			
#ifdef DEBUG_INSTRS
      printf("OP to %d\n", OP_DST(pc));
#endif

      Register *arg1, *arg2;
      
      arg1 = eval(OP_ARG1(pc), &tuple, &old_pc, reg);
      arg2 = eval(OP_ARG2(pc), &tuple, &old_pc, reg);
      
#ifdef DEBUG_INSTRS
      printf ("%ld", MELD_INT(arg1));
      printf ("OP");
      printf ("%ld", MELD_INT(arg2));
      printf ("\n");
#endif

      Register *dest = reg + OP_DST(pc);
      
      switch(OP_OP(pc)) {
      case OP_NEQI: *dest = (MELD_INT(arg1) != MELD_INT(arg2)); break;
      case OP_EQI: *dest = (MELD_INT(arg1) == MELD_INT(arg2)); break;
      case OP_LESSI: *dest = (MELD_INT(arg1) < MELD_INT(arg2)); break;
      case OP_LESSEQI: *dest = (MELD_INT(arg1) <= MELD_INT(arg2)); break;
      case OP_GREATERI: *dest = (MELD_INT(arg1) > MELD_INT(arg2)); break;
      case OP_GREATEREQI: *dest = (MELD_INT(arg1) >= MELD_INT(arg2)); break;
      case OP_MODI: MELD_INT(dest) = (MELD_INT(arg1) % MELD_INT(arg2)); break;
      case OP_PLUSI: MELD_INT(dest) = (MELD_INT(arg1) + MELD_INT(arg2)); break;
      case OP_MINUSI: MELD_INT(dest) = (MELD_INT(arg1) - MELD_INT(arg2)); break;
      case OP_TIMESI: MELD_INT(dest) = (MELD_INT(arg1) * MELD_INT(arg2)); break;
      case OP_DIVI: MELD_INT(dest) = (MELD_INT(arg1) / MELD_INT(arg2)); break;
      case OP_NEQF: *dest = (MELD_FLOAT(arg1) != MELD_FLOAT(arg2)); break;
      case OP_EQF: *dest = (MELD_FLOAT(arg1) == MELD_FLOAT(arg2)); break;
      case OP_LESSF: *dest = (MELD_FLOAT(arg1) < MELD_FLOAT(arg2)); break;
      case OP_LESSEQF: *dest = (MELD_FLOAT(arg1) <= MELD_FLOAT(arg2)); break;
      case OP_GREATERF: *dest = (MELD_FLOAT(arg1) > MELD_FLOAT(arg2)); break;
      case OP_GREATEREQF: *dest = (MELD_FLOAT(arg1) >= MELD_FLOAT(arg2)); break;
      case OP_MODF: MELD_FLOAT(dest) = fmod(MELD_FLOAT(arg1), MELD_FLOAT(arg2)); break;
      case OP_PLUSF: MELD_FLOAT(dest) = (MELD_FLOAT(arg1) + MELD_FLOAT(arg2)); break;
      case OP_MINUSF: MELD_FLOAT(dest) = (MELD_FLOAT(arg1) - MELD_FLOAT(arg2)); break;
      case OP_TIMESF: MELD_FLOAT(dest) = (MELD_FLOAT(arg1) * MELD_FLOAT(arg2)); break;
      case OP_DIVF: MELD_FLOAT(dest) = (MELD_FLOAT(arg1) / MELD_FLOAT(arg2)); break;
      case OP_NEQA: *dest = (MELD_PTR(arg1) != MELD_PTR(arg2)); break;
      case OP_EQA: *dest = (MELD_PTR(arg1) == MELD_PTR(arg2)); break;
      }
      break;
      }

    default:
      fprintf(stderr, "INVALID INSTRUCTION %u", *pc);
      assert(0);
      break;
    }
  }

  return RET_RET;
}