コード例 #1
0
ファイル: binary.c プロジェクト: berkus/lang-e
/* array from 0..n-1, return position or -1 */
hash_ptr mksearch(int n, int *x) {
	static v_code insn[1024];
	v_reg_type val;

	v_lambda("bin-search", "%i", &val, V_LEAF, insn, sizeof insn);
		gen(x, val, 0, n-1, n/2);
	return (hash_ptr)v_end(0).i;
}
コード例 #2
0
ファイル: dcg.c プロジェクト: berkus/lang-e
/* driver */
static void scale(int n, data_t **a, data_t **b, data_t c) {
	struct v_reg  dst,src, src_end, v0, v1, al[10];
	struct v_label  loop1; 
	static unsigned insn[1024];
	v_vptr vp;

	/* simple unroll */
	/* assert(n >= 4 && (n % 4) == 0); */

	v_lambda("foo", "%p%p", al, V_LEAF, insn);

	/* row & c come in as parameters */
	dst 	= al[0];
	src 	= al[1];
	if(!v_getreg(&src_end, V_P, V_TEMP))
		v_fatal("scale: out of registers\n");
	if(!v_getreg(&v0, V_U, V_TEMP))
		v_fatal("scale: out of registers\n");
	if(!v_getreg(&v1, V_U, V_TEMP))
		v_fatal("scale: out of registers\n");

	loop1	= v_genlabel();

	/* relies on contigous memory */
	v_raw_load(v_ldpi(src, src, (0)), 1);	/* perform loads without interlocks */
	v_raw_load(v_ldpi(dst, dst, (0)), 1);
	v_addpi(src_end, src, (n * n) * sizeof **a);

	v_label(loop1);
		/* load 2 to get rid of delay slots */
		v_raw_load(v_ldui(v0, src, (0 * sizeof **a)), 1);
		v_raw_load(v_ldui(v1, src, (1 * sizeof **a)), 1);

		/* multiplies will be strength reduced */
		if(strength_reduce) cmuli(v0, v0, c);
		else		   v_mului(v0, v0, c);

		v_addpi(dst, dst, (2 * sizeof **a));

		if(strength_reduce) cmuli(v1, v1, c);
		else		   v_mului(v1, v1, c);

		v_stui(v0, dst, -(2 * sizeof **a));
		v_addpi(src, src, (2 * sizeof **a));
	/* schedule delay slot instructions */
	v_schedule_delay(
		v_bltp(src, src_end, loop1),
		v_stui(v1, dst, -(1 * sizeof **a))
	);

	vp = v_end().v;
	if(disass)
		v_dump((void *)vp);
	if(!pixie)
		vp(a,b);	/* perform multiplication */
}
コード例 #3
0
ファイル: hello-push.c プロジェクト: berkus/lang-e
int main(void) {
	struct v_cstate c;

	/* Create a function to print standard greeting. */
        v_lambda("hello-world", "", 0, V_NLEAF, malloc(512), 512);
		v_push_init(&c);
		v_push_argpi(&c, "hello, world\n");
		v_ccallv(&c, (v_vptr)printf);
        v_end(0).v(); 	/* Compile & call */
	return 0;
}
コード例 #4
0
ファイル: power.c プロジェクト: berkus/lang-e
/* Power: raise base to n-th power: n > 0; specialized for a runtime constant n. */
v_fptr specialize_power(int n) {
	v_reg_type x, sum;

        v_lambda("power", "%d", &x, V_LEAF, malloc(512), 512);
	{
		int i;

		/* Allocate accumulator */
		v_getreg(&sum, V_D, V_TEMP);
		v_movf(sum, x);		/* initialize sum */

		/* Specialize power to x^n by unrolling the loop to multiply
	 	   x n times: (x * x * ... * x). */
		for(i = 0; i < n - 1; i++)
			v_mulf(sum, sum, x);

		v_retf(sum);	/* return x ^ n */
	}
        return v_end(0).f;	/* return pointer to result. */
}
コード例 #5
0
ファイル: jump-and-link.c プロジェクト: berkus/lang-e
int main(void) {
	static v_code insn[1000]; 	/* Memory to hold code in. */

        /* Test jump and link instruction */
        v_lambda("jump-and-link", "", 0, V_NLEAF, insn, sizeof insn);
        {
                static v_code *linked_addr;
                v_reg_type rdp, rr;
                v_label_type l;

		/* Allocate two registers persistent accross procedure calls. */
                v_getreg(&rdp, V_P, V_VAR);
		/* Allocate register to hold return pointer */
                v_getreg(&rr, V_P, V_VAR);

                l = v_genlabel(); 	  /* Allocate label */
                v_dlabel(&linked_addr, l); /* mark memory to hold target address */
                v_setp(rdp, &linked_addr); /* Load address */
                v_ldpi(rdp, rdp, 0);

                v_scallv((v_vptr)printf, "%P", "Jumping!\n");
                v_jalp(rr, rdp); 	   /* Jump to it. */

                v_scallv((v_vptr)printf, "%P", "Returning!\n");
                v_retv();		/* Done */

                v_label(l);
                        v_scallv((v_vptr)printf, "%P", "Jumping back!\n");
                        v_jp(rr);	/* Jump back to caller. */
        }
        v_end(0).v();
#if 0
{
	v_vptr vp = v_end(0).v;
	v_dump(vp);
	vp();
}
#endif

	return 0;
}
コード例 #6
0
ファイル: jal-test.c プロジェクト: berkus/lang-e
int main() { 
	static v_code insn[1000];
	v_iptr ip;

        /* jal reg  */
        v_lambda("v_jal", "", 0, V_NLEAF, insn, sizeof insn);
        {
        	static void * linked_addr;
        	v_reg_type rdp;
        	v_reg_type rr;
		v_label_type l;

		v_getreg(&rdp, V_P, V_VAR);
		v_getreg(&rr, V_P, V_VAR);

                l = v_genlabel();
                v_dmark(&linked_addr, l);

                v_ldpi(rdp, v_zero, (unsigned long)&linked_addr);
		v_scallv((v_vptr)printf, "%P", "Jumping!\n");
                v_jalp(rr, rdp);
		v_scallv((v_vptr)printf, "%P", "Returning.\n");	
               	v_retii(13);

                v_label(l);
			v_scallv((v_vptr)printf, "%P", "Jumping back!\n");
			v_jp(rr);
        }
	printf("Testing jalr\n");
	ip = v_end(0).i;
#if 0
	v_dump((void*)ip);
#endif
        if(ip() != 13)
		demand(0, bogus value!);
	return 0;
}
コード例 #7
0
ファイル: vm.c プロジェクト: berkus/lang-e
int main() { 
	static unsigned insn[100];
	v_iptr ip;
	v_reg_type arg_list[10];
	v_label_type l;
	unsigned s2u, s1u;

	s1u =  3422929224;
	s2u = 4205332841;

        /* reg <- (reg < imm) */
        v_lambda("bltuli", "%u", arg_list, V_LEAF, insn, sizeof insn);
                l = v_genlabel();
                v_bltui(arg_list[0], s2u, l);
                        v_retii(0);
                v_label(l);
                        v_retii(1);

        ip = v_end(0).i;

	v_dump((void*)ip);
	printf("ip returned %d, should be %d\n", ((int (*)(unsigned))ip)(s1u), s1u < s2u);
	return 0;
}
コード例 #8
0
ファイル: wk.c プロジェクト: aunali1/exopc
/* A predicate is represented as a sum-of-products, that is
   (A1 A2 ... ) OR (B1 B2 ...) OR ...
   where each element in a product (the A?'s and B?'s) are simple
   predicates like v > 10.

   Predicates are represented in memory as an array of wk_term's,
   one term for each immediate, variable, operator, conjunction or
   disjunction. A single product is considered to be a group of
   contiguous wk_term's that are not WK_ORs. The whole mess is
   terminated by a WK_END.  */

#include <vcode/vcode.h>
#include <xok/wk.h>
#include <xok/mmu.h>
#include <xok/sys_proto.h>
#include <xok/kerrno.h>
#include <xok/malloc.h>
#include <xok_include/assert.h>
#include <xok/printf.h>

#ifndef __CAP__
#include <xok/pmapP.h>
#else
#include <xok/pmap.h>
#endif

#define WK_MAX_CODE_BYTES 4096

#define OVERRUN_SAFETY 20
#define OVERRUN_CHECK						\
{								\
  if (v_ip > code + WK_MAX_CODE_BYTES - OVERRUN_SAFETY) {	\
    warn ("wk_compile: out of code space\n");			\
    ret = -E_INVAL;						\
    goto error;							\
  }								\
}

static int next_pp; /* outside function so can be used by cleanup code */
static int wk_compile (struct wk_term *t, int sz, char *code,
		       u_int *pred_pages) {
  int i;
  v_reg_t r1, r2, z, tag;
  v_label_t end_of_term;
  int start_term = 1;
  int op1 = 1;
  cap c;
  struct Ppage *pp;
  u_int ppn;
  int ret = 0;

  next_pp = 0;

  v_lambda ("", "", NULL, 1, code, WK_MAX_CODE_BYTES);
  if (!v_getreg (&r1, V_U, V_TEMP) ||
      !v_getreg (&r2, V_U, V_TEMP) ||
      !v_getreg (&z, V_U, V_TEMP) ||
      !v_getreg (&tag, V_U, V_TEMP))
    panic ("wk_compile: architecture doesn't have enough registers.");

  v_setu (tag, -1);
  v_setu (z, 0);  
  
  for (i = 0; i < sz; i++) {
    if (start_term) {
      end_of_term = v_genlabel ();
      start_term = 0;
    }
    OVERRUN_CHECK;
    switch (t[i].wk_type) {
    case WK_VAR:
      if (next_pp >= WK_MAX_PP-1) {
	warn ("wk_compile: too many pages in predicate\n");
	ret = -E_INVAL;
	goto error;
      }
      if ((ret = env_getcap (curenv, t[i].wk_cap, &c)) < 0) {
	goto error;
      }
      ppn = PGNO((u_int)t[i].wk_var);
      if (!ppn || ppn >= nppage) {
	printf ("at index %d\n", i);
	warn ("wk_compile: invalid physical page\n");
	ret = -E_INVAL;
	goto error;
      }
      pp = ppages_get(ppn);
      switch (Ppage_pp_status_get(pp)) {
      case PP_USER:
	if ((ret = ppage_acl_check(pp,&c,PP_ACL_LEN,0)) < 0) {
	  goto error;
	}
	ppage_pin (pp);
	pred_pages[next_pp++] = ppn;
	break;
      case PP_KERNRO:
	/* user can access pages that each env get's mapped r/o */
	break;
      default:
	printf ("at index %d\n", i);
	warn ("wk_compile: attempt to reference non PP_KERNRO or PP_USER page\n");
	ret = -E_INVAL;
	goto error;
      }
      if (op1) {
	v_ldui (r1, z, (int )ptov (t[i].wk_var));
	op1 = 0;
      } else {
	v_ldui (r2, z, (int )ptov (t[i].wk_var));
	op1 = 1;
      }
      break;
    case WK_IMM:
      if (op1) {
	v_setu (r1, t[i].wk_imm);
	op1 = 0;
      } else {
	v_setu (r2, t[i].wk_imm);
	op1 = 1;
      }
      break;
    case WK_TAG: {
      v_setu (tag, t[i].wk_tag);
      break;
    }
    case WK_OP: {
      switch (t[i].wk_op) {
      case WK_GT: {
	v_bleu (r1, r2, end_of_term); 
	break;
      }
      case WK_GTE: {
	v_bltu (r1, r2, end_of_term); 
	break;
      }
      case WK_LT: {
	v_bgeu (r1, r2, end_of_term);
	break;
      }
      case WK_LTE: {
	v_bgtu (r1, r2, end_of_term); 
	break;
      }
      case WK_EQ: {
	v_bneu (r1, r2, end_of_term);
	break;
      }
      case WK_NEQ: {
	v_bequ (r1, r2, end_of_term);
	break;
      }
      case WK_OR: {
	v_retu (tag);
	v_label (end_of_term);
	start_term = 1; 
	break;
      }
      default: {
	printf ("at index %d\n", i);
	warn ("wk_compile: invalid wk-pred instruction\n");
	ret = -E_INVAL;
	goto error;
      }
      }
      break;
    }
    default:
      printf ("at index %d\n", i);
      warn ("wk_compile: invalid wk-pred type\n");
      ret = -E_INVAL;
      goto error;
    }
  }
      
  /* end the last term */
  OVERRUN_CHECK;
  v_retu (tag);
  v_label (end_of_term);

  v_retui (0);
  v_end (NULL);

error:
  /* have to do this even on error so that our caller can just call
     wk_free to clean memory/ref counts up */
  pred_pages[next_pp] = 0;
  curenv->env_pred_pgs = pred_pages;
  curenv->env_pred = (Spred)code;
  return ret;
}