From: Stuart B. <zu...@us...> - 2007-03-16 20:59:19
|
Update of /cvsroot/hppaqemu/hppaqemu/target-hppa In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv22626 Modified Files: op.c translate.c Log Message: Implement conditions for addc/subb. Cleanup of arithmetic ops/conditions. Index: translate.c =================================================================== RCS file: /cvsroot/hppaqemu/hppaqemu/target-hppa/translate.c,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** translate.c 13 Mar 2007 05:57:44 -0000 1.27 --- translate.c 16 Mar 2007 20:58:57 -0000 1.28 *************** *** 653,665 **** /* T0 == opd1, T1 == opd2 */ ! static GenOpFunc * const gen_cond_cmp[8] = { gen_op_eval_never, ! gen_op_eval_cmp_eq, ! gen_op_eval_cmp_slt, ! gen_op_eval_cmp_slteq, ! gen_op_eval_cmp_ult, ! gen_op_eval_cmp_ulteq, ! gen_op_eval_cmp_sv, ! gen_op_eval_cmp_od, }; --- 653,689 ---- /* T0 == opd1, T1 == opd2 */ ! static GenOpFunc * const gen_cond_sub[8] = { gen_op_eval_never, ! gen_op_eval_sub_eq, ! gen_op_eval_sub_slt, ! gen_op_eval_sub_slteq, ! gen_op_eval_sub_ult, ! gen_op_eval_sub_ulteq, ! gen_op_eval_sub_sv, ! gen_op_eval_sub_od, ! }; ! ! /* T0 == opd1, T1 == opd2 */ ! static GenOpFunc * const gen_cond_addc[8] = { ! gen_op_eval_never, ! gen_op_eval_addc_eq, ! gen_op_eval_addc_slt, ! gen_op_eval_addc_slteq, ! gen_op_eval_addc_nuv, ! gen_op_eval_addc_znv, ! gen_op_eval_addc_sv, ! gen_op_eval_addc_od, ! }; ! ! /* T0 == opd1, T1 == opd2 */ ! static GenOpFunc * const gen_cond_subb[8] = { ! gen_op_eval_never, ! gen_op_eval_subb_eq, ! gen_op_eval_subb_slt, ! gen_op_eval_subb_slteq, ! gen_op_eval_subb_ult, ! gen_op_eval_subb_ulteq, ! gen_op_eval_subb_sv, ! gen_op_eval_subb_od, }; *************** *** 1330,1401 **** break; case 0x1C: /* ADDC */ gen_op_addc_T1_T0_cc(); break; case 0x3C: /* ADDCO */ ! gen_op_addco_T1_T0(); break; case 0x19: /* SH1ADD */ gen_shift_T0(1); if (c && f) ! gen_cond_add[c](); gen_op_add_T1_T0_cc(); break; case 0x39: /* SH1ADDO */ gen_shift_T0(1); if (c && f) ! gen_cond_add[c](); ! gen_op_addo_T1_T0(); break; case 0x1a: /* SH2ADD */ gen_shift_T0(2); if (c && f) ! gen_cond_add[c](); gen_op_add_T1_T0_cc(); break; case 0x3a: /* SH2ADDO */ gen_shift_T0(2); if (c && f) ! gen_cond_add[c](); ! gen_op_addo_T1_T0(); break; case 0x1b: /* SH3ADD */ gen_shift_T0(3); if (c && f) ! gen_cond_add[c](); gen_op_add_T1_T0_cc(); break; case 0x3b: /* SH3ADDO */ gen_shift_T0(3); if (c && f) ! gen_cond_add[c](); ! gen_op_addo_T1_T0(); break; case 0x10: /* SUB */ if (c && f) ! gen_cond_cmp[c](); gen_op_sub_T1_T0_cc(); break; case 0x30: /* SUBO */ if (c && f) ! gen_cond_cmp[c](); ! gen_op_sub_T1_T0(); break; case 0x13: /* SUBT */ if (c && f) ! gen_cond_cmp[c](); ! gen_op_subt_T1_T0(); break; case 0x33: /* SUBTO */ if (c && f) ! gen_cond_cmp[c](); ! gen_op_subto_T1_T0(); break; case 0x14: /* SUBB */ gen_op_subb_T1_T0_cc(); break; case 0x34: /* SUBBO */ ! gen_op_subbo_T1_T0(); break; case 0x11: /* DS */ gen_op_ds_T1_T0(); break; --- 1354,1451 ---- break; case 0x1C: /* ADDC */ + if (c && f) + gen_cond_addc[c](); gen_op_addc_T1_T0_cc(); break; case 0x3C: /* ADDCO */ ! gen_op_eval_addc_sv(); ! /* gen_op_overflow_trap(); */ ! if (c && f) ! gen_cond_addc[c](); ! gen_op_addc_T1_T0_cc(); break; case 0x19: /* SH1ADD */ gen_shift_T0(1); if (c && f) ! gen_cond_add[c](); /* FIXME */ gen_op_add_T1_T0_cc(); break; case 0x39: /* SH1ADDO */ + gen_op_eval_add_sv(); /* FIXME */ + /* gen_op_overflow_trap(); */ gen_shift_T0(1); if (c && f) ! gen_cond_add[c](); /* FIXME */ ! gen_op_add_T1_T0_cc(); break; case 0x1a: /* SH2ADD */ gen_shift_T0(2); if (c && f) ! gen_cond_add[c](); /* FIXME */ gen_op_add_T1_T0_cc(); break; case 0x3a: /* SH2ADDO */ + gen_op_eval_add_sv(); /* FIXME */ + /* gen_op_overflow_trap(); */ gen_shift_T0(2); if (c && f) ! gen_cond_add[c](); /* FIXME */ ! gen_op_add_T1_T0_cc(); break; case 0x1b: /* SH3ADD */ gen_shift_T0(3); if (c && f) ! gen_cond_add[c](); /* FIXME */ gen_op_add_T1_T0_cc(); break; case 0x3b: /* SH3ADDO */ + gen_op_eval_add_sv(); /* FIXME */ + /* gen_op_overflow_trap(); */ gen_shift_T0(3); if (c && f) ! gen_cond_add[c](); /* FIXME */ ! gen_op_add_T1_T0_cc(); break; case 0x10: /* SUB */ if (c && f) ! gen_cond_sub[c](); gen_op_sub_T1_T0_cc(); break; case 0x30: /* SUBO */ + gen_op_eval_sub_sv(); + /* gen_op_overflow_trap(); */ if (c && f) ! gen_cond_sub[c](); ! gen_op_sub_T1_T0_cc(); break; case 0x13: /* SUBT */ if (c && f) ! gen_cond_sub[c](); ! /* gen_cond_trap(); */ ! gen_op_sub_T1_T0_cc(); break; case 0x33: /* SUBTO */ + gen_op_eval_sub_sv(); + /* gen_op_overflow_trap(); */ if (c && f) ! gen_cond_sub[c](); ! /* gen_cond_trap(); */ ! gen_op_sub_T1_T0_cc(); break; case 0x14: /* SUBB */ + if (c && f) + gen_cond_subb[c](); gen_op_subb_T1_T0_cc(); break; case 0x34: /* SUBBO */ ! gen_op_eval_subb_sv(); ! /* gen_op_overflow_trap(); */ ! if (c && f) ! gen_cond_subb[c](); ! gen_op_subb_T1_T0_cc(); break; case 0x11: /* DS */ + /* if (c && f) + gen_cond_ds[c](); */ gen_op_ds_T1_T0(); break; *************** *** 1427,1431 **** case 0x22: /* COMCLR */ if (c && f) ! gen_cond_cmp[c](); gen_movl_T0_im(0); break; --- 1477,1481 ---- case 0x22: /* COMCLR */ if (c && f) ! gen_cond_sub[c](); gen_movl_T0_im(0); break; *************** *** 1716,1720 **** disp = (((w1 << 1) | w) << 2); ! gen_cond_cmp[c](); gen_branch_cond(dc, (long)dc->tb, disp, n, 0); --- 1766,1770 ---- disp = (((w1 << 1) | w) << 2); ! gen_cond_sub[c](); gen_branch_cond(dc, (long)dc->tb, disp, n, 0); Index: op.c =================================================================== RCS file: /cvsroot/hppaqemu/hppaqemu/target-hppa/op.c,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** op.c 13 Mar 2007 05:57:44 -0000 1.23 --- op.c 16 Mar 2007 20:58:57 -0000 1.24 *************** *** 782,785 **** --- 782,793 ---- /* Compare operations */ + #define signed_overflow_add(op1, op2, res) \ + ((((int32_t)(op1) < 0) == ((int32_t)(op2) < 0)) && \ + (((int32_t)(op1) < 0) != ((int32_t)(res) < 0))) + + #define signed_overflow_sub(op1, op2, res) \ + ((((int32_t)(op1) < 0) != ((int32_t)(op2) < 0)) && \ + (((int32_t)(op1) < 0) != ((int32_t)(res) < 0))) + void OPPROTO op_eval_never(void) { *************** *** 799,803 **** void OPPROTO op_eval_add_eq(void) { ! T2 = (T0 == -T1); } --- 807,812 ---- void OPPROTO op_eval_add_eq(void) { ! uint32_t res = T0 + T1; ! T2 = (res == 0); } *************** *** 805,809 **** void OPPROTO op_eval_add_slt(void) { ! T2 = ((int32_t)T0 < -(int32_t)T1); } --- 814,819 ---- void OPPROTO op_eval_add_slt(void) { ! int32_t res = T0 + T1; ! T2 = ((res < 0) != signed_overflow_add(T0, T1, res)); } *************** *** 811,815 **** void OPPROTO op_eval_add_slteq(void) { ! T2 = ((int32_t)T0 <= -(int32_t)T1); } --- 821,826 ---- void OPPROTO op_eval_add_slteq(void) { ! int32_t res = T0 + T1; ! T2 = ((res == 0) || ((res < 0) != signed_overflow_add(T0, T1, res))); } *************** *** 817,821 **** void OPPROTO op_eval_add_nuv(void) { ! T2 = (T0 + T1 >= T0); } --- 828,833 ---- void OPPROTO op_eval_add_nuv(void) { ! uint32_t res = T0 + T1; ! T2 = (res >= T0); } *************** *** 823,827 **** void OPPROTO op_eval_add_znv(void) { ! T2 = ((T0 + T1 == 0) || (T0 + T1 >= T0)); } --- 835,840 ---- void OPPROTO op_eval_add_znv(void) { ! uint32_t res = T0 + T1; ! T2 = ((res == 0) || (res >= T0)); } *************** *** 829,845 **** void OPPROTO op_eval_add_sv(void) { ! if ((((int32_t)T0 < 0) == ((int32_t)T1 < 0)) && ! (((int32_t)T0 < 0) != ((int32_t)(T0 + T1) < 0))) ! T2 = 0; else ! T2 = 1; FORCE_RET(); } /* od */ ! void OPPROTO op_eval_add_od(void) { ! T2 = ((T0 + T1) & 1); } --- 842,914 ---- void OPPROTO op_eval_add_sv(void) { ! int32_t res = T0 + T1; ! T2 = signed_overflow_add(T0, T1, res); ! FORCE_RET(); ! } ! ! /* od */ ! void OPPROTO op_eval_add_od(void) ! { ! uint32_t res = T0 + T1; ! T2 = (res & 1); ! } ! ! /* Addition conditions with carry */ ! ! /* = */ ! void OPPROTO op_eval_addc_eq(void) ! { ! uint32_t res = T0 + T1 + !!(env->psw & PSW_CB7); ! T2 = (res == 0); ! } ! ! /* < */ ! void OPPROTO op_eval_addc_slt(void) ! { ! int32_t res = T0 + T1 + !!(env->psw & PSW_CB7); ! T2 = ((res < 0) != signed_overflow_add(T0, T1, res)); ! } ! ! /* <= */ ! void OPPROTO op_eval_addc_slteq(void) ! { ! int32_t res = T0 + T1 + !!(env->psw & PSW_CB7); ! T2 = ((res == 0) || ((res < 0) != signed_overflow_add(T0, T1, res))); ! } ! ! /* nuv */ ! void OPPROTO op_eval_addc_nuv(void) ! { ! uint32_t res = T0 + T1 + !!(env->psw & PSW_CB7); ! if (env->psw & PSW_CB7) ! T2 = (res > T0); else ! T2 = (res >= T0); ! FORCE_RET(); ! } + /* znv */ + void OPPROTO op_eval_addc_znv(void) + { + uint32_t res = T0 + T1 + !!(env->psw & PSW_CB7); + if (env->psw & PSW_CB7) + T2 = ((res == 0) || (res > T0)); + else + T2 = ((res == 0) || (res >= T0)); FORCE_RET(); } + /* sv */ + void OPPROTO op_eval_addc_sv(void) + { + int32_t res = T0 + T1 + !!(env->psw & PSW_CB7); + T2 = signed_overflow_add(T0, T1, res); + } + /* od */ ! void OPPROTO op_eval_addc_od(void) { ! uint32_t res = T0 + T1 + !!(env->psw & PSW_CB7); ! T2 = (res & 1); } *************** *** 849,897 **** /* = */ ! void OPPROTO op_eval_cmp_eq(void) { ! T2 = (T0 == T1); } /* < */ ! void OPPROTO op_eval_cmp_slt(void) { ! T2 = ((int32_t)T0 < (int32_t)T1); } /* <= */ ! void OPPROTO op_eval_cmp_slteq(void) { ! T2 = ((int32_t)T0 <= (int32_t)T1); } /* << */ ! void OPPROTO op_eval_cmp_ult(void) { ! T2 = (T0 < T1); } /* <<= */ ! void OPPROTO op_eval_cmp_ulteq(void) { ! T2 = (T0 <= T1); } /* sv */ ! void OPPROTO op_eval_cmp_sv(void) { ! if ((((int32_t)T0 < 0) != ((int32_t)T1 < 0)) && ! (((int32_t)T0 < 0) != ((int32_t)(T0 - T1) < 0))) ! T2 = 1; ! else ! T2 = 0; ! FORCE_RET(); } /* od */ ! void OPPROTO op_eval_cmp_od(void) { ! T2 = ((T0 - T1) & 1); } --- 918,1018 ---- /* = */ ! void OPPROTO op_eval_sub_eq(void) { ! uint32_t res = T0 - T1; ! T2 = (res == 0); } /* < */ ! void OPPROTO op_eval_sub_slt(void) { ! int32_t res = T0 - T1; ! T2 = ((res < 0) != signed_overflow_sub(T0, T1, res)); } /* <= */ ! void OPPROTO op_eval_sub_slteq(void) { ! int32_t res = T0 - T1; ! T2 = ((res == 0) || ((res < 0) != signed_overflow_sub(T0, T1, res))); } /* << */ ! void OPPROTO op_eval_sub_ult(void) { ! uint32_t res = T0 - T1; ! T2 = (res < 0); } /* <<= */ ! void OPPROTO op_eval_sub_ulteq(void) { ! uint32_t res = T0 - T1; ! T2 = ((res == 0) || (res < T0)); } /* sv */ ! void OPPROTO op_eval_sub_sv(void) { ! int32_t res = T0 - T1; ! T2 = signed_overflow_sub(T0, T1, res); ! } ! /* od */ ! void OPPROTO op_eval_sub_od(void) ! { ! int32_t res = T0 - T1; ! T2 = (res & 1); ! } ! ! /* Compare operations with borrow */ ! ! /* = */ ! void OPPROTO op_eval_subb_eq(void) ! { ! uint32_t res = T0 - T1 - !(env->psw & PSW_CB7); ! T2 = (res == 0); ! } ! ! /* < */ ! void OPPROTO op_eval_subb_slt(void) ! { ! int32_t res = T0 - T1 - !(env->psw & PSW_CB7); ! T2 = ((res < 0) != signed_overflow_sub(T0, T1, res)); ! } ! ! /* <= */ ! void OPPROTO op_eval_subb_slteq(void) ! { ! int32_t res = T0 - T1 - !(env->psw & PSW_CB7); ! T2 = ((res == 0) || ((res < 0) != signed_overflow_sub(T0, T1, res))); ! } ! ! /* << */ ! void OPPROTO op_eval_subb_ult(void) ! { ! uint32_t res = T0 - T1 - !(env->psw & PSW_CB7); ! T2 = (res < 0); ! } ! ! /* <<= */ ! void OPPROTO op_eval_subb_ulteq(void) ! { ! uint32_t res = T0 - T1 - !(env->psw & PSW_CB7); ! T2 = ((res == 0) || (res < T0)); ! } ! ! /* sv */ ! void OPPROTO op_eval_subb_sv(void) ! { ! int32_t res = T0 - T1 - !(env->psw & PSW_CB7); ! T2 = signed_overflow_sub(T0, T1, res); } /* od */ ! void OPPROTO op_eval_subb_od(void) { ! int32_t res = T0 - T1 - !(env->psw & PSW_CB7); ! T2 = (res & 1); } |