Hello everybody,
in the master branch, marss/ptlsim/x86/decode-complex.cpp, lines 942+,
W64 l_assist_popcnt(Context& ctx, W64 ra, W64 rb, W64 rc, W16 raflags,
W16 rbflags, W16 rcflags, W16& flags) {
W64 sizeshift = rb;
setup_qemu_switch_except_ctx(ctx);
ctx.setup_qemu_switch();
helper_popcnt(ra,sizeshift);
setup_ptlsim_switch_all_ctx(ctx);
return 0;
}
which is called via line 2731+ in the same file,
TransOp ast(OP_ast, rdreg, rareg, REG_zero, REG_zero, sizeshift);
ast.riptaken = L_ASSIST_POPCNT;
The assist function always sets the instruction's destination register to 0.
A fix is simply:
W64 l_assist_popcnt(Context& ctx, W64 ra, W64 rb, W64 rc, W16 raflags,
W16 rbflags, W16 rcflags, W16& flags) {
W64 sizeshift = rb;
setup_qemu_switch_except_ctx(ctx);
ctx.setup_qemu_switch();
W64 n = helper_popcnt(ra,sizeshift);
setup_ptlsim_switch_all_ctx(ctx);
return n;
}
Furthermore, the implementation does not seem to set the flags according to the
operation's result:
http://lists.gnu.org/archive/html/qemu-devel/2008-10/msg00154.html
The operation also might have a somewhat non-standard register encoding:
https://lists.gnu.org/archive/html/qemu-devel/2012-10/msg01224.html
I've come across this bug when investigating a division by 0 exception in the
Linux kernel caused by it, in the scheduler's do_balance_runtime() function. In
order to get Linux to print a core dump helping me track down the issue instead
of MARSS stopping on an unsupported internal exception assertion, I added
case Exception_DivideOverflow:
ctx.exception_index = EXCEPTION_x86_divide;
ctx.page_fault_addr = ctx.eip;
break;
to marss/ptlsim/core/ooo.cpp at line 1474.
Regards,
gunnar.
_______________________________________________
http://www.marss86.org
Marss86-Devel mailing list
[email protected]
https://www.cs.binghamton.edu/mailman/listinfo/marss86-devel