Daniel Jacobowitz <[EMAIL PROTECTED]> writes: > You don't need anything near this complicated: if the register being > set is the base register, copy it into T2 instead of overwriting the > base register. Then at the end, if the base register was loaded, copy > T2 into the base register. That's all the atomicity you need; the > instruction is being restarted after the base register was clobbered.
Eee.. I knew that. I was just.. practicing my fingers (ahem.. is there a saying in english about how the whole body suffers from a stupid head? :-) Something like this? Index: target-arm/op.c =================================================================== RCS file: /sources/qemu/qemu/target-arm/op.c,v retrieving revision 1.17 diff -u -r1.17 op.c --- target-arm/op.c 26 Nov 2005 10:46:39 -0000 1.17 +++ target-arm/op.c 19 Dec 2005 19:14:45 -0000 @@ -106,6 +106,11 @@ T0 = T1; } +void OPPROTO op_movl_T2_T0(void) +{ + T2 = T0; +} + void OPPROTO op_movl_T1_im(void) { T1 = PARAM1; @@ -1175,3 +1180,18 @@ } FORCE_RET(); } + +void OPPROTO op_movl_user_T2(void) +{ + int regno = PARAM1; + if (regno == 13) { + env->banked_r13[0] = T2; + } else if (regno == 14) { + env->banked_r14[0] = T2; + } else if ((env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) { + env->usr_regs[regno - 8] = T2; + } else { + env->regs[regno] = T2; + } + FORCE_RET(); +} Index: target-arm/op_template.h =================================================================== RCS file: /sources/qemu/qemu/target-arm/op_template.h,v retrieving revision 1.2 diff -u -r1.2 op_template.h --- target-arm/op_template.h 31 Jan 2005 20:43:28 -0000 1.2 +++ target-arm/op_template.h 19 Dec 2005 19:14:45 -0000 @@ -48,6 +48,11 @@ SET_REG (T1); } +void OPPROTO glue(glue(op_movl_, REGNAME), _T2)(void) +{ + SET_REG (T2); +} + #undef REG #undef REGNAME #undef SET_REG Index: target-arm/translate.c =================================================================== RCS file: /sources/qemu/qemu/target-arm/translate.c,v retrieving revision 1.35 diff -u -r1.35 translate.c --- target-arm/translate.c 18 Dec 2005 16:55:25 -0000 1.35 +++ target-arm/translate.c 19 Dec 2005 19:14:46 -0000 @@ -228,7 +228,7 @@ }, }; -static GenOpFunc *gen_op_movl_reg_TN[2][16] = { +static GenOpFunc *gen_op_movl_reg_TN[3][16] = { { gen_op_movl_r0_T0, gen_op_movl_r1_T0, @@ -265,6 +265,24 @@ gen_op_movl_r14_T1, gen_op_movl_r15_T1, }, + { + gen_op_movl_r0_T2, + gen_op_movl_r1_T2, + gen_op_movl_r2_T2, + gen_op_movl_r3_T2, + gen_op_movl_r4_T2, + gen_op_movl_r5_T2, + gen_op_movl_r6_T2, + gen_op_movl_r7_T2, + gen_op_movl_r8_T2, + gen_op_movl_r9_T2, + gen_op_movl_r10_T2, + gen_op_movl_r11_T2, + gen_op_movl_r12_T2, + gen_op_movl_r13_T2, + gen_op_movl_r14_T2, + gen_op_movl_r15_T2, + }, }; static GenOpFunc1 *gen_op_movl_TN_im[3] = { @@ -1665,8 +1683,11 @@ if (insn & (1 << 20)) { /* load */ gen_ldst(ldl, s); - if (i == 15) { - gen_bx(s); + if (i == 15) { + /* later */ + } else if (i == rn) { + /* base register */ + gen_op_movl_T2_T0(); } else if (user) { gen_op_movl_user_T0(i); } else { @@ -1691,6 +1712,19 @@ gen_op_addl_T1_im(4); } } + if (insn & (1 << 20)) { + /* check if base register and pc were loaded */ + if (insn & (1 << rn)) { + if (user) + gen_op_movl_user_T2(rn); + else + gen_op_movl_reg_TN[2][rn](); + } + if (insn & (1 << 15)) { + /* r15 is loaded last - value should be in T0 */ + gen_bx(s); + } + } if (insn & (1 << 21)) { /* write back */ if (insn & (1 << 23)) { -- http://www.iki.fi/~ananaza/ _______________________________________________ Qemu-devel mailing list Qemu-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/qemu-devel