int CND(int X) { // CND abs_ins(X, L); //rep_ins(0.2316419, t0); //mul_ins(L, t0, t0); muls_ins(L, 0.2316419, t0); //rep_ins(1.0, t1); //add_ins(t0, t1, t0); adds_ins(t0, 1.0, t0); rep_ins(1.0, t1); div_ins(t1, t0, k); mul_ins(k, k, k2); mul_ins(k2, k, k3); mul_ins(k2, k2, k4); mul_ins(k2, k3, k5); //rep_ins(0.39894228040, is2pi); //rep_ins(0.31938153, t0); //mul_ins(t0, k, t0); muls_ins(k, 0.31938153, t0); //rep_ins(-0.356563782, t1); //mul_ins(t1, k2, t1); muls_ins(k, -0.356563782, t1); add_ins(t0, t1, t0); //rep_ins(1.781477937, t1); //mul_ins(t1, k3, t1); muls_ins(k, 1.781477937, t1); add_ins(t0, t1, t0); //rep_ins(-1.821255978, t1); //mul_ins(t1, k4, t1); muls_ins(k, -1.821255978, t1); add_ins(t0, t1, t0); //rep_ins(1.330274429, t1); //mul_ins(t1, k5, t1); muls_ins(k, 1.330274429, t1); add_ins(t0, t1, w); //mul_ins(w, is2pi, w); muls_ins(w, 0.39894228040, w); neg_ins(L, t0); mul_ins(L, t0, t0); //rep_ins(0.5, t1); //mul_ins(t0, t1, t0); muls_ins(t0, 0.5, t0); exp_ins(t0, t0); mul_ins(w, t0, w); gt0_ins(X, t0); rep_ins(1, t1); sub_ins(t1, w, t1); sel_ins(t0, t1, w); return w; }
ilist ins0(instruction ins, fncode fn) /* Effects: Adds instruction ins to code of 'fn'. Modifies: fn */ { switch (ins) { case OPmexec4 ... OPmexec4 + 15: adjust_depth(-(ins - OPmexec4), fn); break; case OPmset: adjust_depth(-2, fn); break; case OPmpop: case OPmeq: case OPmne: case OPmref: case OPmlt: case OPmle: case OPmgt: case OPmge: case OPmadd: case OPmsub: case OPmmultiply: case OPmdivide: case OPmremainder: case OPmbitand: case OPmbitor: case OPmbitxor: case OPmshiftleft: case OPmshiftright: adjust_depth(-1, fn); break; case OPmcst: case OPmundefined: case OPmint3 ... OPmint3 + 7: adjust_depth(1, fn); break; case OPmreturn: case OPmnegate: case OPmbitnot: case OPmnot: case OPmscheck4 ... OPmscheck4 + 15: break; default: fprintf(stderr, "unknown instruction %d\n", ins); assert(0); } return add_ins(ins, 0, fn); }
void insprim(instruction ins, int nargs, fncode fn) /* Effects: Adds instruction ins to code of 'fn'. Modifies: fn */ { adjust_depth(-(nargs - 1), fn); add_ins(ins, 0, fn); }
void loop_body() { rep_ins(100, S); rep_ins(98, X); rep_ins(2, T); rep_ins(0.02, r); rep_ins(5, v); div_ins(S, X, s0); log_ins(s0, s0); rep_ins(log(10), s1); div_ins(s0, s1, s0); mul_ins(v, v, s1); //rep_ins(0.5, s2); //mul_ins(s1, s2, s1); muls_ins(s1, 0.5, s1); add_ins(s1, r, s1); mul_ins(s1, T, s1); add_ins(s0, s1, s0); sqrt_ins(T, s1); mul_ins(v, s1, s1); div_ins(s0, s1, d1); sqrt_ins(T, s0); mul_ins(v, s0, s0); sub_ins(d1, s0, d2); mul_ins(S, CND(d1), s0); neg_ins(r, s1); mul_ins(s1, T, s1); exp_ins(s1, s1); mul_ins(X, s1, s1); mul_ins(X, CND(d2), s1); sub_ins(s0, s1, result); sum_ins(result,ret_val); }
u8 *ins_closure(value code, u16 clen, fncode fn) /* Effects: Adds code for a 'clen' variable closure with function 'code' to 'fn' Returns: Pointer to area to add the closure variables */ { ilist cins = add_ins(OPmclosure, 1, fn); cins->arg = clen; cins->cst = add_constant(code, fn); cins->cvars = allocate(fnmemory(fn), clen * sizeof(*cins->cvars)); adjust_depth(1, fn); return cins->cvars; }
void branch(instruction abranch, label to, fncode fn) /* Effects: Adds a branch instruction to lavel 'to' to instruction list 'next'. A 1 byte offset is added at this stage. Requires: 'branch' be a 1 byte branch instruction. Modifies: fn */ { switch (abranch) { case OPmba3: break; case OPmbt3: case OPmbf3: adjust_depth(-1, fn); break; default: assert(0); } /* assume a small offset by default */ add_ins(abranch, 0, fn)->to = to; }
void ins1(instruction ins, int arg1, fncode fn) /* Effects: Adds instruction ins to code of 'fn'. The instruction has one argument, arg1. Modifies: fn */ { switch (ins) { case OPmreadl: case OPmreadc: case OPmclosure: adjust_depth(1, fn); break; case OPmexitn: case OPmclearl: case OPmwritel: case OPmwritec: case OPmvcheck4 ... OPmvcheck4 + 15: /* Note: OPmexitn *MUST NOT* modify stack depth */ break; default: assert(0); } add_ins(ins, 1, fn)->arg = arg1; }
void ins2(instruction ins, int arg2, fncode fn) /* Effects: Adds instruction ins to code of 'fn'. The instruction has a two byte argument (arg2), stored in big-endian format. Modifies: fn */ { switch (ins) { case OPmreadg: adjust_depth(1, fn); break; case OPmwriteg: break; case OPmexecg4 ... OPmexecg4 + 15: adjust_depth(-(ins - OPmexecg4) + 1, fn); break; default: assert(0); } add_ins(ins, 2, fn)->arg = arg2; }