diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/common.h | 6 | ||||
| -rw-r--r-- | src/compile/compile.c | 46 | ||||
| -rw-r--r-- | src/ejit.c | 26 | ||||
| -rw-r--r-- | src/interp.c | 22 | 
4 files changed, 100 insertions, 0 deletions
diff --git a/src/common.h b/src/common.h index 661220b..69f1441 100644 --- a/src/common.h +++ b/src/common.h @@ -145,6 +145,12 @@ enum ejit_opcode {  	EJIT_OP_SQRTR_F,  	EJIT_OP_SQRTR_D, +	EJIT_OP_MINR_F, +	EJIT_OP_MINR_D, + +	EJIT_OP_MAXR_F, +	EJIT_OP_MAXR_D, +  	EJIT_OP_EQR,  	EJIT_OP_NER,  	EJIT_OP_GTR, diff --git a/src/compile/compile.c b/src/compile/compile.c index 38c368f..dcf662b 100644 --- a/src/compile/compile.c +++ b/src/compile/compile.c @@ -1977,6 +1977,46 @@ static void resolve_relocs(jit_state_t *j, struct relocs *relocs, struct addrs *  	}  } +static void compile_maxr_f(struct ejit_func *f, jit_state_t *j, +		struct ejit_insn i) +{ +	jit_fpr_t r0 = getfpr(f, i.r0, 0); +	jit_fpr_t r1 = getloc_f(f, j, i.r1, 1); +	jit_fpr_t r2 = getloc_f(f, j, i.r2, 2); +	jit_maxr_f(j, r0, r1, r2); +	putloc_f(f, j, i.r0, r0); +} + +static void compile_maxr_d(struct ejit_func *f, jit_state_t *j, +		struct ejit_insn i) +{ +	jit_fpr_t r0 = getfpr(f, i.r0, 0); +	jit_fpr_t r1 = getloc_d(f, j, i.r1, 1); +	jit_fpr_t r2 = getloc_d(f, j, i.r2, 2); +	jit_maxr_d(j, r0, r1, r2); +	putloc_d(f, j, i.r0, r0); +} + +static void compile_minr_f(struct ejit_func *f, jit_state_t *j, +		struct ejit_insn i) +{ +	jit_fpr_t r0 = getfpr(f, i.r0, 0); +	jit_fpr_t r1 = getloc_f(f, j, i.r1, 1); +	jit_fpr_t r2 = getloc_f(f, j, i.r2, 2); +	jit_minr_f(j, r0, r1, r2); +	putloc_f(f, j, i.r0, r0); +} + +static void compile_minr_d(struct ejit_func *f, jit_state_t *j, +		struct ejit_insn i) +{ +	jit_fpr_t r0 = getfpr(f, i.r0, 0); +	jit_fpr_t r1 = getloc_d(f, j, i.r1, 1); +	jit_fpr_t r2 = getloc_d(f, j, i.r2, 2); +	jit_minr_d(j, r0, r1, r2); +	putloc_d(f, j, i.r0, r0); +} +  static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,                                size_t size)  { @@ -2143,6 +2183,12 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,  		case EJIT_OP_SQRTR_F: compile_sqrtr_f(f, j, i); break;  		case EJIT_OP_SQRTR_D: compile_sqrtr_d(f, j, i); break; +		case EJIT_OP_MINR_F: compile_minr_f(f, j, i); break; +		case EJIT_OP_MINR_D: compile_minr_d(f, j, i); break; + +		case EJIT_OP_MAXR_F: compile_maxr_f(f, j, i); break; +		case EJIT_OP_MAXR_D: compile_maxr_d(f, j, i); break; +  		case EJIT_OP_EQR: compile_eqr(f, j, i); break;  		case EJIT_OP_EQR_F: compile_eqr_f(f, j, i); break;  		case EJIT_OP_EQR_D: compile_eqr_d(f, j, i); break; @@ -901,31 +901,37 @@ void ejit_ret(struct ejit_func *s)  void ejit_retr(struct ejit_func *s, struct ejit_gpr r0)  { +	assert(s->rtype != EJIT_FLOAT && s->rtype != EJIT_DOUBLE);  	emit_insn_oxr(s, EJIT_OP_RETR, r0);  }  void ejit_retr_f(struct ejit_func *s, struct ejit_fpr f0)  { +	assert(s->rtype == EJIT_FLOAT);  	emit_insn_oxf(s, EJIT_OP_RETR_F, f0);  }  void ejit_retr_d(struct ejit_func *s, struct ejit_fpr f0)  { +	assert(s->rtype == EJIT_DOUBLE);  	emit_insn_oxf(s, EJIT_OP_RETR_D, f0);  }  void ejit_reti(struct ejit_func *s, int64_t i)  { +	assert(s->rtype != EJIT_FLOAT && s->rtype != EJIT_DOUBLE);  	emit_insn_oi(s, EJIT_OP_RETI, i);  }  void ejit_reti_f(struct ejit_func *s, float f)  { +	assert(s->rtype == EJIT_FLOAT);  	emit_insn_oF(s, EJIT_OP_RETI_F, f);  }  void ejit_reti_d(struct ejit_func *s, double f)  { +	assert(s->rtype == EJIT_DOUBLE);  	emit_insn_oD(s, EJIT_OP_RETI_D, f);  } @@ -1382,6 +1388,26 @@ void ejit_sqrtr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1)  	emit_insn_off(s, EJIT_OP_SQRTR_D, r0, r1);  } +void ejit_minr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1, struct ejit_fpr r2) +{ +	emit_insn_offf(s, EJIT_OP_MINR_F, r0, r1, r2); +} + +void ejit_minr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1, struct ejit_fpr r2) +{ +	emit_insn_offf(s, EJIT_OP_MINR_D, r0, r1, r2); +} + +void ejit_maxr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1, struct ejit_fpr r2) +{ +	emit_insn_offf(s, EJIT_OP_MAXR_F, r0, r1, r2); +} + +void ejit_maxr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1, struct ejit_fpr r2) +{ +	emit_insn_offf(s, EJIT_OP_MAXR_D, r0, r1, r2); +} +  struct ejit_reloc ejit_bner(struct ejit_func *s, struct ejit_gpr r0,                              struct ejit_gpr r1)  { diff --git a/src/interp.c b/src/interp.c index e7be77b..57dbfbe 100644 --- a/src/interp.c +++ b/src/interp.c @@ -150,6 +150,12 @@ union interp_ret ejit_run(struct ejit_func *f, size_t paramc, struct ejit_arg pa  		[EJIT_OP_SQRTR_F] = &&SQRTR_F,  		[EJIT_OP_SQRTR_D] = &&SQRTR_D, +		[EJIT_OP_MINR_F] = &&MINR_F, +		[EJIT_OP_MINR_D] = &&MINR_D, + +		[EJIT_OP_MAXR_F] = &&MAXR_F, +		[EJIT_OP_MAXR_D] = &&MAXR_D, +  		[EJIT_OP_BNER] = &&BNER,  		[EJIT_OP_BNEI] = &&BNEI,  		[EJIT_OP_BNER_F] = &&BNER_F, @@ -791,6 +797,22 @@ union interp_ret ejit_run(struct ejit_func *f, size_t paramc, struct ejit_arg pa  	fpr[i.r0].f = sqrt(fpr[i.r1].f);  	DISPATCH(); +	DO(MINR_F); +	fpr[i.r0].f = fminf(fpr[i.r1].f, fpr[i.r2].f); +	DISPATCH(); + +	DO(MINR_D); +	fpr[i.r0].d = fmin(fpr[i.r1].d, fpr[i.r2].d); +	DISPATCH(); + +	DO(MAXR_F); +	fpr[i.r0].f = fmaxf(fpr[i.r1].f, fpr[i.r2].f); +	DISPATCH(); + +	DO(MAXR_D); +	fpr[i.r0].d = fmax(fpr[i.r1].d, fpr[i.r2].d); +	DISPATCH(); +  	DO(SQRTR_D);  	fpr[i.r0].d = sqrt(fpr[i.r1].d);  	DISPATCH();  | 
