;
; ppc/core.jit
;
;
; $Id: core.jit,v 1.14 2003/05/27 05:37:08 educated_foo Exp $
;

Parrot_end {
    jit_emit_add_rri_i(NATIVECODE, r1, r1, 64);
    jit_emit_lwz(NATIVECODE, r0, 8, r1);
    jit_emit_mtlr(NATIVECODE, r0);
;    jit_emit_lmw(NATIVECODE, r30, -8, r1);
    jit_emit_blr(NATIVECODE);
}

Parrot_set_i_ic {
    if (MAP[1]) {
        jit_emit_mov_ri_i(NATIVECODE, MAP[1], *INT_CONST[2]);
    }
    else {
        jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[2]);
        jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1); 
    }
}

Parrot_set_i_i {
    if (MAP[1] && MAP[2]) {
        jit_emit_mov_rr(NATIVECODE, MAP[1], MAP[2]);
    }
    else if (MAP[1]) {
        jit_emit_mov_rm_i(NATIVECODE, MAP[1], &INT_REG[2]); 
    } 
    else if (MAP[2]) {
        jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], MAP[2]); 
    }
    else {
        jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[2]); 
        jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1); 
    }
}

Parrot_set_n_nc {
    if (MAP[1]) {
        jit_emit_mov_ri_i(NATIVECODE, ISR1, &NUM_CONST[2]);
        jit_emit_lfd(NATIVECODE, MAP[1], 0, ISR1);
    }
    else {
        jit_emit_mov_ri_i(NATIVECODE, ISR1, &NUM_CONST[2]);
        jit_emit_lfd(NATIVECODE, ISR1, 0, ISR1);
        jit_emit_mov_mr_n(NATIVECODE, &NUM_REG[1], ISR1); 
    }
}

Parrot_neg_i_i {
    if (MAP[1] && MAP[2]) {
        jit_emit_neg_rr(NATIVECODE, MAP[1], MAP[2]);
    }
    else if (MAP[1]) {
        jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[2]); 
        jit_emit_neg_rr(NATIVECODE, MAP[1], ISR1);
    }
    else if (MAP[2]) {
        jit_emit_neg_rr(NATIVECODE, ISR1, MAP[1]);
        jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
    }
    else {
        jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[2]);
        jit_emit_neg_rr(NATIVECODE, ISR1, ISR1);
        jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
    }
}

TEMPLATE Parrot_binop_i_ic {
    if (MAP[1]) {
        jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[2]); 
        jit_emit_<op>_rrr(NATIVECODE, MAP[1], MAP[1], ISR1);
    }
    else {
        jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[1]);
        jit_emit_mov_ri_i(NATIVECODE, ISR2, *INT_CONST[2]);
        jit_emit_<op>_rrr(NATIVECODE, ISR1, ISR2, ISR1);
        jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
    }
}

TEMPLATE Parrot_binop_x_x {
    if (MAP[1] && MAP[2]) {
        jit_emit_<op>_rrr(NATIVECODE, MAP[1], MAP[1], MAP[2]);
    }
    else if (MAP[1]) {
        jit_emit_mov_rm<_N>(NATIVECODE, <s1>, &<T>_REG[2]); 
        jit_emit_<op>_rrr(NATIVECODE, MAP[1], MAP[1], <s1>);
    }
    else if (MAP[2]) {
        jit_emit_mov_rm<_N>(NATIVECODE, <s1>, &<T>_REG[1]);
        jit_emit_<op>_rrr(NATIVECODE, <s1>, <s1>, MAP[2]);
        jit_emit_mov_mr<_N>(NATIVECODE, &<T>_REG[1], <s1>);
    }
    else {
        jit_emit_mov_rm<_N>(NATIVECODE, <s1>, &<T>_REG[1]);
        jit_emit_mov_rm<_N>(NATIVECODE, <s2>, &<T>_REG[2]);
        jit_emit_<op>_rrr(NATIVECODE, <s1>, <s2>, <s1>);
        jit_emit_mov_mr<_N>(NATIVECODE, &<T>_REG[1], <s1>);
    }
}

TEMPLATE Parrot_binop_x_x_x {
    if (MAP[1] && MAP[2] && MAP[3]) {
        jit_emit_<op>_rrr(NATIVECODE, MAP[1], MAP[2], MAP[3]);
    }
    else if (MAP[1] && MAP[2]) {
        jit_emit_mov_rm<_N>(NATIVECODE, <s1>, &<T>_REG[3]); 
        jit_emit_<op>_rrr(NATIVECODE, MAP[1], MAP[2], <s1>);
    }
    else if (MAP[1] && MAP[3]) {
        jit_emit_mov_rm<_N>(NATIVECODE, <s1>, &<T>_REG[2]);
        jit_emit_<op>_rrr(NATIVECODE, MAP[1], <s1>, MAP[3]);
    }
    else if (MAP[2] && MAP[3]) {
        jit_emit_<op>_rrr(NATIVECODE, <s1>, MAP[2], MAP[3]);
        jit_emit_mov_mr<_N>(NATIVECODE, &<T>_REG[1], <s1>);
    }
    else if (MAP[1]) {
        jit_emit_mov_rm<_N>(NATIVECODE, <s1>, &<T>_REG[3]);
        jit_emit_mov_rm<_N>(NATIVECODE, <s2>, &<T>_REG[2]);
        jit_emit_<op>_rrr(NATIVECODE, MAP[1], <s2>, <s1>);
    }
    else if (MAP[2]) {
        jit_emit_mov_rm<_N>(NATIVECODE, <s1>, &<T>_REG[3]);
        jit_emit_<op>_rrr(NATIVECODE, <s1>, MAP[2], <s1>);
        jit_emit_mov_mr<_N>(NATIVECODE, &<T>_REG[1], <s1>);
    }
    else if (MAP[3]) {
        jit_emit_mov_rm<_N>(NATIVECODE, <s1>, &<T>_REG[2]);
        jit_emit_<op>_rrr(NATIVECODE, <s1>, <s1>, MAP[3]);
        jit_emit_mov_mr<_N>(NATIVECODE, &<T>_REG[1], <s1>);
    }
    else {
        jit_emit_mov_rm<_N>(NATIVECODE, <s1>, &<T>_REG[3]);
        jit_emit_mov_rm<_N>(NATIVECODE, <s2>, &<T>_REG[2]);
        jit_emit_<op>_rrr(NATIVECODE, <s1>, <s2>, <s1>);
        jit_emit_mov_mr<_N>(NATIVECODE, &<T>_REG[1], <s1>);
    }
}

TEMPLATE Parrot_binop_i_ic_i {
    if (MAP[1] && MAP[3]) {
        jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[2]);
        jit_emit_<op>_rrr(NATIVECODE, MAP[1], ISR1, MAP[3]);
    }
    else if (MAP[1]) {
        jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[3]);
        jit_emit_mov_ri_i(NATIVECODE, ISR2, *INT_CONST[2]);
        jit_emit_<op>_rrr(NATIVECODE, MAP[1], ISR2, ISR1);
    }
    else if (MAP[3]) {
        jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[2]);
        jit_emit_<op>_rrr(NATIVECODE, ISR1, ISR1, MAP[3]);
        jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
    }
    else {
        jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[3]);
        jit_emit_mov_ri_i(NATIVECODE, ISR2, *INT_CONST[2]);
        jit_emit_<op>_rrr(NATIVECODE, ISR1, ISR2, ISR1);
        jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
    }
}

TEMPLATE Parrot_binop_i_i_ic {
    if (MAP[1] && MAP[2]) {
        jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[3]); 
        jit_emit_<op>_rrr(NATIVECODE, MAP[1], MAP[2], ISR1);
    }
    else if (MAP[1]) {
        jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[3]);
        jit_emit_mov_rm_i(NATIVECODE, ISR2, &INT_REG[2]);
        jit_emit_<op>_rrr(NATIVECODE, MAP[1], ISR2, ISR1);
    }
    else if (MAP[2]) {
        jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[3]);
        jit_emit_<op>_rrr(NATIVECODE, ISR1, MAP[2], ISR1);
        jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
    }
    else {
        jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[3]);
        jit_emit_mov_rm_i(NATIVECODE, ISR2, &INT_REG[2]);
        jit_emit_<op>_rrr(NATIVECODE, ISR1, ISR2, ISR1);
        jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
    }
}

Parrot_band_i_i {
    Parrot_binop_x_x s/<_N>/_i/ s/<op>/and/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
}

Parrot_bor_i_i {
    Parrot_binop_x_x s/<_N>/_i/ s/<op>/or/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
}

Parrot_bxor_i_i {
    Parrot_binop_x_x s/<_N>/_i/ s/<op>/xor/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
}

Parrot_add_i_i {
    Parrot_binop_x_x s/<_N>/_i/ s/<op>/add/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
}

Parrot_sub_i_i {
    Parrot_binop_x_x s/<_N>/_i/ s/<op>/sub/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
}

Parrot_mul_i_i {
    Parrot_binop_x_x s/<_N>/_i/ s/<op>/mul/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
}

Parrot_div_i_i {
    Parrot_binop_x_x s/<_N>/_i/ s/<op>/div/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
}

Parrot_band_i_ic {
    Parrot_binop_i_ic s/<op>/and/
}

Parrot_bor_i_ic {
    Parrot_binop_i_ic s/<op>/or/
}

Parrot_bxor_i_ic {
    Parrot_binop_i_ic s/<op>/xor/
}

Parrot_add_i_ic {
    Parrot_binop_i_ic s/<op>/add/
}

Parrot_sub_i_ic {
    Parrot_binop_i_ic s/<op>/sub/
}

Parrot_mul_i_ic {
    Parrot_binop_i_ic s/<op>/mul/
}

Parrot_div_i_ic {
    Parrot_binop_i_ic s/<op>/div/
}

Parrot_add_n_n {
    Parrot_binop_x_x s/<_N>/_n/ s/<op>/fadd/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<T>/NUM/
}

Parrot_div_n_n {
    Parrot_binop_x_x s/<_N>/_n/ s/<op>/fdiv/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<T>/NUM/
}

Parrot_mul_n_n {
    Parrot_binop_x_x s/<_N>/_n/ s/<op>/fmul/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<T>/NUM/
}

Parrot_sub_n_n {
    Parrot_binop_x_x s/<_N>/_n/ s/<op>/fsub/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<T>/NUM/
}

Parrot_band_i_i_i {
    Parrot_binop_x_x_x s/<_N>/_i/ s/<op>/and/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
}

Parrot_bor_i_i_i {
    Parrot_binop_x_x_x s/<_N>/_i/ s/<op>/or/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
}

Parrot_bxor_i_i_i {
    Parrot_binop_x_x_x s/<_N>/_i/ s/<op>/xor/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
}

Parrot_add_i_i_i {
    Parrot_binop_x_x_x s/<_N>/_i/ s/<op>/add/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
}

Parrot_sub_i_i_i {
    Parrot_binop_x_x_x s/<_N>/_i/ s/<op>/sub/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
}

Parrot_mul_i_i_i {
    Parrot_binop_x_x_x s/<_N>/_i/ s/<op>/mul/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
}

Parrot_div_i_i_i {
    Parrot_binop_x_x_x s/<_N>/_i/ s/<op>/div/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
}

Parrot_band_i_i_ic {
    Parrot_binop_i_i_ic s/<op>/and/
}

Parrot_bor_i_i_ic {
    Parrot_binop_i_i_ic s/<op>/or/
}

Parrot_bxor_i_i_ic {
    Parrot_binop_i_i_ic s/<op>/xor/
}

Parrot_add_i_i_ic {
    Parrot_binop_i_i_ic s/<op>/add/
}

Parrot_sub_i_i_ic {
    Parrot_binop_i_i_ic s/<op>/sub/
}

Parrot_mul_i_i_ic {
    Parrot_binop_i_i_ic s/<op>/mul/
}

Parrot_div_i_i_ic {
    Parrot_binop_i_i_ic s/<op>/div/
}

Parrot_band_i_ic_i {
    Parrot_binop_i_ic_i s/<op>/and/
}

Parrot_bor_i_ic_i {
    Parrot_binop_i_ic_i s/<op>/or/
}

Parrot_bxor_i_ic_i {
    Parrot_binop_i_ic_i s/<op>/xor/
}

Parrot_add_i_ic_i {
    Parrot_binop_i_ic_i s/<op>/add/
}

Parrot_sub_i_ic_i {
    Parrot_binop_i_ic_i s/<op>/sub/
}

Parrot_mul_i_ic_i {
    Parrot_binop_i_ic_i s/<op>/mul/
}

Parrot_div_i_ic_i {
    Parrot_binop_i_ic_i s/<op>/div/
}

Parrot_add_n_n_n {
    Parrot_binop_x_x_x s/<_N>/_n/ s/<op>/fadd/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<T>/NUM/
}

Parrot_sub_n_n_n {
    Parrot_binop_x_x_x s/<_N>/_n/ s/<op>/fsub/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<T>/NUM/
}

Parrot_mul_n_n_n {
    Parrot_binop_x_x_x s/<_N>/_n/ s/<op>/fmul/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<T>/NUM/
}

Parrot_div_n_n_n {
    Parrot_binop_x_x_x s/<_N>/_n/ s/<op>/fdiv/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<T>/NUM/
}

Parrot_cmod_i_i_i {
    if (MAP[1] && MAP[2] && MAP[3]) {
        jit_emit_div_rrr(NATIVECODE, MAP[1], MAP[2], MAP[3]);
        jit_emit_mul_rrr(NATIVECODE, MAP[1], MAP[1], MAP[3]);
        jit_emit_sub_rrr(NATIVECODE, MAP[1], MAP[2], MAP[1]);
    }
    else if (MAP[1] && MAP[2]) {
        jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[3]);
        jit_emit_div_rrr(NATIVECODE, MAP[1], MAP[2], ISR1);
        jit_emit_mul_rrr(NATIVECODE, MAP[1], MAP[1], ISR1);
        jit_emit_sub_rrr(NATIVECODE, MAP[1], MAP[2], MAP[1]);
    }
    else if (MAP[1] && MAP[3]) {
        jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[2]);
        jit_emit_div_rrr(NATIVECODE, MAP[1], ISR1, MAP[3]);
        jit_emit_mul_rrr(NATIVECODE, MAP[1], MAP[1], MAP[3]);
        jit_emit_sub_rrr(NATIVECODE, MAP[1], ISR1, MAP[1]);
    }
    else if (MAP[2] && MAP[3]) {
        jit_emit_div_rrr(NATIVECODE, ISR1, MAP[2], MAP[3]);
        jit_emit_mul_rrr(NATIVECODE, ISR1, ISR1, MAP[3]);
        jit_emit_sub_rrr(NATIVECODE, ISR1, MAP[2], ISR1);
        jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
    }
    else if (MAP[1]) {
        jit_emit_mov_rm_i(NATIVECODE, ISR2, &INT_REG[3]);
        jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[2]);
        jit_emit_div_rrr(NATIVECODE, MAP[1], ISR1, ISR2);
        jit_emit_mul_rrr(NATIVECODE, MAP[1], MAP[1], ISR2);
        jit_emit_sub_rrr(NATIVECODE, MAP[1], ISR1, MAP[1]);
    }
    else if (MAP[2]) {
        jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[3]);
        jit_emit_div_rrr(NATIVECODE, ISR2, MAP[2], ISR1);
        jit_emit_mul_rrr(NATIVECODE, ISR2, ISR2, ISR1);
        jit_emit_sub_rrr(NATIVECODE, ISR2, MAP[2], ISR2);
        jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR2);
    }
    else if (MAP[3]) {
        jit_emit_mov_rm_i(NATIVECODE, ISR2, &INT_REG[2]);
        jit_emit_div_rrr(NATIVECODE, ISR1, ISR2, MAP[3]);
        jit_emit_mul_rrr(NATIVECODE, ISR1, ISR1, MAP[3]);
        jit_emit_sub_rrr(NATIVECODE, ISR1, ISR2, ISR1);
        jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
    }
    else {
; XXX: blech.  Not enough temp registers.
        jit_emit_mov_rm_i(NATIVECODE, ISR2, &INT_REG[3]);
        jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[2]);
        jit_emit_div_rrr(NATIVECODE, ISR1, ISR1, ISR2);
        jit_emit_mul_rrr(NATIVECODE, ISR1, ISR1, ISR2);
        jit_emit_mov_rm_i(NATIVECODE, ISR2, &INT_REG[2]);
        jit_emit_sub_rrr(NATIVECODE, ISR1, ISR1, ISR2);
        jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
    }
}

Parrot_inc_i {
    if (MAP[1]) {
        jit_emit_add_rri_i (NATIVECODE, MAP[1], MAP[1], 1);
    }
    else {
        jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[1]); 
        jit_emit_add_rri_i (NATIVECODE, ISR1, ISR1, 1);
        jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
    }
}

Parrot_dec_i {
    if (MAP[1]) {
        jit_emit_add_rri_i (NATIVECODE, MAP[1], MAP[1], -1);
    }
    else {
        jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[1]); 
        jit_emit_add_rri_i (NATIVECODE, ISR1, ISR1, -1);
        jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
    }
}

Parrot_inc_n {
    static const double one = 1.0;
    jit_emit_mov_ri_i(NATIVECODE, ISR1, &one);
    jit_emit_lfd(NATIVECODE, FSR1, 0, ISR1);
    if (MAP[1]) {
        jit_emit_fadd_rrr(NATIVECODE, MAP[1], MAP[1], FSR1);
    }
    else {
	jit_emit_mov_rm_n(NATIVECODE, FSR2, &NUM_REG[1]);
        jit_emit_fadd_rrr(NATIVECODE, FSR2, FSR2, FSR1);
        jit_emit_mov_mr_n(NATIVECODE, &NUM_REG[1], FSR2);
    }
}

Parrot_dec_n {
    static const double one = 1.0;
    jit_emit_mov_ri_i(NATIVECODE, ISR1, &one);
    jit_emit_lfd(NATIVECODE, FSR1, 0, ISR1);
    if (MAP[1]) {
        jit_emit_fsub_rrr(NATIVECODE, MAP[1], MAP[1], FSR1);
    }
    else {
	jit_emit_mov_rm_n(NATIVECODE, FSR2, &NUM_REG[1]);
        jit_emit_fsub_rrr(NATIVECODE, FSR2, FSR2, FSR1);
        jit_emit_mov_mr_n(NATIVECODE, &NUM_REG[1], FSR2);
    }
}

Parrot_neg_n_n {
    if (MAP[1] && MAP[2]) {
        jit_emit_fneg_rrr(NATIVECODE, MAP[1], MAP[2]);
    }
    else if (MAP[1]) {
        jit_emit_mov_rm_n(NATIVECODE, FSR1, &NUM_REG[2]);
        jit_emit_fneg_rrr(NATIVECODE, MAP[1], FSR1);
    }
    else if (MAP[2]) {
        jit_emit_fneg_rrr(NATIVECODE, FSR1, MAP[2]);
        jit_emit_mov_mr_n(NATIVECODE, &NUM_REG[1], FSR1);
    }
    else {
        jit_emit_mov_rm_n(NATIVECODE, FSR1, &NUM_REG[2]);
        jit_emit_fneg_rrr(NATIVECODE, FSR1, FSR1);
        jit_emit_mov_mr_n(NATIVECODE, &NUM_REG[1], FSR1);
    }
}

Parrot_abs_n_n {
    if (MAP[1] && MAP[2]) {
        jit_emit_fabs_rrr(NATIVECODE, MAP[1], MAP[2]);
    }
    else if (MAP[1]) {
        jit_emit_mov_rm_n(NATIVECODE, FSR1, &NUM_REG[2]);
        jit_emit_fabs_rrr(NATIVECODE, MAP[1], FSR1);
    }
    else if (MAP[2]) {
        jit_emit_fabs_rrr(NATIVECODE, FSR1, MAP[2]);
        jit_emit_mov_mr_n(NATIVECODE, &NUM_REG[1], FSR1);
    }
    else {
        jit_emit_mov_rm_n(NATIVECODE, FSR1, &NUM_REG[2]);
        jit_emit_fabs_rrr(NATIVECODE, FSR1, FSR1);
        jit_emit_mov_mr_n(NATIVECODE, &NUM_REG[1], FSR1);
    }
}

TEMPLATE Parrot_ifunless_i_ic {
    if (MAP[1]) {
        jit_emit_cmp_ri(NATIVECODE, MAP[1], 0);
    }
    else {
        jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[1]);
        jit_emit_cmp_ri(NATIVECODE, ISR1, 0);
    }
    jit_emit_bc(jit_info, <COND>, *INT_CONST[2]);
}

Parrot_if_i_ic {
    Parrot_ifunless_i_ic s/<COND>/BNE/
}

Parrot_unless_i_ic {
    Parrot_ifunless_i_ic s/<COND>/BEQ/
}

TEMPLATE Parrot_ifunless_n_ic {
    static const double zero = 0.0;
    jit_emit_mov_ri_i(NATIVECODE, ISR1, &zero);
    jit_emit_lfd(NATIVECODE, FSR1, 0, ISR1);
    if (MAP[1]) {
        jit_emit_fcmp_rr(NATIVECODE, MAP[1], FSR1);
    }
    else {
	jit_emit_mov_rm_n(NATIVECODE, FSR2, &NUM_REG[1]);
        jit_emit_fcmp_rr(NATIVECODE, FSR2, FSR1);
    }
    jit_emit_bc(jit_info, <COND>, *INT_CONST[2]);
}

Parrot_if_n_ic {
    Parrot_ifunless_i_ic s/<COND>/BNE/
}

Parrot_unless_n_ic {
    Parrot_ifunless_i_ic s/<COND>/BEQ/
}

TEMPLATE Parrot_branch_i_i_ic {
; First, emit the compare op:
    if (MAP[1] && MAP[2]) {
        jit_emit_cmp_rr(NATIVECODE, MAP[1], MAP[2]);
    }
    else if (MAP[1]) {
        jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[2]); 
        jit_emit_cmp_rr(NATIVECODE, MAP[1], ISR1);
    }
    else if (MAP[2]) {
        jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[1]);
        jit_emit_cmp_rr(NATIVECODE, ISR1, MAP[2]);
    }
    else {
        jit_emit_mov_rm_i(NATIVECODE, ISR2, &INT_REG[1]);
        jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[2]);
        jit_emit_cmp_rr(NATIVECODE, ISR2, ISR1);
    }
; Now the branch. XXX: need to handle large displacements.
    jit_emit_bc(jit_info, <CON>, *INT_CONST[3]);
}

TEMPLATE Parrot_branch_i_ic_ic {
    jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[2]);

    if (MAP[1]) {
        jit_emit_cmp_rr(NATIVECODE, MAP[1], ISR1);
    }
    else {
        jit_emit_mov_rm_i(NATIVECODE, ISR2, &INT_REG[1]);
        jit_emit_cmp_rr(NATIVECODE, ISR2, ISR1);
    }
; Now the branch. XXX: need to handle large displacements.
    jit_emit_bc(jit_info, <CON>, *INT_CONST[3]);
   
}

TEMPLATE Parrot_branch_ic_i_ic {
    jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[1]);

    if (MAP[2]) {
        jit_emit_cmp_rr(NATIVECODE, ISR1, MAP[2]);
    }
    else {
        jit_emit_mov_rm_i(NATIVECODE, ISR2, &INT_REG[2]);
        jit_emit_cmp_rr(NATIVECODE, ISR1, ISR2);
    }
; Now the branch. XXX: need to handle large displacements.
    jit_emit_bc(jit_info, <CON>, *INT_CONST[3]);
}

Parrot_gt_i_i_ic {
    Parrot_branch_i_i_ic s/<CON>/BGT/
}

Parrot_gt_i_ic_ic {
    Parrot_branch_i_ic_ic s/<CON>/BGT/
}

Parrot_gt_ic_i_ic {
    Parrot_branch_ic_i_ic s/<CON>/BGT/
}

Parrot_gt_ic_ic_ic {
    if (*INT_CONST[1] > *INT_CONST[2])
        jit_emit_bx(jit_info, 0, *INT_CONST[3]);
}

Parrot_eq_i_i_ic {
    Parrot_branch_i_i_ic s/<CON>/BEQ/
}

Parrot_eq_i_ic_ic {
    Parrot_branch_i_ic_ic s/<CON>/BEQ/
}

Parrot_eq_ic_i_ic {
    Parrot_branch_ic_i_ic s/<CON>/BEQ/
}

Parrot_eq_ic_ic_ic {
    if (*INT_CONST[1] == *INT_CONST[2])
        jit_emit_bx(jit_info, 0, *INT_CONST[3]);
}

Parrot_ge_i_i_ic {
    Parrot_branch_i_i_ic s/<CON>/BGE/
}

Parrot_ge_i_ic_ic {
    Parrot_branch_i_ic_ic s/<CON>/BGE/
}

Parrot_ge_ic_i_ic {
    Parrot_branch_ic_i_ic s/<CON>/BGE/
}

Parrot_ge_ic_ic_ic {
    if (*INT_CONST[1] >= *INT_CONST[2])
        jit_emit_bx(jit_info, 0, *INT_CONST[3]);
}

Parrot_lt_i_i_ic {
    Parrot_branch_i_i_ic s/<CON>/BLT/
}

Parrot_lt_i_ic_ic {
    Parrot_branch_i_ic_ic s/<CON>/BLT/
}

Parrot_lt_ic_i_ic {
    Parrot_branch_ic_i_ic s/<CON>/BLT/
}

Parrot_lt_ic_ic_ic {
    if (*INT_CONST[1] < *INT_CONST[2])
        jit_emit_bx(jit_info, 0, *INT_CONST[3]);
}

Parrot_le_i_i_ic {
    Parrot_branch_i_i_ic s/<CON>/BLE/
}

Parrot_le_i_ic_ic {
    Parrot_branch_i_ic_ic s/<CON>/BLE/
}

Parrot_le_ic_i_ic {
    Parrot_branch_ic_i_ic s/<CON>/BLE/
}

Parrot_le_ic_ic_ic {
    if (*INT_CONST[1] <= *INT_CONST[2])
        jit_emit_bx(jit_info, 0, *INT_CONST[3]);
}

Parrot_ne_i_i_ic {
    Parrot_branch_i_i_ic s/<CON>/BNE/
}

Parrot_ne_i_ic_ic {
    Parrot_branch_i_ic_ic s/<CON>/BNE/
}

Parrot_ne_ic_i_ic {
    Parrot_branch_ic_i_ic s/<CON>/BNE/
}

Parrot_ne_ic_ic_ic {
    if (*INT_CONST[1] != *INT_CONST[2])
        jit_emit_bx(jit_info, 0, *INT_CONST[3]);
}

TEMPLATE Parrot_branch_n_n_ic {
    if (MAP[1] && MAP[2]) {
        jit_emit_fcmp_rr(NATIVECODE, MAP[1], MAP[2]);
    }
    else if (MAP[1]) {
        jit_emit_mov_rm_n(NATIVECODE, FSR1, &NUM_REG[2]);
        jit_emit_fcmp_rr(NATIVECODE, MAP[1], FSR1);
    }
    else if (MAP[2]) {
        jit_emit_mov_rm_n(NATIVECODE, FSR1, &NUM_REG[1]);
        jit_emit_fcmp_rr(NATIVECODE, FSR1, MAP[2]);
    }
    else {
        jit_emit_mov_rm_n(NATIVECODE, FSR2, &NUM_REG[1]);
        jit_emit_mov_rm_n(NATIVECODE, FSR1, &NUM_REG[2]);
        jit_emit_fcmp_rr(NATIVECODE, FSR2, FSR1);
    }
    jit_emit_bc(jit_info, <CON>, *INT_CONST[3]);
}

TEMPLATE Parrot_branch_n_nc_ic {
    if (MAP[1]) {
        jit_emit_mov_ri_i(NATIVECODE, ISR1, &NUM_CONST[2]);
        jit_emit_lfd(NATIVECODE, FSR1, 0, ISR1);
        jit_emit_fcmp_rr(NATIVECODE, MAP[1], FSR1);
    }
    else {
        jit_emit_mov_rm_n(NATIVECODE, FSR2, &NUM_REG[1]);
        jit_emit_mov_ri_i(NATIVECODE, ISR1, &NUM_CONST[2]);
        jit_emit_lfd(NATIVECODE, FSR1, 0, ISR1);
        jit_emit_fcmp_rr(NATIVECODE, FSR2, FSR1);
    }
    jit_emit_bc(jit_info, <CON>, *INT_CONST[3]);
}

TEMPLATE Parrot_branch_nc_n_ic {
    if (MAP[2]) {
        jit_emit_mov_ri_i(NATIVECODE, ISR1, &NUM_CONST[1]);
        jit_emit_lfd(NATIVECODE, FSR1, 0, ISR1);
        jit_emit_fcmp_rr(NATIVECODE, FSR1, MAP[2]);
    }
    else {
        jit_emit_mov_rm_n(NATIVECODE, FSR2, &NUM_REG[2]);
        jit_emit_mov_ri_i(NATIVECODE, ISR1, &NUM_CONST[1]);
        jit_emit_lfd(NATIVECODE, FSR1, 0, ISR1);
        jit_emit_fcmp_rr(NATIVECODE, FSR1, FSR2);
    }
    jit_emit_bc(jit_info, <CON>, *INT_CONST[3]);
}

Parrot_gt_n_n_ic {
    Parrot_branch_n_n_ic s/<CON>/BGT/
}

Parrot_gt_n_nc_ic {
    Parrot_branch_n_nc_ic s/<CON>/BGT/
}

Parrot_gt_nc_n_ic {
    Parrot_branch_nc_n_ic s/<CON>/BGT/
}

Parrot_gt_nc_nc_ic {
    if (*NUM_CONST[1] > *NUM_CONST[2])
        jit_emit_bx(jit_info, 0, *INT_CONST[3]);
}

Parrot_eq_n_n_ic {
        Parrot_branch_n_n_ic s/<CON>/BEQ/
}

Parrot_eq_n_nc_ic {
    Parrot_branch_n_nc_ic s/<CON>/BEQ/
}

Parrot_eq_nc_n_ic {
    Parrot_branch_nc_n_ic s/<CON>/BEQ/
}

Parrot_eq_nc_nc_ic {
    if (*NUM_CONST[1] == *NUM_CONST[2])
        jit_emit_bx(jit_info, 0, *INT_CONST[3]);
}

Parrot_ge_n_n_ic {
    Parrot_branch_n_n_ic s/<CON>/BGE/
}

Parrot_ge_n_nc_ic {
    Parrot_branch_n_nc_ic s/<CON>/BGE/
}

Parrot_ge_nc_n_ic {
    Parrot_branch_nc_n_ic s/<CON>/BGE/
}

Parrot_ge_nc_nc_ic {
    if (*NUM_CONST[1] >= *NUM_CONST[2])
        jit_emit_bx(jit_info, 0, *INT_CONST[3]);
}

Parrot_lt_n_n_ic {
    Parrot_branch_n_n_ic s/<CON>/BLT/
}

Parrot_lt_n_nc_ic {
    Parrot_branch_n_nc_ic s/<CON>/BLT/
}

Parrot_lt_nc_n_ic {
    Parrot_branch_nc_n_ic s/<CON>/BLT/
}

Parrot_lt_nc_nc_ic {
    if (*NUM_CONST[1] < *NUM_CONST[2])
        jit_emit_bx(jit_info, 0, *INT_CONST[3]);
}

Parrot_le_n_n_ic {
    Parrot_branch_n_n_ic s/<CON>/BLE/
}

Parrot_le_n_nc_ic {
    Parrot_branch_n_nc_ic s/<CON>/BLE/
}

Parrot_le_nc_n_ic {
    Parrot_branch_nc_n_ic s/<CON>/BLE/
}

Parrot_le_nc_nc_ic {
    if (*NUM_CONST[1] <= *NUM_CONST[2])
        jit_emit_bx(jit_info, 0, *INT_CONST[3]);
}

Parrot_ne_n_n_ic {
    Parrot_branch_n_n_ic s/<CON>/BNE/
}

Parrot_ne_n_nc_ic {
    Parrot_branch_n_nc_ic s/<CON>/BNE/
}

Parrot_ne_nc_n_ic {
    Parrot_branch_nc_n_ic s/<CON>/BLE/
}

Parrot_ne_nc_nc_ic {
    if (*NUM_CONST[1] != *NUM_CONST[2])
        jit_emit_bx(jit_info, 0, *INT_CONST[3]);
}

Parrot_branch_ic {
    jit_emit_bx(jit_info, 0, *INT_CONST[1]);
}

Parrot_branch_i {
    jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[1]);
    jit_emit_mtlr(NATIVECODE, ISR1);
    jit_emit_blr(NATIVECODE);
}

