static inline void JIT_visit(ASTNode *node, int regs[], int reg) { switch(node->type) { case AST_BINARY_OP: { ASTBinaryOp *binary_op = (ASTBinaryOp*)node; int a_reg = alloc_reg(regs); JIT_visit(binary_op->lhs, regs, a_reg); int b_reg = alloc_reg(regs); JIT_visit(binary_op->rhs, regs, b_reg); switch(binary_op->op) { case '+': jit_addr_i(reg, a_reg, b_reg); break; case '-': jit_subr_i(reg, a_reg, b_reg); break; case '*': jit_mulr_i(reg, a_reg, b_reg); break; case '/': jit_divr_i(reg, a_reg, b_reg); break; } free_reg(regs, a_reg); free_reg(regs, b_reg); break; } case AST_INT: { jit_movi_i(reg, ((ASTInt*)node)->value); break; } } }
/* Store in R0 the result of evaluating the operator TOK with two register operands SRC1 and SRC2. */ void gen_reg_reg (int src1, int src2, int tok) { switch (tok) { case '+': jit_addr_i (JIT_R0, src1, src2); break; case '-': jit_subr_i (JIT_R0, src1, src2); break; case '*': jit_mulr_i (JIT_R0, src1, src2); break; case '/': jit_divr_i (JIT_R0, src1, src2); break; case '%': jit_modr_i (JIT_R0, src1, src2); break; case '&': jit_andr_i (JIT_R0, src1, src2); break; case '|': jit_orr_i (JIT_R0, src1, src2); break; case '^': jit_xorr_i (JIT_R0, src1, src2); break; case '=': jit_eqr_i (JIT_R0, src1, src2); break; case '<': jit_ltr_i (JIT_R0, src1, src2); break; case '>': jit_gtr_i (JIT_R0, src1, src2); break; case LE: jit_ler_i (JIT_R0, src1, src2); break; case GE: jit_ger_i (JIT_R0, src1, src2); break; case NE: jit_ner_i (JIT_R0, src1, src2); break; case LSH: jit_lshr_i (JIT_R0, src1, src2); break; case RSH: jit_rshr_i (JIT_R0, src1, src2); break; case RSHU: jit_rshr_ui (JIT_R0, src1, src2); break; default: abort (); } }
int main() { jit_code code; volatile double x = 0.0; code.ptr = (char *) codeBuffer; jit_set_ip(codeBuffer); jit_leaf(0); jit_ldi_d(JIT_FPR0, &a); jit_movi_d(JIT_FPR1, 0.0); jit_gtr_d(JIT_R0, JIT_FPR0, JIT_FPR1); jit_ltr_d(JIT_R1, JIT_FPR0, JIT_FPR1); jit_subr_i(JIT_RET, JIT_R0, JIT_R1); /* [greater] - [less] = -1/0/1 */ jit_ret(); jit_flush_code(codeBuffer, jit_get_ip().ptr); #ifdef LIGHTNING_DISASSEMBLE disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr); #endif #ifndef LIGHTNING_CROSS int_test("compare", code, -2.6, -2.4, 0, 2.4, 2.6); #endif #ifdef __GNUC__ jit_set_ip(codeBuffer); jit_leaf(0); jit_ldi_d(JIT_FPR0, &a); jit_movi_d(JIT_FPR1, 0.0); jit_eqr_d(JIT_R0, JIT_FPR0, JIT_FPR1); jit_ltgtr_d(JIT_R1, JIT_FPR0, JIT_FPR1); jit_lshi_i(JIT_R1, JIT_R1, 1); jit_orr_i(JIT_RET, JIT_R0, JIT_R1); jit_ret(); jit_flush_code(codeBuffer, jit_get_ip().ptr); #ifdef LIGHTNING_DISASSEMBLE disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr); #endif #ifndef LIGHTNING_CROSS int_test("nans", code, x / x, 1 / (a - a), -1 / (a - a), 0.0, -2.0); #endif #else printf ("nans\t\t1 3 3 0 3\n"); #endif jit_set_ip(codeBuffer); jit_leaf(0); jit_ldi_d(JIT_FPR0, &a); jit_truncr_d_i(JIT_RET, JIT_FPR0); jit_ret(); jit_flush_code(codeBuffer, jit_get_ip().ptr); #ifdef LIGHTNING_DISASSEMBLE disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr); #endif #ifndef LIGHTNING_CROSS int_test("trunc", code, -2.6, -2.4, 0, 2.4, 2.6); int_test("trunc", code, -3, -2, 0, 2, 3); #endif jit_set_ip(codeBuffer); jit_leaf(0); jit_ldi_d(JIT_FPR0, &a); jit_ceilr_d_i(JIT_RET, JIT_FPR0); jit_ret(); jit_flush_code(codeBuffer, jit_get_ip().ptr); #ifdef LIGHTNING_DISASSEMBLE disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr); #endif #ifndef LIGHTNING_CROSS int_test("ceil", code, -2.6, -2.4, 0, 2.4, 2.6); int_test("ceil", code, -3, -2, 0, 2, 3); #endif jit_set_ip(codeBuffer); jit_leaf(0); jit_ldi_d(JIT_FPR0, &a); jit_floorr_d_i(JIT_RET, JIT_FPR0); jit_ret(); jit_flush_code(codeBuffer, jit_get_ip().ptr); #ifdef LIGHTNING_DISASSEMBLE disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr); #endif #ifndef LIGHTNING_CROSS int_test("floor", code, -2.6, -2.4, 0, 2.4, 2.6); int_test("floor", code, -3, -2, 0, 2, 3); #endif jit_set_ip(codeBuffer); jit_leaf(0); jit_ldi_d(JIT_FPR0, &a); jit_roundr_d_i(JIT_RET, JIT_FPR0); jit_ret(); jit_flush_code(codeBuffer, jit_get_ip().ptr); #ifdef LIGHTNING_DISASSEMBLE disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr); #endif #ifndef LIGHTNING_CROSS int_test("round", code, -2.6, -2.4, 0, 2.4, 2.6); int_test("round", code, -3, -2, 0, 2, 3); #endif #if 0 && defined JIT_TRANSCENDENTAL jit_set_ip(codeBuffer); jit_leaf(0); jitfp_sti_d(&a, jitfp_log( jitfp_exp(jitfp_imm(1.0)) ) ); jit_ret(); jit_flush_code(codeBuffer, jit_get_ip().ptr); code.vptr(); #ifdef LIGHTNING_DISASSEMBLE disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr); #endif #ifndef LIGHTNING_CROSS printf("log e = \t%f\n", a); #endif jit_set_ip(codeBuffer); jit_leaf(0); jitfp_sti_d(&a, jitfp_atn( jitfp_imm(1.732050807657) ) ); jit_ret(); jit_flush_code(codeBuffer, jit_get_ip().ptr); code.vptr(); #ifdef LIGHTNING_DISASSEMBLE disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr); #endif #ifndef LIGHTNING_CROSS printf("pi = \t%f\n", a*3); #endif jit_set_ip(codeBuffer); jit_leaf(0); jitfp_sti_d(&a, jitfp_tan( jitfp_ldi_d(&a) ) ); jit_ret(); jit_flush_code(codeBuffer, jit_get_ip().ptr); code.vptr(); #ifdef LIGHTNING_DISASSEMBLE disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr); #endif #ifndef LIGHTNING_CROSS printf("tan^2 pi/3 = \t%f\n", a*a); #endif #endif /* JIT_TRANSCEDENTAL */ return (0); }