new merged instructions and small changes to the emulator.
This commit is contained in:
parent
37b0f7cf9b
commit
15b86cded4
59
C/absmi.c
59
C/absmi.c
@ -3215,6 +3215,35 @@ Yap_absmi(int inp)
|
||||
ENDD(d0);
|
||||
ENDOp();
|
||||
|
||||
Op(get_yy_var, yyxx);
|
||||
CACHE_Y(YREG);
|
||||
BEGD(d0);
|
||||
BEGP(pt0);
|
||||
pt0 = S_YREG + PREG->u.yyxx.y1;
|
||||
d0 = XREG(PREG->u.yyxx.x1);
|
||||
BEGD(d1);
|
||||
BEGP(pt1);
|
||||
pt1 = S_YREG + PREG->u.yyx.y2;
|
||||
d1 = XREG(PREG->u.yyxx.x2);
|
||||
PREG = NEXTOP(PREG, yyxx);
|
||||
#if defined(SBA) && defined(FROZEN_STACKS)
|
||||
Bind_Local(pt0,d0);
|
||||
#else
|
||||
*pt0 = d0;
|
||||
#endif /* SBA && FROZEN_STACKS */
|
||||
#if defined(SBA) && defined(FROZEN_STACKS)
|
||||
Bind_Local(pt1,d1);
|
||||
#else
|
||||
*pt1 = d1;
|
||||
#endif /* SBA && FROZEN_STACKS */
|
||||
ENDP(pt1);
|
||||
ENDD(d1);
|
||||
GONext();
|
||||
ENDP(pt0);
|
||||
ENDD(d0);
|
||||
ENDCACHE_Y();
|
||||
ENDOp();
|
||||
|
||||
/* The code for get_x_val is hard to follow because I use a
|
||||
* lot of jumps. The convention is that in the label
|
||||
* gval_X_YREG X refers to the state of the first argument, and
|
||||
@ -3241,12 +3270,10 @@ Yap_absmi(int inp)
|
||||
/* deref second argument */
|
||||
deref_body(d1, pt0, gvalx_nonvar_unk, gvalx_nonvar_nonvar);
|
||||
/* first argument bound, second unbound */
|
||||
PREG = NEXTOP(PREG, xx);
|
||||
BIND(pt0, d0, bind_gvalx_nonvar_var);
|
||||
BIND_AND_JUMP(pt0, d0);
|
||||
#ifdef COROUTINING
|
||||
DO_TRAIL(pt0, d0);
|
||||
if (pt0 < H0) Yap_WakeUp(pt0);
|
||||
bind_gvalx_nonvar_var:
|
||||
#endif
|
||||
GONext();
|
||||
|
||||
@ -6713,6 +6740,32 @@ Yap_absmi(int inp)
|
||||
GONext();
|
||||
ENDOp();
|
||||
|
||||
Op(put_y_vals, yyxx);
|
||||
ALWAYS_START_PREFETCH(yyxx);
|
||||
BEGD(d0);
|
||||
d0 = YREG[PREG->u.yyxx.y1];
|
||||
#ifdef SBA
|
||||
if (d0 == 0) /* new variable */
|
||||
XREG(PREG->u.yyxx.x1) = (CELL)(YREG+PREG->u.yyxx.y1);
|
||||
else
|
||||
#endif
|
||||
XREG(PREG->u.yyxx.x1) = d0;
|
||||
ENDD(d0);
|
||||
/* allow for some prefetching */
|
||||
PREG = NEXTOP(PREG, yyxx);
|
||||
BEGD(d1);
|
||||
d1 = YREG[PREVOP(PREG,yyxx)->u.yyxx.y2];
|
||||
#ifdef SBA
|
||||
if (d1 == 0) /* new variable */
|
||||
XREG(PREVOP(PREG->u.yyxx,yyxx).x2) = (CELL)(YREG+PREG->u.yyxx.y2);
|
||||
else
|
||||
#endif
|
||||
XREG(PREVOP(PREG,yyxx)->u.yyxx.x2) = d1;
|
||||
ENDD(d1);
|
||||
ALWAYS_END_PREFETCH();
|
||||
GONext();
|
||||
ENDOp();
|
||||
|
||||
Op(put_unsafe, yx);
|
||||
BEGD(d0);
|
||||
BEGP(pt0);
|
||||
|
61
C/amasm.c
61
C/amasm.c
@ -854,13 +854,56 @@ a_vr(op_numbers opcodex, op_numbers opcodey, yamop *code_p, int pass_no, struct
|
||||
int is_y_var = (ve->KindOfVE == PermVar);
|
||||
|
||||
if (is_y_var) {
|
||||
if (pass_no) {
|
||||
OPREG var_offset;
|
||||
if (opcodey == _put_y_val) {
|
||||
struct PSEUDO *ncpc = cpc->nextInst;
|
||||
if (ncpc->op == put_val_op &&
|
||||
((Ventry *) ncpc->rnd1)->KindOfVE == PermVar ) {
|
||||
/* peephole! two put_y_vars in a row */
|
||||
if (pass_no) {
|
||||
OPREG var_offset;
|
||||
OPREG var_offset2;
|
||||
Ventry *ve2 = (Ventry *) ncpc->rnd1;
|
||||
|
||||
var_offset = Var_Ref(ve, is_y_var);
|
||||
code_p->opc = emit_op(opcodey);
|
||||
code_p->u.yx.y = emit_yreg(var_offset);
|
||||
code_p->u.yx.x = emit_x(cpc->rnd2);
|
||||
var_offset = Var_Ref(ve, is_y_var);
|
||||
code_p->opc = emit_op(_put_y_vals);
|
||||
code_p->u.yyxx.y1 = emit_yreg(var_offset);
|
||||
code_p->u.yyxx.x1 = emit_x(cpc->rnd2);
|
||||
var_offset2 = Var_Ref(ve2, is_y_var);
|
||||
code_p->u.yyxx.y2 = emit_yreg(var_offset2);
|
||||
code_p->u.yyxx.x2 = emit_x(ncpc->rnd2);
|
||||
}
|
||||
cip->cpc = ncpc;
|
||||
GONEXT(yyxx);
|
||||
}
|
||||
}
|
||||
if (opcodey == _get_y_var) {
|
||||
struct PSEUDO *ncpc = cpc->nextInst;
|
||||
if (ncpc->op == get_var_op &&
|
||||
((Ventry *) ncpc->rnd1)->KindOfVE == PermVar ) {
|
||||
/* peephole! two put_y_vars in a row */
|
||||
if (pass_no) {
|
||||
OPREG var_offset;
|
||||
OPREG var_offset2;
|
||||
Ventry *ve2 = (Ventry *) ncpc->rnd1;
|
||||
|
||||
var_offset = Var_Ref(ve, is_y_var);
|
||||
code_p->opc = emit_op(_get_yy_var);
|
||||
code_p->u.yyxx.y1 = emit_yreg(var_offset);
|
||||
code_p->u.yyxx.x1 = emit_x(cpc->rnd2);
|
||||
var_offset2 = Var_Ref(ve2, is_y_var);
|
||||
code_p->u.yyxx.y2 = emit_yreg(var_offset2);
|
||||
code_p->u.yyxx.x2 = emit_x(ncpc->rnd2);
|
||||
}
|
||||
cip->cpc = ncpc;
|
||||
GONEXT(yyxx);
|
||||
}
|
||||
}
|
||||
if (pass_no) {
|
||||
OPREG var_offset;
|
||||
var_offset = Var_Ref(ve, is_y_var);
|
||||
code_p->opc = emit_op(opcodey);
|
||||
code_p->u.yx.y = emit_yreg(var_offset);
|
||||
code_p->u.yx.x = emit_x(cpc->rnd2);
|
||||
}
|
||||
GONEXT(yx);
|
||||
}
|
||||
@ -892,6 +935,12 @@ a_vr(op_numbers opcodex, op_numbers opcodey, yamop *code_p, int pass_no, struct
|
||||
code_p->opc = emit_op(opcodex);
|
||||
code_p->u.xx.xl = emit_xreg(var_offset);
|
||||
code_p->u.xx.xr = emit_x(cpc->rnd2);
|
||||
/* a small trick, usualy the lower argument is the one bound */
|
||||
if (opcodex == _get_x_val && code_p->u.xx.xl > code_p->u.xx.xr) {
|
||||
wamreg x1 = code_p->u.xx.xl;
|
||||
code_p->u.xx.xl = code_p->u.xx.xr;
|
||||
code_p->u.xx.xr = x1;
|
||||
}
|
||||
}
|
||||
GONEXT(xx);
|
||||
}
|
||||
|
@ -55,6 +55,7 @@
|
||||
#endif
|
||||
OPCODE(get_x_var ,xx),
|
||||
OPCODE(get_y_var ,yx),
|
||||
OPCODE(get_yy_var ,yyxx),
|
||||
OPCODE(get_x_val ,xx),
|
||||
OPCODE(get_y_val ,yx),
|
||||
OPCODE(get_atom ,xc),
|
||||
@ -142,6 +143,7 @@
|
||||
OPCODE(put_x_val ,xx),
|
||||
OPCODE(put_xx_val ,xxxx),
|
||||
OPCODE(put_y_val ,yx),
|
||||
OPCODE(put_y_vals ,yyxx),
|
||||
OPCODE(put_unsafe ,yx),
|
||||
OPCODE(put_atom ,xc),
|
||||
OPCODE(put_float ,xd),
|
||||
|
12
H/absmi.h
12
H/absmi.h
@ -733,19 +733,17 @@ Macros to check the limits of stacks
|
||||
#endif
|
||||
|
||||
#define store_yaam_regs(AP,I) \
|
||||
{ register yamop *x1 = (yamop *)(AP); \
|
||||
register CELL *x2 = ENV; \
|
||||
/* Jump to CP_BASE */ \
|
||||
{ /* Jump to CP_BASE */ \
|
||||
S_YREG = (CELL *)((choiceptr)((S_YREG)-(I))-1); \
|
||||
/* Save Information */ \
|
||||
HBREG = H; \
|
||||
B_YREG->cp_tr = TR; \
|
||||
B_YREG->cp_h = H; \
|
||||
B_YREG->cp_b = B; \
|
||||
store_yaam_reg_cpdepth(B_YREG); \
|
||||
B_YREG->cp_cp = CPREG; \
|
||||
B_YREG->cp_ap = x1; \
|
||||
B_YREG->cp_env= x2; \
|
||||
store_yaam_reg_cpdepth(B_YREG); \
|
||||
B_YREG->cp_cp = CPREG; \
|
||||
B_YREG->cp_ap = AP; \
|
||||
B_YREG->cp_env= ENV; \
|
||||
}
|
||||
|
||||
#define store_yaam_regs_for_either(AP,d0) \
|
||||
|
@ -744,6 +744,13 @@ typedef struct yami {
|
||||
wamreg x;
|
||||
CELL next;
|
||||
} yyx;
|
||||
struct {
|
||||
yslot y1;
|
||||
yslot y2;
|
||||
wamreg x1;
|
||||
wamreg x2;
|
||||
CELL next;
|
||||
} yyxx;
|
||||
struct {
|
||||
yslot y;
|
||||
yslot y1;
|
||||
|
31
H/amiops.h
31
H/amiops.h
@ -158,9 +158,17 @@ AlignGlobalForDouble(void)
|
||||
((TERM) < (CELL *)B_FZ)) \
|
||||
goto LAB
|
||||
|
||||
#define TrailAndJump(TERM, VAL) \
|
||||
if (IN_BETWEEN(HBREG,TERM,B) && \
|
||||
((TERM) < (CELL *)B_FZ)) \
|
||||
GONext();
|
||||
|
||||
#else
|
||||
#define Trail(TERM, VAL, LAB) \
|
||||
TRAIL(TERM, VAL)
|
||||
|
||||
#define Trail(TERM, VAL, LAB) \
|
||||
TRAIL_AND_JUMP(TERM, VAL)
|
||||
#endif
|
||||
|
||||
#else /* BBREG_TRAIL_SCHEME */
|
||||
@ -173,9 +181,18 @@ AlignGlobalForDouble(void)
|
||||
#define Trail(TERM, VAL, LAB) \
|
||||
if (IN_BETWEEN(HBREG,TERM,BBREG)) \
|
||||
goto LAB
|
||||
|
||||
#define TrailAndJump(TERM, VAL) \
|
||||
if (IN_BETWEEN(HBREG,TERM,BBREG)) \
|
||||
GONext();
|
||||
|
||||
#else
|
||||
#define Trail(TERM, VAL, LAB) \
|
||||
TRAIL(TERM, VAL)
|
||||
|
||||
#define TrailAndJump(TERM, VAL) \
|
||||
TRAIL_AND_JUMP(TERM, VAL)
|
||||
|
||||
#endif
|
||||
|
||||
#define TRAIL_LOCAL(TERM, VAL) \
|
||||
@ -224,6 +241,9 @@ AlignGlobalForDouble(void)
|
||||
#define TRAIL(A,D) if (OUTSIDE(HBREG,A,B)) \
|
||||
DO_TRAIL(A,D);
|
||||
|
||||
#define TRAIL_AND_JUMP(A,D) if (!OUTSIDE(HBREG,A,B)) GONext(); \
|
||||
DO_TRAIL(A,D);
|
||||
|
||||
#define Trail(A, D, LAB) TRAIL(A,D)
|
||||
|
||||
#define TRAIL_GLOBAL(A,D) if ((A) < HBREG) DO_TRAIL(A,D);
|
||||
@ -241,6 +261,10 @@ AlignGlobalForDouble(void)
|
||||
if (OUTSIDE(HBREG,A,B)) \
|
||||
TR++
|
||||
|
||||
#define TRAIL(A,D) TrailTerm(TR) = (CELL)(A); \
|
||||
if (!OUTSIDE(HBREG,A,B)) \
|
||||
GONext();
|
||||
|
||||
#define Trail(A,D,LAB) TRAIL(A,D)
|
||||
|
||||
#define TRAIL_GLOBAL(A,D) TR[0] = (CELL)(A); if ((A) < HBREG) TR++
|
||||
@ -256,6 +280,9 @@ AlignGlobalForDouble(void)
|
||||
#define TRAIL(A,D) if (OUTSIDE(HBREG,A,B)) \
|
||||
DO_TRAIL(A,D)
|
||||
|
||||
#define TRAIL_AND_JUMP(A,D) if (IN_BETWEEN(HBREG,A,B)) GONext(); \
|
||||
DO_TRAIL(A,D)
|
||||
|
||||
#define Trail(A,D,LAB) TRAIL(A,D)
|
||||
|
||||
#define TRAIL_GLOBAL(A,D) if ((A) < HBREG) DO_TRAIL(A,D)
|
||||
@ -276,6 +303,9 @@ AlignGlobalForDouble(void)
|
||||
#define Trail(A,D,LAB) if (IN_BETWEEN(HBREG,A,B)) \
|
||||
goto LAB
|
||||
|
||||
#define TrailAndJump(A,D) if (IN_BETWEEN(HBREG,A,B)) \
|
||||
GONext();
|
||||
|
||||
#define TRAIL_GLOBAL(A,D) if ((A) < HBREG) DO_TRAIL(A,D)
|
||||
|
||||
#define Trail_Global(A,D,LAB) if ((A) >= HBREG) goto LAB
|
||||
@ -316,6 +346,7 @@ Binding Macros for Multiple Assignment Variables.
|
||||
#define Bind_Global(A,D) TRAIL_GLOBAL(A,D); *(A) = (D)
|
||||
#define Bind_and_Trail(A,D) DO_TRAIL(A,D); *(A) = (D)
|
||||
#define BIND(A,D,L) *(A) = (D); Trail(A,D,L)
|
||||
#define BIND_AND_JUMP(A,D) *(A) = (D); TrailAndJump(A,D)
|
||||
#define BIND_GLOBAL(A,D,L) *(A) = (D); Trail_Global(A,D,L)
|
||||
|
||||
#ifdef COROUTINING
|
||||
|
@ -1559,6 +1559,17 @@
|
||||
}
|
||||
cl = NEXTOP(cl,yyx);
|
||||
break;
|
||||
case _get_yy_var:
|
||||
if (!(nofregs = add_regcopy(myregs, nofregs, cl->u.yyxx.x1, cl->u.yyxx.y1))) {
|
||||
clause->Tag = (CELL)NULL;
|
||||
return;
|
||||
}
|
||||
if (!(nofregs = add_regcopy(myregs, nofregs, cl->u.yyxx.x2, cl->u.yyxx.y2))) {
|
||||
clause->Tag = (CELL)NULL;
|
||||
return;
|
||||
}
|
||||
cl = NEXTOP(cl,yyxx);
|
||||
break;
|
||||
#ifdef YAPOR
|
||||
#endif
|
||||
#ifdef TABLING
|
||||
|
@ -642,6 +642,17 @@
|
||||
}
|
||||
cl = NEXTOP(cl,yx);
|
||||
break;
|
||||
case _get_yy_var:
|
||||
if (cl->u.yyxx.x1 == iarg) {
|
||||
clause->Tag = (CELL)NULL;
|
||||
return;
|
||||
}
|
||||
if (cl->u.yyxx.x2 == iarg) {
|
||||
clause->Tag = (CELL)NULL;
|
||||
return;
|
||||
}
|
||||
cl = NEXTOP(cl,yyxx);
|
||||
break;
|
||||
#ifdef YAPOR
|
||||
#endif
|
||||
#ifdef TABLING
|
||||
|
@ -856,6 +856,15 @@ restore_opcodes(yamop *pc)
|
||||
pc->u.yyx.x = XAdjust(pc->u.yyx.x);
|
||||
pc = NEXTOP(pc,yyx);
|
||||
break;
|
||||
/* instructions type yyxx */
|
||||
case _get_yy_var:
|
||||
case _put_y_vals:
|
||||
pc->u.yyxx.y1 = YAdjust(pc->u.yyxx.y1);
|
||||
pc->u.yyxx.y2 = YAdjust(pc->u.yyxx.y2);
|
||||
pc->u.yyxx.x1 = XAdjust(pc->u.yyxx.x1);
|
||||
pc->u.yyxx.x2 = XAdjust(pc->u.yyxx.x2);
|
||||
pc = NEXTOP(pc,yyxx);
|
||||
break;
|
||||
#ifdef YAPOR
|
||||
/* instructions type Otapl */
|
||||
case _getwork:
|
||||
|
@ -655,6 +655,11 @@
|
||||
case _p_func2f_yy:
|
||||
pc = NEXTOP(pc,yyx);
|
||||
break;
|
||||
/* instructions type yyxx */
|
||||
case _get_yy_var:
|
||||
case _put_y_vals:
|
||||
pc = NEXTOP(pc,yyxx);
|
||||
break;
|
||||
#ifdef YAPOR
|
||||
/* instructions type Otapl */
|
||||
case _getwork:
|
||||
|
@ -790,6 +790,7 @@ opinfo("write_y_val",[body]).
|
||||
opinfo("write_y_loc",[body]).
|
||||
opinfo("get_x_var",[dup("xr","xl")]).
|
||||
opinfo("get_y_var",[dup("x","y")]).
|
||||
opinfo("get_yy_var",[dup("x1","y1"),dup("x2","y2")]).
|
||||
opinfo("put_x_var",[new("xl"),new("xr")]).
|
||||
opinfo("put_y_var",[new("x"),new("y")]).
|
||||
opinfo("get_x_val",[unify("xl","xr")]).
|
||||
|
Reference in New Issue
Block a user